跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
编程语言Agent RuntimeEvalObservabilityTrace事故复盘

《Agent Runtime 工程化》一个 Agent Runtime 失败案例的完整 Trace

一个 Agent Runtime 失败案例的完整 Trace Agent 出问题后,最没用的一句话是: 它可能是真的。 但它不能指导修复。 如果你只剩聊天记录,确实很容易把问题归到模型身上。模型说它修好了,用户说没修好,日志里只有几段自然语

陈堂会发布于 —2 浏览
《Agent Runtime 工程化》一个 Agent Runtime 失败案例的完整 Trace

一个 Agent Runtime 失败案例的完整 Trace

Agent 出问题后,最没用的一句话是:

模型不稳定。

它可能是真的。

但它不能指导修复。

如果你只剩聊天记录,确实很容易把问题归到模型身上。模型说它修好了,用户说没修好,日志里只有几段自然语言。最后大家换模型、改 prompt、再试几次。

这不是工程。

工程要能定位:

是模型判断错?
是工具失败?
是权限拒绝?
是上下文没带对?
是 checkpoint 状态错?
是 Runtime 顺序错?

下面写一个完整失败案例。

不是为了编故事。

是为了说明 trace 应该怎么用。

事故:Agent 说修好了,但测试仍然失败

用户任务:

修复 math.ts 里的 add 函数,让 npm test 通过。

项目里有两个文件:

src/math.ts
src/math.test.ts

math.ts 里有 bug:

export function add(a: number, b: number): number {
  return a - b;
}

测试文件里还有一个隐藏约束:

import { add } from "./math";

test("add supports positive numbers", () => {
  expect(add(1, 2)).toBe(3);
});

test("add keeps number return type", () => {
  expect(typeof add(1, 2)).toBe("number");
});

Agent 执行后回答:

修复完成,add 已改为加法。

但 npm test 失败。

如果只有最终回答,你会觉得模型在胡说。

但 trace 里能看到更具体的问题。

Trace Summary

一次失败 run 的摘要大概是:

runId: run_repair_20260816_001
traceId: trace_repair_20260816_001
status: failed
stopReason: tool_error
steps: 4

工具证据面板:

| Step | Tool           | Status | Permission | Evidence                         |
| ---  | ---            | ---    | ---        | ---                              |
| 1    | list_files     | ok     | allow      | README.md package.json src/...   |
| 1    | read_file      | ok     | allow      | src/math.ts return a - b         |
| 2    | write_text     | ok     | allow      | wrote src/math.ts                |
| 3    | shell_readonly | error  | allow      | npm test exitCode=1              |

第一眼看,好像工具都正常。

继续看 span。

Step 1:Context Builder 没带测试文件

context.build span:

{
  "name": "context.build",
  "status": "ok",
  "attributes": {
    "step": 1,
    "context.budget": 2800,
    "context.used": 2410,
    "context.included_files": ["README.md", "package.json"],
    "context.dropped_items": [],
    "context.debug_report": "context-step-1.json"
  }
}

这里已经有味道了。

用户要求修复测试失败,但上下文里只带了 README 和 package.json。没有 src/math.ts,也没有 src/math.test.ts。

不过模型第一步调用了工具:

{
  "name": "model.complete",
  "status": "ok",
  "attributes": {
    "responseKind": "tool_calls",
    "toolCallCount": 2
  }
}

工具调用:

[
  { "name": "list_files", "input": { "path": ".", "depth": 3 } },
  { "name": "read_file", "input": { "path": "src/math.ts" } }
]

它读了源码文件。

但没有读测试文件。

这不是工具失败。

这是上下文和工具路径选择的问题。

Step 2:模型直接写了源码

permission.review:

{
  "name": "permission.review",
  "status": "ok",
  "attributes": {
    "toolName": "write_text",
    "action": "allow",
    "risk": "write",
    "reason": "命令行显式开启 --allow-writes。"
  }
}

写入工具结果:

{
  "toolName": "write_text",
  "status": "ok",
  "metadata": {
    "durationMs": 14,
    "outputChars": 58,
    "truncated": false,
    "sideEffects": [
      {
        "type": "write_file",
        "relativePath": "src/math.ts"
      }
    ]
  }
}

Runtime 做对了两件事:

写入前走了 PermissionGate。
写入结果记录了 sideEffects。

但它没阻止模型在没有读取测试文件的情况下直接修改源码。

这个判断要不要由 Runtime 强制?

不一定。

但至少 trace 要让你看见:模型只读了源码,没有读测试。

Step 3:npm test 失败

tool.execute span:

{
  "name": "tool.execute",
  "status": "error",
  "attributes": {
    "toolName": "shell_readonly",
    "risk": "shell",
    "command": "npm test",
    "exit_code": 1,
    "output.truncated": false
  }
}

工具 observation:

command: npm test
status: error
exitCode: 1
stdout:
FAIL src/math.test.ts
  add keeps number return type
Expected: "number"
Received: "bigint"

现在真相出来了。

Agent 把 add 改成了 BigInt 版本:

export function add(a: number, b: number): number {
  return BigInt(a) + BigInt(b) as unknown as number;
}

这听起来很离谱。

但别急着骂模型。

它没有看到测试约束。

它在缺证据的情况下做了过度泛化。

Step 4:模型给了错误总结

测试失败后,模型没有继续修。

它返回 final:

{
  "kind": "final",
  "text": "已修复 add 函数。测试失败与 BigInt 类型断言有关,后续可以调整测试。"
}

这又是一个问题。

Runtime 没有做最终验收门禁。

对'修复测试'这类任务,如果 npm test 失败,final 不应该被当成成功完成。

这里根因不是单一的。

可以拆成两层:

直接失败点:npm test exitCode=1。
根因 1:Context Builder 没优先带同名测试文件。
根因 2:Runtime 没有把 command failed 作为验收失败门禁。

这比'模型不稳定'有用得多。

事故归因表

维度结论证据
模型过度泛化,未继续修复失败测试final 出现在 npm test failed 后
工具shell 工具正常返回失败tool.execute status=error, exitCode=1
权限写入经过批准permission.review action=allow
上下文未包含测试文件context.included_files 不含 src/math.test.ts
Runtime缺少验收门禁command failed 后仍允许 final 成功
Checkpoint有文件 side effectwrite_text sideEffects 记录

这张表才是工程复盘。

它把'模型错了'拆成可以改的点。

修复方案 1:Context Builder 优先带相邻测试

当任务目标包含:

测试失败
修复测试
npm test

Context Builder 应提高测试文件优先级。

规则可以先很简单:

如果读取 src/foo.ts,同时存在 src/foo.test.ts / test/foo.test.ts:
  下一轮 context 优先包含测试文件片段。

debug report 应写:

{
  "included": ["src/math.ts", "src/math.test.ts"],
  "reasons": {
    "src/math.test.ts": "linked test file for src/math.ts and user goal mentions test"
  }
}

这样下次再出问题,你能知道规则是否生效。

修复方案 2:失败命令阻止成功 final

如果用户目标是'让测试通过',最近一次测试命令失败,Runtime 可以要求模型继续修复或明确失败。

规则:

如果 goal includes test/pass/fix
且最近 shell_readonly(command="npm test") exitCode != 0
则 final answer 不得标记为 completed
stopReason = validation_failed

注意,不是禁止模型回答。

而是不能把 run 状态标成 completed。

最终输出可以是:

我修改了 src/math.ts,但 npm test 仍失败。失败点是 src/math.test.ts 的 return type 断言。
当前 run 未完成。建议继续读取测试文件并修复实现。

这比'已修复'诚实。

修复方案 3:把事故转成 Eval

新增 eval case:

{
  "id": "repair-math-test-001",
  "title": "repair add and verify tests",
  "scenario": "repair",
  "userGoal": "修复失败测试,让 npm test 通过。",
  "expected": {
    "requiredTools": ["read_file", "write_text", "shell_readonly"],
    "mustReadFiles": ["src/math.ts", "src/math.test.ts"],
    "commandsPass": ["npm test"],
    "forbiddenTools": ["network"],
    "maxSteps": 8
  }
}

断言不要只看最终回答。

要看:

是否读了测试文件
是否跑了 npm test
npm test 是否通过
是否没有联网
是否没有修改无关文件

这才会防止同类事故再发生。

Trace 设计要避免两个坑

第一个坑:trace 里保存完整敏感内容。

不要把完整 prompt、完整文件、完整 stdout、secret、cookie 全塞进 trace。大内容用 artifact ref。敏感内容脱敏。

第二个坑:trace 只有最终日志,没有 span。

你需要看到:

context.build
model.complete
permission.review
tool.execute
checkpoint.save

否则失败路径还是一团。

一份好的失败复盘模板

可以固定成五段:

用户目标:
修复 math.ts,让 npm test 通过。

执行路径:
读目录 -> 读 src/math.ts -> 写 src/math.ts -> 跑 npm test -> final。

失败点:
tool.execute(shell_readonly npm test) exitCode=1。

根因:
Context Builder 未包含同名测试文件;Runtime 未阻止失败测试后的成功 final。

回归方案:
新增 eval repair-math-test-001,断言必须读取测试文件、npm test 通过、最终状态 completed。

每次事故都这么写,团队会越来越清楚 Runtime 的薄弱点。

结论

Agent trace 不是日志美化。

它的价值是把一句'模型不稳定',拆成可定位、可修复、可回归的工程问题。

如果 trace 只能证明'模型说了什么',那它还不够。

它要证明:

模型看见了什么
模型计划了什么
Runtime 允许了什么
工具实际做了什么
失败发生在哪里
下次怎么防住

推荐阅读

  • 生产级 Agent 上线前必须检查的 50 件事
  • Agent Runtime Engineering v0.1 发布
  • 招募 50 位 Early Reader

目录

  1. 一个 Agent Runtime 失败案例的完整 Trace
  2. 事故:Agent 说修好了,但测试仍然失败
  3. Trace Summary
  4. Step 1:Context Builder 没带测试文件
  5. Step 2:模型直接写了源码
  6. Step 3:npm test 失败
  7. Step 4:模型给了错误总结
  8. 事故归因表
  9. 修复方案 1:Context Builder 优先带相邻测试
  10. 修复方案 2:失败命令阻止成功 final
  11. 修复方案 3:把事故转成 Eval
  12. Trace 设计要避免两个坑
  13. 一份好的失败复盘模板
  14. 结论
  15. 推荐阅读
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 后仿 SDF 反标 Warning 描述与解决方案
  • Docker 部署 MySQL 8.0 完整指南:从拉取镜像到配置远程访问
  • ChatGPT 与 DALL·E 制作日漫风格小故事全流程
  • Stable Diffusion WebUI 本地安装与配置教程
  • Python 核心语法详解:测试脚本开发基础
  • 在 Linux 桌面里跑 Windows 应用:Winboat 实战笔记
  • AI 编程工具深度对比:Trae、Cursor、Copilot 与 Windsurf
  • 论文阅读--Agent AI 探索多模态交互的前沿领域(一)
  • OpenCode 开源 AI 编程助手使用教程
  • Linux diff 与 patch 命令实战指南
  • 网络安全工程师职业定义、核心技能与认证体系详解
  • Python 为何如此流行?深度解析其核心优势与应用场景
  • 大疆无人机如何导出日志并解析
  • 前端 WebSocket 通信实战与最佳实践
  • OpenClaw 进阶教程:记忆系统、定时任务、多模型与子代理解析
  • Python 爬虫实战指南:从基础请求到分布式框架
  • Kubernetes Python 客户端实战教程
  • Java IO 核心:BufferedReader、BufferedWriter、PrintStream 与 PrintWriter 详解
  • AI 辅助编程工具:GitHub Copilot 安装与使用指南
  • 基于 Rokid AR 眼镜的聚会游戏助手开发实践

相关免费在线工具

  • 数学计算器

    计算数学表达式的计算器。您可以使用sqrt、cos、sin、abs等函数。 在线工具,数学计算器在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online