我读了 DeepSeek Harness 的 505 份 AI 工作笔记,挑出最值钱的 6 个故事

我读了 DeepSeek Harness 的 505 份 AI 工作笔记,挑出最值钱的 6 个故事

最近 DeepSeek 开源了 DeepSeek Harness(dsh)——一个 agent harness,把大模型变成能干活的编程智能体的工程骨架。媒体都在聊“DeepSeek 版 Claude Code”的功能。

我把源码拉下来翻了一遍,却发现 README 只字未提的地方藏着更有意思的东西:.agents/notes/ 目录,里面躺着 505 份中英双语的“Agent Notes”(智能体工作笔记)。

背景交代一句:这个项目本身就是 DeepSeek 用 AI agent 辅助开发的。他们立了条铁律——任何非平凡改动,必须在同一个 PR 里附一份笔记,写明为什么这么决定、放弃了什么方案。两个月(2026.6.11–8.13),45 万行 TypeScript、约 219 个包、505 份笔记:新功能 170、架构 129、bug 修复 77、流程 69、精简 48、测试 12。

每篇笔记一页纸,固定四段:问题、决策、曾考虑的替代方案、后果。我读了其中几十篇,挑出 6 个最值得讲的故事。

故事一:地基之争——为什么会话必须是一本“只许append的账”

6 月 11 日,开工首日,9 篇笔记同时落地,其中一篇决定了整个产品的地基。

问题是:会话要支持完全回放、要有严格的事件追踪。最省事的做法是维护一个可变的消息数组,顺手发点事件通知——所有同类产品都这么起步。

笔记否决了它。理由一句话:状态和日志是两份数据,两份就可能对不上。最终决策:会话是一份只追加的 SessionEvent 事件日志,是唯一真源;模型看到的历史消息全部从日志里派生。原话是:“日志本身即是状态,分歧在结构上不可能发生。”

这个决策的红利后来全部兑现:会话分叉(fork)、回放、遥测、UI 渲染,都从同一条事件流投影出来,不是事后拼接的功能,而是“结构上得到保证”。代价也写得明明白白——派生成本随日志长度增长,所以两个月后他们专门做了上下文压缩来缓解,而不是改写日志。

第一天就把“简单方案为什么不行”论证清楚并记录在案,后面几百篇笔记都建立在这个地基上。

故事二:战争故事——模型返回了“空气”,系统差点信了

7 月 24 日的一篇 bug 修复笔记,记录了所有模型应用都会踩的坑。

provider 偶尔会返回一种诡异的响应:流格式完好、以正常的 stop 结束,但内容为零——没有文本、没有推理、没有工具调用。模型“什么都没说”。

旧代码把它当成功处理:记一条空的 assistant 消息,轮次标记“完成”。后果很阴:系统不重试、不向调用方暴露失败,而像 goal-round-driver 这样按轮次推进的驱动器,白白消耗一轮,毫无进展,还以为一切正常。

修复方案是定义 EMPTY_RESPONSE 错误码:适配器把“已完成但为空”归类为 provider 边界失败,重试策略视为瞬时问题。笔记里连边界都论证了——“只含推理的流”不算空,因为有些模型就是故意推理完就停,误伤它们会引发重试循环;“确实打算什么都不说”的模型会被误重试,这个取舍“经过审慎权衡后接受”,因为一条空消息“与 provider 缺陷无法区分,且对用户毫无价值”。

这就是笔记的价值:半年后有人问“为什么空响应要报错”,答案不在任何代码注释里,在这篇笔记里。

空气泡队列全挂绿勾:空响应被归类为 provider 边界失败

故事三:悼词——删除整个终端 UI

8 月 4 日,精简类笔记里最有人情味的一篇。

DeepSeek Harness 曾经有过一个完整的终端 UI 包:终端渲染器、交互式问答、扩展浮层、测试快照,一应俱全。产品全面转向 Web 界面后,这个包失去了真实用户。

决策:整个删除,不留兼容层、不留别名。

笔记先诚实地给这个包念了一段悼词——“终端 UI 曾在长对话期间保持会话身份可见、为消息附加耗时与阶段状态”——然后话锋一转:“在没有部署的情况下,这不足以证明应保留它。”

更狠的是最后一条:未来如果要重做终端前端,“必须以实际宿主和交互需求为起点,而不是默认继承此实现”。删掉的东西不许轻易复活,想复活,重新论证。

补一个背景:仓库里有个专门的 skill 叫 dsh-find-simplifications,教 AI 系统性地寻找该删的代码——什么候选够格、怎么区分“生产代码在调用”和“只有测试在调用”。48 篇精简笔记不是灵光乍现,是制度化的删除。在 AI 可以无限量产代码的时代,敢删代码成了最稀缺的纪律。

故事四:立法——一张演示 GIF 的证据链

8 月 8 日这篇,是工程严谨性的天花板,起因是一张 GIF。

PR 里附产品演示 GIF,可能每一帧截图都是真的,但无法证明它们来自同一次真实运行——可能拼接自不同会话、用了 mock 数据、或者被旧状态污染。

于是一整套立法:录制前记录 worktree 的精确 commit SHA;每次录制从全新的状态目录开始;所有画面必须来自同一个服务器、同一次真实模型驱动的执行;录制失败就整个丢弃重录,禁止和另一次运行合并;发布后还要用带认证的 API 校验媒体文件的字节大小和校验和;改 PR 正文前,必须再次确认线上 head 和录制时一致。

连 GIF 都要可复现、可审计。看完你就理解,为什么这个仓库的 CI 敢要求源码逐文件 100% 测试覆盖率。

故事五:反转——30 个“优化提案”被一篇笔记集体枪毙

这是我最喜欢的一篇,而且它处于 rejected(已否决)状态。

7 月 26 日,他们做了一次全仓库“NIH 审计”(Not Invented Here,查重复造轮子):十路并行普查,对每一处手写代码追问同一个问题——有没有维护良好的现成依赖能把它替掉?

结果产出一篇笔记,把约 30 个看似可行、实际被否决的依赖替换全部记录在案,每条附精确证据。举两个:

  • 为什么不用 vscode-jsonrpc 替掉手写的 LSP 协议层?可替换的核心只占 1800 行里的 255 行;它表达不了入站消息的大小上限;反转了取消的拆除语义;会在真实服务器输出的横幅前报错;而且在全 ESM 的仓库里它是 CJS。
  • 为什么不用 p-retry 替掉手写的重试?执行模型根本不对——这个项目的重试是一个返回决策的事件监听器,重新执行由 agent loop 依据持久日志负责,根本不存在可供重新调用的函数,而那恰是这类库的全部 API。

笔记的状态行写着否决原因:“记录在案,以免这轮普查日后从零重来。”

这就是被否决笔记的意义:执行者是 AI,AI 没有记忆。这 30 个裁定不落纸面,下个月就会有另一个 agent 兴冲冲地重新提案 vscode-jsonrpc否决也是资产。

REJECTED 证物墙:约 30 个被否决的依赖替换记录在案

故事六:冷幽默——连笔记自己的索引都被删了

7 月 19 日,他们发现自己给几百份笔记维护的“自动生成索引”有问题:任何分支只要加一篇笔记,就会重写同一个索引文件,造成没完没了的合并冲突。

决策:把索引生成器也删了。理由是——笔记的文件路径(implemented/architecture/2026-06-11-xxx.md)本身就编码了生命周期、分类和日期,“目录树 + 全文搜索”已经够用,集中索引是重复信息。

一个连文档系统的索引都要计算“维护成本 vs 发现价值”的团队。对“不产出价值的代码一律删除”的执念,他们对自己都不豁免。

这 6 个故事拼出了什么

单个看,每个故事只是一个聪明的技术决策。连起来看,它们拼出的是 DeepSeek 的 AI 工作流全貌。

人定规则:仓库根目录 15KB 的 AGENTS.md 是给 AI 读的员工手册,细到“空 catch 必须写清吞掉什么”“文档不许用比喻”。AI 按 SOP 干活:.agents/skills/ 里 11 个标准工作流,从“找代码删”到“清理 AI 语病”(有个 skill 专职删掉 AI 写文档时的口头禅,比如“this PR adds”)。决策强制留痕:505 份笔记防的就是 AI 失忆——规范里写明,“记录决策时不记录它击败了什么,就是在邀请反复争论”。验收靠机器:笔记格式、中英配对、测试覆盖率、GIF 校验和,全部脚本化进 CI。

笔记的日产出曲线是这套体系运转的仪表盘:开工首日 9 篇,7 月中旬日产 10 篇上下,7 月 30 日单日 38 篇。代码产量和笔记产量同步放量,留痕从未掉队。

大家都在讨论 DeepSeek Harness 能不能替代 Claude Code。我倒觉得更值得问的是另一个问题:你团队里的 AI,犯错之后、否决之后、删掉一个功能之后——留下记录了吗?

代码会重写,模型会换代。这 505 份笔记所代表的工作方式,可能是 DeepSeek 这次开源里最不过时的部分。


注:本文所有故事均来自 DeepSeek Harness 公开源码中的 Agent Notes(MIT 协议),当前处于开发者预览阶段(0.1.0-rc.5),官方明示未来会有破坏性变更。想亲自体验可运行 npx @deepseek-ai/dsh web

返回博客