Coding agents 在长期迭代的代码库里有个专属翻车姿势:每隔几次会话,它们就会重新提出一个已经被团队评估过、否决掉的方案。读代码时发现一个慢查询,就会建议上 Elasticsearch——而 Elasticsearch 几个月前被否掉的原因只存在于某条聊天记录里。从 agent 的视角看,这件事从来就没讨论过。

人类团队成员也在慢动作地撞同一堵墙。git blame 能告诉你谁改了哪一行、啥时候改的,PR 能告诉你合并了什么,但谁也说不清为什么另一种方案被干掉了。当时知道原因的 reviewer 离职了,半年后有人又在新的 PR 里把整件事重新辩论一遍。

打开网易新闻 查看精彩图片

开源工具 kgai 把这个困境当成一个数据问题来处理。它的思路很简单:别存“记忆”,存“决策”。

首先是数据模型:元素和箭头。每个元素就是一个代码组件,比如搜索 API,上面带有属性,例如 search-api.retry_policy = "idempotency-key + backoff"。元素之间再用连线表示关系。这张图本身没啥稀奇的,真正有意思的是它是怎么来的。

银行不会把账户余额当成一个可以被直接改写的数字,而是存一条条交易记录,余额只是把交易记录求和后算出来的结果。kgai 对代码架构用的就是同一套逻辑:当前架构图是一个“派生值”,真正被记录的原始事实是决策,而且是在做出决策的那个会话里捕获的。

每条决策记录了改了什么、为什么改、影响了哪些元素。比如:“搜索重试改用幂等键 + 指数退避,为什么改:固定 3 次重试在厂商服务降级期间导致重复扣款;设置 search-api.retry_policy = "idempotency-key + backoff";替代旧决策‘简单 3 次重试就够了’”。

查询用的知识图谱就是从第一条决策开始重放整个决策日志算出来的。删掉图再重放日志,结果是字节级一致的,所以日志才是真相,图只是一份可以随时丢弃的缓存。这就是金融系统里的事件溯源模式,在这里,“账户”变成了代码仓库背后的技术推理。

决策从不被修改。任何改动都表现为一条新决策,把旧决策标记为“被取代”。旧决策仍然留在日志里,你能完整看到从“简单 3 次重试就够了”到“幂等键 + 退避”的完整决策链。

这套设计在终端命令行里就能体现出来:

$ kg history "feature:search-api"feature:search-api — 2 decisions, oldest first2026-05-02 Simple 3x retry is enough supersededwhy: provider timeouts are rare, simplest thing that works2026-07-16 Search retries use idempotency keys + backoff ● current...

最终效果是——当你或你的 coding agent 又想重新争论 Elasticsearch 时,至少能够先查一下:这个决策是否已经被做出了、当时是基于什么理由被否掉的。“我们为什么不用 Elasticsearch”这个问题,只要被决策日志记录过一次,就不需要再靠人的记忆或者翻聊天记录来回答了。