---
title: Agent 循环与工具使用
url: https://doc.liz6.com/ai/02-Agent/01-the-agent-loop-and-tool-use
locale: zh
area: ai
tags:
- ai
- Agent
date: 2026-06-30
modified: 2026-07-16
description: agent 和聊天机器人的本质区别不在于模型更聪明,而在于多了一个循环:模型决策→宿主执行→观察结果→再决策。模型自己不执行任何东西——安全边界、权限、审计全落在宿主这一侧。
---

# 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 循环

```mermaid
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 交互里发生的事:

1. 宿主给模型一组**工具定义**(schema)+ 当前对话。
2. 模型回一个响应。若它想用工具,响应里带 `tool_use` block,`stop_reason: "tool_use"`。
3. 宿主**执行**该工具,把输出包成 `tool_result`(带上对应的 `tool_use_id`)塞回 messages。
4. 再次请求模型。重复,直到 `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:

```json
{
  "name": "get_weather",
  "description": "Get current weather for a location. 当用户问当前天气时调用。",
  "input_schema": {
    "type": "object",
    "properties": { "location": {"type": "string", "description": "City, e.g. 北京"} },
    "required": ["location"]
  }
}
```

工具的**名字、描述、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 缓存,见 [上下文工程](/ai/01-models-and-context/01-context-engineering.md))。

## 控制循环:别让它跑飞

裸循环很容易出事。生产里要加这些闸:

- **迭代上限**:`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 | 错了能被发现和回滚?(有测试/审查/回退) |

## 最佳实践

- **记住模型从不执行,宿主才执行。** 安全边界、权限、审计全在宿主侧——这一点决定后面所有工程取舍(见 [安全与防护](/ai/03-applications-and-production/04-security-and-protection.md))。
- **工具描述写清"何时用",不只"做什么"。** 模型靠描述决定何时调,写明触发条件能显著提升该调就调的命中率。
- **错误当观察喂回,别当异常崩。** 失败返回 `tool_result` + `is_error:true` + 一句人话,模型会改路。
- **并行结果放进同一条 user 消息回传。** 拆成多条会悄悄训练模型不再并行。
- **少而精,工具多了用 tool search 按需加载。** 既防选错,又保 [prompt 缓存](/ai/01-models-and-context/01-context-engineering.md)。
- **裸循环要加闸。** 迭代上限、token 预算、危险动作 human-in-the-loop、bash 沙箱白名单。
- **先 bash 求广度,需把关/渲染/审计/并行再提升为专用工具。**
- **能 workflow 写死的别上 agent。** 过复杂度/价值/可行性/错误代价四关再动手。

## 权衡与失败模式

- **死循环**:模型反复调同一工具不收敛 → 迭代上限 + 在 tool_result 里给出更明确的下一步。
- **幻觉工具调用**:调一个不存在的工具或瞎编参数 → 严格 schema(`strict: true`)、清晰描述、tool_choice 约束。
- **观察撑爆上下文**:某次工具输出几万行,把窗口顶满 → 在宿主侧截断/摘要工具输出,或用 context editing 清理旧结果(见 [上下文工程](/ai/01-models-and-context/01-context-engineering.md))。

## 这正是日常在用的循环

[Claude Code](/) 本身就是这个循环:它把 `read`/`write`/`edit`/`bash`/`grep`/`glob` 等做成工具,模型决策、它执行、结果喂回。OMC(oh-my-claudecode)则在这个循环之上做**多 agent 编排**——把探索、规划、执行、审查拆给不同 agent。理解了循环,这些上层框架就只是"循环 + 调度策略"。

另一种形态是 **Managed Agents**:由 Anthropic **托管整个循环**并提供每个 session 一个容器作为工作区(bash/文件/代码在容器里跑,循环在 Anthropic 编排层跑)。它的铁律是:

<svg viewBox="0 0 720 180" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,'Source Han Sans CN','Microsoft YaHei',sans-serif" role="img" aria-label="Managed Agents 的铁律:Agent 持久对象,创建一次;Session 每次运行只引用 agent_id">
  <defs><marker id="masah" markerWidth="10" markerHeight="8" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#475569"/></marker></defs>
  <rect width="720" height="180" fill="#ffffff"/>
  <text x="360" y="28" text-anchor="middle" font-size="17" font-weight="700" fill="#1f2933">Managed Agents 的铁律:Agent 持久,Session 一次性</text>
  <rect x="60" y="56" width="240" height="76" rx="8" fill="#4f46e5"/>
  <text x="180" y="84" text-anchor="middle" font-size="14" font-weight="700" fill="#ffffff">Agent</text>
  <text x="180" y="103" text-anchor="middle" font-size="11" fill="#e0e7ff">创建一次,存 agent_id</text>
  <text x="180" y="119" text-anchor="middle" font-size="11" fill="#e0e7ff">model / system / tools 挂在这层</text>
  <line x1="300" y1="94" x2="416" y2="94" stroke="#475569" stroke-width="1.8" marker-end="url(#masah)"/>
  <rect x="420" y="56" width="240" height="76" rx="8" fill="#0d9488"/>
  <text x="540" y="84" text-anchor="middle" font-size="14" font-weight="700" fill="#ffffff">Session</text>
  <text x="540" y="103" text-anchor="middle" font-size="11" fill="#ccfbf1">每次运行</text>
  <text x="540" y="119" text-anchor="middle" font-size="11" fill="#ccfbf1">只引用 agent_id,不重建</text>
  <rect x="60" y="146" width="600" height="26" rx="6" fill="#f0fdfa"/>
  <text x="72" y="164" font-size="12" fill="#115e59">别在每次运行时 agents.create() ——agent 是带版本的持久对象,创建一次、反复引用。</text>
</svg>

别在每次运行时 `agents.create()`(会堆积孤儿 agent);agent 是带版本的持久对象,创建一次、反复引用。

## 前沿:训练 agent 的"模拟器" —— Qwen-AgentWorld

上面讲的 agent,是在**真实环境**里跑循环——真的调 API、真的执行命令。有一条前沿研究反过来问:能不能训一个模型,让它去**扮演那个环境**?让 agent 模型和它交互,就像在和真环境交互一样?

阿里的 [Qwen-AgentWorld-35B-A3B](https://huggingface.co/Qwen/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 循环。详见[模型架构](/ai/01-models-and-context/03-model-architecture-dense-vs-moe.md)中激活参数与推理深度的讨论。

### 怎么衡量一个 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](https://huggingface.co/Qwen/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*
