Agent 深入
高级 Agent 不是“多加几个模型”。真正的升级,是把不确定判断留给模型,把权限、状态、预算和验收留给代码。任务路径能够预先写清时,固定 Workflow 往往比自主 Agent 更便宜、更快,也更容易排错。
先决定是否真的需要 Agent
| 任务特征 | 推荐结构 | 原因 |
|---|---|---|
| 步骤固定、规则明确、失败必须可预测 | 普通代码或 Workflow | 控制力强,模型只处理模糊节点 |
| 输入可分成稳定类别 | Router + 专用流程 | 每类使用不同工具、Prompt 和评测 |
| 子任务互不依赖 | Parallel / MapReduce | 降低总等待时间,并行后统一聚合 |
| 需要反复生成、检查、修正 | Evaluator–Optimizer | 用明确评分标准驱动迭代 |
| 路径无法预先列举,必须根据环境反馈决定下一步 | Agent loop | 模型动态选择工具与步骤 |
Anthropic 将两者分得很清楚:Workflow 由代码规定路径,Agent 由模型动态决定过程。工程上应从最简单的结构开始,只有真实任务证明固定路径不够时才增加自主性。
普通函数 → 单次 LLM → 固定 Workflow → 带工具的 Agent → Manager + Specialists
每向右一步,能力增加,成本、延迟和故障面也增加。
七种常用编排模式
| 模式 | 数据路径 | 适合 | 主要风险 |
|---|---|---|---|
| Prompt Chaining | A → B → C | 文档生成、分阶段审核 | 上游错误向后传播 |
| Routing | 分类 → 专用分支 | 客服、工单、内容分流 | 错误路由造成隐性失败 |
| Parallelization | A、B、C 同时执行 | 多来源研究、独立检查 | 合并冲突与重复成本 |
| Orchestrator–Workers | Manager 拆任务 → Workers → 汇总 | 子任务数量动态变化 | Manager 过度拆分 |
| Evaluator–Optimizer | 生成 → 评分 → 修正 | 有明确 rubric 的交付物 | 无止境优化循环 |
| Handoff | 当前 Agent → 专家 Agent | 对话式专业分工 | 上下文和责任丢失 |
| Autonomous Loop | 观察 → 决策 → 工具 → 新观察 | 开放环境、未知步骤 | 成本失控与危险副作用 |
不要把“多 Agent”当默认答案。如果一个 Agent 能使用清晰工具完成任务,拆成五个角色只会带来更多 handoff、重复 context 和难以定位的错误。
模型消息不是运行状态库
一轮生产运行至少要保存:
type AgentRun = {
runId: string;
taskId: string;
status: 'queued' | 'running' | 'waiting_approval' | 'verified' | 'failed';
objective: string;
step: number;
maxSteps: number;
budget: { maxTokens: number; maxCostUsd: number; deadlineMs: number };
observations: ObservationRef[];
pendingAction?: ProposedAction;
idempotencyKeys: string[];
finalEvidence?: EvidenceRef[];
};
observations 保存引用和摘要,不应把所有原始工具输出复制进数据库。大文件留在对象存储或业务系统,通过稳定 ID 按需取回。
最小可控循环
async function runAgent(run: AgentRun) {
while (run.status === 'running') {
assertWithinBudget(run);
const decision = await decideNextAction({
objective: run.objective,
recentObservations: await loadWorkingSet(run),
availableTools: await toolsForTask(run.taskId)
});
if (decision.type === 'finish') {
const evidence = await verifyOutcome(decision.claims);
run.status = evidence.every(item => item.valid) ? 'verified' : 'failed';
run.finalEvidence = evidence;
break;
}
validateToolCall(decision.tool, decision.arguments);
if (requiresApproval(decision)) {
run.status = 'waiting_approval';
run.pendingAction = decision;
break;
}
const result = await executeInBoundary(decision, {
timeoutMs: 20_000,
idempotencyKey: `${run.runId}:${run.step}`
});
await appendObservation(run, summarizeToolResult(result));
run.step += 1;
}
}
关键点不是 while,而是每一轮都有预算检查、参数校验、权限判断、幂等键和终点验证。
Tool contract 决定 Agent 上限
一个可用工具必须让模型判断四件事:什么时候用、输入是什么、可能失败在哪里、调用后发生了什么。
const sendRefund = {
name: 'send_refund',
description:
'Refund one captured payment after approval. Do not use for pending payments or goodwill credit.',
inputSchema: {
type: 'object',
properties: {
paymentId: { type: 'string' },
amountCents: { type: 'integer', minimum: 1 },
approvalId: { type: 'string' },
reasonCode: { type: 'string', enum: ['duplicate', 'service_failure'] }
},
required: ['paymentId', 'amountCents', 'approvalId', 'reasonCode']
}
};
写操作还应返回 provider request ID、是否已经执行、可否回滚,以及证据 URL。只返回 success: true 无法支持恢复和审计。
权限与人工审批
| 风险级别 | 示例 | 默认策略 |
|---|---|---|
| 只读 | 搜索文档、读取订单 | 自动执行,限制数据范围 |
| 可恢复写入 | 建草稿、加标签 | 自动或抽样审批,保留撤销能力 |
| 外部沟通 | 发邮件、发消息 | 展示收件人和正文,发送前批准 |
| 金钱与生产 | 退款、部署、删除 | 强制审批、幂等、provider read-back |
| 不可逆或高影响 | 批量删除、公开发布 | 双人审批或禁止 Agent 直接执行 |
审批界面必须展示真实 diff:目标、参数、预计影响、证据来源和回滚方案。只显示“Agent 想调用工具,是否允许?”没有足够信息。
防止循环与失控
至少设置五类停止条件:
- 最大 step、token、成本和墙钟时间。
- 同一工具以相同参数重复调用。
- 连续出现相同错误或空结果。
- 目标已经满足但模型仍继续探索。
- 需要授权、凭证或用户选择却无法继续。
function detectLoop(history: ToolCall[]) {
const recent = history.slice(-3).map(call => JSON.stringify([call.name, call.arguments]));
return recent.length === 3 && new Set(recent).size === 1;
}
命中停止条件后要返回可诊断状态,例如 blocked: missing_approval,而不是笼统的“任务失败”。
Manager 与 Handoff
Manager 保留最终回答权,专家作为工具返回结果。适合需要统一语气、安全策略和跨领域汇总的任务。Handoff 则把对话交给专家,适合专家需要持续追问并直接负责用户结果的场景。
结构化交接不要复制整段聊天:
{
"objective": "Resolve duplicate charge",
"facts": ["payment_1 captured", "payment_2 captured"],
"evidenceIds": ["trace_87", "invoice_42"],
"completed": ["identity verified"],
"openDecision": "refund which payment",
"prohibitedActions": ["send refund without approval"]
}
专家需要的是最小充分 context、已经完成的工作和明确责任边界。
Trace 与评测
每轮 Trace 至少记录 run ID、模型与配置版本、工具参数摘要、延迟、错误、token、成本、审批和 provider receipt。
| 指标 | 要回答的问题 |
|---|---|
| Task success | 用户结果是否真正完成? |
| Tool selection | 选对工具了吗? |
| Argument validity | 参数是否通过 schema 和业务规则? |
| Side-effect precision | 是否产生了多余写操作? |
| Recovery rate | 超时或崩溃后能否安全继续? |
| Cost / latency | 成功一次需要多少成本和时间? |
不要只评最终自然语言。一个回答写得很好,但退款了两次,仍然是严重失败。
常见错误
| 错误 | 后果 | 修法 |
|---|---|---|
| 所有任务都交给自主 Agent | 延迟和失败面扩大 | 固定任务退回 Workflow |
| 工具职责重叠 | 模型随机选择 | 重写边界,缩小本轮工具集 |
| 让模型自己判断“完成” | 过早停止 | 用代码或外部 read-back 验证 |
| 重试写操作没有幂等键 | 重复付款、发信或发布 | 稳定 task ID + provider request ID |
| 多 Agent 共享整段历史 | context 膨胀、指令冲突 | 使用结构化 handoff payload |
动手练习:退款调查 Agent
- 标出固定 Workflow 步骤和必须由模型判断的节点。
- 定义订单、支付、身份验证和退款四个工具的边界。
- 实现最大 8 步、30 秒单工具超时和重复调用检测。
- 退款前输出审批 diff,不直接执行。
- 模拟审批后进程崩溃,验证重跑不会退款两次。
- 只有读回 provider 退款状态后才标记成功。
完成标准
- 我能解释为什么这里需要 Agent,而不是普通 Workflow。
- 每个写工具都有审批或明确自动化策略。
- 循环有 step、成本、时间与重复调用上限。
- Run state 能在进程重启后恢复。
- “完成”由外部证据验证,而不是模型自报。
相关阅读
官方参考
📚 相关资源
❓ 常见问题
点击问题,查看本章对应的实践答案。
ReAct、Plan-and-execute、Tree of Thoughts 这几种 agent 风格怎么选?
按任务形态选。ReAct(reasoning + tool use 交替)适合 search / code 这种需要边查边想的任务,每步看 tool result 再决定下一步。Plan-and-execute(先规划再执行)适合较长任务 —— 一次性出 plan 比 ReAct 每步重新决策更稳,少跑偏。Tree of Thoughts / Reflexion 适合需要探索多条方案、自我批评、择优的任务(比如解谜、复杂数学)。Router agents 适合按 intent / domain 把请求分发给专门的 sub-agent,节省 token。
Agent 怎么防止陷入死循环或无限调 tool?
靠 stop conditions —— 至少三个上限:max steps(如最多 10 步)、max tool calls(如最多 20 次)、max time(如 60 秒),任何一个触发就 break。loop detection 可以记录最近 N 步的 (tool, args) hash,重复就停。本章伪代码就是标准模式:`while not done: ... if stop_condition(): break`。生产场景再加:异常 / 超时退出码区分(让上游知道是任务完成还是被 kill)、cancel rate 监控、把死循环 case 记入 trace store 做 post-mortem。
什么是 dual-model verification?为什么用便宜模型 + 贵模型 review?
Dual-model verification:便宜模型(如 GPT-4o-mini)执行 agent 主循环跑 tool 调用,贵模型(如 Claude Sonnet 4.5 / GPT-5)只在最后做 review,验证答案是否引用了 tool outputs、是否符合指令、有没有 hallucination。理由是 80% 的执行步骤不需要顶级推理力,最贵的算力放在最关键的 "质量门禁" 上 ROI 最高。配合 self-critique(让 agent 自己核对答案 vs. instructions / citations),生产质量提升明显但成本只增加 10-20%。
Agent 的高风险操作(发邮件、改生产)该怎么加 human approval?
三层防护:(1) 工具层 allowlist 外部域名 / API,blockwrites 默认禁止写操作除非明确允许;(2) Guardrails 在 tool call 前后跑 PII / dangerous-action 检查;(3) Human approval steps 把 risky actions(emails、transactions、prod changes)做成必须用户确认才执行的 node。LangGraph 这种支持 human-in-the-loop 的框架可以暂停在 approval node 等用户回复。OpenAI Agent Mode 也是这套思路 —— sensitive / irreversible 步骤前 deliver 到 final channel 等确认。
Agent observability 至少要 log 哪些字段?
Trace per run 必须有:steps(第几步)、chosen tool(用了哪个)、inputs / outputs(参数和返回)、duration(耗时)、errors(错误码 + 信息)、tokens(消耗)。指标层至少四个:success rate、avg steps、tool error rate、cancel rate。Replay 能力关键:存 deterministic inputs(同样输入能复现),加上 same seed / config 让线下 reproduce 一致。生产 agent 不加 trace 等于裸奔 —— 出 bug 你完全不知道是 plan 错了、tool 挂了、还是模型自己幻觉。