本页目录
Agent 循环与工具使用
agent 和聊天机器人的本质区别不在于模型更聪明,而在于多了一个循环:模型决策→宿主执行→观察结果→再决策。模型自己不执行任何东西——安全边界、权限、审计全落在宿主这一侧。
概述
一个 agent 和一个聊天机器人的本质区别,不在于模型更聪明,而在于多了一个循环。聊天机器人是"输入→一次输出";agent 是"输入→决策→调用工具→观察结果→再决策→…→完成"。模型本身没变,变的是宿主(harness)在它外面套了一个反复喂回观察结果的循环。把这件事看清楚,就理解了 Claude Code、Cursor、各种"AI agent"底下其实是同一个骨架。
这件事的历史并不长。2023 年 function calling / tool use 出现,让模型能产出结构化的工具调用而不只是文本;ReAct 这类工作把"推理 + 行动"交织起来;到 2024–2026 年,Anthropic 把这个循环逐步产品化——Claude Code 是它的命令行化身,Managed Agents 则把整个循环搬到服务端托管。理解循环,胜过记住任何一个具体框架。
一个反直觉但关键的事实:模型自己从不执行任何东西。它不会真的去读文件、跑命令、调 API。它只会"说":我想调用 read_file,参数是 {path: ...}。真正去执行的是宿主程序。模型是大脑,宿主是手脚。安全边界、权限、审计,全都落在宿主这一侧——这一点决定了后面所有的工程取舍。
核心:think → act → observe 循环
flowchart TD
M["模型决策 think<br/>产出结构化 tool_use"]
H["宿主执行工具 act"]
O["把结果喂回模型 observe<br/>tool_result"]
E["最终回答"]
M -->|tool_use| H
H -->|tool_result| O
O --> M
M -->|"stop_reason = end_turn (无更多工具调用)"| E
一轮 API 交互里发生的事:
- 宿主给模型一组工具定义(schema)+ 当前对话。
- 模型回一个响应。若它想用工具,响应里带
tool_useblock,stop_reason: "tool_use"。 - 宿主执行该工具,把输出包成
tool_result(带上对应的tool_use_id)塞回 messages。 - 再次请求模型。重复,直到
stop_reason: "end_turn"(模型不再要工具)。
停止条件由 stop_reason 给出,宿主必须分支处理:
| stop_reason | 含义 | 宿主该做什么 |
|---|---|---|
end_turn | 自然结束 | 退出循环 |
tool_use | 想调工具 | 执行工具,喂回 tool_result,继续 |
max_tokens | 撞输出上限 | 调大 max_tokens 或改用流式 |
pause_turn | 服务端工具循环暂停 | 原样回传,服务端自动续 |
refusal | 安全拒绝 | 别原样重试;读 stop_details |
工具是 agent 通往世界的 API
工具定义 = 名字 + 描述 + JSON schema:
工具的名字、描述、schema 比想象中重要得多——它们就是 agent 认识世界的全部接口。模型靠描述决定何时调用,所以描述要写清"在什么情况下用",而不只是"它做什么"。近期 Opus 模型对工具更"克制",在描述里写明触发条件能显著提升该调就调的命中率。
get_weather 只是个最小例子;真实 agent 的工具覆盖各个领域,但都是同一副骨架(名字 + 触发条件描述 + 类型化 schema):
| 领域 | 工具 | schema 关键参数 |
|---|---|---|
| 文件 | read_file / write_file / edit | path、content、old_str/new_str |
| 检索 | search_docs | query、top_k、filter |
| 数据 | query_db | sql(只读)或结构化 table/where |
| 外部 API | send_email / create_pr | to/subject/body、repo/branch |
| 系统 | bash | command(不透明、需重点把关,见下) |
Claude Code 本身就是 read/write/edit/bash/grep/glob 这组工具;本会话接的 context7、code-review-graph(MCP)也以同样形态出现在模型眼里。领域千差万别,模型看到的都是"带类型参数的钩子"——这正是把动作提升成专用工具的价值所在。
几条经手就会踩的原则:
- 错误当观察喂回,别当异常崩。 工具失败时返回
tool_result且is_error: true+ 一句人话错误信息("城市 xyz 不存在,请给有效城市名")。模型会读懂并改路,而不是整个循环挂掉。 - 并行工具调用:一条 assistant 消息可能含多个
tool_use。并发执行后,所有tool_result要放进同一条 user 消息里回传——拆成多条会悄悄训练模型不再并行。 - 少而精:工具太多会让模型选错;工具集大了用 tool search 按需加载,而非一次性全塞(也保护 prompt 缓存,见 上下文工程)。
控制循环:别让它跑飞
裸循环很容易出事。生产里要加这些闸:
- 迭代上限:
max_iterations,防死循环。 - 预算:task budget / 监控累计 token,到顶优雅收尾。
- human-in-the-loop:危险/不可逆动作(发邮件、删数据、
git push)走人工确认——用手动循环在每次工具执行前插审批,或给该工具设"总是询问"权限策略。 - 权限/沙箱:
bash这类工具的命令是不可信的模型输出,要在隔离环境里跑、用可执行程序白名单、设超时、记日志。黑名单不够。
为什么把动作"提升"成专用工具而不是全走 bash?因为 bash 给宿主的只是一个不透明命令串,而专用工具(如 send_email)给的是带类型参数的钩子,宿主能拦截、确认、渲染、审计、并行调度。经验法则:先用 bash 求广度,需要把关/渲染/审计/并行时再提升为专用工具。
workflow 还是 agent?先别急着上 agent
不是所有任务都需要 agent。固定、可完全预先描述的流程,用确定性流水线(workflow)——代码控制每一步、只在需要时调一次模型——比 agent 更稳、更便宜、更可控。
上 agent 前过四道关(任一为否就退回更简单的层):
| 判据 | 问自己 |
|---|---|
| 复杂度 Complexity | 任务多步且无法预先完全规定?("把设计文档变成 PR" 是;"从 PDF 抽标题" 不是) |
| 价值 Value | 结果值得更高的成本与延迟? |
| 可行性 Viability | 模型确实擅长这类任务? |
| 错误代价 Cost of error | 错了能被发现和回滚?(有测试/审查/回退) |
最佳实践
- 记住模型从不执行,宿主才执行。 安全边界、权限、审计全在宿主侧——这一点决定后面所有工程取舍(见 安全与防护)。
- 工具描述写清"何时用",不只"做什么"。 模型靠描述决定何时调,写明触发条件能显著提升该调就调的命中率。
- 错误当观察喂回,别当异常崩。 失败返回
tool_result+is_error:true+ 一句人话,模型会改路。 - 并行结果放进同一条 user 消息回传。 拆成多条会悄悄训练模型不再并行。
- 少而精,工具多了用 tool search 按需加载。 既防选错,又保 prompt 缓存。
- 裸循环要加闸。 迭代上限、token 预算、危险动作 human-in-the-loop、bash 沙箱白名单。
- 先 bash 求广度,需把关/渲染/审计/并行再提升为专用工具。
- 能 workflow 写死的别上 agent。 过复杂度/价值/可行性/错误代价四关再动手。
权衡与失败模式
- 死循环:模型反复调同一工具不收敛 → 迭代上限 + 在 tool_result 里给出更明确的下一步。
- 幻觉工具调用:调一个不存在的工具或瞎编参数 → 严格 schema(
strict: true)、清晰描述、tool_choice 约束。 - 观察撑爆上下文:某次工具输出几万行,把窗口顶满 → 在宿主侧截断/摘要工具输出,或用 context editing 清理旧结果(见 上下文工程)。
这正是日常在用的循环
Claude Code 本身就是这个循环:它把 read/write/edit/bash/grep/glob 等做成工具,模型决策、它执行、结果喂回。OMC(oh-my-claudecode)则在这个循环之上做多 agent 编排——把探索、规划、执行、审查拆给不同 agent。理解了循环,这些上层框架就只是"循环 + 调度策略"。
另一种形态是 Managed Agents:由 Anthropic 托管整个循环并提供每个 session 一个容器作为工作区(bash/文件/代码在容器里跑,循环在 Anthropic 编排层跑)。它的铁律是:
别在每次运行时 agents.create()(会堆积孤儿 agent);agent 是带版本的持久对象,创建一次、反复引用。
前沿:训练 agent 的"模拟器" —— Qwen-AgentWorld
上面讲的 agent,是在真实环境里跑循环——真的调 API、真的执行命令。有一条前沿研究反过来问:能不能训一个模型,让它去扮演那个环境?让 agent 模型和它交互,就像在和真环境交互一样?
阿里的 Qwen-AgentWorld-35B-A3B 做的就是这件事。注意:它不是一个 agent。 它不调用工具、不执行命令、不产生最终答案。它是一个 world model——扮演环境的角色,接收 agent 的动作,预测环境应该返回什么观察。角色类比:强化学习里 gym 的 simulator,不是在 simulator 里训练的 policy。
架构与训练
基于 Qwen3.5-35B-A3B-Base,MoE 架构:35B 总参,256 个专家,每 token 激活 8 routed + 1 shared(约 3B 激活参数)。40 层,采用混合注意力:10 个重复块,每块 = 3×(Gated DeltaNet→MoE)→1×(Gated Attention→MoE)。Gated DeltaNet 是一种线性注意力变体,把长序列注意力的 O(n²) 降到近线性,支撑 256K 上下文。
三段训练使其成为 native world model(从预训练阶段就以环境建模为目标,不是给通用 LLM 事后加的能力):CPT(注入环境知识)→SFT(激活 next-state 预测推理)→RL/GSPO(提升模拟保真度)。
模拟七类环境
覆盖 MCP(tool calling)、Search、Terminal、软件工程(SWE)、Android、Web、OS——文本和 GUI 交互环境统一在一个模型里。Agent 向它发起动作,它用 <think> 块推理环境状态变迁后,输出观察作为响应。这正好是 agent 循环里 "observe" 那一环。
为什么有价值
agent 的训练和评估卡在"环境"上——真环境慢、贵、有副作用、不可复现。一个 world model 能用语言可控地模拟这些环境:不仅复现真实场景,还能构造真实环境不存在的情景(可控扰动、虚构世界),让 agent 在不可能用真环境实验的条件下做试错、跑 RL、做评估。它还展现出零样本泛化:对训练中未见过的环境(如 OpenClaw)也能提供有意义的模拟。
为什么 3B 激活做 world model 行,做 agent 却不行
AgentWorld 做的是单步 next-state 预测:收到一个动作,预测环境返回什么观察。这是单步推理——不需要在脑中维持"我第一步做了什么、第二步该做什么"的串行链条。而 agent 的工具调用是多步串行推理——每一步的决策依赖前一步的结果和初始意图。3B 激活参数的单步推理能力足够做 next-state 预测,但撑不住需要维持意图一致性的多步 agent 循环。详见模型架构中激活参数与推理深度的讨论。
怎么衡量一个 world model 好不好
AgentWorldBench 用五维评分(Format / Factuality / Consistency / Realism / Quality)按环境域打分量化为 0–100,总体均值 56.39。参照:GPT-5.4 为 58.25,Claude Opus 4.8 为 56.59——一个仅 3B 激活参数的语言世界模型,在模拟保真度上几乎持平最强的通用模型,远超同尺寸基座 Qwen3.5-35B-A3B(47.73)。这也意味着 world model 这条路不需要数据中心级别的算力:消费级硬件就能跑一个看得过去的 agent 仿真环境。
参考
- Anthropic 官方文档: Tool Use Overview、Building Effective Agents、Managed Agents(platform.claude.com)
- 研究: "ReAct: Synergizing Reasoning and Acting in Language Models" (Yao et al., 2022)
- 前沿模型: Qwen-AgentWorld-35B-A3B
Keywords: agent loop, think-act-observe, tool use, function calling, tool schema, tool_result, stop_reason, end_turn, parallel tool use, is_error, human-in-the-loop, workflow vs agent, Managed Agents, agent toolset, world model, Qwen-AgentWorld, AgentWorldBench, MoE