Files
zclaw_openfang/docs/wiki-methodology.md
iven 62578d9df4
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
docs: wiki 知识库编制方法论 — 基于ZCLAW实战提炼的可复用指南
6条设计原则 + 5节模块模板 + 集成契约/不变量/症状导航机制
+ 维护工作流 + AI辅助开发特殊考量 + 检查清单

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 22:49:08 +08:00

12 KiB
Raw Blame History

项目 Wiki 知识库编制方法论

基于 ZCLAW 项目实战经验10 crates + React 前端,~155KB wiki 重构)提炼。 适用于任何有 AI 辅助开发参与的中大型项目。 一句话总结Wiki 只记录代码无法告诉你的东西。


一、设计原则

原则 1Wiki 记录"代码不能告诉你的"

记录在 Wiki 不记录在 Wiki
为什么这样设计WHY 字段列表、函数签名
跨模块数据流走向 单文件内的代码逻辑
历史踩坑和教训 可用 grep 直接查到的信息
必须始终成立的约束(不变量) CRUD 操作、getter/setter
模块间调用接口(集成契约) 具体的行号、变量名

判断标准:如果 git loggrep 能在 30 秒内回答这个问题,就不需要写在 wiki 里。

原则 2每个模块页统一 5 节结构

阅读优先级排列(先给最重要的信息):

1. 设计决策 (WHY)     — 为什么这样设计、历史背景、权衡取舍
2. 关键文件 + 数据流    — 3-7 个核心文件 + 跨模块接口
3. 代码逻辑           — 数据流走向 + 不变量 + 非显而易见的算法
4. 活跃问题 + 陷阱     — 当前未解决 + 历史教训
5. 变更记录           — 最近 5 条,超出的归入全局日志

为什么是这个顺序:新的 AI 会话(或开发者)首先需要知道"这个模块为什么存在"和"文件在哪",然后才是"怎么工作的",最后是"有什么问题"。

原则 3页面大小必须有预算

页面类型 行数预算 原因
首页/索引 ≤ 120 行 需要快速扫描AI 一次加载
模块页 100-200 行 AI 一次加载 2-3 个模块不爆 context
全局日志 ≤ 50 条活跃 防止无限膨胀,旧条目归档

超过预算怎么办:把详细内容归档到 archive/ 目录,模块页只保留摘要 + 链接。

原则 4单一真相源

同一信息只出现在一个页面。其他需要该信息的地方只放引用。

错误:安全认证流程同时写在 saas.md、security.md、middleware.md
正确security.md 拥有完整描述saas.md 只写"详见 [[security]]"

检查方法grep 关键内容,如果出现在 ≥ 3 个页面,就需要去重。

原则 5Append-only 内容必须封顶

日志、问题列表等只增不减的内容,必须设置上限并定期归档。

活跃日志 ≤ 50 条 → 旧条目归入 archive/log-{YYYY-MM}.md
活跃问题 ≤ 5 条/模块 → 修复后立即移除
变更记录 ≤ 5 条/模块 → 旧记录在全局 log.md

原则 6用症状导航补充模块导航

模块导航解决"这个模块是什么"的问题。但实际开发中,人们更多是在解决"出了问题该看哪里"。

症状导航表格式:

症状 先查 再查 常见根因
流式响应卡住 routing chat → middleware 连接断开 / 超时
数据没持久化 data-model 对应模块 表结构 / 迁移缺失

放在首页/索引页,让新来的人(或 AI 会话0 跳就能定位排查方向。


二、结构模板

2.1 三级层级

项目 Wiki
├── Level 1: index.md       — 纯导航 + 症状索引(≤ 120 行)
├── Level 2: {module}.md    — 每个功能模块一个页面100-200 行)
├── Level 3: archive/       — 历史内容归档
└── (可选) known-issues.md  — 活跃问题全局索引

2.2 首页模板 (index.md)

# {项目名} 知识库

> 一句话定位。使用方式说明。

## 关键数字
| 指标 | 值 | 验证方式 |
|------|-----|---------|

## 系统数据流
{ASCII 全景图}

## 模块导航
- [[module-a]] — 一句话说明
- [[module-b]] — 一句话说明

## 症状导航
| 症状 | 先查 | 再查 | 常见根因 |
|------|------|------|----------|

2.3 模块页模板 ({module}.md)

---
title: {模块名}
updated: {YYYY-MM-DD}
status: active | stable | developing
tags: [{tags}]
---

# {模块名}

> 从 [[index]] 导航。关联: [[related-1]] [[related-2]]

## 1. 设计决策

{为什么这样设计、历史背景、权衡取舍}
{用 Q&A 格式记录关键架构决策}

## 2. 关键文件 + 数据流

### 核心文件
| 文件 | 职责 |
|------|------|
| `path/to/file` | 一句话说明 |

### 数据流
{ASCII 流程图}

### 集成契约
| 方向 | 模块 | 接口 | 触发时机 |
|------|------|------|---------|
| 调用 → | {module} | `{function/API}` | {when} |
| 被调用 ← | {module} | `{function/API}` | {when} |

## 3. 代码逻辑

### 关键数据流
{跨函数/跨文件的完整路径,附意图说明}

### 不变量
⚡ {不变量 1}: {必须始终成立的约束}
⚡ {不变量 2}: {描述}

### 非显而易见的算法
{读代码难以理解的逻辑}

## 4. 活跃问题 + 陷阱

### 活跃问题
| 问题 | 级别 | 状态 | 说明 |
|------|------|------|------|
{0-5 条,修复后移除}

### 历史教训
- {教训}: {一句话描述}

### 注意事项
⚠️ {易出错的地方}

## 5. 变更记录
| 日期 | 变更 |
|------|------|
{最近 5 条}

三、关键机制详解

3.1 集成契约

问题:跨模块边界的信息(谁调谁、接口形状)是最难从代码中获取的知识,也是 wiki 最大的结构性缺口。

做法:每个模块页的"关键文件"节下增加一个"集成契约"小表,回答四个问题:

问题 对应列
这个模块调用了谁? 调用 →
这个模块被谁调用? 被调用 ←
通过什么接口? 接口(函数名/API路径
什么时候触发? 触发时机

示例(中间件模块):

方向 模块 接口 触发时机
被调用 ← kernel create_middleware_chain() 内核启动
调用 → runtime run_before_completion() 每次聊天请求
提供 → 所有模块 AgentMiddleware trait 14 个实现

3.2 不变量标记

问题:系统中有一些"必须始终成立的约束",它们不像代码那样显式存在,但一旦被违反就会产生隐蔽的 bug。

做法:用 标记不变量,放在"代码逻辑"节下。

⚡ Priority 是升序排列0-999数值越小越先执行
⚡ memories.db 和 data.db 是独立数据库,跨库查询需确认目标库
⚡ 记忆注入在中间件@150在管家路由@80之后技能索引@200之前

判断什么是好的不变量

  • 它描述的是一种关系或顺序,不是单个组件的行为
  • 如果有人不知道这个约束,修改代码时很可能无意中违反它
  • 违反的后果不会立即显现,而是演化几轮后变成隐性 bug

3.3 去重规则

重复类型 处理方式
完整描述出现在 A 和 B 选择一个为真相源,另一个只引用
相同信息出现在 ≥ 3 页 必须去重,指定唯一归属
概述 vs 详情 概述页保留一句话 + 链接,详情页拥有完整描述

去重检查命令

grep -l '关键内容' wiki/*.md | wc -l
# 结果 ≥ 3 → 需要去重

3.4 症状导航

为什么需要:模块导航是"模块→功能"方向,但排查问题时需要的是"症状→模块"方向。

编制方法

  1. 收集团队/AI 会话中反复出现的调试场景8-12 个)
  2. 每个场景记录:症状、先查哪个页面、再查哪个、最常见根因
  3. 放在首页,新会话/新人 0 跳可达

示例

症状 先查 再查 常见根因
API 返回 502 saas routing Token 耗尽 / 服务超时
数据不持久 data-model 对应模块 表缺失 / 字段不匹配
流式中断 chat middleware 连接断开 / 超时守护

四、维护工作流

4.1 什么时候更新 Wiki

触发事件 更新什么
修复 bug 对应模块页"活跃问题" + 全局 known-issues 索引
架构变更 对应模块页"设计决策" + 集成契约
文件结构变化 对应模块页"核心文件"表
跨模块接口变化 涉及双方的"集成契约"表
发现新不变量 对应模块页"代码逻辑"节的
每次更新 模块页"变更记录"(保持5条) + 全局 log.md

4.2 防止 drift 的策略

策略 做法
页面大小预算 超过 200 行强制裁剪,移入 archive/
活跃问题生命周期 修复后立即移除,不保留已修复项
变更记录滑动窗口 只保留最近 5 条,旧的自然滚入全局日志
数字验证 关键数字标注验证命令,定期执行确认
"最后验证"日期 在 frontmatter 的 updated 字段记录,超过 30 天需要复查

4.3 重构 Wiki 的执行顺序

如果需要对已有 wiki 进行重构,按依赖关系分阶段:

Phase 1: 归档/封顶 — 压缩日志、归档旧内容(无依赖)
Phase 2: 确立真相源 — 最被其他页面引用的模块优先重构
Phase 3: 依赖页面 — 引用 Phase 2 模块的页面去重
Phase 4: 剩余模块 — 独立页面逐一重构
Phase 5: 首页/索引 — 最后改(依赖所有模块页完成)

关键约束:每个模块页独立提交,可安全 git revert 回滚单个页面。


五、AI 辅助开发的特殊考量

5.1 Wiki 的主要读者可能是 AI

在 AI 辅助开发中wiki 的主要读者是每次新会话的 AI 实例context 从零开始)。这改变了 wiki 的设计优先级:

传统 wiki AI 辅助 wiki
详细、全面 精炼、可快速加载
按主题组织 按任务场景导航
历史记录丰富 只保留活跃信息
人工索引 症状→页面直接映射

5.2 Context 预算思维

AI 的 context window 是有限资源。wiki 的每个字节都在消耗这个预算。

优化策略

  • 首页只放导航,不放内容(让 AI 按需读取模块页)
  • 模块页控制在 100-200 行(一次加载 2-3 个不爆 context
  • 代码逻辑只写流向和不变量,不写可从代码读取的细节
  • 使用 archive/ 存放低频需要的历史内容

5.3 Wiki 作为新会话的启动燃料

设计 wiki 时要问:一个全新的 AI 会话,读完首页后能定位问题吗?读完 2 个模块页后能开始工作吗?

如果答案是"不能",说明 wiki 的导航层不够好(首页缺症状导航)或模块页的结构不对(信息不在前两节)。


六、检查清单

创建 Wiki 时

  • 首页 ≤ 120 行,包含:项目一句话定位、关键数字、模块导航、症状导航
  • 每个模块页统一 5 节结构
  • 每个模块页有集成契约表
  • 每个模块页有 不变量
  • 每个模块页 100-200 行
  • 无内容重复出现在 ≥ 3 个页面
  • 全局日志封顶 50 条,有归档机制

维护 Wiki 时

  • 修复 bug 后更新对应模块"活跃问题"
  • 架构变更后更新对应模块"设计决策"+ 集成契约
  • 每次更新追加全局 log.md 条目
  • 每次更新模块页变更记录(保持 5 条)
  • 定期检查页面是否超过大小预算

附录ZCLAW 重构效果

指标 重构前 重构后 变化
模块页总行数 ~2,800 ~1,547 -45%
重复内容 安全×3, 进化×3 ×1 消除
集成契约覆盖 0/10 页 10/10 页 全覆盖
症状导航 8 条路径 新增
首页 144 行 101 行 +症状导航
最大单页 424 行 199 行 控住