乐于分享
好东西不私藏

梳理项目知识库:从零文档到 AI 可消费的知识体系

梳理项目知识库:从零文档到 AI 可消费的知识体系

「AI 看不懂屎山代码,不是因为它不够聪明——是因为你把所有隐性约束都写成了代码。而代码是 AI 最差的输入格式。」


场景还原:AI 和你的认知鸿沟

你把支付回调模块的代码贴给 AI:"帮我理解这段代码,然后写一份概要。"

AI 读了几分钟。返回了一份分析:

这是一个支付回调处理模块,主要处理支付宝、微信、银联三种渠道的回调。代码结构不够清晰,建议使用策略模式重构。

你觉得 AI 说得没错——代码确实不够清晰。但你心里也知道,AI 完全没有触碰到这个模块的核心。它不知道:

  • 支付宝的 sub_trade_type 字段是支付宝文档里没写但回调里会返回的扩展字段——库存回补全靠它
  • 微信的金额负数修正是微信支付团队确认过的已知 bug——修正逻辑不能提取到"公共校验层"
  • 银联的回调在 2021 年升级过接口——现在的新旧两种格式并存,需要兼容处理

这些东西没有一个写在代码注释里,更没有一个写在文档里。它们存在于以前同事的离职交接邮件里、三年前的线上事故复盘文档里、和支付渠道的对接聊天记录里——对这些信息,AI 完全是盲的。

AI 和屎山之间的核心矛盾不是"AI 太笨",是"知识在代码里的表达方式 AI 无法消费"。


第一层:问题诊断——为什么 AI 看不懂屎山

要给 AI 看懂屎山,得先精确理解"看不懂"的根因在哪。不是"代码太乱"这种模糊的判断——是知识在什么形式上出现了断裂

诊断结论:屎山项目的知识以三种形态存在——文本类(注释和文档)、结构类(模块依赖和 API 契约)、历史类(架构决策和补丁原因)。AI 需要的不是"更多代码",而是这三种形态的知识被提取为结构化文档,让 AI 不用从代码中逆向推断。

知识类型
在屎山中的状态
AI 需要的格式
鸿沟
文本类
(注释/文档)
零散、过时、误写为 TODO
精确的功能描述 + 约束条件 + 边界条件
AI 无法区分"有用注释"和"废弃 TODO"
结构类
(依赖/契约)
隐含在 import 和函数调用中
显式的模块依赖图 + API 输入/输出契约
AI 需要遍历全部 import 才能重建依赖
历史类
(决策/补丁)
仅在 git log 和前同事的记忆里
ADR(架构决策记录)+ 补丁原因说明
git log 只是"什么时候改的",不是"为什么这样改"

一个具体的知识断裂案例

# ═══════════════════════════════════════════════════════════
# AI 只能在代码中看到的
# ═══════════════════════════════════════════════════════════

defhandle_refund_callback(data: dict) -> bool:
    order = Order.objects.select_for_update().get(id=data["order_id"])

# ── AI 视角 ──
# select_for_update() 会锁定这行记录,直到事务提交
# 为什么退款回调需要行锁?可能有并发问题
# ── AI 不知道的 ──
# 支付宝的退款通知和微信的退款通知可能在毫秒内同时到达
# 如果不加行锁,两个通知同时处理会导致双倍退款
# 这是2020年"618退款翻倍事故"后的修复——select_for_update 不是设计选择,是止血措施

# ── AI 视角 ──
# trade_status 是交易状态,为什么退款回调里要检查?
# ── AI 不知道的 ──
# 支付宝在退款成功后可能会再发一条 trade_status='TRADE_CLOSED' 的通知
# 这条通知不应该触发退款逻辑——需要在入口就过滤掉
# 支付宝文档里没有明确说明这个行为,是我们对接时踩到的坑
if data.get("trade_status") == "TRADE_CLOSED":
returnFalse# 不做处理

# ... 后续退款逻辑

知识断裂的三层放大效应


第二层:根因分析——"给人看的文档"和"给 AI 消费的知识"有什么本质差异

第一层诊断了"知识以什么形式断裂"。第二层追问:如果我现在开始补文档,应该写成什么样子 AI 才能消费? 因为大多数开发者的直觉是"写一份架构文档"——但这类文档是给人看的,对 AI 来说粒度太粗、表达太模糊。

给人看的文档 vs 给 AI 消费的知识

对比两者的本质差异:

维度
给人看的文档
给 AI 消费的知识
粒度
模块级:"支付回调模块"
约束级:"select_for_update() 的存在是为了防止 2020 年的双退款事故"
表达
意图式:"需要注意并发安全"
指令式:"两个渠道的通知可能同时到达,用行锁保证至少一个被阻塞"
完整度
80% 说清楚就够了(人自行补全)
100% 精确——AI 不能自行补全缺失的 20%,会补错
结构
叙事式(章节、段落)
结构化(key-value、表格、契约定义)
更新周期
写完很少更新 → 腐化
随代码变更同步更新 → Delta 机制

粒度的本质差异

以"支付回调"为例:

# ═══════════════════════════════════════════════════════════
# 给人看的文档:一段话即可
# ═══════════════════════════════════════════════════════════
human_doc = """
支付回调处理模块负责接收支付宝、微信、银联三方的回调通知,
验证签名后将回调数据转换为内部格式。
需要注意支付宝可能发送重复通知,需要做去重处理。
"""


# ═══════════════════════════════════════════════════════════
# 给 AI 的知识库:每条约束精确到可执行
# ═══════════════════════════════════════════════════════════
ai_knowledge = {
"module""payment_callback",
"constraints": [
        {
"id""C001",
"type""security",
"description""防伪造校验: order_id 和 amount 来自回调不可信",
"logic""通过 select_for_update() 读数据库获取真实订单状态和金额",
"code_location""handle_refund_callback:line 45",
"test""传入伪造的 amount=99999, 断言实际使用的是数据库中的真实金额"
        },
        {
"id""C002",
"type""business_rule",
"description""支付宝重复通知去重",
"logic""notify_type='async' 时检查 notify_id 是否已存在于 dedup_cache(Redis)",
"code_location""handle_refund_callback:line 32",
"test""连续发送两个相同 notify_id 的通知, 断言第二个被跳过"
        },
        {
"id""C003",
"type""compatibility",
"description""微信金额负数修正",
"logic""amount < 0 时取绝对值, 不能 raise 异常(否则正常退款被阻断)",
"code_location""handle_refund_callback:line 78",
"reason""微信已知 bug, 在他们修复之前必须容错",
"test""传入 amount=-100, 断言内部使用 abs(100) 且不抛异常"
        }
    ]
}

关键差异:给人看的文档中"需要注意支付宝可能发送重复通知"这句话,AI 需要自行推断"在哪里做去重、用什么机制去重、去重失败了怎么处理"。给 AI 的知识库中 C002 精确到"在 notify_type='async' 时检查 notify_id 是否存在于 Redis 的 dedup_cache 中"——AI 不需要推断,直接执行。


第三层:策略对比——三种知识提取方式

第一层诊断了问题(知识断裂),第二层分析了要求(粒度差异)。第三层对三种不同的知识提取方式进行对比。

策略
方式
优点
致命缺陷
纯人工
人逐个文件读,手写知识库
100% 可控,质量保证
3000 行模块要 >2 天,全项目不现实
AI 一次性
贴全部代码给 AI,让它生成概要
快,几分钟
上下文溢出导致 >30% 的隐性约束遗漏
分层渐进提取
AI 辅助 + 分层 + 人类确认
完整 + 可验证
需要设计分层策略和验证机制

分层渐进提取的递进逻辑

不是"把代码拆成小块逐块分析"——这只是物理切分。分层渐进提取的核心是按知识类型分层,每层用 AI 辅助提取,人类验证


第四层:三模知识库——系统性方案

前三层完成了"问题→要求→策略"的分析。第四层给出系统性的知识库设计——参考 knowledge-init skill 的三模结构,为 AI 提供完整的项目理解。

Business 业务知识库:让 AI 理解"做什么"

业务知识库回答的问题是:"这个项目在业务上做了什么,用什么术语,有什么规则。"

# .aisdd/knowledges/business/glossary.md
# 业务术语表 — 消除 AI 对术语的歧义

terms:
-term:"退款 (refund)"
definition:"用户支付的款项退回给用户。分为全额退款和部分退款"
related: ["支付回调""订单状态""库存回补"]
ai_note:"refund 不等于 cancel——cancel 是未支付取消, refund 是已支付退回"

-term:"库存回补 (inventory_restore)"
definition:"退款后将商品库存数量恢复。仅在支付宝渠道场景下触发"
channel_specific:"alipay"
ai_note:"微信和银联在支付环节已预扣库存,不需要回补。不要把回补逻辑提取到通用退款层"
# .aisdd/knowledges/business/rules-config.md
# 业务规则配置 — AI 可直接消费的规则

rules:
-id:"RULE-REFUND-001"
description:"支付宝退款触发库存回补"
condition:"channel == 'alipay' AND sub_trade_type == 'refund'"
action:"调用 restore_inventory(order_id)"
priority:"critical"
reason:"支付宝渠道设计和微信/银联不同——这不可修改"
test:"模拟 alipay 退款回调, 验证 inventory 数量是否正确恢复"

-id:"RULE-REFUND-002"
description:"退款金额不能超过订单金额"
condition:"refund_amount > order.total_amount"
action:"拒绝退款, 返回 AMOUNT_EXCEEDS"
priority:"critical"
reason:"防止超退——基本财务安全"
test:"传入 refund_amount=99999, order.total_amount=100, 断言返回 AMOUNT_EXCEEDS"

Tech 技术知识库:让 AI 理解"怎么做"

Tech 知识库回答的问题:"这个项目在技术上怎么实现的,模块之间什么关系,API 长什么样。"

# .aisdd/knowledges/tech/contracts/payment_callback_api.md
# API 契约 — 精确到类型和约束级别

# ═══ 函数: handle_refund_callback ═══
"""
Input:
  data (dict): 回调通知, 来自第三方支付网关
    注意: data 不可信——所有字段在内部重新从数据库获取

  data 结构:
    {
        "order_id": str,      # 订单号, 必填, 格式: ORD-{timestamp}-{random}
        "amount": float,       # ⚠️ 不可信! 内部用 Order.total_amount 覆盖
        "channel": str,        # 渠道: "alipay"|"wechat"|"unionpay"
        "notify_type": str,    # 通知类型: "async"|"sync", 支付宝特有
        "notify_id": str|None, # 通知ID, 用于去重, 支付宝异步通知必传
        "trade_status": str,   # 交易状态, TRADE_CLOSED 时不处理
        "sub_trade_type": str, # 子交易类型, "refund" 表示退款, 支付宝特有
    }

Output:
  bool: True=处理成功, False=跳过处理(TRADE_CLOSED)

Side Effects:
  - 数据库: SELECT ... FOR UPDATE (行锁)
  - 数据库: UPDATE inventory (仅支付宝退款)
  - Redis: SET dedup_cache:{notify_id} (去重)
  - 通知: 发送退款处理结果通知 (事务内)
"""

Engineering Manual:让 AI 理解"怎么协作"

Engineering Manual 回答的问题:"这个项目怎么运行、怎么贡献、有什么历史决策。"

文档
内容
对 AI 的价值
project-overview.md
项目简介、技术栈、架构速览
每次对话自动加载,AI 知道项目背景
quickstart.md
环境搭建、启动步骤
AI 知道本地环境配置,调试时不会用错端口/数据库
faq.md
常见陷阱、已知问题
AI 知道"这个项目的 Redis key 前缀是 app:prod: 不是 app:"
adr/ADR-001.md
为什么选 Redis 而不是数据库做去重
AI 知道历史决策,不会提出"用数据库去重"这种已被排除的方案
external-integrations.md
支付宝/微信/银联的回调格式差异
AI 知道三个渠道的具体差异,不在通用层做统一处理

知识库的 INDEX.md 全局索引

# .aisdd/knowledges/INDEX.md — AI 的导航地图
index:
project:"电商平台支付系统(存量改造项目)"
business:
-glossary:"术语表: refund/callback/settlement 等 27 个术语"
-domain_model:"核心实体: Order/Refund/Inventory/Payment 的 ER 图+状态机"
-rules:"12 条关键业务规则, 7 条有 channel_specific 限制"

tech:
-architecture:"Django + PostgreSQL + Redis, 3 个核心服务"
-diagrams:"组件图/核心流程时序图/类图/模块引用关系图"
-contracts:"payment_callback/order_service/inventory_service 三个 API 契约"
-patterns:"select_for_update 悲观锁 / transaction.atomic 事务边界"

manual:
-quickstart:"Python 3.11, Django 4.2, Redis 7"
-adr:"ADR-001: 用 Redis SETNX 做去重而不是数据库唯一索引"
-faq:"Q: 为什么 refund 不用乐观锁? A: ADR-001 说明了双通知场景乐观锁漏检的问题"

全局审视:知识库在整个改造路径中的位置

回顾这一篇在整个屎山改造系列中的位置和这篇内部的分析路径:

核心洞察:知识库梳理的本质不是"写文档"——是把散布在代码、注释、git log、前同事记忆中的隐性约束,翻译为 AI 可精确消费的结构化知识。这个翻译的精度决定了后续所有 AI 操作的安全上限。如果知识库里漏掉了一条"库存回补仅支付宝"的约束,后面的 Spec 反推、测试补全、渐进替换全部会在这个缺口上出问题——不是后面的环节做得不好,是前面的输入就不完整。

在系列中的位置:知识库梳理是破局三支柱的第一根——没有它,渐进式加载没有内容可加载,SDD 安全改造没有约束来源。它是整个改造链条的质量上限


延伸思考

个人判断:知识库最大的敌人不是技术难度,是维护意愿

知识库梳理的技术门槛不高——分层渐进提取的方法论不难掌握。真正让知识库失效的不是"不知道怎么建",而是"建完之后不维护"。

知识库的腐化速度取决于两个因素:代码变更频率和团队的维护习惯。一个每两周有 3 次变更的模块,如果每次变更不在知识库中同步 Delta,两个月后知识库的准确度可能降到 60%。AI 基于 60% 准确度的知识库工作,它的推断错误率会比没有知识库时更高——因为它在"相信"一份不完全正确的知识。

我的判断是:知识库的价值随时间推移呈倒 U 型曲线。建库初期价值快速上升,峰值在维护最好的那段时间,然后随腐化开始下降。关键不是把曲线推得更高,而是让峰值持续更久。这就需要在 CI 管线中加知识库同步检查——Spec/Delta 变更时触发对应知识库模块的更新提醒。

替代路径的审视

替代路径
与当前方案的差异
为什么没有采用
只用代码注释替代知识库
不建独立知识库,约束写在注释里,AI 直接读代码
注释散布在代码各处,上下文溢出问题仍在——AI 还是需要跨文件找注释。且注释无结构、无索引、无法按任务类型分层加载
用 RAG 向量检索替代分层加载
知识库嵌入向量,AI 按语义检索相关片段
RAG 检索 80% 的相关性不等于 100% 的覆盖——漏掉的那条隐性约束可能刚好是改造的关键。分层加载的"层"是人工确认过的,RAG 的"检索"是概率性的
不做知识库,直接让 AI 追问
AI 遇到不确定的代码时主动向开发者提问
可行但低效。开发者每次被问都要重新翻代码回答——本质上是在没有文档的情况下人工做了知识库的工作。且 AI 不知道"自己不知道什么"——最危险的隐性约束恰恰是 AI 不觉得需要问的

选择三模知识库方案的核心判断是:屎山场景下需要的是确定性,不是概率性。RAG 检索的"80% 相关性"对于代码生成任务有 20% 的遗漏概率——这个概率在屎山上意味着"关键约束有 20% 的概率被 AI 当作需要优化的代码删除"。分层加载的确定性——每层经过人类验证——是这个方案的核心价值,不是性能更优,而是遗漏概率更低

适用边界

三模知识库最适合的核心条件是:隐性约束密度高 + 文档空白 + 团队有至少一个对模块比较熟悉的开发者。如果没有人对模块有基本理解,知识库梳理的第一步(反向提取)就没法做——你无法验证 AI 提取出的约束是否正确。

不适用的场景:已经有完善文档的项目(知识库已经在文档里,不需要重建)、团队里没人对模块有基本理解且无法从前同事获取信息(只能靠纯逆向分析,这种情况下知识库的质量天花板很低)、快速废弃的模块(知识库的投入回报不成比例)。

一个实操建议:不要对全项目做知识库梳理。挑 2-3 个最核心、变更最频繁、出事影响最大的模块先做。做完这几个模块后你会得到两个东西:知识库模板(可以直接复制到其他模块使用)和团队对知识库维护的习惯。这两样东西到位之后,再考虑推广到更多模块。