DeepSeek Harness 事故复盘与工程文化

2026-09-08 00:00    #AI   #工具   #DeepSeek  

一个 bug 的价值,不在于那行修复,而在于为什么流程放过了它,以及新增了什么防护让同类问题下次明确报错。

复盘文化:四问

四问要回答什么
什么坏了用简短段落让忙碌的读者三十秒内吸收要点
机制是什么用直白的话说清根因,不归咎个人
为什么每道安全网都没拦住找出测试、工具、约定的缺口,而非一次性笔误
新增了什么防护测试、AGENTS.md 规则、ADR,让同类 bug 下次明确报错

三个条件同时满足才写复盘:隐蔽(机制不显而易见)、系统性(逃逸原因是测试/工具/约定缺口)、重新发现的代价高。

四个真实案例

复盘 0001:ACP 服务器在连接时崩溃——export default 丢掉了插件的 inject。

复盘 0002:文件系统快照工具被一个字面量 !!js 对象永久禁用。

复盘 0003:Web agent 验收了替代服务器,而非承载其会话的 GUI。

复盘 0004:Landlock 部分强制执行通知导致子进程失败被误归类。

共同经验:测试必须走真实入口路径。手动挂载、mock 一切、把快照刷新当验收——都会让"单元全绿、产品却坏了"成为可能。

测试四层

层级命令抓什么
单元测试pnpm run testvitest 跑包内测试,优先边界、错误路径、事件顺序、并发竞态
覆盖率门禁pnpm run test:coverage按文件 100% 覆盖;未覆盖行往往是该删除的死代码
真实 API e2epnpm run test:e2e带密钥调用真实提供方 API;缺密钥自动跳过,keyless CI 保持绿色
快照pnpm run test:snapshot / test:web无密钥预期输出覆盖对外行为;浏览器快照用 Chromium 回放比较

文档纪律:一个事实一个家

动手示例:三十秒执行摘要模板

1# 复盘 0005:runoob 演示环境的工具黑名单没有生效
2
3## 摘要
4demo 环境里模型仍能调用被禁用的 fs_write,直接写入了工作区。
5根因是黑名单插件用 `tools/pre-execute` 返回了 `next()`6而真正负责拦截的守卫注册在插件卸载之后——加载顺序错了。
7逃逸原因是加载顺序没有测试覆盖,`cordis.yml` 只测了「能起来」。
8新增防护:给黑名单插件补一条「顺序敏感」的装配测试,
9并在 AGENTS.md 记录「pre-execute 与 guard 的注册顺序」规则。

三十秒摘要公式:坏什么 → 直白说根因 → 为什么逃逸 → 可长期沿用的教训。

系列结语(四句带走)

  1. 模型负责聪明,Harness 负责可靠。约束不是限制,而是让 Agent 可预测、可审计、可回放的基石。
  2. 一切皆插件。把策略放在扩展点上,而不是写进循环里。
  3. 真实入口路径胜过一切 mock。覆盖率、快照、冒烟测试各司其职,共同防止"全绿却坏了"。
  4. 故障不可怕,可怕的是不知道为什么。复盘文化把一次事故变成一套防护。

跨篇速查表(关键命令汇总)

 1# 安装插件到 profile
 2dsh plugin --profile demo add ./hello-plugin
 3dsh plugin --profile demo add github:you/hello-plugin
 4dsh plugin --profile demo add github:you/hello-plugin#<sha>   # 锁定 commit
 5dsh plugin --profile demo add ./hello-plugin-0.1.0.tgz
 6dsh plugin --profile demo add your-package
 7
 8# 移除 / 验证
 9dsh plugin --profile demo remove dsh-hello-plugin
10dsh --profile demo --dump-config
11dsh --profile demo
12
13# 发布
14pnpm build && pnpm publish    # npm 发布
15pnpm pack                     # tarball

关键运行时可组合要素ctx.sandbox.confine(沙箱 argv 包装)、ctx.sandboxPolicy.resolve(策略解析)、ctx.approval / approval/request waterfall、ctx.tools.guard()(单调守卫)、ctx.permissionPresets(具名预设)、Session.deriveMessages()(日志投影)、tools/* / agent/* / session/event 事件流。