- 项目信息
- 它想解决什么问题
- 使用方式
- 项目结构
- 核心运行链路
- 为什么用 DeepAgents
- 模型和 Provider
- Prompt 策略
- Git evidence 和增量更新
- 内容快照和元数据
- GitHub Actions 自动更新
- 和普通 README 生成器的差异
- 适用场景
- 风险和注意点
- 我对这个项目的判断
- 参考
项目信息
- 项目地址: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 先读这些文档再改代码。
它想解决什么问题
大部分代码库的文档有两个老问题:
- 初始化难:新项目往往只有 README,系统架构、数据流、业务规则、测试策略都散在源码里。
- 维护难:代码变了之后,文档经常不同步,最终变成误导信息。
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()。它做了几件事:
- 加载
~/.openwiki/.env。 - 解析 provider 和 model。
- 确认对应 API key 存在。
- 构建运行上下文,包括 Git 状态、最近提交、上次更新时间。
- 创建模型客户端。
- 创建 DeepAgents agent。
- 流式运行,并把 text/tool event 回传给 CLI。
- 如果本次文档内容真的变了,写入
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.2、openrouter/fusion、anthropic/claude-sonnet-5、openai/gpt-5.5 |
| Fireworks | accounts/fireworks/models/glm-5p2、accounts/fireworks/models/kimi-k2p7-code |
| Baseten | zai-org/GLM-5.2、moonshotai/Kimi-K2.7-Code |
| OpenAI | gpt-5.4-mini、gpt-5.5 |
| Anthropic | claude-haiku-4-5、claude-sonnet-5、claude-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.md 或 CLAUDE.md 引用 openwiki/quickstart.md。
这一步是整个设计的闭环:文档生成出来之后,还要让未来进入仓库的 agent 知道先读它。否则 openwiki/ 很容易成为没人看的旁路文档。
它允许修改源码外的文件非常少:
openwiki/目录- 顶层
AGENTS.md - 顶层
CLAUDE.md
其他源码不应该被这个 agent 修改。
Git evidence 和增量更新
OpenWiki 的另一个核心是 src/agent/utils.ts 里的 Git evidence。
初始化或更新前,它会生成一段 Git 上下文:
git status --shortgit rev-parse HEAD- init 时读取最近 20 个提交和文件变化
- update 时优先读取上次记录的
gitHead..HEAD - 如果没有 gitHead,就用
updatedAt做git 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 本身。
逻辑是:
- run 前 hash 一遍
openwiki/内容。 - agent 运行并可能修改文档。
- run 后再 hash 一遍。
- 如果内容没变,不更新
.last-update.json。
这个细节很重要,因为否则定时任务每天都会修改 metadata,制造无意义 commit。OpenWiki 用内容快照避免了这种“元数据空转”。
GitHub Actions 自动更新
项目提供了 examples/openwiki-update.yml,用于每天跑一次文档更新并自动开 PR。
流程是:
- checkout 仓库
- setup Node.js 22
npm install --global openwikiopenwiki --update --print- 用
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 机制。
从工程设计看,我最认可三点:
- 增量更新基于 Git evidence,不是盲目重写。
- 内容快照避免 metadata 空转,适合 CI 定时任务。
- 文档面向 future agents,这和普通人类 README 的信息组织不一样。
如果后续我要在自己的项目里引入它,我会先用 openwiki --init 生成文档,然后把自动更新放到 GitHub Actions 里每天开 PR,而不是直接合并。这样既能利用 agent 的阅读能力,也能保留人工 review 的质量边界。