OpenWiki 项目解读

"面向 Agent 的代码库文档维护 CLI"

Posted by zwt on July 5, 2026

项目信息

  • 项目地址:langchain-ai/openwiki
  • npm 包名:openwiki
  • 技术栈:TypeScript / Node.js / Ink / LangChain / DeepAgents / LangGraph SQLite checkpoint
  • 代码版本:本文阅读基于 58b4bd3,提交信息为 release: 0.0.1 (#20)
  • 一句话定位:OpenWiki 是一个用 Agent 自动生成和维护代码库文档的 CLI,它把文档写到仓库内的 openwiki/ 目录,并让后续 coding agent 先读这些文档再改代码。

它想解决什么问题

大部分代码库的文档有两个老问题:

  1. 初始化难:新项目往往只有 README,系统架构、数据流、业务规则、测试策略都散在源码里。
  2. 维护难:代码变了之后,文档经常不同步,最终变成误导信息。

OpenWiki 的目标不是生成一份面向用户的官网文档,而是生成一份面向工程协作和未来 agent 的代码库地图。它希望以后无论是人还是 AI agent 接手这个仓库,都能先从 openwiki/quickstart.md 进入,再按链接理解架构、流程、领域概念和修改注意事项。

这个定位很有意思:它不是一个“聊天式问答工具”,而是一个“文档维护 agent”。它把 agent 的输出落到仓库里,变成可以 review、commit、CI 更新的长期资产。

使用方式

官方 README 给出的安装方式很简单:

1
npm install -g openwiki

常用命令:

1
2
3
4
5
6
openwiki
openwiki "Please generate documentation for this repository"
openwiki -p "Summarize what you can do"
openwiki --init
openwiki --update
openwiki --help

语义上可以分成三类:

命令 含义
openwiki --init 第一次为当前仓库生成 openwiki/ 文档
openwiki --update 基于 Git 变化增量更新已有文档
openwiki / openwiki "message" 进入交互式 chat,用现有 wiki 和源码回答问题

首次运行时,它会引导用户配置 provider、API key、模型 ID,以及可选的 LangSmith tracing。配置和密钥写到本机 ~/.openwiki/.env,不会写进目标仓库。

项目结构

仓库本身很小,核心目录如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
src/
  cli.tsx             # Ink 终端 UI 和运行编排
  commands.ts         # CLI 参数解析和 help 文案
  constants.ts        # provider、模型、环境变量、目录常量
  credentials.tsx     # 首次配置 provider/key/model 的交互界面
  env.ts              # 读写 ~/.openwiki/.env
  agent/
    index.ts          # Agent 主运行时
    prompt.ts         # 系统 prompt 和模式 prompt
    utils.ts          # Git 证据、内容快照、更新元数据
    types.ts          # OpenWikiCommand、RunContext 等类型
examples/
  openwiki-update.yml # GitHub Actions 定时更新示例
openwiki/
  quickstart.md       # 项目自带的 OpenWiki 文档入口
  architecture/...

比较特别的是,项目自己也带了一个 openwiki/ 目录。也就是说,它用自己的工具给自己生成了文档。这对读源码很有帮助,因为可以对照源码看它想让 OpenWiki 输出什么样的结构。

核心运行链路

整体链路可以概括成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
CLI 参数 / 交互输入
        |
        v
src/cli.tsx
        |
        v
parseCommand / credential setup
        |
        v
runOpenWikiAgent()
        |
        v
收集 Git evidence + 旧 wiki metadata
        |
        v
创建 LangChain 模型客户端
        |
        v
DeepAgents + LocalShellBackend + SQLite checkpointer
        |
        v
Agent 读取代码、生成/修改 openwiki 文档
        |
        v
内容快照对比,有变化才写 .last-update.json

其中最关键的入口是 src/agent/index.ts 里的 runOpenWikiAgent()。它做了几件事:

  1. 加载 ~/.openwiki/.env
  2. 解析 provider 和 model。
  3. 确认对应 API key 存在。
  4. 构建运行上下文,包括 Git 状态、最近提交、上次更新时间。
  5. 创建模型客户端。
  6. 创建 DeepAgents agent。
  7. 流式运行,并把 text/tool event 回传给 CLI。
  8. 如果本次文档内容真的变了,写入 openwiki/.last-update.json

为什么用 DeepAgents

OpenWiki 并没有自己从零实现文件工具和 agent runtime,而是使用 deepagents

1
2
3
4
5
6
7
8
9
10
11
12
createDeepAgent({
  model,
  tools: [],
  checkpointer,
  backend: new LocalShellBackend({
    maxOutputBytes: 100_000,
    rootDir: cwd,
    timeout: 120,
    virtualMode: true,
  }),
  systemPrompt: createSystemPrompt(command),
})

这里有几个设计点:

  • rootDir: cwd:把当前仓库作为 agent 工作根目录。
  • virtualMode: true:文件工具使用虚拟根路径,prompt 里要求用 /README.md/openwiki/quickstart.md 这种路径。
  • timeout: 120:shell 命令最多跑 120 秒。
  • maxOutputBytes: 100_000:控制工具输出大小,避免上下文被日志冲爆。
  • SqliteSaver:用 ~/.openwiki/openwiki.sqlite 保存 LangGraph checkpoint。

这说明 OpenWiki 的核心不是“写文件 API”,而是把 DeepAgents 包装成一个专门做文档的 agent 产品。

模型和 Provider

OpenWiki 当前内置支持:

  • OpenRouter
  • Fireworks
  • Baseten
  • OpenAI
  • Anthropic

默认 provider 是 OpenRouter。如果环境里有 OPENROUTER_API_KEY,也会优先使用 OpenRouter。模型配置集中在 src/constants.ts,比如:

Provider 示例模型
OpenRouter z-ai/glm-5.2openrouter/fusionanthropic/claude-sonnet-5openai/gpt-5.5
Fireworks accounts/fireworks/models/glm-5p2accounts/fireworks/models/kimi-k2p7-code
Baseten zai-org/GLM-5.2moonshotai/Kimi-K2.7-Code
OpenAI gpt-5.4-minigpt-5.5
Anthropic claude-haiku-4-5claude-sonnet-5claude-opus-4.8

模型创建逻辑在 createModel()

  • Anthropic 走 ChatAnthropic
  • OpenRouter 走 ChatOpenRouter
  • Fireworks / Baseten / OpenAI 走 ChatOpenAI,通过不同 base URL 适配 OpenAI-compatible API

OpenRouter 分支还有 fallback route:选中模型失败时,可以尝试 OPENROUTER_FALLBACK_MODEL_IDS 里的后备模型。非 OpenRouter provider 没有这套 fallback。

Prompt 策略

src/agent/prompt.ts 是这个项目最值得读的文件。OpenWiki 的行为主要靠 prompt 约束,而不是靠大量硬编码。

系统 prompt 里有几类关键规则:

1. 文档必须基于证据

它要求 agent 使用源码、已有文档、Git 历史作为依据,不允许编造文件、API、业务规则或行为。

这点很重要。文档生成工具最大的问题就是“看起来很完整,但细节是幻觉”。OpenWiki 明确要求 important claim 都要落到 source files、existing docs 或 git evidence。

2. 不要穷举读所有文件

它要求优先看:

  • repository tree
  • package/config files
  • README-style docs
  • entrypoints
  • routing files
  • database/schema files
  • 每个主要 domain 的代表文件

同时禁止从根目录做 **/* 这种无差别 glob。这个规则是在控制成本,也是在避免 agent 把上下文浪费在构建产物、依赖目录和生成文件上。

3. 文档结构要克制

它要求初始文档不要无限拆页:

  • openwiki/quickstart.md 必须是入口
  • 初始 run 最多 8 个文档页,除非仓库明显很小
  • 不要创建很多薄页面
  • 单文件目录只有在边界清晰且未来会增长时才允许
  • 小项目尽量只保留 quickstart 加 1 到 2 个辅助页

这个规则很实用。很多自动文档工具会生成一堆“文件清单式文档”,看起来覆盖面大,但可读性差。OpenWiki 明确要求组织成 human documentation,而不是 raw file inventory。

4. 必须更新 AGENTS.md / CLAUDE.md

OpenWiki 会确保顶层 AGENTS.mdCLAUDE.md 引用 openwiki/quickstart.md

这一步是整个设计的闭环:文档生成出来之后,还要让未来进入仓库的 agent 知道先读它。否则 openwiki/ 很容易成为没人看的旁路文档。

它允许修改源码外的文件非常少:

  • openwiki/ 目录
  • 顶层 AGENTS.md
  • 顶层 CLAUDE.md

其他源码不应该被这个 agent 修改。

Git evidence 和增量更新

OpenWiki 的另一个核心是 src/agent/utils.ts 里的 Git evidence。

初始化或更新前,它会生成一段 Git 上下文:

  • git status --short
  • git rev-parse HEAD
  • init 时读取最近 20 个提交和文件变化
  • update 时优先读取上次记录的 gitHead..HEAD
  • 如果没有 gitHead,就用 updatedAtgit log --since
  • 读取 git diff --name-status HEAD

这些信息被塞进 user prompt,让 agent 判断哪些文档需要变。

这套设计的重点不是“给模型更多上下文”,而是让 update run 有边界。它要求:

  • 只更新受最近源码变化影响的页面
  • 不做格式化-only 修改
  • 不刷新所有页面
  • 如果 wiki 已经准确,可以 no-op
  • 小变更最多更新 1 到 2 个 wiki 页面

这和很多“每天重写一遍文档”的自动化非常不同。OpenWiki 更像一个谨慎的文档维护 bot。

内容快照和元数据

OpenWiki 会写 openwiki/.last-update.json,内容大概是:

1
2
3
4
5
6
{
  "updatedAt": "...",
  "command": "update",
  "gitHead": "...",
  "model": "..."
}

但它不是每次运行都写。它会对 openwiki/ 目录做 SHA-256 内容快照,并且排除 .last-update.json 本身。

逻辑是:

  1. run 前 hash 一遍 openwiki/ 内容。
  2. agent 运行并可能修改文档。
  3. run 后再 hash 一遍。
  4. 如果内容没变,不更新 .last-update.json

这个细节很重要,因为否则定时任务每天都会修改 metadata,制造无意义 commit。OpenWiki 用内容快照避免了这种“元数据空转”。

GitHub Actions 自动更新

项目提供了 examples/openwiki-update.yml,用于每天跑一次文档更新并自动开 PR。

流程是:

  1. checkout 仓库
  2. setup Node.js 22
  3. npm install --global openwiki
  4. openwiki --update --print
  5. peter-evans/create-pull-request 创建文档更新 PR

这说明 OpenWiki 的目标工作流不是让模型直接改主分支,而是:

1
定时检查代码变化 -> 自动更新 openwiki/ -> 开 PR -> 人 review 后合并

这条链路比直接 push 更适合文档维护,因为文档错误同样需要 code review。

和普通 README 生成器的差异

我觉得 OpenWiki 的差异点主要有四个:

维度 普通 README 生成器 OpenWiki
输出目标 单个 README 或 docs 页面 仓库内 openwiki/ 文档体系
更新方式 一次性生成 init + update + chat
上下文来源 当前源码快照 源码、已有文档、Git history、上次 metadata
面向对象 人类读者 人类和未来 coding agent
自动化 通常手动运行 可用 GitHub Actions 定时开 PR

它最有价值的地方不是生成 Markdown,而是把文档维护变成一个 agent workflow。

适用场景

比较适合:

  • 代码库架构复杂,但文档长期缺失
  • 多人协作,需要一个统一的代码库地图
  • 经常使用 coding agent,希望减少每次重新读源码的成本
  • 希望文档随代码变更定期更新,但仍通过 PR review 控制质量
  • 想在仓库里沉淀 agent-readable context

不太适合:

  • 极小项目,README 已经足够
  • API 文档必须和代码强一致,需要类型系统或注释驱动生成
  • 对隐私和源码读取有严格限制,但又不能使用本地模型或私有 provider
  • 不希望 agent 改动 AGENTS.md / CLAUDE.md

风险和注意点

1. 文档准确性仍要 review

OpenWiki 的 prompt 很强调 source evidence,但它本质上仍是 LLM agent。它能降低文档维护成本,不能替代技术 review。

尤其是业务逻辑、权限边界、部署约束、数据一致性这类内容,最好人工核对。

2. 它会读取大量源码上下文

虽然 prompt 要求不要读取 .env 和秘密文件,但代码库内容会发送给模型 provider。企业或私有项目使用前要确认 provider 合规。

3. 自动更新要走 PR

官方示例用 create-pull-request 是合理的。不要让定时任务直接提交到主分支,否则文档幻觉或误删会更难发现。

4. 对 Git 元数据有依赖

--update 的效果依赖 .last-update.json 和 Git history。如果仓库经常 squash、force push,或者文档目录被手动改乱,更新判断可能需要人工介入。

我对这个项目的判断

OpenWiki 的思路很务实。它没有试图做一个大型知识库平台,也没有做复杂 Web UI,而是抓住了 coding agent 时代的一个真实痛点:

每个 agent 进入仓库都要重新探索一遍,而探索成本很高。

OpenWiki 的解法是把探索结果结构化地写回仓库,让它成为下一次 agent 的上下文入口。openwiki/quickstart.md 加上 AGENTS.md/CLAUDE.md 引用,形成了一个简单但有效的 context bootstrapping 机制。

从工程设计看,我最认可三点:

  1. 增量更新基于 Git evidence,不是盲目重写。
  2. 内容快照避免 metadata 空转,适合 CI 定时任务。
  3. 文档面向 future agents,这和普通人类 README 的信息组织不一样。

如果后续我要在自己的项目里引入它,我会先用 openwiki --init 生成文档,然后把自动更新放到 GitHub Actions 里每天开 PR,而不是直接合并。这样既能利用 agent 的阅读能力,也能保留人工 review 的质量边界。

参考

  1. langchain-ai/openwiki GitHub 仓库
  2. OpenWiki README
  3. OpenWiki GitHub Actions 示例