AI-Native 软件工程(11):Knowledge Layer——为什么知识层半年就馊了
上篇拆了反馈层——什么信号值得回流,什么必须丢掉。被四维筛子留下来的那一小撮信号,最后流到了知识层。这一篇聊的就是:这些信号到了知识层之后,会发生什么。
剧透一下结论:大多数情况下,它们会以远比你预期更快的速度腐烂。
去年这个时候,我们团队搭过一套”经验库”。立项书上写得很正经:把过去半年所有 Agent 跑过的成功路径抽象成可复用的知识条目,未来同类任务直接命中检索,省 token、省时间、省踩坑。立项时大家很兴奋,觉得这是把”组织记忆”变成”Agent 记忆”的关键基础设施。
第一个月条目还不多,两百条左右。Agent 命中率挺高,团队里几个工程师都跑来夸——”这条建议给力,省了我半天”。
第三个月,条目膨胀到一千七百多条。Agent 还在用,但开始出现一些怪现象:它会信誓旦旦地按一条三个月前的”经验”去操作一个早已重构过的系统,结果在前两步就撞墙。撞完之后它居然还会引用同一条经验解释为什么撞墙:”根据 lesson #834,这个模块需要先获取 X 权限。”——可那个权限模型上个月被换掉了。
第六个月,没人再敢直接信这套经验库。它没坏,每天还在被检索,但所有人在引用它之前都得手动验证一遍。原本”省时间”的工具,变成了”多一步验证”的负担。后来我们把它砍了,回到无知识库的状态,反而轻松了。
复盘的时候我意识到:我们不是输在”做不出来知识库”,我们是输在默认了知识是不会过期的东西。在传统软件工程里,文档放一年没人改也还可以参考——因为文档描述的系统也一年没动。但 AI-Native 系统里,代码、依赖、API、提示词、Agent 行为本身都在以周为单位演化。半年前的”最佳实践”,今天可能是反模式。知识没坏,是世界变了。
知识层的核心命题,因此不是”知识怎么组织”,而是另外一个完全不同的问题:知识是有半衰期的。你怎么知道一条经验是不是已经馊了?怎么在它馊之前用,馊之后丢?
知识 ≠ 文档,更不等于经验池
我先把三个经常被混在一起的概念拆开,否则后面没法谈。
文档是显性的、人写给人看的、长生命周期的、版本管理的。一份 API 文档是文档。一份 ADR(架构决策记录)是文档。它的主要消费者是同事,主要质量保证手段是 review 和审稿。
经验池是 Agent 跑过任务之后留下的痕迹的集合。一条经验池条目可能长这样:”上次给 user-service 加字段时,先在 staging 跑了三遍迁移才发现 rollback 脚本忘了写。”它是半结构化的、原始的、未经裁剪的。
知识是从经验池里被抽象、归纳、提纯之后的可复用判断。从上面那条经验池条目里,可以蒸馏出一条知识:”对 user-service 这类核心服务做 schema 迁移,必须先在 staging 验证 forward + rollback 双向脚本。”
很多团队的”知识库”其实是经验池披了一层壳。原始 trace 直接打上 tag 就丢进去,号称”AI 时代的知识管理”。这套东西在 Agent 看来是个垃圾堆——它检索回来一大堆 stdout 片段,需要自己再做一次归纳。结果就是每次决策都在重复同样的归纳工作,token 成本和延迟都吃不消。
知识层真正要存的,是已经被蒸馏过、可以直接作为判断依据的那一层。这一层比经验池小一到两个数量级,比文档活得短一到两个数量级。它的产出有成本——你得有人或者另一个 Agent 来做蒸馏——这是工程取舍,不是技术细节。
半衰期:知识层最容易被忽略的轴
我现在判断一条知识值不值得入库,第一道关不是”它写得对不对”,而是”它的半衰期有多长”。
什么是知识的半衰期?我的定义是:从这条知识被记录开始,过多久之后,它有 50% 的概率已经不再准确。
这个数字差别巨大。我把日常碰到的知识大致分了五档。
| 半衰期档位 | 典型内容 | 入库策略 |
| 周级 | 某个 PR 的临时 workaround、调试中开的临时端口、当前 sprint 的优先级 | 不入库,留在任务级缓存 |
| 月级 | 当前项目的 API 命名约定、临时引入的第三方依赖版本 | 进项目级 memory,自动衰减 |
| 季度级 | 团队当前用的部署流程、当前架构下的故障域 | 进项目级,需季度复审 |
| 年级 | 公司技术栈选型、核心服务的边界契约、领域模型 | 进全局,但要绑定版本 |
| 多年级 | 工程原则、架构判断方法、对某类问题的思考框架 | 全局,长期 |
我以前犯过的最大错误,是把不同档位的知识混在一个池子里,用同一种检索策略。结果就是 Agent 检索一个稳定的”领域模型”问题,被一条周级的临时 workaround 干扰,给出了一个三个月前才有意义的建议。
这个错误的本质,是没有区分”事实”和”约定”。事实可以长期稳定——勾股定理一万年也是对的。约定的稳定性取决于环境,环境一变,约定就废了。AI-Native 系统里的”知识”大部分是约定不是事实,这就是为什么它腐烂得这么快。
知识衰减的三种模式
一条知识从准到不准,不是某个时间点突然失效,而是渐进式衰减。理解衰减模式,才能设计对应的应对策略。
第一种是底层变化触发的衰减。底层代码、API、依赖、数据模型变了,所有依赖于它的知识都失效。这种衰减是”硬失效”——一旦发生,旧知识不只是不准,是会主动误导。我之前那个经验库踩的就是这个坑。应对手段是版本绑定:每条知识入库时绑定它依赖的”底层指纹”——可以是 commit hash、API 版本号、schema 版本。底层一变,所有绑定的知识自动标记为”待复审”。
第二种是累积漂移导致的衰减。没有一个明确的”变化事件”,但环境在慢慢变。比如团队规模从 5 个人变成 50 个人,原来”开会决定”的流程不再成立;比如服务规模从 QPS 100 变到 QPS 10 万,原来”直连数据库”的做法不再 OK。这种衰减没有明确的失效时间点,只能用渐进降权:知识入库时记录上下文(团队规模、QPS 量级、数据规模),检索时如果当前上下文跟入库时差距太大,自动降权或要求人工确认。
第三种是反例累积触发的衰减。一条知识本来 80% 准,用着用着发现某些边界条件下不对,反例越积越多,可信度逐步下降。这种衰减是最隐蔽的,因为单看任何一次反例都”看起来不严重”。应对手段是反例计数器:每条知识在使用过程中如果被反例覆盖,记一次。反例数超过阈值,知识自动降级——从”建议”降到”参考”,再降到”归档”。
三种衰减叠加,意味着知识层不是一个”写入即永久”的系统,而是一个持续自我修剪的系统。它的健康度不取决于”存了多少条”,而取决于”过期条目占比有多低”。

检索 vs 灌注:两种使用模式的取舍
知识入库的姿势讲完了,下一步是 Agent 怎么用它。这里有一条经常被忽略的分界线。
第一种用法是检索:Agent 在决策点主动发起查询,”我需要关于 X 的过往经验”,知识层返回最相关的若干条,Agent 自己判断是否采纳。RAG 是这个模式的代表。
第二种用法是灌注:相关知识在 Agent 看到任务之前就被注入到 system prompt 或 context 前缀里。这种方式下 Agent 不需要主动检索——它在”已经知道”的状态下开始决策。
两种用法的取舍非常具体:
检索是按需付费的。Agent 用不到,就不查,零成本。代价是 Agent 必须有”我应该查这个”的元认知——它要先意识到自己有知识盲区。这件事对一些复杂任务可以做到,对简单任务往往做不到,因为 Agent 不知道自己不知道。
灌注是预付费的。所有相关知识默认在场,Agent 不需要自觉。代价是固定的 context 占用,而且无关知识会干扰决策。我之前提过反馈层的”context 预算”——灌注模式下,每条灌注的知识都在挤压决策空间。
我自己的取舍:稳定的、跨任务必用的少量知识走灌注(比如”我们用 pytest 不是 unittest”),数量控制在 10 条以内、总长度不超过 1000 字;其他都走检索,由 Agent 在需要时主动发起查询。
有些团队会问到第三种方案——fine-tune。把知识 fine-tune 进模型权重。这个方案在工程上几乎不该被首先考虑。原因有三:第一,fine-tune 后知识无法精确删除,一旦知识过期你没法干净撤销;第二,fine-tune 的成本和周期跟 AI-Native SE 里”知识半衰期以月计”的现实不匹配;第三,fine-tune 后的知识不再可观测——Agent 用了什么判断、为什么用,看不出来。fine-tune 在”长期稳定 + 大量样本 + 风格而非事实”的场景下有价值,但这跟我们这里讨论的工程知识不是同一回事。
隐性知识:最值钱也最难落
显性知识相对好处理——它已经被人想清楚、写下来了,剩下的是组织、索引、检索。
真正难的是隐性知识。架构决策背后的”为什么这样选”、风格偏好里”为什么这种命名我们不接受”、踩过的坑里”为什么当时没看出来”——这些东西通常没人写下来,因为写下来需要的精力比直接做事多得多。
隐性知识在 AI-Native SE 里的价值,比显性知识高一个量级。因为显性知识 Agent 自己查文档也能查到,但隐性知识只能从你的团队里来。一个 Agent 接手新项目,知道”用 pytest 不是 unittest”是基础;知道”这个项目里测试覆盖率追求 90% 是因为去年一次生产事故源于一段未覆盖的 fallback 分支”,才是真正能影响决策的判断。
把隐性知识落到 Agent 能用的形态,工程上有几条具体路径。
一是决策点采集:在反馈层的”决策点记录”机制里,强制要求 Agent 解释”为什么选 A 不选 B”。理由本身就是隐性知识的种子。
二是人工注入接口:让团队成员能在工作流里随手补一句”对了,这种情况我们一般这么处理”,自动归档成知识候选。注意是”随手”而不是”专门”——专门的知识管理动作大家都不愿意做,能在做事的同时顺便做的才有持续性。
三是事故复盘强制蒸馏:每次出事故的复盘报告,结尾必须有一条”如果 Agent 下次遇到类似情境,它应该知道什么”的强制字段。这条字段的产出物直接进知识库。
四是风格知识由示例承载:架构师的判断很多没法用规则描述清楚,但可以用”好的例子”和”坏的例子”成对承载。这种成对示例的检索效果,往往比规则陈述更准。
这四条路径都有一个共同特点:它们不是另起炉灶建一个”知识工程”流程,而是把知识蒸馏嵌入到现有工作流里。在 AI-Native SE 里,单独的”知识管理工具”几乎都会失败——只有跟工作流深度耦合的知识沉淀机制才能持续。

知识层与 Planner / Verify 的接口
知识不是”被读”,是”被引用进推理路径”。这句话听起来有点抽象,我用具体例子说清楚。
Planner 在做任务分解时,需要知识层告诉它”这类任务通常分几步、风险在哪、哪些步骤可以并行”。如果知识层只是返回一堆文本片段,Planner 还得自己做归纳——这就退化成了 Agent 在写代码前先读了一遍文档,价值有限。
更好的设计是:知识层提供结构化输出。同样一条”用户认证迁移”的知识,可以同时暴露三种视图——给 Planner 的视图是步骤模板、给 Verify 的视图是验证清单、给 Agent 自己的视图是叙事说明。同一条知识,按消费者的需要分发不同切面。
Verify 层调用知识层的方式更隐蔽。Verify 不是”读知识”,是”知道有哪些 invariant 必须验”。比如”用户认证迁移”这条知识里,应该附带一组验证断言——”迁移后老 token 是否还能登陆?”、”迁移后审计日志的用户 ID 是否对得上?”。这些断言是知识的一部分,但 Verify 在调用时只关心断言列表,不关心叙事内容。
这种”按消费者切面”的设计,要求知识入库时不是写一段散文,而是按预定义的结构填字段。听起来很重,但好处是 Agent 真的能”引用”知识进推理,而不是把知识当成另一段需要再次解读的文本。
我现在的实现:每条入库知识至少有四个字段——叙事(人读的)、Planner 模板(步骤分解)、Verify 断言列表(可执行验证)、版本指纹(底层依赖)。前三个字段是消费侧,第四个字段是衰减管理用的。蒸馏这件事不便宜,但它把”被动文档”变成了”主动可用的判断”,差别值得这个投入。
共享边界:什么知识全局,什么必须隔离
多 Agent 系统里有一个非常容易被忽略的设计问题:知识层的共享边界。
最幼稚的设计是”所有 Agent 共用一个知识库”。听起来很合理——共享知识不是更高效吗?但你试一下:Agent A 在客户 X 的项目里学到的”这个客户的 prod 库密码存在 vault 路径 Y”,被 Agent B 在客户 Z 的项目里检索到了——你的知识层刚刚帮你做了一次数据泄露。
知识共享有边界,边界由两个维度决定:租户边界和抽象级别。
租户边界决定了”哪些 Agent 之间可以共享”。客户 A 的项目知识不应该泄漏到客户 B。同一公司内部不同业务线的知识可不可以共享,看具体合规要求。这一层是硬边界,违反就是事故。
抽象级别决定了”什么样的知识有资格跨边界共享”。具体到某个数据库、某个 API 密钥、某个文件路径的知识,永远不能跨租户。抽象到”这一类问题应该这么思考”的知识,可以跨。中间这一大片,需要逐条判断。
我用的简单规则是:只有不带任何具体标识符的、纯方法论级别的知识,才允许进入全局池。 任何含有客户名、项目名、密钥、地址、IP、路径的条目,强制隔离在该租户的知识空间内。蒸馏阶段就要做这次过滤——蒸馏时如果发现一条候选知识无法剥离具体标识符,它就该被降级到租户级,而不是上升到全局级。
这个边界比想象中难维护。一个工程师在写”如何调优 PostgreSQL 慢查询”这样看起来纯方法论的知识时,可能不经意带上一个”我们生产库的连接池上限是 200″的细节——这条细节就把它从全局降级到了租户级。需要工具层面的强制检查,不能靠自觉。
我现在的设计选择
把上面这些拆完,我自己实际在用的知识层架构是这样的——同样不是推荐给所有人,是我现在场景下的取舍。
知识入库走显式蒸馏路径。原始经验池里的 trace 不会直接进知识库。每条候选知识要经过一次蒸馏步骤,产出四字段结构:叙事 + Planner 模板 + Verify 断言 + 版本指纹。蒸馏可以由人做,也可以由专用的”reviewer Agent”做,但必须留蒸馏痕迹。
知识带半衰期标签。入库时强制选择档位(周/月/季度/年/多年),不同档位走不同的过期策略——周级到期直接删,年级到期触发复审。
衰减监测自动化。底层指纹绑定 git commit / API version / schema version,底层变化时自动标记相关知识”待复审”。反例计数器记录每次使用后的反馈,超阈值自动降级。
检索默认按需,灌注严格白名单。Agent 主动检索为主,只有不超过 10 条的”必备知识”走灌注,且这 10 条要定期复审。
共享边界用蒸馏阶段卡死。蒸馏时强制检查具体标识符,发现则降级到租户级。全局知识池入门门槛远高于租户池。
健康度指标,跟”条目数”无关。我盯的是三个数字:过期占比(应该低于 5%)、命中后被采纳率(应该高于 60%)、平均被反例覆盖次数(应该低于 1)。这三个数字一旦恶化,砍知识库比扩张更紧迫。
这套设计也不是终态。它解决了”知识库越积越馊”的问题,但带来新的代价——蒸馏成本不便宜,每条知识入库前的工程开销显著高于”直接存 trace”。我现在认为这个代价值得,但在小团队或者快速验证的场景下,可能直接用经验池不蒸馏反而更经济。
系列下一站
知识层处理的是”信号活下来之后怎么沉淀、怎么用”。下一篇是这个系列的最后一篇——Collaboration Layer:当 Agent 不止一个,当人和 Agent 同时在改一个系统,决策权、知识、上下文怎么协调?为什么大多数”多 Agent 协作”系统其实是几个 Agent 各自为政?
写在结尾
知识层的设计错误,跟反馈层的设计错误是同构的——都源于”以为更多就是更好”。反馈层错在以为收集越多越聪明,知识层错在以为入库越多越值钱。
最干净的知识层是空的——零过期,零误导,零维护成本,但也零价值。最丰富的知识层是把所有 trace 都存下来——理论上信息完整,实际上 Agent 每次决策都被噪声埋掉。
中间这一大片地带怎么走,没有标准答案。但有一个判断标准,可能比所有具体设计都重要:你的知识层在第 N 天,是在帮 Agent 做出更好的判断,还是在帮 Agent 复制旧的错误?
如果你的知识库已经存到几千条但说不清最近一周谁用过哪条,它大概率在腐烂。如果你的 Agent 引用知识时给出的理由总是”根据 lesson #X”,但没人能说清 lesson #X 是不是还成立——它已经在退化。
知识层不是软件工程的存档室,它是 Agent 的工作记忆。工作记忆里塞满过期的、不准的、自相矛盾的东西,比空白的工作记忆更糟。
去看一下你的知识库,里面有多少条是过去三个月没被任何 Agent 主动用过的?把那些先清理掉,再谈扩张。
夜雨聆风