Agent 综合指南¶
大语言模型擅长理解自然语言和生成候选内容,但单独的模型调用通常只能完成“输入一次、输出一次”的推理。Agent 在模型周围加入目标、状态、工具、控制循环、权限和反馈,使系统能够观察环境、选择行动、读取行动结果,再决定下一步。它由此从回答问题的模型,变成推进任务的软件系统。
Agent 并不是一个拥有神秘自主意识的数字员工。工程上,它仍然是一个受程序控制的循环:模型提出下一步,运行时验证并执行允许的工具,结果重新进入上下文,直到得到终止答案、达到预算上限、遇到错误或请求人工决定。理解这一点非常重要,因为 Agent 的可靠性主要来自模型之外的约束、验证和恢复机制。
本章以 2026 年 7 月仍活跃的开放协议和官方项目为参考,包括 OpenAI Agents SDK、Anthropic Claude Agent SDK、Google Agent Development Kit、Microsoft Agent Framework、LangGraph、AutoGen、CrewAI、PydanticAI、MCP 和 A2A。框架接口会持续变化,正文重点放在可迁移的系统原理;示例代码用于解释结构,生产项目应以对应版本的官方文档为准。
1. Agent、模型、助手和工作流的区别¶
模型是一个函数式抽象:给定上下文 \(x\) 和参数 \(\theta\),生成输出 \(y\)。可以简写为 \(y=f_\theta(x)\)。聊天助手在模型之外增加会话历史、界面和一些内置工具。工作流则由开发者提前规定步骤和分支,例如“收到文件后提取字段,再写入数据库”。Agent 的差异在于部分控制流由模型根据当前状态动态决定。
如果任务步骤稳定、业务规则明确,应优先使用普通代码或确定性工作流。把“读取 CSV、验证字段、计算总和、写入数据库”交给模型自由规划,通常比直接编程更昂贵、更慢、更难验证。只有当输入变化大、规则难穷举、需要理解自然语言或环境反馈决定下一步时,Agent 才真正有价值。
| 形态 | 谁决定下一步 | 适合场景 | 可预测性 |
|---|---|---|---|
| 普通程序 | 开发者 | 规则明确、计算确定 | 最高 |
| 固定工作流 | 开发者定义图和分支 | 稳定业务流程 | 较高 |
| 路由器 | 模型只选择预设分支 | 分类、分流、专家选择 | 中高 |
| 单 Agent | 模型动态选择工具和顺序 | 开放式研究、排错、编码 | 中等 |
| 多 Agent | 多个模型角色协作 | 可明确分工且需要并行的复杂任务 | 较低 |
判断是否需要 Agent,可以依次询问:能否用一段确定性代码解决;能否用固定 DAG 解决;是否只需要模型做一次分类或抽取;是否必须根据不可预知的中间结果继续行动。只有最后一个问题为“是”时,才需要完整 Agent 循环。
优先选择最简单的可行架构
单次模型调用能完成的任务,不要做成 Agent;单 Agent 能完成的任务,不要急于拆成多 Agent。复杂度必须换来可测量的质量、吞吐或隔离收益。
2. Agent 的控制循环如何工作¶
一个最小 Agent 循环包含目标、当前状态、可用行动和终止条件。模型读取状态,产生一段最终答案或一个结构化工具调用。运行时不应直接相信工具调用,而要先检查工具名称、参数 schema、权限、预算和审批策略。执行结果被记录后重新提交给模型。
flowchart TD
G["目标与约束"] --> P["模型分析当前状态"]
P --> D{"输出类型"}
D -->|"最终答案"| V["结果验证"]
D -->|"工具调用"| A["权限与参数检查"]
A -->|"拒绝"| H["请求人工处理或返回错误"]
A -->|"允许"| T["在受控环境执行工具"]
T --> R["记录结果、成本和状态"]
R --> P
V -->|"通过"| E["结束"]
V -->|"未通过且有预算"| P
下面的伪代码展示了运行时真正需要承担的责任:
def run_agent(goal, model, tools, policy, max_steps=12):
state = {"goal": goal, "events": []}
for step in range(max_steps):
decision = model.decide(state, tool_schemas=tools.schemas())
if decision.type == "final":
return validate_final(decision.output, state)
call = policy.authorize(decision.tool_call, state)
if call.requires_approval:
call = request_human_approval(call)
if not call.allowed:
state["events"].append({"error": call.reason})
continue
result = tools.execute(
call,
timeout_seconds=30,
idempotency_key=f"{state['goal']}:{step}",
)
state["events"].append({"call": call, "result": result})
raise RuntimeError("Agent reached its maximum step budget")
生产实现还要处理流式输出、并发、取消、重试、模型超时、工具异常、上下文压缩和持久化。最重要的终止条件包括最大步骤、最大总 token、最大费用、总耗时、连续失败次数和人工取消。缺少上限的 Agent 可能在两个工具之间无限循环。
Agent 优化目标不应该只是“完成任务”。更完整的目标函数是:
\(\pi\) 是 Agent 策略,\(\tau\) 是一次完整执行轨迹,\(Q\) 表示质量,\(C\) 表示成本,\(T\) 表示延迟,\(R\) 表示风险。一个花费无限时间和预算完成任务的策略不是好策略;一个快速完成但可能删除数据的策略更不是。
3. 指令、状态与结构化输出¶
Agent 指令不是一段性格描述,而是控制策略的一部分。高质量指令应该说明角色范围、成功标准、允许工具、禁止行为、何时请求审批、证据要求和结束条件。诸如“你是一个聪明而有帮助的 Agent”几乎不提供控制信息。
职责:分析只读监控数据并提出故障假设。
成功标准:结论必须引用查询结果和时间范围。
允许:查询指标、读取日志、读取部署记录。
禁止:修改配置、重启服务、访问客户明文数据。
升级条件:发现疑似安全事件、查询需要更高权限、连续两次工具失败。
结束条件:给出证据排序后的根因候选和下一步人工操作。
状态应区分事件日志与派生摘要。事件日志记录发生过什么,是审计依据;摘要是为了控制上下文长度,可以重新生成。不能只保存模型摘要而丢弃原始工具结果,否则发生争议时无法复盘。敏感工具结果可加密保存并设置更短留存期,但仍要保留调用时间、调用者、工具名称、权限决定和结果状态等元数据。
模型输出应该尽量结构化。让模型输出 JSON 并不自动保证有效,运行时需要 JSON Schema 或类型模型进行验证。以下 schema 把最终诊断限制为固定字段:
{
"type": "object",
"properties": {
"summary": {"type": "string"},
"confidence": {"type": "number", "minimum": 0, "maximum": 1},
"evidence": {
"type": "array",
"items": {
"type": "object",
"properties": {
"source": {"type": "string"},
"observation": {"type": "string"}
},
"required": ["source", "observation"],
"additionalProperties": false
}
},
"next_action": {"type": "string"}
},
"required": ["summary", "confidence", "evidence", "next_action"],
"additionalProperties": false
}
结构化输出解决的是语法和字段完整性,不保证语义正确。confidence: 0.99 只是模型生成的数字,不是经过校准的概率。真正的置信度必须用历史评测比较预测分数与实际正确率。
4. 工具调用:Agent 能力和风险的入口¶
工具是带名称、说明和参数 schema 的受控函数。模型只负责提出调用意图,真正的凭据、网络请求和文件操作由运行时执行。工具说明会直接影响选择质量:名称应明确,描述要说明何时使用和何时不使用,参数应尽量少而具体。
{
"type": "function",
"name": "search_incidents",
"description": "查询指定服务和时间范围内的只读事故记录;不能创建或修改事故。",
"parameters": {
"type": "object",
"properties": {
"service": {
"type": "string",
"description": "服务的规范名称,例如 auth-api"
},
"start_time": {
"type": "string",
"format": "date-time"
},
"end_time": {
"type": "string",
"format": "date-time"
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 100
}
},
"required": ["service", "start_time", "end_time"],
"additionalProperties": false
},
"strict": true
}
不要设计一个名为 run_command(command: string) 的万能生产工具。它把所有系统权限压进一个自由文本参数,使静态检查、审批和审计几乎失效。更安全的设计是提供语义明确的窄工具,例如 get_service_logs、restart_staging_service,并在实现层限制服务名、环境、时间范围和最大返回量。
每个工具至少需要输入验证、身份认证、授权、超时、返回大小限制、速率限制、审计日志和错误分类。写操作还需要幂等性与乐观并发控制。工具错误应返回结构化类别,例如 INVALID_ARGUMENT、PERMISSION_DENIED、NOT_FOUND、RATE_LIMITED 和 TEMPORARY_UNAVAILABLE,让 Agent 判断是修正参数、请求权限还是延迟重试。
重试不是越多越好。如果一次独立调用成功概率为 \(p\),最多尝试 \(k\) 次后至少成功一次的理论概率为:
这个公式假设各次失败独立。权限错误、参数错误和确定性业务拒绝并不独立,重复一百次也不会成功,只会浪费资源。只有网络抖动、临时限流等可恢复错误适合指数退避重试。
5. MCP:统一连接上下文、数据与工具¶
Model Context Protocol(MCP)提供了一种开放方式,让 AI 主机连接外部能力。传统集成往往为每个模型和每个数据源分别编写适配器;MCP 把连接抽象为客户端与服务器,使支持该协议的主机能够复用服务器暴露的工具、资源和提示模板。
MCP 的典型角色包括 Host、Client 和 Server。Host 是用户正在使用的 AI 应用;Client 维护与某个 Server 的协议连接;Server 暴露受控能力。常见本地传输使用标准输入输出,远程服务通常使用基于 HTTP 的传输。协议消息采用结构化请求和响应,具体版本和传输要求应以当前规范为准。
flowchart LR
H["AI Host"] --> C1["MCP Client:代码库"]
H --> C2["MCP Client:工单系统"]
H --> C3["MCP Client:数据库"]
C1 --> S1["本地 MCP Server"]
C2 --> S2["远程 MCP Server"]
C3 --> S3["只读查询 Server"]
工具(Tools)允许模型发起行动,资源(Resources)提供可读取上下文,提示(Prompts)提供可复用交互模板。三者的安全含义不同:读取一份文档与执行一次删除操作不能使用同样审批策略。Host 最终负责向用户展示服务器身份、工具描述和权限请求,Server 不能因为使用开放协议就自动获得信任。
下面是一个说明结构的本地配置示例,不对应某个必须安装的第三方服务器:
{
"mcpServers": {
"team-docs": {
"command": "python",
"args": ["-m", "company_docs_mcp"],
"env": {
"DOCS_ROOT": "./approved-docs",
"MODE": "read-only"
}
}
}
}
配置文件不应直接提交令牌。使用操作系统密钥链、短期凭据或受控环境变量;远程服务器要验证身份、来源和 TLS;服务器返回的文档仍属于不可信内容,不能让其中的提示文字覆盖 Host 规则。安装社区 MCP Server 前,应审查源码、发布者、依赖、所需目录和网络权限。
6. A2A 与 Agent 之间的互操作¶
MCP 主要解决 Agent 或模型如何连接工具和上下文,Agent2Agent(A2A)协议关注独立 Agent 应用之间如何发现能力、交换消息、跟踪长任务和传递产物。二者可以同时存在:一个采购 Agent 通过 MCP 查询内部目录,再通过 A2A 把物流子任务交给另一个独立 Agent。
A2A 的核心思想是让协作方不必暴露内部提示、记忆或实现。Agent 可以通过 Agent Card 描述身份、端点和能力;一次工作以 Task 为状态实体;参与者交换 Message,最终产生 Artifact;长任务可以通过流式更新或异步通知报告进展。具体字段会随规范演进,应以 A2A 官方规范 为准。
不能因为对方是“另一个 Agent”就默认信任。调用方要验证对方身份、授权范围、数据用途、返回签名和任务状态。跨组织协作还要处理租户隔离、数据驻留、审计和撤销。A2A 提供通信机制,不替代业务信任和合同边界。
7. 记忆、检索与 RAG¶
Agent 的“记忆”不是单一数据库。工作记忆保存当前运行需要的信息;会话记忆保存同一用户或任务的连续状态;情景记忆保存过去轨迹和结果;语义记忆保存可检索知识;程序性记忆保存规则和技能。不同记忆应有不同写入条件和保留时间。
最常见错误是把所有聊天内容永久写入向量库。用户临时说出的错误信息、模型幻觉和敏感数据会被长期放大。记忆写入前应确定来源、置信度、适用范围、过期时间和删除机制。用户偏好可以记录,但高风险决策不应仅根据过去对话自动推断。
RAG 通常将文档切分为片段,计算嵌入向量,再按相似度检索。余弦相似度为:
相似度高只表示向量接近,不表示文档真实、最新或有权限被当前用户读取。因此检索前要应用访问控制,检索后要保留来源元数据,并使用重排序、时间过滤和文档等级改善质量。回答时要求引用原片段,验证时检查引用是否支持结论。
上下文过长时可压缩历史,但摘要必须保留目标、已确认事实、关键约束、未解决问题、工具副作用和审批决定。删除这些信息会让 Agent 重复行动或越过已经明确的边界。
8. 规划、反思和验证¶
复杂 Agent 常使用“先规划再执行”。计划能够暴露遗漏和依赖,但不应被当成不可修改的合同。环境反馈可能证明原计划错误,系统需要重新规划。较好的计划步骤包含目标、输入、预计工具、完成条件和失败处理,而不是只有“分析问题”“解决问题”等空泛描述。
反思机制让模型检查前一步,但同一个模型重复说“请检查”并不等于独立验证。它可能坚持原有错误。更强验证包括运行测试、使用计算器、查询权威来源、让不同模型独立判断,或者把结果交给确定性规则。验证方法应与输出类型匹配。
对于代码任务,最可信的信号通常按以下顺序增强:代码看起来合理;静态检查通过;单元测试通过;集成测试通过;真实场景验收通过。Agent 的文字自述排在这些信号之后。对于研究任务,验证信号则包括原始来源、交叉来源、数据口径和反例。
可以把一个由 \(n\) 个关键步骤组成的流程粗略看成串联系统。如果第 \(i\) 步可靠率为 \(p_i\),全部步骤都正确的概率近似为:
即使每步正确率为 0.95,十个步骤全部正确的概率也只有 \(0.95^{10}\approx0.60\)。这解释了为什么无限延长自主链条会快速降低端到端可靠性。解决办法不是只追求更强模型,还包括减少步骤、在关键节点验证、允许回滚以及把高风险决定交给人。
9. 单 Agent、路由和多 Agent¶
单 Agent 配多个清晰工具通常是首选。它的上下文、日志和责任边界更容易理解。任务类型差异很大时,可以增加一个路由器,把请求送到研究、代码或数据专家。只有在子任务真正可并行、需要不同权限隔离、上下文不能放在一起,或需要独立批判角色时,多 Agent 才可能产生净收益。
多 Agent 常见组织方式包括主管委派、Agent 作为工具、显式 handoff、共享黑板和事件驱动协作。主管模式便于统一控制,但主管可能成为瓶颈;handoff 让责任转移更清晰,但必须携带必要状态;共享黑板便于并行,却需要处理并发和冲突。
flowchart TB
U["用户目标"] --> O["编排器 / 主管"]
O --> R["研究 Agent:只读网络"]
O --> C["代码 Agent:仓库沙箱"]
O --> D["数据 Agent:受限查询"]
R --> J["证据与来源"]
C --> J["补丁与测试"]
D --> J["指标与口径"]
J --> O
O --> A["人工审批后交付"]
每增加一个 Agent,都要回答它为何不能被一个工具或函数替代,它拥有什么独特上下文和权限,它的输出由谁验证。如果答案只是“听起来更智能”,就不应增加。
10. 人在回路与权限分级¶
人在回路(Human in the Loop)不是失败兜底,而是系统设计。审批点应放在风险发生之前,并给审批者足够信息:将执行什么、目标对象是谁、使用什么身份、影响范围、是否可撤销、为什么需要执行。只显示一个“允许/拒绝”按钮却隐藏参数,不算有效审批。
可以把工具按风险分四类。只读低敏感工具可以自动执行;受限写操作可以在明确范围内自动执行并记录;高影响可逆操作需要执行前审批;不可逆或受监管操作需要多人审批或完全禁止自动化。分类依据是数据敏感度、权限、影响范围、可恢复性和合规要求,而不是工具名称。
预期风险可表示为:
\(P(E_j)\) 是第 \(j\) 类事故概率,\(I(E_j)\) 是影响。低概率但灾难性影响仍然可能要求严格控制。删除生产数据、对外汇款、修改访问控制和发送法律承诺都属于这一类。
审批也要防止疲劳。如果系统每一步都弹窗,用户会机械点击允许。应合并同类低风险操作,清楚标出异常变化,只在权限扩大、目标变化、成本超限和外部副作用前中断。审批结果与理由应进入审计轨迹。
11. 安全:提示注入、越权与数据外泄¶
提示注入是 Agent 系统最重要的风险之一。攻击文字可以隐藏在网页、邮件、代码注释、文档或工具返回中,诱导模型泄露秘密、调用危险工具或忽略用户目标。模型无法仅凭语言理解稳定地区分“资料里的文字”和“应遵循的系统指令”,因此必须在架构层隔离。
第一道防线是最小权限。研究 Agent 不应拥有发送邮件权限,代码审查 Agent 不应拥有生产部署凭据。第二道防线是数据与指令分离,对外部内容明确标记来源,不允许其修改系统策略。第三道防线是工具策略,在模型之外检查目标域名、文件路径、SQL 类型、金额、接收者和环境。第四道防线是敏感操作审批。第五道防线是输出过滤和审计。
不要把秘密放进模型上下文本身,再期待提示词阻止泄露。更安全的方式是让工具在服务端使用秘密,并只向模型返回最小结果。例如支付工具接收受限订单 ID,在服务端查找支付凭据,而不是把完整信用卡信息交给模型生成请求。
代码执行必须使用沙箱,限制文件系统、网络、CPU、内存、运行时间和子进程。容器能提供隔离基础,但默认容器并不等于安全边界;仍需去除特权模式、只读挂载、非 root 用户、能力裁剪和网络策略。浏览器自动化应使用专用配置文件和测试账户,避免继承用户日常登录态。
12. 评估:从一次演示走向可度量系统¶
Agent 演示通常展示成功轨迹,生产评估必须研究失败分布。评测集应包含正常任务、边界条件、工具失败、权限拒绝、恶意输入、冲突信息、长上下文、超时和取消。每个样本定义成功条件、允许工具、禁止副作用、预算和人工判定规则。
至少记录以下指标:任务成功率、端到端正确率、工具选择准确率、参数有效率、平均步骤数、总 token、总成本、P50/P95 延迟、人工介入率、策略违规率和恢复成功率。只统计“模型最终说已完成”没有意义,成功应由外部状态或验证器确认。
一次运行的总延迟可以分解为:
这个分解有助于定位优化方向。如果主要时间花在外部 API,换更快模型不会明显改善;如果人工审批占比高,应优化风险分级和审批信息,而不是简单取消审批。
评估应区分离线回放和在线观测。离线回放在固定样本上比较提示、模型和框架,适合回归测试;在线观测反映真实分布和用户行为,但需要隐私保护和渐进发布。新版本先进入 shadow 或小流量,达到质量和风险阈值后再扩大。
评测数据不能只来自模型生成。合成数据可扩充边界情况,但真实历史任务、专家设计的对抗样本和生产失败案例更重要。每次事故修复后,都应把对应案例加入回归集。
13. 可观测性、追踪和故障恢复¶
普通应用日志通常记录请求和错误,Agent 还需要轨迹(trace):每次模型输入的版本、输出类型、工具调用、参数摘要、权限决定、工具结果、token、费用、延迟和状态转换。追踪使开发者能够回答“Agent 为什么这样做”,并比较不同版本。
日志要避免记录秘密和完整敏感内容。可以保存内容哈希、分类标签、脱敏摘要和受控对象引用。调试者在获得额外授权后才能读取原始内容。追踪数据同样需要访问控制、保留期限和删除流程。
恢复策略应依据副作用。纯读取步骤可以安全重试;幂等写操作使用相同 idempotency key 重试;非幂等操作必须先查询外部状态,确认上一次是否已经成功。长任务要持久化检查点,使进程重启后从确定状态恢复,而不是重放全部操作。
Agent 状态机至少应区分 queued、running、waiting_for_approval、succeeded、failed、cancelled 和 expired。不能把“等待用户审批”伪装成长时间运行,也不能在取消后继续执行后台工具。
14. 框架与平台如何选择¶
框架的价值是提供运行循环、工具封装、状态、追踪、人工审批和部署接口,而不是替代架构判断。选择时应先做一个最小原型,再根据需求增加框架。
| 项目 | 主要定位 | 适合关注的能力 |
|---|---|---|
| OpenAI Agents SDK | 轻量 Agent 与多 Agent 工作流 | tools、handoffs、guardrails、sessions、tracing、realtime、sandbox |
| Anthropic Claude Agent SDK | 构建可读文件、运行命令和使用工具的 Agent | Claude Code 同类 agent loop、权限和工具集成 |
| Google ADK | code-first Agent 开发、评估与部署 | Agent 组合、工具、会话、评测与 Google 生态 |
| Microsoft Agent Framework | Python/.NET Agent 与多 Agent 工作流 | 企业集成、编排、部署和微软生态 |
| LangGraph | 状态图与耐久执行 | checkpoint、human-in-the-loop、长任务、显式控制流 |
| AutoGen | Agentic AI 编程框架 | 多 Agent 对话与研究原型 |
| CrewAI | 角色、任务和团队编排 | 角色化协作与流程抽象 |
| PydanticAI | 类型驱动的 Python Agent | 结构化结果、依赖注入、验证和 Python 类型系统 |
不要只根据 GitHub star 数量选框架。应检查许可证、维护频率、版本兼容、可替换模型、异步支持、持久化、流式输出、工具权限、追踪导出、测试能力和部署方式。企业项目还需评估身份系统、网络边界、数据驻留和供应商锁定。
MCP 和 A2A 是协议,不等同于上述运行框架。一个系统可以用 LangGraph 管理状态,用 OpenAI 或其他模型推理,用 MCP 连接工具,再通过 A2A 与外部 Agent 协作。分层选择比寻找一个“包办一切”的框架更稳健。
15. 使用 OpenAI Agents SDK 理解最小实现¶
下面示例采用官方 openai-agents Python 包展示 Agent、Runner 和函数工具的关系。它不是生产模板,但比纯伪代码更接近可运行结构。安装前需要 Python 3.10 或更高版本,并应在虚拟环境中操作。
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install openai-agents
# 通过安全的本地秘密管理方式提供密钥;不要提交 .env 或 shell 历史
export OPENAI_API_KEY='replace-with-your-key'
from agents import Agent, Runner, function_tool
@function_tool
def lookup_service_owner(service: str) -> str:
"""Return the owner of an approved service name."""
owners = {
"auth-api": "identity-team",
"billing-api": "payments-team",
}
return owners.get(service, "unknown")
agent = Agent(
name="Incident Assistant",
instructions=(
"Help route incidents. Use the owner lookup tool instead of guessing. "
"Do not claim that a notification was sent; this agent has no send tool."
),
tools=[lookup_service_owner],
)
result = Runner.run_sync(agent, "Who owns auth-api, and what should I check first?")
print(result.final_output)
@function_tool 将 Python 函数转换为模型可见的工具 schema,Runner 管理模型与工具之间的循环。示例故意只提供只读查询工具,因此 Agent 无法真的通知团队。能力边界由可用工具决定,而不是由提示词里“不要发送”决定。
真实服务还要将同步字典替换为受认证的数据源,增加参数白名单、超时、审计和错误类型;运行结果进入结构化验证;高风险工具增加人工审批;执行轨迹发送到可观测平台。升级 SDK 时运行固定评测集,因为模型行为、默认值和工具序列化都可能变化。
16. 从零设计一个生产 Agent¶
首先选择一个窄而有价值的目标,例如“根据只读日志生成事故初步报告”,而不是“做一个全能运维 Agent”。写出成功条件和禁止副作用,收集真实样本并建立人工基线。然后用单次模型调用验证模型是否能理解输入;如果中间结果决定后续查询,再增加最小 Agent 循环。
第二步设计工具。每个工具只完成一个业务动作,使用结构化参数,服务端执行授权。先提供只读工具,记录真实调用分布;确认价值后再增加受限写操作。第三步设计状态、终止条件和预算。第四步建立评测和追踪,在离线环境反复测试正常、失败和恶意输入。
第五步增加安全边界:独立身份、最小权限、沙箱、网络限制、秘密管理、提示注入防护和人工审批。第六步采用渐进发布,先让 Agent 只建议不执行,再让它在测试环境执行,最后只对已评估的低风险动作开放有限自动化。高风险动作保持审批。
第七步准备运行手册。它应说明如何暂停 Agent、撤销凭据、定位轨迹、恢复检查点、回滚副作用、处理数据删除请求和切换备用模型。没有停止按钮和恢复路径的 Agent 不应进入生产。
17. 常见失败模式与修复¶
Agent 不停调用同一个工具,通常是工具错误没有提供可行动信息,或者终止条件不清。返回明确错误类别和建议,设置连续失败上限。Agent 选择错误工具,通常是工具名称和描述重叠,应合并或重新划分工具,并用选择准确率评测。
Agent 声称已经完成但实际没有完成,是因为系统把自然语言当成成功信号。应检查数据库状态、文件哈希、测试结果或外部 API 回执。模型的“已完成”只能触发验证,不能直接改变任务状态为成功。
Agent 忘记早期约束,通常是上下文过长或摘要丢失。把稳定策略放在独立规则层,把审批决定写入结构化状态,对历史进行保真压缩。Agent 泄露数据,通常不是一句提示词能修复的问题,应撤销权限、轮换凭据、检查日志和数据流,并减少模型可见内容。
多 Agent 相互争论不结束,是因为缺少拥有最终决策权的编排器和停止标准。为每个角色定义输入输出,限制往返次数,使用外部验证器裁决。成本突然升高,则检查循环、工具返回大小、重复检索、历史增长和失败重试,设置硬预算并告警。
18. 架构与命令速查¶
| 需要解决的问题 | 推荐机制 | 不应只依赖 |
|---|---|---|
| 参数格式正确 | JSON Schema、类型验证 | 提示词要求“输出 JSON” |
| 防止越权 | 服务端授权、最小权限 | 模型承诺“不越权” |
| 防止无限循环 | 步骤、时间、token、费用上限 | 模型自行判断停止 |
| 处理临时故障 | 分类重试、退避、熔断 | 无差别重复调用 |
| 证明任务完成 | 外部状态和测试 | Agent 的完成陈述 |
| 防止提示注入 | 数据/指令隔离、工具策略、审批 | 一段安全提示词 |
| 支持恢复 | 检查点、幂等键、状态机 | 从头重放全部步骤 |
| 改善质量 | 真实评测集、轨迹分析 | 单次演示和主观印象 |
开发期间常用的环境与验证命令如下:
# 创建隔离环境
python3 -m venv .venv
source .venv/bin/activate
# 固定依赖,避免框架升级造成不可重复行为
python -m pip freeze > requirements.lock.txt
# 运行类型检查、测试和安全扫描,具体命令按项目替换
ruff check .
pytest -q
# 检查敏感文件是否误入 Git
git status --short
git ls-files | rg '(\.env|credential|secret|private)'
# 查看 Agent 修改的真实差异
git diff --check
git diff --stat
git diff
生产系统还应监控任务队列、成功率、P95 延迟、单任务成本、工具错误率、审批等待时间和策略拒绝次数。任何指标异常都应能追踪到具体运行,但展示时必须脱敏。
19. 延伸阅读¶
- OpenAI Agents SDK 官方文档:Agent、tools、handoffs、guardrails、sessions、tracing 与 realtime
- Anthropic Claude Agent SDK Python:基于 Claude Agent 循环构建应用
- Google Agent Development Kit:code-first Agent 开发、评估和部署
- Microsoft Agent Framework:面向 Python 与 .NET 的 Agent 和多 Agent 工作流
- LangGraph 官方文档:耐久执行、状态图、记忆与人在回路
- PydanticAI 官方文档:类型驱动的 Python Agent 开发
- Model Context Protocol 规范与文档:工具、资源、提示和传输协议
- Agent2Agent Protocol:独立 Agent 应用之间的发现、任务和消息互操作
- OWASP Agentic Applications Initiative:Agentic 系统威胁、治理和安全实践
- NIST AI Risk Management Framework:AI 系统风险治理方法