# 第十一章 Agent、工具与行动系统

Chapter from the Chinese-language book Anatomy of the Stochastic Parrot: 第十一章 Agent、工具与行动系统.

## Metadata

- HTML: https://glenzli.com/en/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-01/ch11-agents-tools-systems/
- Markdown: https://glenzli.com/en/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-01/ch11-agents-tools-systems.md
- Collection: Dr. Stochastic Parrot
- Language: en
- Published: 2026-07-17
- Status: published
- Tags: ai-generated, stochastic-parrot, stochastic-parrot-anatomy, ai

## Content

语言模型生成候选 token；Agent 系统把模型放入一个带状态、工具和停止条件的循环。Agent 的能力因此来自模型、上下文、运行时、工具和环境的组合，而不是参数文件新增了一种人格。

![Agent 系统中的模型、运行时、工具与外部世界](/images/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-01/chapter-06/images/agent_system_stack.svg)

## 11.1 最小 Agent 循环

一个最小循环可以写成：

```text
state <- task, context, prior events
while not stopped:
    observation <- runtime observes state
    proposal <- model(observation, available tools)
    checked_action <- runtime validates proposal
    result <- execute or reject checked_action
    state <- update(state, proposal, result)
```

模型负责提出内容，运行时负责解析、验证、授权、执行和记录。把两者分开后，模型输出非法参数不必等于现实工具被非法调用。

更精确地，令运行时状态为 $s_t\in\mathcal S$，可见观察为 $o_t=\operatorname{Obs}(s_t)$，模型提议为

$$
u_t\sim M_\theta(\cdot\mid o_t,\mathcal T_t),
$$

其中 $\mathcal T_t$ 是本轮可见工具接口。运行时判定器不返回布尔值，而返回带类型的结果：

$$
\operatorname{Check}(s_t,u_t)
\in
\{\operatorname{Reject}(e),
\operatorname{AwaitApproval}(a),
\operatorname{Executable}(a)\}.
$$

只有 $\operatorname{Executable}(a)$ 可以进入环境执行器；执行得到回执 $r_t$ 或未知结果，再由确定的状态归约器

$$
s_{t+1}=\delta(s_t,u_t,\operatorname{status}_t,r_t)
$$

写入事件和 artifact。模型可以是随机的，权限判定、预算扣减和提交状态机仍应由运行时确定地执行。

循环至少要有三个停止来源：任务完成谓词、不可恢复失败和资源预算耗尽。最大轮数只是最后一道边界；可靠系统还维护循环不变量，例如“已执行动作都在当前 capability 集中”“提交的动作摘要与批准摘要一致”“预算不为负”“未知提交不会被当成未发生”。

![Agent 的观察、提议、执行与状态更新循环](/images/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-01/chapter-06/images/agent_control_loop.svg)

## 11.2 工具调用是什么

工具通常由名称、说明和参数 schema 暴露给模型。模型生成结构化候选，例如：

```json
{
  "tool": "search_flights",
  "arguments": {"flight": "SP404", "date": "2026-07-19"}
}
```

这段 JSON 只是提议。运行时必须依次完成有界解析、版本化 schema 校验、语义规范化、对象级授权、动作摘要绑定和提交前复检。顺序很重要：先审批自然语言摘要、后解析真实收件人会产生检查—使用时间差；资源在 preview 与 commit 之间变化时，也要重新验证版本或前置条件。若工具有副作用，必须区分 preview、approval 和 commit。字段级状态转换与失败分支由[卷二第六章](/en/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-02/ch06-tools-runtime-boundary/)沿一次调用展开。

协议标准可以统一工具、资源和消息接口，但不会自动解决工具是否可信、用户是否授权或调用是否可撤销。MCP 等协议的作用范围见[卷内来源说明](/en/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-01/SOURCE-NOTES/#ref-mcp-2025-11-25)。

## 11.3 ReAct、规划与反思

ReAct 把中间推理或任务状态与行动交替组织，使模型根据工具返回继续决策。常见编排还包括：

- planner-executor：规划与执行角色分开；
- router：先选择专用模型或工具；
- graph workflow：把允许转移预先写成图；
- agents-as-tools：主 Agent 把子任务委托给另一个受限 Agent；
- verifier loop：候选结果经测试或验证器检查后再提交。

更多循环不保证更好。每轮都会增加延迟、费用、上下文长度和错误机会。反思文本也可能只是再次生成，而不是独立证据。

还要区分 **workflow** 与 **policy**。workflow 的允许节点和边由程序预先定义，模型只在局部参数或分支中选择；policy 则让模型在较大动作集合中决定下一步。前者牺牲开放性换取可枚举状态和明确恢复点，后者覆盖长尾任务却更依赖运行时约束。把固定图编排宣传成“自主 Agent”，或把开放循环当成确定工作流，都会误导风险判断。

planner 生成的计划只是候选数据。执行器必须根据当前状态逐步验证；旧计划中的权限、文件版本和外部价格都可能已经变化。验证器若与生成器共享模型、提示和上下文，只能算重复采样，不能自动视为独立证明。

## 11.4 状态、记忆与 Artifact

长任务不能只靠聊天记录。运行时通常需要保存：

- 当前目标和完成条件；
- 已确认参数；
- 工具调用及返回；
- 生成或修改的 artifact；
- 待审批动作；
- 重试和未知结果；
- 预算和停止原因。

Artifact 应有明确类型，例如文件 diff、查询结果、计划、测试日志或草稿。把所有中间内容压成自然语言摘要会丢失可执行结构，也会让后续模型把猜测当成已发生事件。

状态更新适合采用追加事件而不是反复覆盖一段总结。事件至少含 `event_id`、父事件、主体、动作摘要、状态、时间和 artifact digest；当前状态由事件归约得到。这样可以重放“为什么进入当前状态”，并把模型声称“已经发送”与执行器记录的 `ACKNOWLEDGED` 区分。自然语言摘要仍可作为读取优化，但不能成为唯一事实源。

## 11.5 工具结果是不可信输入

网页、邮件、文档和工具返回可能包含恶意或错误文本。它们是数据通道，不应因为进入上下文就获得系统指令的权力。间接 prompt injection 的典型模式是：有权限的 Agent 读取攻击者控制的内容，再用自己的发送、读取或支付能力替攻击者行动。

防护需要多层组合：

1. 标记来源和通道；
2. 工具能力按任务最小化；
3. 高风险参数由独立策略检查；
4. 审批绑定具体动作，而非笼统询问“是否继续”；
5. 秘密不直接暴露给模型；
6. 所有真实提交经过唯一运行时入口。

这些是正常安全工程，不需要假设模型具有恶意意图。

![Agent 中可信指令、不可信数据与工具能力的边界](/images/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-01/chapter-06/images/agent_trust_boundaries.svg)

## 11.6 权限应绑定动作

工具权限不能只按工具名称授予。“可以发邮件”仍需限制账户、收件人、次数、附件、时间和用途；“可以运行命令”仍需限制目录、网络、系统调用、凭据和资源。

能力最好表示为不可伪造的运行时句柄，而不是提示里的工具名称。若父 Agent 的能力集为 $C_p$，任务允许集为 $C_{\mathrm{task}}$，则子 Agent 应满足

$$
C_c\subseteq C_p\cap C_{\mathrm{task}}.
$$

还要约束资源、动作、时限、次数和委托深度。复制父 Agent 的全部凭据会扩大攻击面，也使后续无法判断哪个主体实际使用了权限。

这也是 confused deputy 问题：攻击者自己没有发送或读取权限，却诱导一个有权限的 Agent 代为执行。运行时必须同时检查“调用者有何能力”和“当前用户是否授权这个具体用途”，不能因为工具凭据有效就跳过委托链。

## 11.7 幂等、重试与未知提交

网络超时不能说明操作未发生。支付、写文件或发送消息可能已经提交，只是回执丢失。对可重试副作用，客户端应提供稳定幂等键 $k$：

```text
prepare(action, k)
-> approve(action digest)
-> commit(action, k)
-> query_status(k) when response is unknown
```

重试时沿用同一个 $k$，先查询状态，再决定是否继续。生成一个新键并盲目重试会造成重复付款、重复消息或重复写入。

幂等键只有在服务端持久保存“键—结果”映射、并把参数摘要纳入冲突检查时才提供 at-most-once 效果。客户端本地生成一个 UUID 本身没有语义。对不支持幂等或状态查询的外部系统，在“副作用已发生、确认尚未持久化”之间崩溃后，通常无法保证端到端 exactly-once；正确状态是 `UNKNOWN`，而不是猜测成功或失败。

跨多个系统的任务可使用 saga：每个已提交步骤配一个尽力而为的补偿动作，例如取消预订或发出更正消息。补偿不是时间倒流：邮件可能已被阅读，价格可能变化，物理动作不可撤销。一次调用的精确状态、幂等契约和重试矩阵见[卷二第六章](/en/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-02/ch06-tools-runtime-boundary/#62-工具调用状态机)。

## 11.8 代码执行与沙箱

代码 Agent 会读取仓库、运行构建脚本、加载依赖并产生文件。沙箱至少限制文件系统、网络、进程、系统调用、凭据、时间、内存和输出大小。

“在临时目录运行”不等于隔离：仓库脚本可能读取宿主挂载，依赖安装可能执行供应链代码，编译器插件也可能启动子进程。隔离边界要与威胁模型匹配：容器共享宿主内核，虚拟机边界更强却更重；禁网环境仍可能通过预挂载凭据和输出通道泄露信息。运行记录应保存实际命令、环境、镜像或工具链版本、资源限制和退出状态。

模型不应直接持有长期云凭据。运行时可按动作签发短时、限资源 token，并在提交后撤销。读取权限与写入权限应分离；“测试需要访问生产数据库”必须成为显式例外，而不是继承宿主环境变量。

## 11.9 可观测性

长任务失败时，仅保存最终聊天文本几乎无法诊断。最小事件记录包括：

- 模型和运行配置；
- 上下文摘要及外部来源；
- 工具提议、校验和实际调用；
- 权限与审批结果；
- artifact digest；
- commit、回执和补偿；
- 重试、超时和停止原因。

日志不是越多越好。敏感内容应最小化或脱敏，事件 ID 和因果关系应比重复保存整段上下文更稳定。trace 还要区分提议时间、授权时间、发送时间与确认时间；一个统一的“tool_call succeeded”时间戳无法诊断排队、执行和回执延迟。

可观测性本身不能成为旁路权限。日志查看者、评测平台和调试模型不应自动获得原工具返回中的全部秘密；脱敏规则与日志 schema 也需要版本化。

## 11.10 Agent 怎样评测

最终成功率会隐藏过程风险。至少分开报告：

| 维度 | 问题 |
| --- | --- |
| 任务结果 | 目标是否完成 |
| 工具过程 | 调用、参数和顺序是否正确 |
| 安全 | 是否越权、过度行动或受注入影响 |
| 恢复 | 超时、部分失败和未知提交后能否收束 |
| 成本 | token、工具、时间和人工审批消耗 |

评测应同时覆盖正常任务、对抗输入和故障注入。正常任务测端到端成功与成本；对抗任务在网页、邮件或工具返回中放入越权指令；故障注入模拟超时、重复回执、部分写入、过期凭据和工具 schema 变化。每次试验要固定模型、采样配置、工具版本、初始状态和预算，并报告多次运行的分布，而不只挑选最好轨迹。

开放式 Agent 基准还受训练污染和环境漂移影响。静态题目可能进入训练语料，网页与 API 会在评测期间变化。可执行、隔离且可重置的环境比只凭语言模型裁判更容易复现；仍应保存任务快照和验证脚本。共享底模的多个 Agent 也不是多份独立证据。独立检查需要不同来源、形式验证器、可执行测试或真正不同的失败模式。

本章的研究入口见 [ReAct](/en/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-01/SOURCE-NOTES/#ref-yao-react-2022)、[Toolformer](/en/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-01/SOURCE-NOTES/#ref-schick-toolformer-2023)、[WebArena](/en/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-01/SOURCE-NOTES/#ref-zhou-webarena-2024)、[间接 prompt injection](/en/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-01/SOURCE-NOTES/#ref-greshake-indirect-injection-2023)与 [MCP 规范](/en/dr-stochastic-parrot/stochastic-parrot-anatomy/vol-01/SOURCE-NOTES/#ref-mcp-2025-11-25)。模型与工具怎样在一次具体运行中交替，将在卷二逐事件展开；本卷最后一章先完成模型、数据和部署版本的生命周期。
