深色模式
Agent 核心概念与 ReAct 范式
摘要:本文面向需要把大模型从「问答工具」升级为「能调用工具、能执行多步任务」的工程团队。先厘清 Agent 与训练/微调/推理/RAG/工具调用的边界,再拆解 ReAct(Reasoning + Acting)这一最经典的控制流范式(Thought-Action-Observation 循环),最后给出可运行的最小闭环示例与生产落地的安全、成本要点。适用模型:支持工具调用(tool use / function calling)的 LLM,如 Claude 4 Sonnet(200K 上下文)、GPT-4o/4.1 系列;具体模型名与上下文长度见各章标注
[版本相关]。
核心概念:Agent 到底是什么
在 LLM 语境下,Agent(智能体) 指「以 LLM 为推理核心、能感知环境、能调用工具、能根据反馈自我修正以完成目标」的系统。它区别于一次性生成文本的单轮推理,关键在于 循环(loop) 与 动作(action)。
先厘清几个容易混用的术语边界(生产沟通中必须对齐):
| 术语 | 本质 | 是否改变模型权重 | 是否调用外部工具 | 典型触发 |
|---|---|---|---|---|
| 训练 (Training) | 从数据学习参数 | 是 | 否 | 离线、GPU 集群 |
| 微调 (Fine-tuning) | 在预训练基础上适配 | 是 | 否 | 离线、特定语料 |
| 推理 (Inference) | 用固定权重生成 | 否 | 否(除非配合 Agent) | 线上请求 |
| RAG | 检索增强生成 | 否 | 仅检索 | 每次请求前检索 |
| 工具调用 (Tool Calling) | 模型输出结构化调用 | 否 | 是 | 模型决定 |
| Agent | 多步循环 + 工具 + 状态 | 否 | 是(多次) | 目标驱动 |
Agent 的最小定义
一个 Agent 至少包含三要素:推理核心(LLM)、可执行动作(工具/环境)、状态与记忆(上下文或外部存储)。缺少任一,要么退化为单次推理,要么退化为脚本。
架构与原理:ReAct 范式
ReAct(Yao et al., 2022,arXiv:2210.03629,ICLR 2023)把「链式思考(CoT)」与「动作执行」交错进行,形成 Thought → Action → Observation 的循环。推理轨迹(Thought)不参与环境交互,只更新模型内部状态;动作(Action)调用外部 API 并拿到观察(Observation)回填上下文。
ReAct 论文的实验(PaLM-540B 等)显示:在交互式决策基准上,ReAct 相较模仿学习基线,ALFWorld 成功率绝对提升 34%、WebShop 提升 10%,且仅用 1–2 个 in-context 示例。其价值在于「act to reason」(用外部事实纠正幻觉)与「reason to act」(用推理决定下一步)。注意:本文不引用该论文之外的第三方榜单数字,避免编造 Benchmark 结论。
生产实践:最小可运行闭环
下面给出一个不依赖框架的极简 ReAct 风格循环(以 Anthropic Messages API 的 tool_use 为例,逻辑同样适用于 OpenAI Responses API)。代码为教学示意,真实生产请用官方 SDK 并加限流与超时。
python
# agent_minimal.py —— 极简 ReAct 闭环(示意,[未实测] 请在真实环境替换 API key 与工具实现)
import anthropic
client = anthropic.Anthropic() # 环境变量 ANTHROPIC_API_KEY
tools = [{
"name": "get_weather",
"description": "获取指定城市的当前天气",
"input_schema": {
"type": "object",
"properties": {"location": {"type": "string"}},
"required": ["location"],
},
}]
def run_tool(name, args):
# 真实实现调用天气 API;这里返回占位
return f"[mock] weather in {args['location']}: 18C, sunny"
def agent_loop(user_msg, max_steps=5):
messages = [{"role": "user", "content": user_msg}]
for step in range(max_steps):
resp = client.messages.create(
model="claude-sonnet-4-20250514", # [版本相关] 模型 ID 以官方文档为准
max_tokens=1024,
tools=tools,
messages=messages,
)
# 若没有 tool_use,说明模型已给最终答案
tool_uses = [b for b in resp.content if b.type == "tool_use"]
if not tool_uses:
return resp.content[0].text
# 执行动作并回填 Observation
for block in resp.content:
messages.append({"role": "assistant", "content": resp.content})
if block.type == "tool_use":
result = run_tool(block.name, block.input)
messages.append({
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": block.id,
"content": result,
}],
})
return "[达到最大步数,未完成]"
print(agent_loop("北京现在天气怎么样?适合穿什么?"))1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
必须设置 max_steps 上限
没有步数上限的 Agent 在遇到工具持续报错或模型陷入重复思考时会形成无限循环,直接造成成本失控(见「成本/性能」)。生产环境 max_steps 建议 5–15,并结合超时与总 token 预算双重熔断。
操作步骤 / 配置
- 选定支持工具调用的模型并确认上下文长度(Claude 4 Sonnet 200K
[版本相关];GPT-4o 128K[版本相关])。 - 定义工具 Schema(JSON Schema),描述务必清晰——模型靠描述决定何时调用。
- 实现工具执行层,统一异常返回为「可被模型理解的文本」,不要让异常堆栈直接进上下文。
- 套上循环 + 步数上限 + 总预算上限。
- 接入可观测(见
../../ai/observability/llmops-overview与本目录10-observability-eval.md)。
验证
bash
# 用一条需要工具的真实问题验证闭环
python agent_minimal.py
# 期望:模型先 tool_use(get_weather) -> 你返回 Observation -> 模型基于观察给建议
# 验证失败信号:模型反复 tool_use 同一参数、或从不调用工具直接编造1
2
3
4
2
3
4
bash
# 单元测试工具层(与模型解耦)
pytest tests/test_tools.py -k get_weather1
2
2
回滚 / 清理
上线变更需灰度
把「是否启用 Agent 循环」做成开关(feature flag)。若线上出现循环失控或工具误调用,立即回退到「纯 RAG / 单轮问答」模式,再排查。工具账号的 API Key 与数据库凭证要可一键吊销。
故障排查
- 模型从不调用工具:检查工具 description 是否含触发词;确认未误设
tool_choice: "none"(OpenAI)或等效限制。 - 循环不收敛:在 system prompt 显式要求「拿到足够信息后直接给最终答案,不要重复调用」;降低
max_steps。 - Observation 过大撑爆上下文:对工具返回做截断 / 摘要(如只取前 N 条记录),或改用检索式工具返回引用而非全文。
安全与合规
Agent 的核心风险来自「模型能触发真实动作」。至少覆盖四类:
- 提示注入(Prompt Injection):工具返回的文本可能含恶意指令,被模型当作用户意图。对策:将工具结果明确标记为不可信数据,并在 system prompt 中强调「数据 ≠ 指令」。
- 越权工具调用:模型可能调用未被授权的工具或越权参数(如
delete)。对策:工具层做授权校验,敏感动作加 human-in-the-loop。 - 数据泄露:工具返回值可能含 PII 并被模型外发。对策:工具层脱敏 + 输出侧敏感信息扫描。
- 成本失控:无限循环 / 失控调用。对策:
max_steps+ 总 token 预算 + 单请求并发限制。详见11-safety-guardrails.md。
成本 / 性能
以 Claude 4 Sonnet(200K 上下文)为参考 [版本相关,价格以 anthropic.com/pricing 为准]:输入约 $3/MTok、输出约 $15/MTok(不同快照差异大)。一个 5 步 Agent 调用,若每步平均 2K 输入 + 1K 输出,单任务约 10K 输入 + 5K 输出 ≈ $0.03–$0.1。若并发 100、每日 1 万任务,日成本约 $300–$1000。性能上,Agent 的延迟 = 步数 × 单次 LLM 延迟,多步会显著放大 P95 延迟,需对长任务做异步化。
降本三板斧
- 用 Prompt Caching 缓存稳定 system prompt 与工具定义(命中后输入成本可降至 ~10%)。
- 简单任务用 Haiku 级小模型,仅复杂规划用 Opus/Sonnet。
- 用 Batch API(非实时场景)可享约 50% 折扣
[版本相关]。