这一周折腾 AI coding,我不断撞上同一个问题:每次 Agent 接手新任务,我都要重新解释这个项目为什么会变成今天这样。
代码、测试和提交记录都在仓库里,它还是会缺掉最影响判断的那部分信息。某个边界为什么划在这里,上次为什么放弃另一条路,哪些做法看着合理却踩过坑,哪些技术债暂时不能动。这些事情散落在聊天记录、PR 讨论、外部文档和我的脑子里。Agent 只看得到结果,但不知道 Why,只好从几句口头交代猜我的想法。等它猜错了,我再愤怒纠正“你在干什么.jpg”。
我累,AI 也贵。
我想要的效果其实很朴素:让 Agent 替我编程,而不是只是完成编程。后来读到 OpenAI 的 Harness engineering 和 yage 的 Context Infrastructure,我才发现大家处理的是同一类问题。模型已经能完成不少复杂任务,实际效果却越来越依赖它进入任务时拿到了什么上下文,以及这些上下文能否指导后续行动。
于是我开始给仓库加一套结构化记忆,最后做成了 doc-flow。
Git 记得改住变更,仓库还要记得为什么
Git 可以回看代码如何变化,却很少保存一次选择背后的完整理由。commit message 会说明改了什么,偶尔也会解释为什么改,但项目里的约束、放弃方案、现实 trade-off 和经验判断,通常没有稳定的去处。
这些信息全塞进 AGENTS.md 也解决不了问题。入口文件越写越长,Agent 每次进入仓库都要先吞下一整套规则。真正和当前任务有关的内容反而被埋住了。上下文窗口容量再大,也不等于每一段内容都能被同样有效地利用。
我希望项目记忆满足几个条件。它应该跟仓库一起存活,可以被 Codex、Claude Code 等不同工具读取;新项目和已有项目都能接入;Agent 做事时会留下现场记录,任务结束后再把少量长期有效的结论沉淀下来。以后换一个人或一个 Agent 接手,先读仓库就能理解项目,而不是等待原作者重新口述一遍历史。
麻烦在于,记录得越积极,仓库越容易变成我家的储藏室:什么都有,什么都找不到。doc-flow 最重要的约束因此落在“什么不要长期保存”上。
两层文档,把任务现场和长期判断分开
doc-flow 只保留两层内容。
- 一层是 durable docs,也就是相对稳定、未来仍然有指导意义的东西,例如 architecture、constraints、decisions、lessons、risks。
- 一层是 worklog,也就是任务进行中的临时记录:计划、发现、pivot、验证、summary。
这两层分开以后,中间过程不必急着写进长期文档。任务现场允许杂乱,durable docs 则需要证据和筛选。只有那些经过验证、以后还会改变选择的结论,才从 worklog 进入长期记忆。
我最初以为一个 bootstrap 就够了,做下去才发现 fresh repo 和 existing repo 面临的风险完全不同。空仓库可以直接搭脚手架,已有历史的仓库往往已经有自己的文档、约定和事实来源,接入时最怕新系统篡位。最后我把入口收敛成四个 mode:
bootstrap:仓库还没有这套记忆系统时,建立最小结构。adopt:接入已有仓库,先识别并沿用原来的文档边界。work:任务进行时维护 worklog,记录计划、发现和验证。
另一个容易失控的地方是 AGENTS.md。我一开始想把自动化规则都放进去,后来发现这会同时制造重复和上下文污染。最后只留下一个 pointer:去看 docs/index.yaml,需要维护项目记忆时使用 doc-flow。具体怎么 work,由 skill 自己说明。
入口负责路由,文档索引负责指路,skill 负责行为。每一层只保存自己必须知道的内容。
另外,这背后还有一个技术前提:使用的模型经过后训练,具备主动、渐进式检索的能力。
Trellis 让我看清了另一种控制强度
后来我发现了 Trellis。第一眼看过去,它和 doc-flow 很像:同样使用很短的 AGENTS.md 做路由,同样强调 repo-local context,也都希望 Agent 的工作能留下可复用的记录。
我当时查看它的实现时,真正的控制面在 .trellis/ 里。里面有 spec、tasks、workspace journal 和 workflow,还会为不同工具生成 commands、skills 与 hooks。以 Claude 为例,/trellis:* 命令按需调用,session-start hook 则会在固定阶段注入 workflow、spec index、当前任务状态和 start 指令。
我起初看到十几个命令文件,下意识地觉得这套系统开始变重了。仔细看完才发现,它们没有在每次会话里一起进入上下文。高频注入主要由 session-start hook 完成,其余命令只在需要时加载。它建立的是一个范围明确的反馈回路:会话开始时读取 workflow、spec 和任务状态,后续再通过对应命令维护这些记录。固定事件提高了触发的确定性,比单靠 instruction 要求 Agent 自觉执行更可靠。
不过目前为止我没有发现什么 benchmark 能证明“注入更多指令、拆出更多命令”,模型效果一定更好。能支持它的主要还是更广义的 harness 经验。OpenAI 的 Harness engineering 和 Anthropic 的 Effective Harnesses for Long-Running Agents 都在强调外部脚手架、任务状态和 repo-local context 的价值;但另一方面,像 Lost in the Middle 这类长上下文研究也在提醒我们,更多上下文不等于更有效的上下文。上下文窗口不是无限垃圾桶,这点和人脑其实没什么本质区别。
到这里,doc-flow 和 Trellis 的边界也清楚了。doc-flow 更接近 memory substrate,回答什么进入长期记忆、什么停留在任务现场、下一个 Agent 从哪里开始。Trellis 更接近 workflow controller,还要决定什么时候读写、哪些事件由 hook 捕捉、任务怎样切分、检查、归档和迁移。
两者处理的是同一个母问题,承担的自动化成本不同。跨工具、长周期、多任务、多 Agent 的开发 harness,需要 commands、hooks、状态管理以及模板升级和用户修改冲突处理。这些组件有明确用途,也会带来对应的维护成本。
我现在只需要一个轻量闭环
Trellis 没有促使我把 doc-flow 扩成一套 workflow OS。它反而帮我确认了当前边界:我需要项目记忆能够持续运转,但暂时不想让流程接管整个开发现场。
这套轻量闭环有四个选择:
- 高频事件先进入 working memory,避免频繁重写 durable docs。
- durable docs 只在少数高价值边界更新,例如 handoff、push 或 PR 前。
- always-on routing 保持极简,入口只告诉 Agent 去哪里找。
- 自动化优先放在便宜、可逆、低噪声的控制点上。
这样做会牺牲一部分强制性。Agent 可能漏掉,某些工具也没有合适的 hook。好处是系统容易理解,接入已有仓库时改动有限,我也不必长期维护一整套迁移和命令体系。等任务规模真的需要更强控制,再为那部分确定的需求付成本。
说白了,我不想让 Agent 每次进仓库都先读一遍四书五经。我们做这些,只是为了让它更像一个能持续记住上下文的工作伙伴。
当仓库比人记得更完整
这次折腾也改变了我对文档的理解。README、方案设计和接口说明偏向描述某个稳定结果。在 agentic workflow 里,文档还承担工作记忆:它把边界、理由、任务现场和验证结果留给未来的协作者,无论后来接手的是人还是 Agent。
一套项目记忆至少要回答三件事:
- 哪些信息、原则和标准会长期影响这个项目?
- 哪些内容只属于当前任务的进度追溯?
- 系统应该在多大程度上自动维护这条分界?
如果这三件事能够持续运转,人需要反复补充的上下文会减少。与此同时,一个更远的问题也会出现: 假如人不再拥有全部的上下文,是否还拥有跟 AI 协作的基础条件? 我们现在仍在努力给 AI 提供更完整的上下文。假如某一天,仓库和 Agent 比任何一个人都更了解项目,人还要审核什么、补充什么,又该在哪些地方授权?
我也没有答案。
至少眼前,我希望 Agent 有办法获取项目里的隐性上下文。这样下次开工时,我就不必再给 AI 交代这个项目的病历了 ;)