一只阿木木

架构治理新范式:我用 Claude-obsidian 把技术文档 RFC + ADR + API 变成可问答的知识图谱

把技术文档变成可问答的知识图谱

ingest RFC、ADR、API 文档,让 Claude 在跨文档中自动找矛盾

作者:一只阿木木我相信:在 AI 时代,每个普通人都该拥有一个自动生长的知识系统。

先说一件你可能每周都在经历的事

你的团队有 ADR,有 RFC,有 API 文档,有 Confluence 页面,有架构评审记录。

你们不是没有文档——你们文档太多了。

但这些文档分散在不同地方,用不同格式,写于不同时期,由不同工程师维护(或者说,没有维护)。

然后有一天,一个新工程师问:“我们的 API 鉴权方案到底用的是 JWT 还是 Session?”

你打开 RFC-012,它说 JWT。 你打开 ADR-037,它说 Session。 你打开上季度的架构评审记录,它说"两种方案都在用,待统一"。

没有人知道哪个是现在真正在用的。你花了两个小时找到写过这段代码的工程师,他已经离职了。

这是企业架构文档管理里最典型的四重失效:没有统一的真相来源、缺少决策与架构的关联链接、因为没有持续追踪而依赖过时信息、以及利益相关者把无数小时浪费在翻查旧决策或争论未解决的问题上。

这不是人的问题,这是系统性的文档基础设施失效。

真正的问题不是文档不够,而是文档之间没有关联

我见过两种工程师:

第一种:觉得写文档没用,因为没人看,也没人维护。于是越来越少写,最后全靠口口相传,换了几个人之后,历史决策就消失了。

第二种:认真写了大量文档,RFC、ADR、设计稿、API 文档全都有。结果三年后,文档仓库里有 300 个文件,互相之间没有任何引用关系,新来的工程师打开来看,完全不知道哪个是最新的,哪个已经被废弃,哪个和哪个是矛盾的。

ADR 和 RFC 是用于捕获关键技术决策及其背后逻辑的结构化文档,可以把它们看成工程组织的活记忆——一份版本控制的日志,记录"我们为什么这么做",尤其是在权衡了多个选项、做出了取舍、并预判了长期影响的时候。

但问题是:就像代码随 commit 演进一样,数据架构也随决策演进。没有结构化的文档,团队就面临忘记关键洞察、重复相同错误、或者在不同模块之间引入相互矛盾的标准的风险。

“引入相互矛盾的标准”——这是最致命的那个。它是静默的,它不会触发 CI/CD 报警,也不会导致线上事故,但它会让每一个新工程师在入职的前三个月里,每天花一两个小时搞清楚"我们真正的规范是什么"。

在 50 人的工程团队里,这个隐性成本每年可能高达数百个工程师工时。

这件事,以前没有好的解法

在这套系统出现之前,我们有两种不完美的应对方式:

方式 A:人工维护"文档地图"

指定一个人(通常是 Tech Lead 或架构师)定期审阅所有文档,标注过时的,合并矛盾的,更新索引。这个方式在团队 10 人以下的时候还勉强可行。超过这个规模,它的维护成本会超过它带来的价值——于是这件事被搁置,文档地图变成比文档本身更过时的东西。

方式 B:把所有文档搬进 Confluence / Notion,依赖搜索

搜索可以找到包含关键词的文档,但找不到"文档 A 和文档 B 说法相互矛盾"这件事。它没有语义理解,没有关联发现,也没有矛盾检测。

两种方式的共同问题:把维护知识一致性的责任,放在了人的肩上。而人是会累的、会离职的、会遗忘的。

解法:让 AI 编译你的技术文档,建立可问答的知识图谱

现在有了第三种方式。

你从不(或极少)亲自写 wiki——LLM 负责写和维护它的全部内容。你负责的是资料的筛选、探索方向和提出正确的问题。LLM 做所有繁重的工作——摘要、交叉引用、归档,以及那些让知识库真正随时间保持有用的日常维护。

具体到技术文档场景,这套系统做的是:

把你的 RFC、ADR、API 文档、架构评审记录全部 ingest 进 wiki。AI 在 ingest 的过程中,不只是做摘要——它会读取每一份文档,提取关键声明,与已有页面交叉对比,发现矛盾,自动打上 [!contradiction] 标注,然后把所有文档的知识编译成一张互联的知识图谱。

每次 ingest,系统会提取实体和概念,先搜索已有的 vault,在匹配的时候编辑并交叉链接,只有在没有合适页面时才新建。Wikilink 和矛盾标注是自动添加的。

之后,当有工程师问"我们的鉴权方案用的是什么"——AI 不是在三百个文件里搜索关键词,而是在一张已经理解了这三百个文件之间关系的知识图谱里导航,并告诉你:“RFC-012 和 ADR-037 对这个问题的答案有矛盾,具体矛盾点在这里,原始来源是这两个文件。”

第一部分:理解技术文档的三种类型,再开始 ingest

在动手之前,你需要先理解技术文档的角色分工——因为不同类型的文档,在知识图谱里承担不同的角色。

ADR 和 RFC 有重叠但功能不同。ADR 是记录重要架构决策及其背景和后果的文档,帮助未来的团队成员理解决策背后的逻辑,促进透明度和知识共享;它们通常针对特定项目,解决具体的技术问题,比如选择技术、框架、模式或功能实现方式。RFC 范围更广,通常用于提议系统的新功能、方法论或变更,在提议变更或新功能的早期阶段用来征求反馈和建立共识。

用一张表来记住它们在知识图谱里的不同角色:

文档类型
核心内容
在知识图谱里的角色
RFC
提案 + 讨论过程 + 多个选项对比
决策前的"思考轨迹"节点
ADR
最终决策 + 背景 + 后果
决策结果节点,带状态(active/superseded)
API 文档
接口规范 + 参数 + 行为约定
实体节点,关联到相关 ADR
架构评审记录
会议讨论 + 审查意见 + 行动项
来源节点,触发矛盾检测
Confluence 页面
混合内容(设计稿/操作手册/规范)
按内容分类,归入对应节点

理解了这个分工,你 ingest 的时候就知道:同一个主题下,RFC、ADR、API 文档三者都要 ingest,矛盾检测才能有意义。只 ingest 其中一种,系统就是瞎子。

第二部分:实战——从零 ingest 技术文档

Step 1:建立技术文档专用的 vault 结构

技术文档的 vault 需要比通用 vault 更细致的组织结构:

text

~/tech-docs-wiki/
├── .raw/
│   ├── rfcs/             ← RFC 原始文档(不可修改)
│   │   ├── RFC-001-auth-strategy.md
│   │   ├── RFC-012-jwt-vs-session.md
│   │   └── RFC-037-api-versioning.md
│   ├── adrs/             ← ADR 原始文档(不可修改)
│   │   ├── ADR-001-database-choice.md
│   │   ├── ADR-037-auth-implementation.md
│   │   └── ADR-052-api-gateway.md
│   ├── api-docs/         ← API 文档、OpenAPI spec
│   ├── arch-reviews/     ← 架构评审记录、会议纪要
│   └── confluence/       ← 从 Confluence 导出的页面
├── wiki/
│   ├── concepts/         ← 技术概念(JWT / Session / OAuth)
│   ├── entities/         ← 系统/服务/组件(UserService / AuthGateway)
│   ├── decisions/        ← 决策摘要页(RFC + ADR 编译后的结果)
│   ├── contradictions/   ← 矛盾登记册(自动生成)
│   ├── sources/          ← 每个原始文档的摘要页
│   ├── index.md
│   ├── hot.md
│   └── log.md
└── CLAUDE.md

注意两个关键文件夹:

  • wiki/decisions/
    :这是 RFC 和 ADR ingest 后的编译产物,是"我们最终决定了什么"的单一真相来源
  • wiki/contradictions/
    :这是整个系统最有价值的产物,专门存放自动检测出的矛盾

Step 2:写好 CLAUDE.md 的技术文档专用规则

技术文档的 CLAUDE.md 需要比通用配置更严格的规则,特别是矛盾处理和状态追踪:

Markdown

# 技术文档知识图谱

## Vault 用途
这个 vault 用于管理工程团队的技术决策文档(RFC、ADR、API 文档)。
核心目标是:建立跨文档的一致性视图,自动检测矛盾,提供可追溯的决策查询。

## 文档分类规则
- RFC:提案类文档,ingest 时提取"提议内容"、"对比方案"、"最终结论"
- ADR:决策类文档,ingest 时提取"决策状态"、"背景"、"后果"
- API 文档:规范类文档,ingest 时提取"接口约定"、"行为边界"
- 架构评审:会议类文档,ingest 时提取"讨论要点"、"遗留问题"

## 矛盾检测规则(最重要)
- 每次 ingest 新文档时,必须和已有所有 decisions/ 页面对比
- 发现矛盾时,用 [!contradiction] callout 在两个相关页面都标注
- 同时在 contradictions/index.md 里登记:矛盾描述、涉及文档、严重程度
- 严重程度分三级:🔴 blocking(影响当前开发)/ 🟡 pending(需要决策)/ 🟢 historical(已过时的矛盾)

## 状态追踪规则
每个 decisions/ 页面必须有以下 frontmatter:
status: active | superseded | draft | deprecated
superseded_by: [如果已被取代,链接到新页面]
last_updated: [日期]
source_docs: [关联的 RFC / ADR 编号列表]

## 特别禁止
- 不允许在没有来源引用的情况下在 decisions/ 页面添加内容
- 不允许删除任何 contradictions/ 里的矛盾记录(只能标注为已解决)
- raw/ 文件夹里的任何文档,ingest 后永远不能修改

LLM 永远不编辑 raw/ 里的文件,永远不。来源是不可变的。所有 LLM 的写入都进入 wiki/。如果你需要修正一个来源,自己在 raw/ 里做——然后重新 ingest。

Step 3:第一次 ingest——选一个矛盾最密集的主题

不要一次性把所有文档都 ingest。从一个你知道"这个主题文档最混乱"的领域开始。

比如,你知道"鉴权方案"在团队里一直有争议,有好几个互相矛盾的文档——那就从这里开始。

Bash

# 把相关文档放进 .raw/
cp docs/rfcs/RFC-012-jwt-vs-session.md .raw/rfcs/
cp docs/adrs/ADR-037-auth-implementation.md .raw/adrs/
cp docs/api/auth-api-spec.yaml .raw/api-docs/
cp docs/reviews/2025-Q3-arch-review.md .raw/arch-reviews/

# 执行 ingest
ingest RFC-012-jwt-vs-session.md

第一个文档 ingest 完之后,先不要急着 ingest 第二个。先看一下系统生成了什么。

你应该看到:

  • wiki/sources/RFC-012-jwt-vs-session.md
    :这个 RFC 的摘要页
  • wiki/concepts/JWT.md
    :JWT 概念页(如果之前没有的话)
  • wiki/concepts/Session-Authentication.md
    :Session 鉴权概念页
  • wiki/decisions/auth-strategy.md
    :鉴权方案决策页(第一个版本)

然后 ingest 第二个文档:

Bash

ingest ADR-037-auth-implementation.md

这是见证魔法的时刻。

在每次 ingest 时,系统会提取实体和概念,先搜索已有 vault,在匹配时进行编辑和交叉链接,只有在没有合适页面时才创建新页面。Wikilink 和矛盾标注会被自动添加。

如果 RFC-012 和 ADR-037 在鉴权方案上有不一致的说法,你会在 wiki/decisions/auth-strategy.md 页面里看到:

Markdown

## 鉴权方案

当前团队使用 JWT 进行无状态鉴权。

> [!contradiction]
> RFC-012(2025-03-10)建议使用 JWT 进行跨服务鉴权
> ADR-037(2025-08-22)记录的最终实现选择了 Session-based 方案
> **这两个文档之间存在矛盾,需要确认当前实际使用的方案**
> 来源:[[sources/RFC-012]]、[[sources/ADR-037]]

同时,wiki/contradictions/index.md 里会自动新增一条:

Markdown

## 🔴 BLOCKING | 鉴权方案矛盾
- 文档 A:[[sources/RFC-012]] → JWT
- 文档 B:[[sources/ADR-037]] → Session
- 发现时间:2026-05-31
- 状态:未解决
- 影响范围:所有涉及跨服务鉴权的开发

你不需要手动发现这个矛盾。系统替你发现了。

Step 4:批量 ingest 的正确顺序

批量 ingest 时,顺序有讲究。错误的顺序会导致系统生成大量碎片页面,之后的矛盾检测也不够准确。

推荐顺序(从"基础"到"具体"):

text

第一轮:概念定义类文档
├── API 文档、OpenAPI spec
├── 技术选型 ADR(选了哪些技术栈)
└── 目的:先建立好基础概念节点

第二轮:提案类文档
├── RFC(按时间顺序,从老到新)
└── 目的:建立决策演进的时间线

第三轮:决策结果类文档
├── 所有 ADR(按时间顺序)
└── 目的:和 RFC 对比,找出"提案 → 实际决策"的偏差

第四轮:讨论过程类文档
├── 架构评审记录
├── 会议纪要
└── 目的:找出"已讨论但没写进 ADR"的决策

这个顺序确保每次 ingest 都能和已有内容充分交叉对比,矛盾检测的覆盖率最高。

Step 5:用 wiki-query 做"跨文档一致性检查"

ingest 完成后,是真正的考验时刻。

试着问一些你确实不确定答案的问题:

text

query: 我们目前的 API 版本控制策略是什么?
有没有不同文档之间说法不一致的地方?

text

query: UserService 和 AuthGateway 之间的调用关系,
是同步还是异步?这个决策在哪里有记录?

text

query: 我们有没有关于数据库事务隔离级别的明确规定?
如果有,规定在哪里?是否和实际代码一致?

在 RAG 系统中,每次查询都重新读取原始来源。在 LLM Wiki 中,LLM 在摄入阶段就处理来源、提取概念、创建结构化页面并建立交叉引用。

这意味着你问的不是"哪个文档包含这个关键词",而是"整个文档体系对这个问题的立场是什么,以及这个立场是否一致"。

验收标准:

一个好的查询结果应该包含:

  1. 明确的答案(或者明确说明"存在矛盾,答案不确定")
  2. 引用具体的 wiki 页面链接(不是原始文档,是编译后的知识页面)
  3. 如果存在矛盾,列出矛盾的两端和来源文档
  4. 标注信息的"新鲜度"(来自哪个时期的文档)

Step 6:矛盾处理工作流——让 [!contradiction] 变成团队的行动项

矛盾被自动检测出来之后,下一步是处置,而不是忽视。

我建议建立一个矛盾处理的标准流程:

① 每周 lint 一次,生成矛盾报告

Bash

lint the wiki

Lint 会找出孤儿页、死链接、过时内容和矛盾,以及查看一个摘要,显示哪些内容已经被摄入,哪些还在待处理。

② 按严重程度分类处置

Markdown

# 矛盾处理 SOP

🔴 BLOCKING(影响当前开发)
→ 当天找相关工程师确认,24 小时内更新 ADR 记录正确答案
→ 在 wiki 里标注已解决,链接到新的 ADR

🟡 PENDING(需要团队决策)
→ 在下次架构评审时讨论
→ 结论写成新 ADR,ingest 后矛盾自动解决

🟢 HISTORICAL(历史遗留,不影响现在)
→ 在矛盾记录里标注"历史矛盾,已超过适用期"
→ 不需要新 ADR,直接标注 deprecated

③ 解决矛盾后,更新来源文档状态

Bash

# 在 .raw/adrs/ADR-037-auth-implementation.md 的头部加上:
# status: superseded
# superseded_by: ADR-089-auth-final.md
# 然后重新 ingest

ingest ADR-037-auth-implementation.md

重新 ingest 之后,系统会自动更新 wiki/decisions/auth-strategy.md 页面,把矛盾标注从 [!contradiction] 改为 [!info](历史说明),并在页面顶部清晰标注当前有效的决策。

第三部分:进阶用法——让知识图谱替你做新工程师 Onboarding

这套系统建立起来之后,还有一个极高价值的用法:新工程师入职。

传统的 onboarding 流程里,新工程师花大量时间"找文档"和"找人问"。他们不知道 RFC-012 和 ADR-037 之间有矛盾,不知道某个设计决策的历史背景,也不知道哪些文档已经过时了。

有了技术文档知识图谱,你可以给新工程师一个专属的 query 清单:

Markdown

# 新工程师入职:知识图谱查询清单

## 第一天:了解系统全貌
query: 这个项目有哪些核心服务?它们之间的调用关系是什么?

## 第二天:了解技术选型背景
query: 我们为什么选择了这个技术栈?有没有我需要知道的重要取舍?

## 第三天:了解当前已知问题
query: 目前有哪些未解决的架构矛盾?哪些是 blocking 级别的?

## 第一周结束:建立工作边界
query: 我负责的模块,有哪些相关的 ADR 和 RFC 是我必须知道的?

随着团队成长和所有权分散,ADR 和 RFC 确保决策保持透明和可追溯。它们让新团队成员通过理解架构历史更快地完成入职,帮助现有工程师做出有依据的改动,并通过保留意图和背景为未来的审计提供支撑。

有了知识图谱,新工程师不再需要花三个月弄懂"我们真正的规范是什么"——他可以在入职第一周就问出正确的问题,并得到有来源追踪的答案。

第四部分:一个被忽视的强大用法——用矛盾检测替代部分架构评审

大型工程团队通常有定期的架构评审(Architecture Review Board,ARB)。这些会议的一个重要功能是:发现不同团队之间的技术决策是否互相冲突。

ADR 在维护软件架构质量方面扮演核心角色,但许多决策违规行为无人察觉,因为项目缺乏系统化的文档和自动化检测机制。大型语言模型的最新进展为大规模自动化架构推理开辟了新的可能性。 21 一项研究分析了 109 个 GitHub 仓库里的 980 条 ADR,使用多模型流水线进行检测。研究发现,LLM 对显性的、可从代码推断的决策有很高的准确性;对于依赖部署配置或组织知识的隐性决策,准确率相对较低。因此,LLM 可以有意义地支持架构决策合规验证,但对于非代码决策,还不能替代人类专家。

用人话翻译:AI 能自动发现的,是"文档里写了 A,另一个文档写了 B"这类显性矛盾。 而"这个决策在实践中其实行不通"这类隐性问题,仍然需要有经验的工程师判断。

所以推荐的使用方式是:

text

每次架构评审前:
1. 运行 lint,生成最新的矛盾报告
2. 把矛盾报告作为评审的"议题预热"
3. 评审会只处理系统无法自动判断的隐性矛盾

效果:
- 评审会不再花时间讨论"哪两个文档说法不一样"
- 更多时间用于"为什么会有这个矛盾,我们应该怎么解决"
- 评审结论写成新 ADR,ingest 后矛盾自动从系统里消失

将 ADR 与 RFC 结合用于前期讨论,团队可以更有效地构建决策过程,确保每个决策都经过充分思考并有文档记录。ADR 的采用使架构决策的管理变得透明和可访问,这对敏捷项目的成功至关重要。

第五部分:一个真实场景的完整演示

让我用一个虚构但高度真实的场景,把上面所有步骤串起来。

背景:你是一个 15 人工程团队的 Tech Lead。团队做了两年产品,积累了 40 多个 ADR 和 20 多个 RFC,分散在 GitHub 的 /docs 文件夹和 Confluence 里。最近新来了两个工程师,每次问"我们怎么处理 X"都要花很长时间找答案。

第一天(2 小时):建立 vault,ingest 核心文档

Bash

# 1. 初始化 vault
git clone claude-obsidian && bash bin/setup-vault.sh

# 2. 把最重要的 20 个 ADR 和 10 个 RFC 复制进 .raw/
# (优先选:技术选型 ADR、被引用最多的 RFC)

# 3. 按顺序 ingest(API 文档 → RFC → ADR)
ingest api-gateway-spec.yaml
ingest RFC-001-service-mesh.md
ingest RFC-012-auth-strategy.md
# ... 继续 ingest 其他文档

第二天(30 分钟):第一次矛盾报告

Bash

lint the wiki

你会得到一份矛盾清单。假设发现了 3 个 🔴 BLOCKING 矛盾。把这三个矛盾截图发给团队,问:哪个是当前实际在用的方案?

大概率你会发现:其中一两个"矛盾"其实不是矛盾,只是文档没有更新,实际早就有了共识,但没人把旧 ADR 标成 superseded。这个发现本身,就值回这两个小时的配置成本。

第三天(15 分钟):更新状态,解决矛盾

把确认的决策写进新的 ADR,或者在旧 ADR 上加上 superseded_by 标注,重新 ingest。矛盾从系统里消失。

第一周结束:给新工程师一张 query 清单

上面"新工程师入职"那一节的查询清单,直接发给他们用。

一个月后:知识图谱自动生长

30 天定期摄入后,典型的 vault 有 80 到 200 个 wiki 页面。Obsidian 的 Graph View 让这种复利变得可见:相关概念的集群、跨领域的桥接、以及标示知识空缺的孤立节点。

每次新 RFC 写完,先 ingest,系统告诉你"这个提案和 ADR-052 有潜在冲突,要不要在 RFC 里说明你的处理方式"——在评审之前就发现问题。

每次新工程师入职,让他自己 query,自己发现疑问,带着具体的问题来找 Tech Lead——而不是花三个月靠猜测理解系统。

坦诚说一个边界:这套系统不能替代所有人工判断

我需要在这里说一句真话。

这套系统能检测的是显性矛盾——文档 A 说一件事,文档 B 说另一件事,AI 可以发现并标注。

但它目前还不能可靠地检测:

  • 一个决策在纸面上没矛盾,但在实践中根本行不通
  • 隐含在代码里的"事实上的架构"和文档记录的"名义上的架构"之间的偏差
  • 需要领域经验才能判断的设计取舍好坏

这个取舍是真实的:编译后的知识可能积累错误。如果 LLM 在 ingest 时误解了来源,这个误解会传播。这就是为什么需要 lint 操作和来源链接约定来解决这个问题。

这也是为什么你的 raw/ 文件夹里保存着所有原始文档,永远不被修改——当你怀疑某个 wiki 页面的结论时,点进去看来源,直接核对原始文档。知识图谱是导航层,不是替代原始文档的权威层。

用一句话记住这个边界:AI 负责发现"文档里写了不一样的东西",工程师负责判断"哪个对,为什么,现在应该怎么办"。

总结:一张可以贴在工程师手边的速查卡

text

=== 技术文档知识图谱 日常操作 ===

【新建 RFC/ADR 后】
→ 写完立刻 ingest
→ 系统自动检测和已有文档的矛盾

【发现矛盾时】
→ lint the wiki(生成矛盾报告)
→ 找相关工程师确认正确答案
→ 写新 ADR 或更新旧 ADR 状态
→ 重新 ingest,矛盾自动解决

【架构评审前】
→ lint the wiki(生成议题预热报告)
→ 评审会只讨论无法自动判断的隐性问题

【新工程师入职时】
→ 给他们 query 清单
→ 让他们自己查,带着具体问题来找你

【核心文件】
→ wiki/contradictions/  ← 矛盾登记册
→ wiki/decisions/       ← 决策摘要(单一真相来源)
→ wiki/index.md         ← 全局目录
→ wiki/log.md           ← 操作日志

【每周一次】
→ lint the wiki
→ 处理 🔴 BLOCKING 矛盾
→ 归档 🟢 HISTORICAL 矛盾

写在最后

在项目的整个生命周期中,大量时间花在决策上——比如如何设计一个集成新服务的方案、从遗留数据库迁移数据、选择哪个第三方服务等等。缺乏一个跟随项目成长的文档流程,会带来长期问题:回头去回忆为什么做出某个决策,通常是一件极其复杂的事情。

你们花了两年积累了这些 RFC 和 ADR,不是为了让它们在 GitHub 文件夹里吃灰的。它们记录了你们团队最宝贵的决策历史——每一次权衡、每一次放弃、每一次"我们想清楚了"。

这套系统做的,是让这些历史变得可查、可问、可对比,而不只是可以被搜索到。

当你第一次运行 lint,看到系统自动列出的矛盾清单,你会意识到:你们团队之前每周在架构评审里反复讨论的那些"说不清楚"的问题,其实有一部分根本原因就是——没有人把"我们已经决定了什么"整理成一个单一的、可信任的来源。

现在你可以了。

技术文档不只是存档,它是你的工程团队的集体记忆。让它真正活起来。

—— 一只阿木木在 AI 时代,每个普通人都该拥有一个自动生长的知识系统。

我是【一只阿木木】,AI 知识系统架构师,坐标杭州。

扫码加入行动营👇获取更多Obsidian + AI数字大脑实践

Image

关注【一只阿木木】。

我相信:在 AI 时代,每个普通人都该拥有一个自动生长的知识系统

去做,才是真的学。🌊