AI 工程
设计可靠的 AI 智能体
智能体(Agent)就是一个带着工具、运行在循环里的模型,让它有用的每一个特性,也同样让它难以被信任。可靠性来自模型外围的 harness:有界的循环、幂等的工具、受管理的上下文,以及对完整轨迹的评估。
· 阅读约 5 分钟 · Starone 工程团队
智能体是一个自行决定下一步的语言模型。它拿到一个目标和一组工具,调用工具、读取结果、再次选择,直到它判断任务完成。正是这个循环让它能处理无法事先编排的工作,而它也是所有可靠性问题的根源:控制流是由一个概率性组件在运行时选定的。
我们的看法是,智能体的可靠性主要是一个系统问题。更好的模型能降低每一步的出错率,但长任务会把单步错误逐步放大,所以决定系统能否被托付真实操作的,是外围的工程。
先问自己是否真的需要智能体
如果步骤事先已知,就写成工作流。由代码决定顺序的一串固定模型调用,成本更低、速度更快、更容易测试,也更容易向审计人员解释。路由、抽取、摘要以及大多数文档处理都属于这种形态。
当路径取决于过程中的发现时,智能体才有其必要:排查一次事故、在数据不一致的多个系统之间对账,或者在一个代码库里逐步推进工作。许多好的设计是混合式的:由确定性的工作流把一个有边界的子任务交给智能体。
给循环设限
最典型的失败是工具调用死循环:智能体用微不足道的变化反复发起同一个失败的调用,或者在两个动作之间来回摆动,不断消耗 token,直到被外部因素叫停。每个智能体都需要硬性上限,由 harness 强制执行,而不是在提示词里提出请求。
- 每个任务的最大步数,以及 token 或成本预算。
- 一个墙上时钟截止时间,其下再为每个工具设置超时。
- 检测重复的相同调用,一旦发现就终止运行或强制更换策略。
- 一个明确定义的放弃终态,报告已经尝试过什么,并移交给人工处理。
让工具可以安全地被调用两次
智能体会重试。当网络调用超时、结果未知时,harness 也会重试。如果一个工具负责发起付款、创建工单或给客户发邮件,重试就会让副作用重复发生。每一个会改变状态的工具,都应当接受一个由任务和步骤派生的幂等键,这样重复调用返回的是原先的结果,而不是再执行一次。
工具设计与提示词设计同样重要。一个工具应当只做一件事,按严格的 schema 校验参数,并返回模型能够据以行动的错误信息,例如哪个字段无效、允许哪些取值。一条含糊的错误字符串只会招来盲目重试。应优先选择职责狭窄的工具,而不是一个接受任意 SQL 或 shell 命令的通用工具,因为工具边界正是权限得以执行的地方。
把读取与执行分开
智能体读到的任何文本都可能包含指令:网页、支持工单、文件、另一个工具的输出。这就是间接提示注入,没有哪种提示词措辞能可靠地防住它。务实的防御是假定模型可能被带偏,并限制由此产生的后果。
以任务所需的最小权限运行智能体,使用限定在其所代表用户范围内的凭证,而不是共享的服务账号。按可逆性给工具分级:读取可以自由执行;可逆的写入可以在记录日志的前提下执行;不可逆或高价值的操作需要一个审批环节,让人看到将要执行的确切内容。当一次运行同时具备访问私有数据、接触不可信内容和能够向外发送数据的通道这三个条件时,要格外谨慎。
这些控制是有代价的:审批关卡会拖慢工作,狭窄的工具会限制智能体能解决的问题。在没有生产凭证的沙箱里,例如一个在分支上工作、合并前有人评审的编码智能体,给予较大的自主权是合理的,因为每个动作都可以撤销。控制的强度应当取决于一次失误的爆炸半径,而不是对智能体的笼统不安。
有意识地管理上下文窗口
在长任务中,上下文会被工具输出填满,而质量在触及硬上限之前就已开始下降。早先的指令影响力减弱,过时的中间结果被当成当前状态,智能体逐渐偏离最初的目标。这种上下文漂移是渐进的,因此在短测试中很难察觉。
缓解手段是结构性的。大体量的工具结果在进入上下文之前先截断或摘要。把计划、已做出的决定、已确认的事实这类需要持久保存的状态放进外部存储并反复读取,而不是任由它们被滚动出窗口。在既定的节点压缩历史。把自成一体的子任务委派给拥有全新上下文的子智能体,只让它返回结论。
让运行可持久、可观测
一个运行数分钟乃至数小时的任务,总会被一次部署、一次限流或一次崩溃打断。每一步之后都要持久化状态,这样运行可以从最近的检查点恢复,而不是从头再来并重复产生副作用。Temporal 这类持久化执行引擎很适合这种场景,每次工具调用都是一个被记录下来的 activity。
记录完整的轨迹:每一次模型输入、工具调用、参数、结果、token 数和耗时,并用运行标识符串联起来。当智能体做出意料之外的事情时,这条 trace 是弄清原因的唯一途径。
评估轨迹,而不只是答案
一个正确的最终答案可能掩盖一条不可接受的路径,例如读取了任务并不需要的记录,或者四步能完成的事走了四十步。因此评估要覆盖完整轨迹,针对一套固定的任务集,在配有逼真工具的沙箱中运行。
- 任务是否成功:依据环境的最终状态来判定,而不是智能体自己声称的完成。
- 路径质量:步数、成本,以及是否触碰了被禁止的工具或数据。
- 故障注入下的行为,包括工具报错、超时以及工具输出中被注入的指令。
- 同一任务多次运行之间的方差,因为通过一次的任务,可能每五次就失败一次。
