AI Agent 为什么失败:四层故障分类与运行时 Harness 改造

本文基于 Cobus Greyling 对 LIFE-Harness 论文的解读,重新梳理 AI Agent 失败的四层分类:环境契约、操作技能、动作落地和轨迹调节。文章重点说明,很多 Agent 失败并不是模型本身不够聪明,而是模型和运行环境之间缺少稳定、可验证、可修复的接口层。

阅读时长: 8 分钟
共 3611字
作者: longlikun

AI Agent 为什么失败:四层故障分类与运行时 Harness 改造

很多人调试 AI Agent 时,第一反应是换模型、加提示词、调温度、扩大上下文。这样做有时有效,但它也容易遮住真正的问题:Agent 不是一个裸模型,而是“模型 + 工具 + 环境 + 反馈回路”的组合系统。

如果系统失败了,未必是模型不会推理。它可能是不知道界面有哪些隐性规则,可能是工具调用格式差一点,可能是执行动作时和环境状态错位,也可能是已经走错了却没有及时停下来。

Cobus Greyling 在《The Four-Layer Agent Failure Taxonomy》中提到的重点,正是把 Agent 失败从“模型能力不足”拆成更具体的运行时问题。背后的论文 LIFE-Harness 也给了一个很实用的思路:不要急着改模型,先改模型和环境之间的接口层。

这个接口层可以理解为 runtime harness。它不替模型思考,但负责把环境说清楚、把动作落稳、把反馈转成模型能利用的信号,并在轨迹偏离时做干预。

先别把所有锅都甩给模型

今天的 Agent 系统越来越像一个小型软件栈。模型只是其中的决策核心,外面还有:

  • 任务描述和系统提示词
  • 工具 schema 和函数调用协议
  • 浏览器、终端、文件系统、API 等执行环境
  • 状态记录、重试、回滚和错误恢复机制
  • 评测集、日志、轨迹分析和人工反馈

只要其中任何一层表达不清楚,模型就会在“看似会做、实际做错”的状态里反复打转。

举个简单例子:让 Agent 在网页后台里新建一条记录。模型也许完全理解任务目标,也能推理出应该点击“新建”、填写表单、保存。但如果页面加载慢、按钮文案变化、输入框没有明确 label,或者保存后没有稳定反馈,它就可能在最后一步失败。

这类失败看起来像“模型笨”,实质上更像传统软件里的接口契约问题。调用方和被调用方之间缺少稳定约定,系统当然容易碎。

四层 Agent 失败分类

把失败拆细之后,才知道该修哪里。原文把 Agent 的失败大致放进四层:环境契约、操作技能、动作落地、轨迹调节。它们从外部接口一路深入到执行过程,越往后越接近 Agent 的闭环行为。

第一层:环境契约失败

环境契约指的是 Agent 对外部世界的理解边界。它需要知道现在处在哪个页面、有哪些可用操作、每个字段是什么意思、什么时候算成功、什么时候算失败。

如果这些信息没有被明确表达,模型只能靠猜。

常见问题包括:

  • UI 元素没有稳定名称,模型只能根据视觉位置判断
  • API 返回结构复杂,但缺少清晰字段解释
  • 成功状态没有明确标志,只能从页面变化里推断
  • 任务规则藏在产品流程里,没有进入 Agent 上下文
  • 同一个动作在不同状态下含义不同,但系统没有暴露状态机

这一层失败最容易被误判成“提示词不够好”。但真正该修的,往往是把环境契约结构化:给按钮、字段、状态、错误码、成功条件更明确的描述。

对浏览器 Agent 来说,这可能意味着更好的 accessibility tree、更稳定的 data-testid、更少依赖视觉猜测。对 API Agent 来说,这可能意味着更清楚的 OpenAPI 描述、更窄的工具参数、更明确的返回语义。

第二层:操作技能失败

环境被看清楚之后,Agent 还需要知道“怎么做”。这就是操作技能层。

同样是“创建用户”,它可能不是一次 API 调用,而是一串步骤:

  1. 查询是否已有同名用户
  2. 创建用户主体
  3. 绑定角色
  4. 写入组织关系
  5. 发送邀请
  6. 检查最终状态

如果 Agent 只知道目标,不知道这套操作流程,就容易漏步骤、顺序错、重复执行,或者在中间失败后不知道如何恢复。

这一层最适合沉淀为可复用的过程知识。比如:

  • 把高频任务写成 workflow
  • 把领域规则写进 task guide
  • 把容易出错的步骤封成工具
  • 把前置检查和后置验证固定下来
  • 把“不要做什么”也写进运行规则

这也是很多编码 Agent 需要 AGENTS.mdCLAUDE.md、skills、playbook 的原因。模型本身有通用能力,但项目里的操作惯例需要额外告诉它。

第三层:动作落地失败

第三层失败发生在“模型知道该做什么,但动作没有真正落到环境里”。

这类问题在工具调用和浏览器自动化里很常见。模型已经决定要点击某个按钮,但页面还没加载完;模型想修改某个文件,但路径拼错了;模型调用 API 时参数类型不匹配;模型以为保存成功了,其实服务端返回了校验错误。

动作落地失败通常有几个特征:

  • 决策方向是对的,但执行细节错了
  • 单步错误不大,但会污染后续状态
  • 日志里能看到工具报错,但模型没有充分利用
  • 系统缺少自动验证,导致错误被延迟发现

解决办法不是继续写长提示词,而是给动作层加工程护栏:

  • 工具参数尽量用强 schema 限制
  • 对关键动作加 dry-run 或 preview
  • 每次写入后立即读取验证
  • 把错误信息压缩成模型能读懂的反馈
  • 失败时保留可恢复状态,而不是盲目重试

对 Agent 来说,“执行”不能只是把命令发出去。执行之后必须有观察、有校验、有下一步决策。

第四层:轨迹调节失败

最难的问题不在单步动作,而在整条轨迹。

Agent 做复杂任务时,往往要走很多步。前面一步的小误差,后面可能被不断放大。模型也可能陷入局部循环:反复搜索、反复点击、反复改同一个 bug,却没有意识到路线已经错了。

轨迹调节层关注的是:

  • 什么时候继续
  • 什么时候暂停
  • 什么时候回滚
  • 什么时候换策略
  • 什么时候承认当前路径不可行

一个成熟的 Agent harness 需要在这里提供更强的调度能力。比如设置最大步数、识别重复动作、比较当前状态和目标状态、在关键节点生成检查点、失败后从最近的稳定点恢复。

这也是“让模型自己跑起来”最容易翻车的地方。没有轨迹调节,Agent 只是一个会连续调用工具的模型;有了轨迹调节,它才更接近一个可控的执行系统。

LIFE-Harness 的启发:改接口,不急着改模型

LIFE-Harness 的思路很有工程味:在不重新训练模型的前提下,通过 runtime harness 学习和修正模型与环境之间的接口。

它关注的不是“让模型变聪明”,而是让模型更稳定地使用已有能力。也就是说,模型可能已经能推理出正确答案,但它需要一个更好的运行时把这些推理转换成可靠动作。

这个方向有几个现实价值:

  • 成本更低:不用重新训练或微调模型
  • 迭代更快:harness 可以随日志和失败样本持续改进
  • 可解释性更强:失败能落到具体层级,而不是一句“模型没做好”
  • 可迁移性更好:很多接口修复能服务同类任务
  • 工程收益更稳定:改 schema、改校验、改状态反馈,通常比碰模型更可控

如果把 Agent 系统看成一条流水线,模型不是唯一的优化点。输入怎么表达、工具怎么暴露、动作怎么验证、轨迹怎么调度,都会决定最终质量。

对工程团队有什么用

这套四层分类最直接的价值,是让排障从“凭感觉调 prompt”变成“按层定位问题”。

当一个 Agent 失败时,可以先问四个问题:

  1. 环境契约是否清楚? Agent 是否真的知道有哪些对象、状态、约束和成功标准?

  2. 操作技能是否完整? 它是否掌握完成任务所需的步骤、顺序、前置条件和后置检查?

  3. 动作是否可靠落地? 工具调用、页面操作、文件修改和 API 请求是否有 schema、校验和错误反馈?

  4. 轨迹是否可控? 系统是否能识别偏航、循环、过度重试和不可恢复状态?

这四个问题能帮助团队把失败样本变成待修事项,而不是把所有问题都扔回“模型再强一点就好了”。

一个更实用的 Agent 调试清单

如果你正在做自己的 Agent 系统,可以按下面这个顺序检查。

1. 先把成功标准写死

不要只写“完成用户创建”。要写清楚完成后系统应该出现什么状态,例如:

  • 用户记录存在
  • 邮箱唯一
  • 角色绑定成功
  • 邀请邮件已发送
  • 审计日志有对应事件

成功标准越清楚,Agent 越容易自检。

2. 给工具更窄的接口

工具不是越通用越好。一个万能 run_commandclick_anything 看似灵活,实际会把大量判断压力推给模型。

能封成业务动作的,就封成业务动作。能用枚举限制的,就不要让模型自由填写字符串。能提前校验的,就不要等服务端报错。

3. 把失败样本沉淀成规则

每一次失败都应该留下结构化记录:

  • 当时目标是什么
  • Agent 看到了什么
  • 它选择了什么动作
  • 工具返回了什么
  • 最后偏离在哪里
  • 这属于四层里的哪一层

记录多了以后,harness 才有改进方向。否则团队只会在聊天记录里反复找原因。

4. 给长任务加检查点

长任务不要一口气跑到底。每完成一个关键阶段,就保存状态并做验证。

比如代码 Agent 可以在“修改完成”“测试通过”“lint 通过”“生成变更摘要”这几个点设置检查。浏览器 Agent 可以在“进入正确页面”“表单填写完成”“提交后状态确认”几个点设置检查。

检查点不是为了拖慢 Agent,而是为了让失败更早暴露。

5. 把重试设计成策略,而不是本能

盲目重试会放大错误。更合理的重试应该带条件:

  • 是临时网络错误,还是参数错误?
  • 当前状态是否已经改变?
  • 重试前是否需要重新观察环境?
  • 是否应该换工具或换路径?
  • 是否已经超过可接受成本?

很多 Agent 的问题不是“不够坚持”,而是“太坚持错误路线”。

结语

Agent 失败不是一个单点问题。它更像分布式系统里的故障:有接口契约,有执行语义,有状态同步,也有调度控制。

四层分类的好处,是把“模型不行”这句粗糙判断拆开。环境契约不清,就补契约;操作技能缺失,就沉淀流程;动作落地不稳,就加 schema 和验证;轨迹失控,就加检查点、回滚和停止条件。

真正可靠的 Agent,不是靠一条神奇提示词跑出来的。它需要一个能持续吸收失败、修正接口、强化反馈的 runtime harness。

换句话说,模型负责思考,harness 负责让思考变成可控的行动。

参考资料

关于

关注我获取更多资讯

月球基地博客公众号二维码,扫码关注获取更多 AI 与编程资讯
📢 公众号
月球基地博客作者个人微信二维码,扫码交流 AI 与编程话题
💬 个人号
使用 Hugo 构建
主题 StackJimmy 设计