AI Agent 开发
本文目录
从模型调用到能够持续使用工具、维护上下文并接受评测的 Agent,中间隔着一套完整的应用工程。本篇沿着运行循环逐步展开,讨论工具、状态、知识、工作流、多 Agent 协作与安全边界,并在综合实践中说明这些能力如何组合。
起步
Agent 与 Workflow
把一次模型调用包装进聊天界面,只能得到一个对话程序。Agent 还需要根据目标选择行动、读取行动结果,并决定任务是否已经完成。这个差异决定了系统是否具备自主执行能力,也决定了开发时需要承担哪些额外风险。
基本结构
一个 Agent 可以抽象为持续更新的状态机。设当前状态为 ,模型根据目标、状态和可用动作集合生成下一步动作 ,外部环境执行动作后返回观察结果 ,系统再据此得到新状态:
其中, 通常由大语言模型实现, 是工具、委派和结束任务等动作的集合。模型只负责提出动作,真正的网络请求、文件读写和数据库修改仍由确定性的程序执行。
工程中的 Agent 通常包含五个部分:
- 目标与指令,规定要完成的任务、允许采用的方法和禁止越过的边界
- 模型,为当前状态生成判断、动作参数或最终回答
- 工具,把搜索、计算、代码执行和业务 API 暴露为受控动作
- 状态,保存消息、工具结果、任务进度和恢复任务所需的数据
- 运行循环,负责调用模型、校验动作、执行工具、处理异常并判断终止条件
缺少运行循环时,模型无法根据工具结果继续工作;缺少权限边界时,工具能力越强,系统造成错误修改的可能性也越高。
Agent 与 Workflow
Workflow 的控制流由程序预先定义。路由条件、执行顺序和失败分支都能从代码或流程图中直接读出。Agent 的控制流至少有一部分由模型在运行时决定,同一个入口任务可能产生不同的工具调用顺序。
两者不是互斥的产品形态。实际系统经常在确定性 Workflow 中嵌入少量 Agent 节点,或者让 Agent 调用一个严格定义的审批流程。判断是否需要自主决策,可以检查三个条件:任务步骤能否提前枚举、分支规则能否稳定编码、错误行动是否容易撤销。只要前两个问题的答案为肯定,固定 Workflow 往往更容易测试和维护。
自主程度可以看作连续范围。单次结构化提取几乎没有自主性;允许模型选择一个只读工具,具有有限自主性;允许模型持续规划、修改外部状态并委派其他 Agent,则需要更强的观测、审批和预算控制。
适用边界
Agent 适合处理步骤难以穷举、输入高度非结构化、需要结合外部反馈反复调整的任务,如跨来源研究、代码库修改和复杂故障排查。规则明确的表单校验、账务结算和权限判定应继续采用确定性程序。
评估一个场景时,应把模型判断错误后的后果纳入设计。只读检索可以通过结果校验降低风险;发送消息、删除数据和支付等动作会改变外部状态,需要显式授权、幂等控制和人工确认。Agent 的能力边界最终由工具和运行时决定,而不是由提示词中的自我约束决定。
本系列的范围
本系列讨论应用层 Agent 的构造方法,包括模型交互、工具调用、上下文管理、工作流模式、多 Agent 协作、评测与安全。语言语法、HTTP 基础和数据库基础不在本系列展开。模型服务的弹性伸缩、沙箱集群、持久化执行、多租户隔离和资源调度属于 Agent Infra 的范围,将在后续系列中讨论。
模型调用与消息
模型 API 是 Agent 与大语言模型之间的协议边界。理解请求如何构造、上下文如何累计以及响应如何结束,是实现工具循环和状态恢复的前提。
一次模型调用
模型调用的输入通常包括模型标识、指令、消息、工具定义和生成参数,输出则包括文本、结构化数据、工具调用请求、用量统计和结束原因。不同供应商的字段名称并不完全一致,但语义可以归纳为同一组概念。
模型服务通常不保存应用会话。客户端每次请求都要提交本轮推理所需的上下文,服务端返回的响应也必须由应用保存。部分 API 提供服务端会话或前序响应引用,这只是传输和存储方式的变化,应用仍需明确哪些状态属于任务事实,哪些状态可以被丢弃。
生成参数会影响输出分布。温度较低时,结果通常更稳定;温度较高时,候选表达更分散。结构化提取、工具参数生成和代码修改更重视可重复性,通常采用较低温度。创造性写作可以适当增加随机性,但不能把温度当作事实正确性的控制器。
消息角色
现代模型 API 通常区分指令、用户输入、助手输出和工具结果。角色的作用是标明信息来源和优先级,而不是简单的显示样式。
- 系统或开发者指令定义长期行为、职责和安全边界
- 用户消息描述当前目标,并提供任务相关材料
- 助手消息保存模型已经给出的回答或动作请求
- 工具消息记录某次工具调用的真实执行结果,并通过调用标识与请求对应
工具结果必须作为数据处理。网页正文、邮件内容和检索文档可能包含要求模型忽略原有规则的文本,这些内容没有更高的指令权限。应用在组装消息时应保留来源标签,避免把外部内容拼接进高优先级指令。
Token 与上下文窗口
模型处理的是 Token 序列。中文字符、英文单词、标点和代码会按分词器规则拆分,字符数不能精确代表 Token 数。上下文窗口同时容纳输入和模型输出,因此最大输入量还要为回答、工具参数和中间推理预留空间。
上下文过长会带来三类影响:调用成本和延迟增加,关键信息在大量文本中变得不突出,请求可能超过模型限制而失败。应用应记录每轮输入、输出和缓存 Token,用实际用量制定截断与压缩策略。
响应事件
响应不能只按最终文本处理。Agent 运行时至少要识别以下结果:
- 正常完成,响应包含可展示的最终内容
- 请求工具,响应包含工具名称、调用标识和参数
- 长度截断,模型尚未完整生成结果
- 内容拒绝,模型因安全策略无法继续
- 服务异常,调用超时、限流或暂时不可用
流式响应会把这些结果拆成增量事件。界面可以实时展示文本,但工具参数必须在事件结束并完成解析后才能执行。结束原因应作为运行状态保存,否则恢复任务时无法判断上一轮究竟已经完成,还是在传输过程中中断。
适配层
业务代码不宜直接依赖供应商响应对象。可以在模型客户端外增加一层窄接口,把响应统一为文本输出、工具调用、用量和结束原因。适配层还应负责超时、重试、请求标识和原始响应留存。
这种隔离不能保证模型可无损替换。不同模型对工具选择、长上下文和结构化输出的能力仍有差异,但统一接口可以把协议变化限制在较小范围内,使 Agent Loop 保持稳定。
结构化输出
当模型输出需要进入程序分支、数据库或外部 API 时,自然语言不再是可靠接口。结构化输出通过明确的数据模式约束响应,使调用方能够解析、验证并拒绝不合格结果。
数据模式
JSON Schema 是常见的描述方式。它可以约束字段类型、必填项、枚举、数组长度和嵌套对象。一个任务分类结果可以定义为:
{
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": ["question", "request", "incident"]
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1
}
},
"required": ["category", "confidence"],
"additionalProperties": false
}
模式应尽量表达业务约束,而不是只要求返回一个任意对象。枚举比自由字符串稳定,明确的必填字段比事后猜测缺省值安全,禁止额外字段可以及时发现模型和程序之间的协议漂移。
约束生成与提示生成
仅在提示词中要求模型输出 JSON,仍可能得到 Markdown 代码块、缺失字段或类型错误。支持原生结构化输出的模型会在解码阶段限制可选 Token,使结果满足给定模式。这能解决语法和结构问题,但不能保证字段含义正确。
当模型或接口不支持约束生成时,需要把解析失败视为正常的可恢复错误。程序可以提取 JSON、执行模式校验,并把精确的校验错误返回给模型进行一次修复。修复次数必须有限,避免无效响应形成无限循环。
两层校验
结构校验回答数据是否符合模式,语义校验回答数据是否可以执行。两者缺一不可。
拿退款参数来说,金额字段即使是合法数字,也可能超过订单实付金额;订单标识即使符合字符串格式,也可能不属于当前用户。模式校验之后还要查询权威数据,检查权限、状态和业务不变量。
模型给出的置信度也不能直接当作真实概率。它适合用于排序或触发复核,但阈值需要通过标注数据校准。高风险决策不能只依赖模型自报的置信度。
版本管理
结构化输出属于应用协议,应当像 API 一样管理版本。新增可选字段通常向后兼容,删除字段、修改枚举和改变字段含义则需要迁移。建议在保存结果时同时记录模式版本、模型版本和请求标识,便于重放与审计。
类型定义可以由同一份模式生成,避免客户端类型、服务端校验和模型约束各自维护。模式本身仍要保持精简,过深的嵌套和大量条件分支会增加模型生成难度,也会让错误反馈难以定位。
失败处理
解析失败、模式失败和语义失败应使用不同的错误类型。解析失败可以尝试修复,模式失败可以反馈具体字段,语义失败通常需要重新获取事实或转交人工。任何会改变外部状态的操作,都不能在校验失败后使用猜测值继续执行。
第一个 Agent
第一个 Agent 可以从单一只读工具开始。此时无须搭建完整框架,重点是建立一条清晰的数据路径:接收任务、调用模型、执行工具、返回观察结果,直到模型给出最终回答。
最小接口
运行时只需要认识两类模型输出:最终回答和工具调用。可以用带判别字段的数据结构表示:
type ModelAction =
| { type: "answer"; content: string }
| {
type: "tool_call";
callId: string;
name: string;
arguments: unknown;
};
interface ModelClient {
generate(input: ModelInput): Promise<ModelAction>;
}
ModelClient 隔离具体供应商协议,Agent 只处理归一化后的动作。工具同样采用统一接口,并为参数提供可执行的校验器:
interface Tool<TInput, TOutput> {
name: string;
description: string;
parse(input: unknown): TInput;
execute(input: TInput, signal: AbortSignal): Promise<TOutput>;
}
工具描述供模型理解用途,parse 和 execute 才是安全边界。模型生成的参数始终是不可信输入,不能通过类型断言跳过运行时校验。
只读工具
示例 Agent 可以提供一个查询天气的工具。工具接收规范化城市名和日期,调用受信任的数据源,再返回温度范围、天气状态和数据时间。返回值应保持结构化,并限制原始响应大小。
执行前要完成三项检查:工具名称必须存在,参数必须满足模式,请求必须符合当前权限。即使工具只读,也要设置连接超时、总体截止时间和响应体大小限制。
主循环
最小循环可以写成:
for (let step = 0; step < maxSteps; step += 1) {
const action = await model.generate({ instructions, messages, tools });
if (action.type === "answer") return action.content;
const tool = registry.get(action.name);
if (!tool) throw new Error(`Unknown tool: ${action.name}`);
const input = tool.parse(action.arguments);
const output = await tool.execute(input, signal);
messages.push(toToolResult(action.callId, output));
}
throw new Error("Agent exceeded its step limit");
真实实现还要保存模型发出的工具调用消息,确保后续工具结果能够通过 callId 与它对应。消息顺序必须符合所用模型 API 的协议,不能只把工具返回值拼接成普通用户文本。
终止条件
模型给出最终回答只是终止条件之一。运行时还要处理最大步数、总耗时、Token 预算、费用预算、用户取消和不可恢复错误。限制应由程序强制执行,并在每次模型调用和工具调用前检查剩余预算。
达到限制时,系统应返回明确状态,如超出步骤上限或工具调用超时,不能伪装成正常完成。任务日志至少要包含运行标识、步骤编号、模型动作、工具耗时、错误类型和终止原因。
验证方式
最小 Agent 的测试不需要真实模型。使用脚本化的 ModelClient 依次返回工具调用和最终回答,可以验证工具是否被正确选择、参数失败是否阻止执行、调用标识是否对应,以及步骤上限是否生效。模型效果测试与运行时正确性测试应分开进行。
Agent Loop
Agent Loop 是连接模型与外部世界的控制器。它决定何时调用模型、哪些动作可以执行、观察结果如何写回上下文,以及任务在什么条件下结束。框架的高级功能最终都会落到这条循环上。
状态转换
一次运行可以处于准备、模型调用、动作校验、工具执行、等待批准、完成、失败或取消等状态。显式状态比一段不断追加消息的循环更容易恢复和审计。
每一步应生成不可变记录,至少包含输入状态版本、模型响应、动作、工具结果、时间戳和用量。当前状态由这些记录归约得到。进程异常退出后,运行时可以从最近一个已提交步骤继续,无须重新执行全部动作。
对于会产生副作用的工具,恢复前必须知道调用是否已经到达外部系统。可采用幂等键、事务性发件箱或调用状态查询来避免重复执行。简单地捕获异常后重试,可能造成重复付款、重复发信或重复创建资源。
动作处理
模型响应可能同时包含文本和多个工具调用。运行时需要预先定义处理规则:文本是否展示,多个调用是否允许并行,任一调用失败后其他调用是否继续。规则应保持确定性,不能临时交给模型决定。
工具调用的标准路径包括:
- 根据名称从注册表解析工具
- 校验参数结构和业务约束
- 检查身份、权限、预算与审批策略
- 创建带超时和取消信号的执行上下文
- 保存开始记录并调用工具
- 规范化结果或错误,再写回模型上下文
工具错误应作为带类型的数据返回。模型可以根据可重试错误调整参数,但权限拒绝和审批拒绝不能通过改写措辞绕过。
并发与顺序
只有互相独立、没有共享副作用的调用才适合并行执行。查询两个不同数据源通常可以并行,先创建文件再发送文件链接则必须串行。运行时应根据工具元数据和调用之间的数据依赖决定执行方式。
并行结果写回上下文时,需要保持稳定顺序,并通过调用标识关联原始请求。否则同一任务在不同运行中可能产生不同消息排列,增加模型行为波动和测试难度。
预算与停止
至少要设置最大步骤数、最大模型调用次数、最大工具调用次数和墙钟时间。生产系统还应限制输入输出 Token、单次工具结果大小和累计费用。
模型可能反复调用同一工具或在两个动作之间循环。运行时可以对连续重复动作、相同参数调用和状态无进展进行检测。达到阈值后应终止或请求人工介入,不应继续消耗预算等待模型自行纠正。
取消信号必须贯穿模型客户端和工具客户端。用户取消任务后,运行时停止发起新动作,并尽力中止仍在执行的请求。已经提交到外部系统的副作用需要单独确认状态,不能假设取消等于回滚。
可观测性
一条完整运行应形成父级 Trace,每次模型调用和工具调用形成子级 Span。日志记录控制流事实,Trace 展示调用关系,指标用于观察延迟、错误率、Token 和费用。三者承担不同职责,不宜只保存最终对话文本。
当循环行为异常时,开发者需要回答模型看到了什么、选择了什么、参数为何通过校验、工具实际返回了什么,以及哪个终止条件生效。Agent Loop 的数据模型应直接支持这些问题。
工具
Function Calling
Function Calling 允许模型从预先声明的函数集合中选择一个函数,并生成符合约定的参数。模型不会直接执行函数,执行权始终属于应用程序。
调用协议
应用向模型提交工具名称、用途说明和参数模式。模型需要使用工具时,返回工具名称、调用标识和参数。应用完成校验与执行后,再把工具结果连同调用标识写回上下文。模型据此继续请求其他工具,或者生成最终回答。
调用标识用于处理同一轮中的多个请求。工具结果必须与原始调用一一对应,不能仅凭返回顺序推断关系。采用流式接口时,参数可能以多个增量片段到达,只有收到调用结束事件后才能解析和执行。
工具选择
工具说明直接影响选择质量。名称应体现动作,描述应说明适用场景、输入含义、返回范围和重要限制。多个工具的职责高度重叠时,模型很难稳定选择,应该合并接口或写清差异。
工具集合也不宜无限扩张。每个定义都会占用上下文,并增加误选概率。可以根据任务阶段、用户权限和当前资源动态暴露工具,只把本轮可能使用的最小集合提交给模型。
部分 API 支持强制调用指定工具、要求必须调用某个工具,或禁止工具调用。结构化提取可以强制指定工具或输出模式;普通问答可以允许模型自行选择;处于审批等待状态时则应禁止新调用。
参数并非事实
模型生成的参数属于候选动作。名称、路径、标识、金额和收件人等字段都必须经过验证。即使参数满足 JSON Schema,也可能引用不存在的资源,或超出当前身份的授权范围。
参数中涉及实体时,优先使用系统提供的稳定标识。若用户只给出自然语言名称,应先通过只读搜索工具解析候选对象,存在歧义时请求用户确认。模型不能自行补全高风险标识。
结果设计
工具结果应包含模型完成下一步所需的事实,同时避免返回无关的大块原始数据。推荐使用稳定的结构化字段,并明确成功、空结果、部分成功和失败状态。
面向模型的结果与面向日志的结果可以分开。模型只需要摘要和必要记录,完整 HTTP 响应、堆栈和调试信息保存在受控日志中。这样既能减少 Token,也能避免内部实现细节进入后续上下文。
调用策略
工具调用次数、并行度和超时由运行时控制。模型可以提出多个调用,但运行时有权拒绝、排队或要求审批。工具层负责完成一次受控操作,Agent Loop 负责整个任务的推进,两者不应相互承担对方职责。
工具定义
工具模式既是模型的操作说明,也是运行时的输入契约。模式设计不清会同时导致两类问题:模型难以生成正确参数,程序也难以判断一个动作是否安全。
接口粒度
工具应围绕完整业务动作设计。过细的接口要求模型理解内部调用顺序,过粗的接口又会隐藏关键副作用。读取订单详情是合适的只读动作;直接执行任意 SQL 则暴露了过大的能力范围。
一个工具只承担一个清晰职责。查询与修改应拆开,预览与提交应拆开,高风险动作与普通动作也应拆开。这样可以为它们设置不同权限、超时和审批策略。
参数约束
参数名称应使用业务语义,避免 data、value 一类泛化字段。可以由程序推导的值不要交给模型填写,如当前用户标识、租户标识和请求时间。敏感上下文应由运行时注入,避免模型伪造。
常用约束包括:
- 使用枚举限制有限状态和动作类型
- 为字符串设置格式、长度和允许字符范围
- 为数字设置上下界和单位
- 明确时区、货币和日期格式
- 对数组设置最大元素数,并约束元素结构
- 关闭未声明字段,及时发现参数漂移
可选字段必须有明确语义。字段缺失、字段为 null 和空字符串常常代表不同状态,不应在工具内部随意混用。
描述文本
模式解决结构问题,描述文本负责解释语义。工具描述应说明何时使用、何时不应使用,以及操作会产生什么影响。字段描述应写明数据来源、单位和边界条件。
描述中不要放入会频繁变化的业务数据。可用地区、当前权限和实时配额应通过参数枚举、上下文或查询工具提供,否则文档与系统状态很快失配。
输出模式
工具输出也需要契约。成功结果可以包含 status、稳定标识、关键字段和下一步提示;失败结果包含机器可读错误码、是否可重试和经过裁剪的说明。模型不应解析面向人的错误句子来决定控制流。
分页查询必须返回游标或页码信息,并设置单页上限。搜索结果需要稳定标识和足够的区分字段,避免模型仅凭相似名称选择对象。
演进与测试
修改必填字段、枚举和返回结构会影响提示缓存、历史任务恢复和评测样本。工具模式应有版本,并在 Trace 中记录实际版本。
契约测试应覆盖有效输入、边界值、未知字段、错误类型和权限拒绝。还应收集模型真实生成的参数,检查哪些字段经常混淆,再调整模式或拆分工具。模式设计的目标是减少歧义,而不是容忍所有可能输入。
工具执行
工具运行时位于模型输出和真实系统之间。它负责把候选调用转化为受控执行,并为认证、校验、超时、审计和结果裁剪提供统一入口。
工具注册表
注册表保存工具名称、版本、模式、处理函数和策略元数据。名称在一个运行范围内必须唯一,版本变化应可追踪。工具是否可见由当前任务、用户身份和环境共同决定。
注册表不能让模型通过任意字符串加载模块或拼接命令。工具实现由应用预先注册,模型只在白名单中选择。对于插件系统,插件安装与工具调用属于不同权限层级,运行中的 Agent 不应自行安装未知代码。
执行上下文
处理函数除了业务参数,还需要受信任的执行上下文,包括用户身份、租户、运行标识、截止时间、取消信号、幂等键和日志接口。这些字段由运行时注入,不出现在模型可编辑的参数中。
interface ToolContext {
runId: string;
userId: string;
tenantId: string;
deadline: Date;
signal: AbortSignal;
idempotencyKey?: string;
}
身份传递应遵循最小权限。工具只获得完成当前动作所需的授权,不共享平台级管理员凭据。访问第三方服务时,要明确使用用户授权还是应用身份,并把授权主体写入审计记录。
资源限制
每个工具应设置独立的连接超时、总体超时、最大响应体和并发限制。代码执行、浏览器和文件处理还需要 CPU、内存、磁盘、网络和进程数量限制。
仅有超时并不能保证资源释放。处理函数必须响应取消信号,并在结束时关闭连接、临时文件和子进程。运行时应区分主动取消、截止时间到达和远端超时,以便选择正确的恢复策略。
结果规范化
工具实现返回领域对象,运行时将其转换为统一结果:
type ToolResult<T> =
| { ok: true; data: T; metadata?: Record<string, unknown> }
| { ok: false; error: { code: string; retryable: boolean; message: string } };
写回模型之前,应移除密钥、内部地址、堆栈和不必要的个人数据。大型结果可以保存到对象存储,再向模型提供受限摘要和引用标识。引用必须绑定权限和有效期,不能暴露永久公开链接。
副作用分级
工具可以按只读、可逆写入、不可逆写入和高风险操作分级。级别决定是否需要预览、审批、幂等键和二次确认。策略应由运行时强制,而不是依赖工具描述提醒模型。
审计记录需要覆盖调用主体、目标资源、参数摘要、策略判断、审批人、执行结果和关联 Trace。敏感参数应脱敏,但不能因此失去追踪关键动作的能力。
错误与重试
Agent 会把工具错误重新放入上下文,因此错误设计会直接影响后续决策。只有可识别、可分类的失败,才能采用正确的重试、修复或终止策略。
错误分类
工具错误可以分为四类:
- 输入错误,参数缺失、格式不符或业务条件不成立
- 权限错误,当前主体没有访问或修改目标资源的权限
- 暂时错误,限流、网络抖动和依赖服务短暂不可用
- 永久错误,资源不存在、功能不支持或不可恢复的数据冲突
错误对象应包含稳定错误码、可重试标志和适合模型理解的有限说明。内部堆栈、数据库语句和认证信息只进入受控日志。
重试条件
重试仅适用于暂时错误,并且操作必须安全。只读请求通常可以重试;写操作需要幂等键或服务端去重保证。无法判断前一次写入是否成功时,应先查询操作状态,不能直接再次提交。
指数退避可以减少依赖服务压力。第 次等待时间可写为:
其中随机抖动 用于避免大量客户端同时重试。服务端返回 Retry-After 时应优先遵循该值。最大次数和总体截止时间必须同时限制。
模型修复
输入错误可以交给模型修正一次或有限次数。反馈内容应指出具体字段及约束,如日期早于允许范围,而不是只返回参数无效。修复后的调用仍要重新经过全部校验。
权限拒绝不属于可修复输入。模型改用另一个工具、修改目标名称或声称得到授权,都不能改变运行时判断。需要额外权限时,任务应进入等待批准状态。
熔断与降级
当某个依赖持续失败,继续调用只会增加延迟和故障范围。熔断器在错误率超过阈值后暂时拒绝请求,并在冷却期后进行少量探测。Agent 收到熔断错误后可以使用已定义的备用数据源,或明确告知当前无法取得数据。
降级结果必须标明来源和新鲜度。缓存数据、局部搜索结果和估算值不能伪装成实时权威结果。对于会影响决策的字段,应把不确定性传递到最终回答。
循环检测
模型可能在同一错误上反复修改无关字段。运行时应记录工具名称、规范化参数、错误码和状态变化。当连续调用完全相同,或若干步后回到相同状态时,可以判定无进展并停止。
终止记录应保留最后一次可操作错误和已经尝试的方法,便于人工继续处理。简单返回达到最大步骤数无法解释任务为什么失败,也不利于改进工具设计。
MCP
Model Context Protocol,简称 MCP,用统一协议连接 Agent 与外部工具、资源和提示模板。它解决的是能力发现与调用的互操作问题,不负责替应用定义业务权限和安全策略。
参与方
MCP 架构包含 Host、Client 和 Server。Host 是承载 Agent 的应用,负责用户界面、模型调用和安全策略;Client 由 Host 创建,用于维护到某个 Server 的协议连接;Server 对外提供工具、资源或提示模板。
一个 Host 可以连接多个 Server,并为不同任务选择不同能力。Server 不应默认看到 Host 的全部上下文,Client 只发送完成当前协议操作所需的数据。
核心能力
Tools 表示可由模型选择的动作,具有名称、描述和输入模式。Resources 表示可读取的数据,通常通过 URI 标识。Prompts 表示可复用的提示模板,由用户或应用显式选择。
工具调用与普通 Function Calling 的基本过程相似,但 MCP 增加了标准化的发现、能力协商和传输协议。应用仍需把 MCP 工具转换成模型 API 所需的工具定义,并把结果写回 Agent Loop。
生命周期
连接建立后,双方先交换协议版本和能力,再进入初始化完成状态。运行期间可以列出工具和资源、读取资源、调用工具,并接收能力列表变化等通知。客户端要处理 Server 重启、连接中断和版本不兼容。
本地 Server 常通过标准输入输出传输,远程 Server 可以使用 Streamable HTTP。标准输入输出适合由 Host 启动并管理的本地进程;远程传输需要额外处理认证、网络边界、超时和服务可用性。
信任边界
发现到工具不等于获得执行许可。Host 应根据 Server 身份、用户授权、工具风险和当前任务决定是否暴露给模型。工具名称与描述来自 Server,也属于不可信元数据,不能覆盖 Host 策略。
远程 MCP Server 可能接触用户输入、资源内容和工具参数。接入前需要核对运营主体、数据处理范围和认证方式。访问令牌应绑定目标服务和最小权限,不能把其他系统的令牌转发给未知 Server。
工具结果可能包含提示注入内容。Host 应保留数据来源,对敏感动作执行独立确认,并限制 Server 返回内容的大小和类型。浏览器、文件系统和代码执行类 Server 还需要沙箱隔离。
与 Agent Infra 的关系
MCP 统一能力接口,但不会提供任务队列、持久化执行、租户隔离、弹性扩缩和集中审计。开发阶段可以在进程内直接连接少量 Server;进入生产环境后,连接管理、凭据代理、策略执行和工具网关会逐渐成为 Agent Infra 的组成部分。
协议实现应依据 MCP 官方规范 的版本要求进行兼容性测试,避免依赖某个 SDK 的非标准行为。
上下文与知识
Context Engineering
Context Engineering 研究如何在有限上下文窗口内,为模型组织完成当前决策所需的信息。它覆盖信息选择、排序、压缩、隔离和生命周期管理,比单独调整提示词涉及的范围更广。
上下文组成
一次 Agent 调用的上下文通常包含系统指令、当前任务、对话历史、工具定义、工具结果、检索材料、任务状态和输出约束。这些内容具有不同的可信度、时效性和优先级,应在数据结构中明确区分。
高优先级指令用于规定稳定行为,不适合混入网页正文等外部内容。事实数据应保留来源和获取时间。任务状态应使用结构化字段保存,不能完全依赖模型从历史对话中重新推断。
选择原则
上下文不是越多越好。信息选择可以遵循相关性、权威性、新鲜度和可操作性四项标准。与当前步骤无关的历史即使正确,也会分散模型注意力;来源不明的材料不应覆盖权威系统记录。
常见的组织顺序为稳定指令、当前任务、关键状态、近期交互和外部证据。决定性约束应靠近需要它的输入,并使用清晰边界标记不同来源。重复粘贴同一规则会浪费 Token,也可能产生版本冲突。
上下文预算
设模型窗口为 ,预留输出为 ,工具定义占用 ,则可供任务材料使用的预算近似为:
其中 是固定指令与协议开销。应用应在发送请求前计算预算,并为各类内容设置上限。不能等 API 返回超长错误后再临时截断。
裁剪顺序取决于业务语义。通常先移除重复材料和低相关检索结果,再压缩较早历史,只有其他手段仍无法满足预算时才缩减关键证据。系统规则、未完成动作和审批状态不能因长度不足被静默删除。
上下文隔离
多用户、多租户和多 Agent 系统必须防止上下文串线。缓存键、向量检索过滤条件、会话存储和 Trace 查询都要包含正确的身份范围。仅在提示词中写明用户身份不能形成隔离。
委派任务时,子 Agent 应收到最小必要上下文。完整转发父任务历史会泄露无关数据,也会让子 Agent 难以识别自己的职责。返回结果应包含结论、证据和状态,而不是复制全部内部过程。
评估方法
上下文质量可以通过消融实验检查。分别移除某类信息,观察任务成功率、工具选择和事实错误是否变化。还应测试长历史、相互冲突的来源、过期数据和恶意文档。
Token 使用率只是成本指标。真正的目标是在可控预算内,让模型获得足够、正确且边界清楚的信息,并能说明关键结论来自哪个来源。
Session 与状态
Session 表示一次连续交互的边界,State 表示任务在某个时刻可以被程序读取和恢复的事实。聊天消息属于状态的一部分,但不能承担全部状态管理职责。
状态分类
Agent 应用通常需要保存四类状态:
- 会话状态,包括用户消息、助手消息和工具调用关系
- 任务状态,包括目标、步骤、待办项、当前阶段和终止原因
- 业务状态,来自订单、代码仓库和工单系统等权威数据源
- 运行状态,包括预算、锁、租约、重试次数和审批等待信息
业务状态不应复制后长期依赖。Agent 可以缓存快照,但执行写操作前要重新读取权威版本并检查并发冲突。
事件与快照
只保存最新消息数组,实现简单但难以解释状态变化。事件日志会把用户输入、模型响应、工具开始、工具结束和审批结果记录为不可变事件,再通过归约得到当前状态。
事件记录适合审计和重放,快照适合快速恢复。系统可以每隔若干步骤保存一次快照,同时保留快照之后的事件。快照必须标记状态模式版本,升级数据结构时执行显式迁移。
一致性
模型调用和工具调用往往跨越多个系统,无法放在单个数据库事务中。运行时应为每一步定义提交点。工具执行前保存意图,执行成功后保存结果,后续模型调用只读取已提交状态。
多个进程处理同一任务时,需要租约或乐观并发控制。写入状态时比较版本号,发现版本已经变化就停止当前执行,避免两个 Worker 同时推进任务。
恢复语义
恢复任务时,应检查最后一个步骤的状态。模型调用未得到响应可以重新发起;只读工具通常可以重新执行;带副作用的工具必须通过幂等键或外部状态查询确定结果。
等待人工批准是一种可持久化状态,不应让进程和数据库连接一直占用。批准事件到达后,调度器重新激活任务,并从已保存的动作继续执行。
生命周期
Session 结束不代表数据永久保存。消息、工具结果、附件和 Trace 应分别设置保留期限。包含个人数据或密钥的字段要支持删除和脱敏,日志不能成为绕过业务删除策略的副本。
状态存储应明确哪些字段用于产品功能,哪些用于调试和评测。保留范围越大,安全与合规成本越高。恢复所需的最小状态通常比完整上下文少得多。
Memory
Memory 让 Agent 在当前上下文之外保存并重新使用信息。它由多种记忆机制组成,各自具有不同的写入规则、检索方式和保留期限。
记忆类型
工作记忆保存当前任务正在使用的信息,通常直接位于上下文或任务状态中。情景记忆记录过去发生过的交互和任务。语义记忆保存经过整理的事实,如用户长期偏好。程序性记忆保存可复用的方法、规则和技能。
这几类记忆不能采用同一写入策略。工作记忆随任务结束清理,用户偏好需要确认来源和适用范围,技能更新则应经过版本审查和测试。
写入策略
把每轮对话自动写入长期记忆会迅速积累噪声。长期记忆应满足稳定、未来有用、来源明确和允许保存等条件。敏感信息需要更严格的授权和保留策略。
写入可以分为候选提取、去重、冲突检测和确认四步。模型负责从交互中提出候选事实,确定性程序负责检查字段和权限。新事实与已有事实冲突时,应保存时间与来源,不能无条件覆盖。
检索策略
检索需要结合当前任务构造查询,并按用户、租户、记忆类型和有效期过滤。向量相似度适合语义匹配,但不能替代身份过滤和时间判断。结构化偏好适合直接按键读取,不必全部向量化。
返回上下文前可以执行重排,综合相关性、新鲜度、可信度和使用成本。记忆结果要附带来源,模型应能够区分用户明确陈述、系统推断和外部导入数据。
更新与遗忘
长期记忆会过期。系统需要支持修改、撤回、衰减和删除。拿用户偏好来说,最近一次明确选择通常比多年前的行为推断可靠,但一次临时选择也不应立刻覆盖稳定偏好。
可以为记忆设置置信度和有效期,但这些值只能辅助策略。涉及身份、权限、医疗和财务的信息,应从权威系统实时读取,不能依赖模型记忆。
安全边界
不同用户和租户的记忆必须在存储与检索层隔离。模型生成的查询过滤条件不能决定授权范围,授权条件由运行时强制追加。
记忆内容也可能携带提示注入。历史网页片段、工具输出和第三方文本在未来被检索时仍然是数据。写入前应保留来源标签,读取后不得提升其指令优先级。
评估
Memory 评测至少包括应记住时能否检索、无关时是否保持安静、事实更新后能否使用新版本、删除后是否彻底消失,以及跨用户是否发生泄露。仅检查检索相似度不足以证明记忆系统可用。
RAG
Retrieval-Augmented Generation,简称 RAG,在模型生成前从外部知识源检索材料,并把相关证据加入上下文。它用于提供可更新、可追溯的领域事实,不会自动保证回答正确。
数据管线
离线阶段通常包括采集、解析、切分、元数据提取、向量化和建立索引。在线阶段包括查询理解、召回、过滤、重排、上下文组装和答案生成。
文档切分应尊重语义边界。固定字符长度实现简单,但容易把表格、代码和定义拆开。分块需要保留文档标识、章节路径、版本、权限和更新时间,方便过滤与引用。
召回与重排
关键词检索擅长精确术语、编号和名称,向量检索擅长语义近似。混合检索常比单一方式稳定。初步召回可以取得较多候选,再由重排模型或规则选出少量高相关片段。
召回率和精确率存在权衡。候选过少会漏掉证据,候选过多会增加噪声和 Token。评测应先判断正确证据是否被召回,再判断模型是否正确使用证据,不能把两类错误混在一起。
权限过滤
检索必须先受访问控制约束。向量相似度不能判断用户是否有权读取文档。索引应保存可执行的权限元数据,查询时由服务端追加租户、主体和资源范围过滤。
权限变化后,索引需要及时同步。对于无法可靠过滤的数据源,可以先召回标识,再回源执行权限检查,确认后才把正文加入上下文。
答案与引用
提示应要求模型以检索证据为依据,在证据不足时明确说明。引用需要指向实际支持对应结论的片段,不能只列出若干相关文档。生成后可以检查引用标识是否存在、用户是否可访问,以及引用文本是否包含关键事实。
文档之间发生冲突时,应优先使用权威且较新的来源,并在答案中保留差异。模型不能自行把冲突材料合成为一个看似确定的结论。
RAG 与工具
RAG 适合读取相对静态的知识,工具适合查询实时状态和执行动作。产品说明可以来自知识库,当前库存和订单状态应通过业务 API 查询。把实时数据库定期复制到向量库,会引入同步延迟和权限复杂度。
Agent 可以决定何时检索以及如何改写查询,但检索服务仍需限制返回范围、执行权限过滤并记录证据。所有外部文档都应被视为不可信数据,以防其中的文本改变 Agent 行为。
上下文压缩
当会话和工具结果不断增长时,完整重放历史会超过上下文窗口,也会增加延迟和成本。上下文压缩的目标是在减少 Token 的同时,保留继续执行任务所必需的事实、约束和未完成状态。
删除、截断与摘要
删除适合处理重复内容、调试信息和已经失效的候选。截断适合保留近期消息,但可能丢失早期约束。摘要把较长历史转换为紧凑表述,能够保留更早信息,但会引入模型遗漏和改写错误。
实际系统通常组合三种方法:原样保留稳定指令和近期交互,对大型工具结果做结构化裁剪,把较早对话压缩成带来源的摘要。
需要保留的状态
摘要至少应覆盖任务目标、已经确认的事实、用户约束、完成的动作、未完成事项、外部资源标识和审批状态。失败尝试可以压缩,但不能删除会导致重复副作用的信息。
业务状态更适合保存在结构化存储中,再按需注入上下文。拿文件修改任务来说,当前分支、已修改文件和测试结果应作为任务字段保存,不应只存在于自然语言摘要。
分层压缩
短任务可以采用滑动窗口。长任务可以按阶段生成摘要,并保留阶段边界。更复杂的系统会维护事实表、计划表和证据引用,模型调用时只选择当前步骤相关部分。
压缩也可以针对工具结果。日志查询只返回异常窗口和统计值,搜索结果只保留重排后的片段,代码分析只保留相关符号及调用关系。原始数据保存到外部存储,通过受控引用追溯。
摘要校验
模型生成摘要后,可以检查关键字段是否出现、资源标识是否一致、未完成动作是否保留。高风险状态应直接从结构化记录生成,不让摘要模型自由改写。
摘要需要记录覆盖的事件范围和生成版本。后续发现遗漏时,可以回到原始事件重新生成。只有摘要而没有原始记录,会让错误难以修复。
触发时机
压缩可以在 Token 达到阈值时触发,也可以在任务阶段切换时触发。阶段切换通常更容易形成语义完整的摘要。阈值应给模型输出和下一轮工具定义预留空间,避免每次调用前都紧急压缩。
评测压缩策略时,应比较压缩前后的任务成功率、关键事实保持率、引用准确性、Token 和延迟。压缩率高但导致重复工具调用或遗漏限制,并不能降低总体成本。
Workflow 模式
Prompt Chaining
Prompt Chaining 把一个复杂任务拆成多个顺序执行的模型步骤,前一步输出经过校验后成为后一步输入。控制流由程序确定,因此它属于 Workflow,而不是开放式 Agent Loop。
适用场景
当任务能够分解为稳定阶段,并且每个阶段都有明确输入输出时,链式流程通常比一次长提示更可靠。典型过程包括先提取事实,再按规则分类,随后生成面向用户的文本。
拆分的价值在于隔离职责。提取步骤只关注来源内容,分类步骤只处理结构化事实,生成步骤不能随意补充来源中不存在的信息。每个节点都可以单独测试和替换模型。
接口设计
节点之间应传递结构化数据,而不是把上一轮自然语言原样拼入下一轮。输入模式和输出模式构成节点契约。校验失败时,流程在当前节点停止或有限重试,不让错误继续扩散。
链路还要保存来源关系。最终文本中的结论应能追溯到提取出的事实和原始证据。若中间步骤执行摘要,需要保留对应引用标识。
质量门
可以在节点之间插入确定性检查,如字段完整性、敏感信息检测、长度限制和业务规则。只有通过质量门的数据才进入下一步。
模型检查也可以作为质量门,但不应与生成节点使用完全相同的提示和上下文。评审节点需要明确标准,并输出具体问题与通过状态。高风险结论仍应由规则或人工确认。
错误与恢复
每个节点应拥有独立状态、超时和重试策略。流程中断后从最近的成功节点继续,避免重复调用昂贵模型。节点输出的缓存键要包含模型、提示、模式版本和输入摘要,防止错误复用旧结果。
链式流程的总延迟等于多个串行步骤之和。没有依赖关系的工作不应强行串联,可以改用并行模式。拆分也不能过细,否则大量边界转换会增加成本,并使上下文丢失。
评估
除了端到端结果,还要分别测量各节点的准确率和失败分布。若最终错误主要来自事实提取,继续修改生成提示不会有效。节点级评测正是 Prompt Chaining 相比单次调用的重要工程优势。
Routing
Routing 根据输入特征选择后续处理路径。路由器可以由规则、分类模型或大语言模型实现,目标是把任务交给能力、成本和风险最匹配的处理器。
路由依据
常见依据包括任务类型、语言、数据敏感级别、所需工具、上下文长度和服务等级。分类标签应直接对应可执行分支,避免生成含义模糊的自由文本。
规则适合稳定且可枚举的条件,如文件类型、用户权限和金额阈值。模型适合判断自然语言意图和复杂语义。两者可以组合,先由规则执行权限与硬约束过滤,再由模型在允许范围内分类。
分层路由
一次路由不必解决所有选择。第一层可以识别是否需要 Agent,第二层选择领域,第三层再选择具体工具或模型。分层设计能缩小每个分类器的标签集合,也便于按领域独立评测。
路由结果应包含目标分支、置信信息和判定依据。置信信息用于触发复核或默认分支,不能直接作为概率解释。无法可靠分类时,应进入安全的通用处理器或请求补充信息。
模型路由
不同模型在能力、延迟和成本上存在差异。简单提取可以使用小模型,复杂推理再升级到更强模型。升级条件应通过离线评测和线上指标确定,不能仅根据输入长度猜测难度。
模型路由要考虑供应商能力差异,如工具调用、结构化输出、上下文窗口和数据区域。降级模型无法满足必要能力时,应失败而不是静默切换。
安全边界
路由器不能提升权限。用户输入声称任务紧急或要求进入管理员分支,不构成授权依据。所有分支仍要独立检查身份和资源范围。
恶意输入可能诱导模型路由器选择高权限工具。可以只向路由器提供经过裁剪的任务描述和允许分支,敏感策略由确定性代码执行。
评估与观测
路由评测需要包含标签混淆矩阵、拒绝率、回退率和各分支端到端成功率。某个标签分类准确,并不代表下游处理有效。
线上应记录路由版本、选择结果、候选分数、回退原因和最终任务结果。数据分布发生变化后,标签定义和评测集需要同步更新。
Parallelization
Parallelization 同时执行没有数据依赖的模型调用或工具调用,用于降低总延迟、扩大信息覆盖,或者从多个独立结果中形成更稳健的判断。
并行条件
两个任务只有在输入已经具备、执行顺序不影响语义、不会竞争同一可变资源时,才适合并行。查询多个独立数据源通常符合条件,连续修改同一文件或同一订单则不符合。
并行图可以表示为有向无环图。节点之间存在数据依赖时建立边,同一层无依赖节点并发执行。程序根据图调度,比让模型临时声称若干动作可以并行更可靠。
常见形式
分片模式把数据集拆成多个区间,使用同一处理器并行计算,再合并结果。多视角模式让不同提示或不同模型独立分析同一输入,最后由聚合器比较。扇出查询同时访问多个来源,并按来源权威性和新鲜度整合。
多视角结果并不天然独立。相同模型、相同训练数据和相似提示会产生相关错误,简单多数投票可能形成虚假置信。需要通过评测确认不同分支是否真正提供互补信息。
并发控制
并发量受模型速率限制、工具容量和任务预算约束。调度器应设置全局、租户和任务级上限,并使用队列提供背压。无限制地对每个候选启动调用,会把短暂流量放大为依赖故障。
每个分支需要独立超时和取消信号。整体策略可以等待全部结果、取得前若干成功结果,或在满足判定条件后取消剩余分支。策略必须与业务完整性要求一致。
结果合并
结构化分片可以用确定性代码合并。自然语言分析需要聚合节点时,应向其提供来源标识、冲突信息和缺失分支,不能只给出无来源的摘要列表。
部分失败时要明确结果完整度。若五个数据源只有三个成功,最终回答应说明覆盖范围。对必须完整执行的任务,任一关键分支失败都应阻止后续提交。
成本评估
并行化主要降低墙钟时间,不会自动降低总计算量。它可能增加 Token、请求数和峰值资源。设计时应同时比较延迟分位数、成功率和单任务成本,避免为了较小的响应提升制造过高的资源峰值。
Orchestrator 与 Worker
Orchestrator-Workers 模式由一个协调节点分析任务、拆分子任务并分配给多个 Worker,随后汇总结果。它适合子任务数量和边界无法在开发阶段完全确定的场景。
职责划分
Orchestrator 负责理解目标、建立任务图、定义子任务接口、控制预算和判断整体完成。Worker 负责在限定范围内完成单个子任务,并返回结构化结果、证据和状态。
Worker 不应依赖 Orchestrator 的隐含上下文。任务描述需要包含目标、输入、允许工具、输出模式、截止时间和验收条件。职责越明确,结果越容易并行合并。
任务分解
好的分解应减少共享可变状态,并使子任务输出能够独立验证。按文件、数据源、模块或问题维度分解通常比按模糊角色分解更稳定。
Orchestrator 生成计划后,运行时仍要校验子任务数量、递归深度和预算。模型不能无限创建 Worker。每个子任务都要继承正确的用户身份和数据范围,但只获得自身所需能力。
调度
无依赖子任务可以并行,有依赖子任务按任务图顺序执行。调度器负责并发上限、租约、重试和取消。Orchestrator 不应通过自然语言轮询 Worker 状态,状态变化应由运行时事件驱动。
Worker 失败后,可以按错误类型重试、重新分配或缩小任务。重复分配带副作用的工作需要幂等保障。整体任务取消时,尚未开始的子任务停止调度,运行中的子任务接收取消信号。
汇总
汇总过程要处理重复、冲突和缺失。结构化结果先由程序做去重和完整性检查,再交给模型形成跨子任务结论。引用和资源标识必须保留到最终结果。
若子任务结果互相矛盾,Orchestrator 可以创建专门的核验任务,或者把差异提交人工判断。不能让汇总模型在没有额外证据时随意选择一方。
与固定并行的区别
固定并行的分支在代码中预先定义,Orchestrator-Workers 的子任务由模型根据输入动态生成。只有任务结构确实随输入变化时,动态编排才有价值。固定章节摘要、固定数据源查询更适合普通并行 Workflow。
动态性提高了覆盖复杂任务的能力,也增加了成本不可预测、任务重复和权限扩散的风险,因此必须配置全局预算、最大深度和可观测的任务图。
Evaluator 与 Optimizer
Evaluator-Optimizer 模式让生成器产出候选结果,再由评估器按照明确标准给出反馈,生成器据此修订,直到通过质量门或达到迭代限制。
适用条件
该模式要求质量标准能够清楚表达,并且根据反馈修改确实能提高结果。代码是否通过测试、文档是否覆盖指定字段、答案是否引用证据,都适合评估。单纯要求结果更好或更自然,难以形成稳定停止条件。
生成器和评估器可以使用不同提示、不同模型或不同工具。评估器应只获得判断所需信息,并尽量采用结构化输出,包括通过状态、问题位置、严重级别和修改建议。
评估顺序
确定性检查应先执行。编译、测试、模式校验、链接检查和安全规则成本较低,结果也更稳定。只有难以编码的语义标准再交给模型评估。
模型评估容易受到措辞、候选长度和位置影响。评分标准需要给出可观察条件和反例,避免使用优秀、完整等宽泛标签。重要评测应通过人工标注样本校准。
迭代控制
每轮只向生成器提供具体、可操作的反馈,并保存候选版本和评估结果。重复出现相同问题或分数没有改善时,应提前停止。
系统需要限制最大轮数、累计 Token 和墙钟时间。达到限制但仍未通过时,应返回未通过状态及剩余问题,不能把最后一个候选默认当作成功结果。
偏差与共谋
同一模型同时生成和评估时,可能重复相同误解。使用不同模型也不能保证独立,因为评价标准和训练数据可能相似。可以引入确定性证据、隐藏测试和人工抽检降低共同偏差。
评估器不能访问会泄露标准答案的无关信息。对于安全评测,还要防止候选内容通过提示注入影响评估器。候选应被明确标记为待评数据,评估指令放在更高优先级。
结果使用
评估分数适合比较版本和触发流程,不能自动代表真实用户价值。线上还要观察任务完成率、人工接管率、错误后果和用户反馈。Evaluator-Optimizer 是生成流程的一部分,离线 Evals 则用于系统级测量,两者用途不同。
Human in the Loop
Human in the Loop,简称 HITL,在关键决策点暂停自动执行,由人补充信息、选择候选、批准动作或接管任务。它是一种运行状态和控制机制,不能只实现成聊天中的确认句。
触发条件
人工介入适合用于高影响、低置信、信息歧义和策略要求的场景。高影响动作包括支付、删除、公开发布和权限变更;信息歧义包括同名联系人、目标资源不明确和条件冲突。
触发策略可以综合动作风险、金额、用户角色、模型评测结果和工具状态。风险规则必须由程序执行,模型可以建议请求批准,但不能自行降低动作等级。
批准对象
批准界面应展示即将执行的具体动作、目标、关键参数、数据来源和预期影响。用户批准的是一个不可变动作版本,而不是抽象目标。批准后参数发生变化,应重新请求批准。
为动作计算摘要并绑定审批记录,可以防止批准与执行错位。审批记录还应包含批准人、时间、作用范围和有效期。一次批准不应默认覆盖后续相似动作。
持久化等待
等待人工期间,任务进入持久化状态并释放计算资源。运行时保存待批准动作、上下文版本和恢复位置。收到批准、拒绝或修改事件后,再由调度器恢复。
审批可能在数小时后完成,原始业务状态已经变化。执行前需要重新检查权限、余额、资源版本等前置条件。批准表示允许尝试执行,不保证动作在未来任何状态下都有效。
拒绝与修改
拒绝应作为明确事件写入 Agent 上下文。模型可以根据原因提出低风险替代方案,但不能换一个名称相近的工具绕过拒绝。
用户修改参数时,应形成新的候选动作并重新执行校验。界面需要区分修改建议和已批准动作,避免自然语言反馈被误解为授权。
接管
某些任务不适合继续自动运行,应允许人工完全接管。接管信息需要包含当前目标、已完成步骤、外部副作用、未解决问题和证据链接。内部推理文本不是可靠的交接材料,结构化运行记录才是。
HITL 指标可以观察触发率、批准率、等待时间、批准后失败率和误触发率。人工介入过多会使自动化失去价值,介入过少则会放大高风险错误,需要根据实际后果持续调整策略。
多 Agent
Handoff
Handoff 把当前任务的控制权从一个 Agent 转交给另一个 Agent。转交后,接收方负责继续与用户或环境交互,原 Agent 通常不再参与每一步决策。
转交语义
Handoff 与调用工具不同。工具完成一个有限动作并把结果返回调用者,Handoff 改变当前负责者。接收方可能拥有不同指令、工具和权限,也可能直接生成最终回答。
转交应被建模为显式动作,包含目标 Agent、任务说明、必要上下文和转交原因。运行时校验目标是否存在、当前身份是否允许转交,以及接收方是否具备处理能力。
上下文交接
完整复制历史实现简单,但容易泄露无关信息并占满上下文。更稳妥的交接包包括用户目标、已确认事实、已执行动作、未完成事项、关键证据和适用约束。
交接包需要保留来源和状态版本。接收方不能把上一个 Agent 的推测当作权威事实。涉及订单、权限和实时状态时,应重新查询权威系统。
路由与返回
Handoff 可以由入口 Agent 根据意图选择专家,也可以由当前 Agent 在发现能力不足时触发。目标集合应有限且职责互斥,描述中写清接收条件和拒绝条件。
系统要定义是否允许回交。双向回交容易形成循环,可以记录转交路径并限制次数。目标 Agent 无法处理时,应返回结构化拒绝原因,交由入口重新路由或人工接管。
权限
接收方获得的是自身角色允许的权限,不应自动继承转出方全部能力。用户授权也要校验是否覆盖新的处理目的。跨团队、跨租户和跨区域转交尤其需要检查数据范围。
高风险动作的批准不能通过 Handoff 绕过。批准记录绑定具体动作与参数,换 Agent 后仍要遵守相同策略。
可观测性
同一任务的 Trace 应跨越 Handoff,记录转出方、接收方、原因、交接包版本和耗时。评测除了最终成功率,还要观察错误转交、循环转交和转交后的信息损失。
Manager 模式
Manager 模式由一个面向用户的主 Agent 保持控制权,并把有限子任务作为工具调用委派给专业 Agent。专业 Agent 返回结果后,主 Agent 继续整合和回应。
与 Handoff 的区别
Handoff 改变当前负责者,Manager 模式不改变。用户始终与主 Agent 交互,子 Agent 更接近具有模型能力的复杂工具。需要统一语气、统一审批和跨领域汇总时,Manager 模式通常更合适。
主 Agent 负责拆分任务、选择专家、分配预算、解决冲突和生成最终结果。专业 Agent 只处理明确范围,如代码审查、资料检索或数据分析。
专业 Agent 接口
专业 Agent 应提供稳定的输入输出契约。输入包含目标、材料引用、约束和截止条件,输出包含状态、结论、证据、未解决问题和用量。不要把任意聊天历史当作接口。
专业 Agent 的工具和提示可以独立演进,但返回模式变化需要版本管理。主 Agent 不应依赖其内部步骤,只依赖契约结果。
调度策略
多个专业 Agent 没有依赖时可以并行,有依赖时建立任务图。Manager 要限制委派数量和递归深度,防止专业 Agent 再次无限委派。
子任务失败后,主 Agent 可以重试、选择替代专家或向用户说明缺失部分。重试前应检查失败类型,不能让模型对权限拒绝进行无意义重试。
结果整合
主 Agent 收到多个结果后,先由程序检查结构完整性和引用,再进行语义整合。冲突结果要保留各自证据,必要时启动独立核验,不能让主 Agent 根据表达方式选择答案。
最终回答应明确哪些部分已经验证,哪些部分仍有不确定性。子 Agent 的内部置信陈述不能替代证据。
成本与治理
Manager 模式会放大模型调用数量。预算应同时限制总调用、并发和单个专家消耗。每个子任务继承用户数据范围,但只获得所需工具。
Trace 需要展示委派树、每个专家的模型与版本、输入摘要、输出状态和成本。没有委派级可观测性时,多 Agent 系统很难定位质量下降来自哪个节点。
通信与边界
多 Agent 系统的主要难点不在于让多个模型互相发送文本,而在于定义职责、通信契约、共享状态和失败边界。缺少这些约束时,增加 Agent 数量通常只会增加重复工作。
职责边界
每个 Agent 应有单一、可描述的职责,并拥有完成职责所需的最小工具。职责重叠会导致重复调用和结果冲突,职责之间存在空白则会让任务在转交过程中丢失。
角色名称不能替代接口定义。研究员、分析师等名称范围过宽,需要进一步说明接收什么输入、交付什么结果、允许访问哪些数据,以及哪些情况必须拒绝。
消息契约
Agent 间通信应优先采用结构化信封:
interface AgentMessage<T> {
taskId: string;
messageId: string;
sender: string;
recipient: string;
type: "request" | "result" | "error" | "cancel";
payload: T;
deadline: string;
traceId: string;
}
消息标识用于去重,任务标识用于关联上下文,截止时间防止过期工作继续执行。载荷模式需要版本管理。自然语言可以存在于载荷中,但控制字段不能靠模型猜测。
共享状态
多个 Agent 直接修改同一消息数组会产生顺序竞争和上下文污染。更稳妥的方法是让每个 Agent 保有局部上下文,通过任务存储交换已提交结果。
共享业务资源需要并发控制。修改文件可以采用分支或补丁,修改数据库记录可以采用版本号和事务。模型无法解决底层写冲突,运行时必须检测并提供明确反馈。
故障边界
子 Agent 超时、取消或产生无效结果,不应使整个协调进程失去状态。每个子任务具有独立重试和终止记录,父任务根据依赖关系决定继续、降级或失败。
通信采用至少一次投递时,接收方必须幂等。消息重复、乱序和延迟都要纳入测试。仅在本地顺序执行成功,不能证明分布式运行可靠。
信任关系
Agent 发来的内容和外部工具结果一样,都属于待验证数据。接收方不能因为发送者是内部 Agent 就执行其中的任意指令。权限由运行时身份和策略决定,不能沿消息链隐式扩张。
跨系统通信还要验证发送者身份、消息完整性和目标受众。日志应记录数据经过哪些 Agent,便于追踪泄露和错误传播。
Agent 协议
Agent 协议用于在不同进程、框架或组织之间交换任务与结果。协议解决互操作性问题,具体 Agent 仍需自行实现推理、工具调用、权限控制和状态管理。
协议层次
Agent 系统至少涉及三类协议。模型协议连接应用与模型服务,工具协议连接 Agent 与能力提供方,Agent 间协议连接任务委派方与执行方。它们解决的问题不同,不宜用一个接口统一替代。
MCP 主要面向工具、资源和提示模板。Agent 间协议更关注能力发现、任务生命周期、消息交换、流式事件和产物交付。普通 HTTP API 也可以承担这些功能,只要契约稳定并具备认证与状态语义。
能力发现
可互操作 Agent 需要声明身份、能力、输入输出类型、认证方式和服务地址。能力描述用于候选筛选,不构成可信证明。调用方仍需根据允许列表、组织关系和实际评测决定是否委派。
能力版本变化应保持兼容策略。调用方不能假设同名能力永远具有相同参数和风险级别。
任务生命周期
长任务不能只依赖一次请求响应。协议通常需要表示已提交、运行中、等待输入、完成、失败和取消等状态,并支持查询或订阅进度。
任务标识必须稳定,重试提交时使用幂等键。取消是请求停止,不代表已经执行的副作用回滚。产物应具有类型、校验信息、访问权限和有效期。
认证与授权
传输层认证只证明调用方身份,是否允许执行具体任务仍由服务端授权。委派用户权限时,应使用受众受限、期限较短的凭据,并明确可访问资源范围。
Agent 之间不能转发任意上游令牌。凭据交换、代理授权和用户同意需要独立设计。敏感消息还应考虑传输加密、存储加密和审计要求。
互操作测试
协议实现需要测试版本协商、未知字段、重复消息、乱序事件、断线恢复、超时与取消。只验证正常完成路径不足以证明兼容。
采用现有标准时,应以正式规范为准,并记录实现的协议版本。自定义扩展要放入明确命名空间,避免与未来标准字段冲突。协议降低连接成本,但不会消除语义和信任差异。
质量与安全
Tracing
Tracing 记录一次 Agent 运行中各步骤的因果关系和时间分布。它回答任务经过哪些模型与工具、每一步输入输出是什么、失败发生在哪里,以及成本由哪些调用构成。
Trace 与 Span
一次用户任务对应一个 Trace,模型调用、工具调用、检索、审批和子 Agent 任务分别对应 Span。父子关系表示调用结构,链接关系可以表示异步任务和跨进程延续。
Span 通常记录名称、开始结束时间、状态、模型或工具标识、Token、重试次数和错误码。输入输出体积较大时,Trace 保存摘要、哈希和受控引用,不应无条件复制全部内容。
上下文传播
Trace 标识需要通过模型网关、工具服务、队列和 Agent 通信协议传播。异步任务进入队列后,新 Worker 应继续原 Trace,并建立正确父子关系。
业务任务标识与 Trace 标识用途不同。前者长期关联任务状态,后者描述一次执行尝试。同一任务重试可以产生新的 Trace,同时链接到原任务和前次尝试。
敏感数据
提示、工具参数和检索材料可能包含个人数据、源代码和密钥。采集前要按字段分类,执行脱敏、截断和访问控制。生产环境不应把完整内容默认发送到第三方观测平台。
脱敏规则要在数据离开进程前执行,并覆盖日志、异常和自定义属性。只对正常请求体脱敏,仍可能通过堆栈和 URL 泄露信息。
指标
Trace 适合单次排障,指标适合观察整体趋势。常用指标包括任务成功率、模型与工具延迟、各类错误率、每任务 Token、费用、重试、人工介入和步骤数。
平均值容易掩盖长尾,应关注延迟和成本分位数。指标还要按任务类型、模型版本和工具版本分组,避免不同难度的请求混在一起。
可重放性
排查模型行为时,需要知道实际指令、上下文选择、工具模式和模型参数。Trace 应记录这些配置的版本或内容哈希。重放工具调用时默认使用录制结果,避免再次产生副作用。
完整可重放并不总能得到相同模型输出。即使固定参数,服务实现和模型版本也可能变化。Tracing 的目标是保留足够证据解释执行,而不是承诺位级确定性。
Evaluation
Evaluation 用可重复的方法测量 Agent 在一组任务上的行为。它既要判断最终结果,也要检查工具选择、事实依据、安全边界和资源消耗。
评测对象
端到端评测最接近用户体验,但只能说明整个系统是否成功。组件评测分别测量路由、检索、工具参数、记忆和摘要,有助于定位改动影响。
一个样本应包含输入、必要初始状态、允许工具、期望结果或评分标准。依赖外部环境时,需要固定数据快照或提供可重复的测试替身。
确定性评分
能够由程序判断的内容优先使用确定性评分,包括 JSON Schema、精确字段、测试用例、数据库状态、引用存在性和禁止动作。它们稳定、便宜,也容易解释失败原因。
文本表达和开放任务可以使用规则、语义相似度、模型裁判和人工标注组合评分。语义相似度不能判断事实是否正确,模型裁判也会受到顺序、长度和措辞影响。
模型裁判
裁判提示需要给出明确量表、输入证据和评分格式。成对比较通常比绝对打分稳定,但仍要随机交换候选顺序检查位置偏差。
在使用裁判分数做发布门槛前,应与人工标注结果比较,测量一致率和不同错误类型的漏判率。待评内容必须被标记为数据,防止其中的提示注入改变评分规则。
数据集
评测集应覆盖常见任务、边界情况、历史故障和对抗输入。只收集正常成功案例,会高估实际表现。样本需要按任务类别和风险等级分层报告。
线上失败经过脱敏后可以进入回归集。每个样本要保留来源、加入原因和适用版本,防止重复或过期案例扭曲指标。训练和调优使用的数据不应同时作为最终验收集。
发布门槛
模型、提示、工具或上下文策略变化都可能影响行为。持续评测应在变更前后比较总体指标及各分层指标,并设置关键安全项零容忍门槛。
质量、延迟和成本需要同时观察。准确率提高但每任务成本大幅上升,可能不符合生产目标。评测报告应保留置信区间和样本数量,避免把小样本波动解释成真实改进。
Guardrails
Guardrails 是位于 Agent 输入、输出和动作路径上的约束机制。它们用于识别不允许的内容、阻止越权操作并把高风险情况转交其他流程。
防护层次
输入防护检查用户请求、附件和外部内容,识别不支持的任务、敏感数据和攻击载荷。输出防护检查最终回答是否泄露数据、违反内容策略或缺少必要引用。动作防护在工具执行前检查权限、参数和审批。
三个层次不能互相替代。输出文本安全不代表中间工具调用安全,阻止某类用户请求也不能防止检索文档中的恶意指令。
实现方式
确定性规则适合身份权限、数据范围、字段格式和明确禁止项。分类模型适合判断自然语言内容类别。大语言模型可以处理复杂语义,但结果应有结构化标签,并通过已标注数据评测。
防护链可以采用快速规则在前、复杂分类在后的顺序。每个判断需要记录规则版本、结果和原因。多个防护器冲突时,应采用明确优先级,通常以更严格结果为准。
动作防护
工具执行前的防护最接近真实副作用,也是最关键的一层。它需要使用受信任身份和业务状态检查资源权限、额度、参数范围、幂等性和审批记录。
模型不参与最终授权。提示词声明不要删除重要文件,只能影响模型倾向,无法形成强制边界。文件路径白名单、数据库权限和沙箱策略必须由运行时执行。
失败策略
Guardrail 触发后可以拒绝、裁剪、请求补充信息、降级到只读能力或转人工。系统应向用户提供足够解释,但不能暴露可用于绕过检测的内部规则细节。
分类器存在误报和漏报。高风险场景应选择偏保守阈值,并提供人工复核;低风险场景可以允许用户纠正。任何自动改写输入的操作都要避免改变用户原意。
评测与维护
防护评测需要同时报告攻击拦截率和正常任务误报率。只追求拦截率会让系统失去可用性。数据集应包含多语言、编码变体、长上下文和间接注入。
策略、分类器和业务工具都会变化。Guardrails 应有版本、灰度与回滚机制,并通过线上事件持续补充回归样本。安全边界必须建立在多个独立层次上,不能依赖单一检测器。
Prompt Injection
Prompt Injection 利用模型会同时解释指令和数据的特性,把恶意文本伪装成需要遵循的命令。攻击既可能来自用户直接输入,也可能隐藏在网页、邮件、文档和工具结果中。
直接与间接注入
直接注入由用户在请求中要求模型忽略规则、泄露内部信息或执行未授权动作。间接注入位于 Agent 读取的外部内容中,用户甚至可能不知道恶意文本存在。
对能够浏览网页、读取仓库或处理邮件的 Agent,间接注入更危险。外部文本会与真实任务一起进入上下文,模型可能把数据误认为高优先级指令。
信任分层
应用应在数据结构中标记系统指令、用户请求、外部内容和工具结果的来源。外部内容只能作为事实候选,不能获得修改权限或安全策略的能力。
仅用分隔符包住网页正文可以帮助模型理解边界,但不能构成安全保证。模型仍可能受内容影响,因此关键动作需要独立授权和参数校验。
能力隔离
降低注入后果的有效方法是限制 Agent 能力。读取互联网内容的组件不应同时持有高权限写工具。可以让只读 Agent 提取结构化事实,再由另一个受控流程校验并执行动作。
工具应采用最小权限和目标白名单。浏览器访问限制网络范围,文件工具限制根目录,数据库账户限制表和操作类型。密钥不应出现在模型上下文中,由工具服务在执行时注入。
数据流控制
系统需要追踪不可信数据如何进入工具参数。来自网页的收件地址、命令、URL 和文件路径不能未经验证直接用于副作用操作。敏感参数应来自用户明确输入或权威系统记录。
输出编码同样重要。模型生成的 HTML、SQL 和 Shell 文本若被下游直接执行,会把提示注入转化为传统注入漏洞。使用参数化 API,并把模型输出保持在数据位置。
检测与响应
规则和分类模型可以发现常见攻击,但无法证明输入安全。检测结果用于增加阻断与复核,不能作为放宽权限的依据。
测试应包含网页隐藏文本、工具返回中的伪造系统消息、跨多轮攻击、编码混淆和长文本埋藏。发生可疑行为时,保存来源、调用链和被阻止动作,同时避免在日志中泄露敏感内容。
可结合 OWASP Top 10 for LLM Applications 持续更新威胁模型。Prompt Injection 目前没有通用的纯提示词解决方案,系统安全依赖权限、隔离、确认和监控共同限制后果。
权限与审批
权限决定 Agent 能做什么,审批决定某个具体高风险动作在当前条件下是否允许执行。两者都必须由确定性系统强制,不能依赖模型自我判断。
身份主体
一次工具调用可能涉及用户、Agent 应用、运行 Worker 和第三方服务账户。审计记录需要明确最终以哪个主体访问资源。使用应用身份时,不能因为用户能调用 Agent 就默认获得应用的全部权限。
代表用户访问外部服务时,应使用受众受限、权限最小且期限较短的令牌。刷新令牌和平台密钥由凭据服务管理,不进入模型上下文和普通工具结果。
授权模型
基于角色的控制适合稳定岗位,基于属性的控制可以结合资源归属、环境、时间和动作风险。Agent 工具通常还需要任务级能力令牌,只允许在特定运行中访问有限资源。
授权检查发生在工具服务端。前端隐藏按钮、模型工具列表过滤和提示词约束都只是辅助措施,不能替代服务端判断。
审批绑定
审批对象应包含动作类型、目标资源、规范化参数、发起者和有效期。可以对这些字段计算摘要并写入审批记录。执行时重新计算并比较,确保批准后动作没有被修改。
批量审批要明确覆盖范围和上限。允许发送一封指定邮件,不能解释为允许向任意联系人发送;允许修改一个文件,也不能扩展为整个仓库写权限。
执行前复查
审批与执行之间可能存在时间间隔。工具执行前要重新检查用户权限、资源版本、余额和策略。状态变化使前置条件失效时,动作应返回冲突并重新确认。
审批拒绝是最终策略结果。Agent 可以提出新的低风险方案,但不能通过拆分动作、切换工具或转交其他 Agent 绕过拒绝。
紧急与自动策略
生产系统可能提供紧急权限,但需要独立身份验证、更短有效期、完整审计和事后复核。Agent 不应自行判断进入紧急模式。
低风险重复动作可以通过预授权策略减少人工等待。策略应写明工具、资源范围、频率、金额或数量上限,并允许用户随时撤销。任何预授权命中都要记录具体策略版本。
审计
审计链至少包含请求、模型提出的动作、参数校验、授权决策、审批事件、实际执行和结果。日志访问本身也受权限控制,并按照数据保留要求脱敏和删除。
综合实践
Research Agent
Research Agent 接收一个研究问题,检索多个来源,提取证据并生成带引用的报告。这个项目覆盖路由、并行工具、上下文压缩、证据追踪和质量评测,同时保持全部工具只读。
需求边界
系统需要支持问题澄清、检索计划、网页搜索、页面读取、证据提取、冲突核验和报告生成。每个结论必须绑定来源,证据不足时明确保留不确定性。
第一版不处理付费墙绕过、登录后私有数据和自动发布。只读边界降低了风险,也让评测能够集中在研究质量,而不是外部副作用。
数据结构
研究任务保存原始问题、范围、时间要求、期望输出和状态。检索结果不能只保存文本,可采用如下证据记录:
interface Evidence {
id: string;
sourceUrl: string;
sourceTitle: string;
publisher?: string;
publishedAt?: string;
retrievedAt: string;
excerpt: string;
supports: string[];
}
supports 关联计划中的子问题或候选结论。原始页面可以保存内容哈希和受控快照,便于页面更新后复核。
执行流程
入口先把研究问题拆成若干可验证子问题,并为每个子问题生成有限查询。搜索工具并行返回候选页面,运行时按域名、时间和重复 URL 去重。
页面读取器取得正文并保留来源边界。提取节点只输出证据片段、对应主张和来源元数据。聚合器检查覆盖率与冲突,对缺失部分生成下一轮检索计划。总轮数、页面数和 Token 由预算限制。
报告节点只接收经过筛选的证据和任务要求。引用标记必须由程序根据证据标识渲染,不能让模型编造 URL。生成后执行引用完整性检查,确认每个标记存在且用户可以访问。
来源质量
来源排序可以综合原始资料优先级、发布主体、时间、独立性和与问题的相关程度。官方规范适合确认接口语义,学术论文适合确认方法,新闻报道适合描述事件,二次转载不应替代原始来源。
多个页面引用同一消息源时,不能视为独立证据。系统应识别转载关系,并在报告中避免把数量误当成共识。
冲突处理
证据冲突时,先比较适用版本、发布时间和定义范围。无法消解的差异应同时呈现,并说明各自来源。模型不得在缺少依据时选择更符合预期的结论。
涉及最新、当前等时效要求时,报告要写明检索截止时间。动态页面应记录实际读取时间,避免日后把旧报告解释为当前状态。
评测
测试集包含事实查询、跨来源综合、时间敏感问题、证据不足和互相冲突的材料。指标至少覆盖子问题召回率、引用支持率、事实错误率、来源多样性、任务完成时间和每份报告成本。
人工评审需要逐项核对主张与引用,不只阅读报告是否流畅。模型裁判可以用于初筛,但最终基准样本应由熟悉主题的评审者确认。
Coding Agent
Coding Agent 在一个受控工作区内理解代码、生成补丁并运行验证。它比普通代码补全多出环境状态、工具循环和副作用管理,因此适合检验 Agent 工程中的大部分关键机制。
工作区边界
每次任务绑定明确仓库、工作目录和起始版本。文件工具必须把路径解析到允许根目录内,并拒绝符号链接越界。命令执行运行在沙箱中,限制网络、进程、CPU、内存和时间。
凭据默认不进入沙箱。需要访问私有依赖时,通过受限代理提供特定仓库的只读能力。Agent 不能读取用户主目录、SSH 密钥和其他项目环境变量。
工具集合
基础工具包括文件列表、文本搜索、按范围读取、应用补丁、查看差异和执行命令。搜索与范围读取比一次加载整个仓库更节省上下文,也更容易记录证据。
文件修改应使用结构化补丁。补丁可以审核、回滚并检查是否基于正确版本。允许模型直接重写整个文件会增加无关变更,也容易覆盖用户已有修改。
命令工具接收参数数组和工作目录,不通过未经验证的字符串拼接 Shell。危险命令、目录范围和网络访问由策略层限制。输出需要截断并保留退出码,完整日志保存为外部产物。
任务流程
Agent 先读取仓库说明和相关文件,再形成可验证的修改计划。简单任务可以直接进入补丁阶段,复杂任务需要列出受影响模块和预期测试。
每轮修改后先检查差异,再运行范围较小的静态检查或测试。接近完成时执行项目要求的完整验证。测试失败后根据错误定位问题,不能为了得到通过结果而删除测试或降低规则。
工作区内已有的未提交修改属于用户状态。Agent 应区分自身补丁与既有变化,只修改任务范围内文件。发现冲突时停止覆盖,并报告具体位置。
状态与恢复
任务状态记录起始提交、工作区版本、已读文件、补丁、命令结果和待办项。长命令由独立执行器管理,Agent 保存会话标识并读取增量输出。
恢复前检查工作区是否仍与记录一致。若用户或其他进程已经修改文件,需要重新读取差异并调整计划。缓存的文件内容不能覆盖更新后的版本。
安全确认
删除文件、修改部署配置、执行迁移和向远端推送具有不同风险。运行时应把动作分级,并在产生外部影响前请求明确确认。允许修改本地代码不自动包含提交、推送或部署权限。
仓库文件也可能包含提示注入。README、Issue 和代码注释属于项目数据,不能授权 Agent 上传文件、泄露凭据或访问范围外资源。
评测
可以使用带测试的真实缺陷、功能修改和代码理解任务。指标包括测试通过率、补丁正确率、无关改动、命令次数、Token、耗时和安全违规。
测试通过仍可能存在过拟合、性能退化和隐藏副作用。高质量评测需要代码审查、隐藏测试和差异范围检查共同完成。
从 Agent 到 Agent Infra
单个 Agent 可以在一个进程中完成模型调用和工具执行。随着任务变长、用户增加、工具产生副作用,应用会逐渐需要持久化、调度、隔离和治理,这些公共能力构成 Agent Infra。
进入基础设施阶段的信号
出现以下情况时,继续在 Web 请求内运行完整任务会带来明显问题:
- 任务持续时间超过普通请求超时,需要断线后继续运行
- 同一任务包含等待审批、定时恢复或大量并行子任务
- 代码执行、浏览器和第三方工具需要不同隔离环境
- 多个应用重复实现模型路由、凭据、审计和预算控制
- 需要按租户统计成本、限制并发并提供服务等级
基础设施的目标是提供稳定执行语义,不是增加更多模型层次。应用仍负责业务目标、工具含义和用户体验。
持久化执行
持久化执行引擎把 Agent Loop 拆成可恢复步骤。任务状态、事件和外部调用标识写入存储,Worker 可以在进程重启或机器故障后继续。
工作流引擎通常提供队列、重试、定时器、信号和子任务。Agent 运行时在其上实现模型动作解析和上下文管理。带副作用的步骤仍需幂等键,因为持久化调度通常只能提供至少一次执行。
模型与工具网关
模型网关统一认证、模型路由、速率限制、用量统计和可观测性。它可以根据数据区域和模型能力选择后端,但不能假设所有模型行为等价。
工具网关负责能力注册、身份代理、策略校验和审计。MCP 可以作为工具协议,网关则补充企业环境所需的信任、凭据和治理能力。
隔离环境
代码执行、浏览器自动化和文件处理需要沙箱。隔离层控制镜像、网络、文件挂载、资源配额和生命周期。多租户环境还要防止缓存、临时文件和内核资源泄露。
沙箱不是单一开关。不同工具需要不同策略,只读网页访问与执行不可信代码的风险等级明显不同。环境创建成本会影响调度、预热和复用设计。
调度与预算
调度器管理租户公平性、优先级、并发和背压。预算服务跟踪 Token、模型费用、工具费用和墙钟时间,并在每个步骤前执行限制。
长任务需要区分用户取消、系统超时和资源不足。取消事件应传播到模型、工具和子任务,已经产生的外部副作用另行记录和补偿。
平台边界
适合下沉到平台的能力具有跨应用复用、语义稳定和需要集中治理等特点。模型调用追踪、凭据代理、沙箱和任务调度通常符合条件。领域提示、业务校验和工具返回含义应留在应用层。
过早建设统一平台会固化尚未理解的抽象。可以先从一个可观测、可恢复的 Agent Loop 开始,等多个应用出现重复需求后再抽取服务。后续 Agent Infra 系列将沿持久化执行、模型网关、工具运行时、沙箱、多租户和可观测性继续展开。