过去一年多,AI 编程工具从尝鲜变成了很多开发者的日常。GitHub Copilot、Cursor、Claude Code 这些工具在新项目上的表现确实让人眼前一亮,写个函数、生成个模块、跑个测试,AI 都能接得住。但用久了就会发现一个现象,同一个工具在不同项目上的表现差距很大,新项目上顺滑得不行,老项目上频繁翻车,改一个函数牵连出五个报错,修一个 bug 引入三个新 bug,写出来的代码风格和现有代码完全不搭。

这个现象在开发者社区里讨论得挺多,大部分人的反应是模型不够聪明,或者上下文窗口太小塞不下。把窗口从 128K 拉到 200K 之后问题依然在,该翻车还是翻车,说明原因可能不在模型能看到多少信息,而在模型能理解多少信息。

新项目从第一行代码开始写的时候,所有上下文都在当前代码库里,目录结构就是架构,函数签名就是接口定义,README 就是需求文档。信息密度低、信噪比高,几千个 token 就能覆盖项目全貌,AI 拿到这些信息就能高效工作。

老项目的信息分布完全不一样,三五年积累下来的代码库里,真正的架构决策散落在很多地方,有些在老员工的脑子里,有些在两年前某条 Slack 消息里,有些在某次代码评审的一条评论中,有些在某次站会上五分钟的口头讨论里,连记录都没有。这些信息加起来的总量远超任何上下文窗口,而且它们根本不是以模型可以高效消费的格式存在的。

举个例子,我们团队有个模块用了一种挺奇怪的错误处理方式,和项目其他地方都不一样。写这段代码的同事说三年前踩过一个坑,某个第三方库在特定并发场景下会吞掉标准错误,所以换了一种绕过去的方式。这个信息只在他脑子里,代码里没有注释,PR 描述里写的是"优化错误处理",git commit message 是"fix error handling"。模型看不到这些背景,它只看到代码,看到这段错误处理和其他地方不一样,于是"帮忙"统一了风格,把那个绕过的逻辑改成了标准写法,测试跑不过,模型又改,还是跑不过,来回几轮就开始编造一些不存在的 API。

这类事情在老项目上每天都在发生,例如,新来的工程师入职老项目,前几个月大部分时间不是在写代码而是在理解项目,理解为什么某个模块用了看起来奇怪的设计模式,理解哪些文件不能随便改因为上下游有隐式依赖,理解代码风格为什么在不同目录里不一样因为不同时期换了不同的人来写。这个过程是把人脑中的隐性知识转化为自己可以使用的显式知识,新人花几个月慢慢学,逐渐建立起对整个项目的理解。AI 模型面临的困境和新人一模一样,只不过它没有几个月的时间,需要在一次调用中就用对。

更隐蔽的一层是老项目里有很多规矩从来没被任何人明确说出来。它们存在于 git blame 里,存在于某个合并后删掉的 PR 讨论里,存在于某次已经想不起来的站会里。团队老成员知道这些规矩所以不违反,新成员不知道就踩坑,AI 更不可能知道。这些规矩随着项目年龄增长不断累积,三年后五年后十年后,积累到一定程度,连老成员自己都可能记不全了。

从信息论的角度看,新项目的信息熵很低,所有信息都是显式的、结构化的、集中存放的,模型需要处理的信息量小。老项目的信息熵极高,关键信息是隐式的、非结构化的、分散在人脑和聊天记录里的,模型能接触到的只是冰山一角,上下文窗口再大也只能处理写下来的东西,对于没写下来的部分完全无能为力。

我们在做 Octo 的过程中把这个观察沉淀成了一个判断,AI 编程在复杂项目上的效率瓶颈不在模型侧,在项目知识的结构化程度。模型能力每年都在进步,上下文窗口从 4K 涨到 200K,但如果项目知识一直以当前的方式散落在代码、文档、聊天记录和人脑里,模型能力的进步能转化成的实际产出提升会越来越小。

Octo 用了三层机制来处理这个问题,每一层解决的是不同类型的信息缺失。

Context 层解决的是项目背景信息的结构化存储。项目的历史决策、技术选型理由、讨论记录在 Octo 里被结构化地保存下来,新的 Bot 或者新的团队成员加入时直接查 Context 就能了解来龙去脉,不用从零开始翻聊天记录和 git log。Context 不是写完就不变的文档,它随着项目推进持续更新,每次有新的技术决策或踩坑记录都会补进去。前面说的那个"三年前踩坑所以换了错误处理方式"的例子,如果当时有 Context 机制,这条信息就会被记录下来,下次不管是新人还是 Bot 都能查到。

Taste 层处理的是那些通常只存在于团队默契中的东西。代码风格偏好、评审标准、验收习惯,Octo 通过验收、打回、批注等操作记录下来形成偏好卡片,Bot 执行任务时自动参考这些偏好。一张偏好卡片里记的是具体的行为规则和来源证据,不是一句"请保持一致"这种模糊指令,而是"这个项目的错误处理统一用 Result 类型而不是 panic,参考 src/error.rs 里的实现"这种可以直接执行的规则。偏好卡片之间可以互相引用和组合,用了一段时间之后,团队的品味从少数人的默契变成整个组织可复用的资产。

Matter 层负责把每次代码交付从对话流里拎出来变成结构化工作单元,带有负责人、交付物、验收结论和反馈记录。一个函数为什么这样写、上次重构为什么被退回、某个技术方案在什么场景下被否决过,这些信息都挂在对应的 Matter 下面,下次遇到类似场景时自动注入,避免重复踩坑。Matter 和工单的区别在于工单是先填表再干活,Matter 是先聊清楚自然变成任务,对开发团队来说后者摩擦小很多。

三层加在一起的效果是把老项目里那些只有老员工知道的隐性知识变成 Bot 可以消费的显式信息,让 Bot 在需要的时候查到需要的信息,比暴力堆 token 高效得多。

这个思路不只适用于编程。竞品调研做到后面也会积累大量隐性知识,哪个渠道的信息可靠、哪些竞品的哪些功能是被高估的、上次调研为什么漏掉了某个关键信号。产品设计也一样,为什么某个交互方案被否决过、用户反馈里哪些是噪音哪些是真需求。不做结构化沉淀,AI 每次都要从零开始,每次都在同样的地方翻车。

新项目天然结构化,老项目天然非结构化,要让 AI 在老项目上也好用,需要的不是更大的上下文窗口,需要的是把散落在人脑和聊天记录里的知识结构化地沉淀下来,让模型能按需消费。

Octo 已在 GitHub 开源,Apache 2.0 协议:https://github.com/Mininglamp-OSS/octo-server

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐