OpenWiki 深度解析:LangChain 出品的 Agent 驱动文档生成工具

66 阅读11分钟

仓库地址:github.com/langchain-a… License:MIT | 版本:0.2.0 | 语言:TypeScript | 运行要求:Node.js ≥ 22

这是什么

OpenWiki 是 LangChain 团队开源的命令行工具,用 AI Agent 自动生成和维护代码库文档。做法很直接:把 LLM 塞进一个受控的 Agent 运行时,让它像人类工程师一样读代码、查 git history、写文档,输出结构化的 wiki 存到仓库的 openwiki/ 目录下。

跟 Javadoc / Sphinx / TypeDoc 这类传统文档生成器的区别在于:那些工具解析 AST 提取签名信息,OpenWiki 让 Agent 理解代码的意图、架构和演进脉络。它不生成 API 参考,生成的是"这个仓库是干嘛的、怎么跑、架构怎么分层"这类工程师真正想知道的东西。

另外有个"个人大脑"模式,可以接入 Gmail、Slack、Notion、X、HackerNews、Web Search 等数据源,把碎片化信息合成一份个人知识库 wiki。


核心架构

OpenWiki 架构总览

整个项目分五层:

职责关键文件
CLI 入口交互终端 UI、命令解析、自动退出src/cli.tsxsrc/commands.ts
凭据管理Provider 选择、API Key/OAuth 引导、环境文件src/credentials.tsxsrc/env.ts
Agent 运行时Provider 解析、模型创建、Git 证据收集、Prompt 构建src/agent/index.tssrc/agent/prompt.ts
DeepAgents 后端虚拟文件系统、写保护、SQLite 检查点src/agent/docs-only-backend.ts
连接器系统7 个内置数据源摄取 → 原始缓存 → LLM 合成src/connectors/src/ingestion.ts

安装

全局安装(推荐)

npm install -g openwiki

要求 Node.js ≥ 22。Windows 用户建议用 npm 或 pnpm 安装,不要用 Bun(Bun 全局安装时 better-sqlite3 原生模块编译需要 VS Build Tools,且 Bun 默认不跑生命周期脚本,没法在安装时给出警告)。

从源码构建

git clone https://github.com/langchain-ai/openwiki.git
cd openwiki
pnpm install
pnpm run build
pnpm link --global

pnpm link --global 后,openwiki 命令会指向 dist/cli.js。改完源码后 pnpm run build 即可生效,不需要重新 link。

如果不想配 pnpm 全局路径,用 alias 也行:

alias openwiki='node /path/to/openwiki/dist/cli.js'

开发模式

cd /path/to/target/repo
OPENWIKI_DEV=1 openwiki --dry-run    # 不调用 Agent,仅测试 CLI

配置:Provider 和模型

OpenWiki 支持 12 个 Provider,配置全部存在 ~/.openwiki/.env(权限 0600,目录 0700):

Provider认证方式环境变量模型示例
openaiAPI KeyOPENAI_API_KEYgpt-5.6-terra / 5.6-luna / 5.5 / 5.4-mini
openai-chatgptOAuth 登录OPENAI_CHATGPT_ACCESS_TOKEN同 OpenAI,走 Codex 后端
anthropicAPI KeyANTHROPIC_API_KEYHaiku / Sonnet / Opus
geminiAPI KeyGEMINI_API_KEYGemini 3.5 Flash / 3.1 Pro
gemini-enterpriseGoogle ADCGOOGLE_CLOUD_PROJECT(必填)Gemini + Claude Model Garden
openrouterAPI KeyOPENROUTER_API_KEYGLM 5.2 / Kimi / Claude / GPT
openai-compatibleAPI Key + Base URLOPENAI_COMPATIBLE_API_KEY + OPENAI_COMPATIBLE_BASE_URL(必填)自定义
bedrockAWS Access Key + Secret + RegionBEDROCK_AWS_ACCESS_KEY_ID账号区域相关
fireworksAPI KeyFIREWORKS_API_KEYGLM 5.2 / Kimi K2.7 Code
basetenAPI KeyBASETEN_API_KEYGLM 5.2 / Kimi K2.7 Code
nebiusAPI KeyNEBIUS_API_KEYKimi K2.6
nvidiaAPI KeyNVIDIA_API_KEYNemotron 3 / DeepSeek V4 / GPT-OSS 120B

Provider 解析优先级

  1. 如果设了 OPENWIKI_PROVIDER,直接用它
  2. 否则按顺序找第一个有 API Key 的 Provider:OpenAI → OpenAI-Compatible → OpenRouter → Anthropic → Baseten → Fireworks → Nebius → NVIDIA → Bedrock
  3. 都没有就回退到默认 openai,默认模型 gpt-5.6-terra

交互式首次配置

第一次运行时(chat/init/update 都会触发),CLI 会引导你选 Provider → 输入 API Key → 选模型 → 可选填 LangSmith Key。全程箭头键选择,不用手写配置文件。

非交互模式(CI 环境)

stdin 不是 TTY 或用了 --print 时,不会弹交互提示。凭据必须在 ~/.openwiki/.env 或环境变量中就绪,缺了直接报错退出。

环境变量速查

# Provider 选择
OPENWIKI_PROVIDER=openrouter
OPENWIKI_MODEL_ID=z-ai/glm-5.2
OPENWIKI_PROVIDER_RETRY_ATTEMPTS=3  # 可选,默认 3

# OpenRouter
OPENROUTER_API_KEY=sk-or-...

# Anthropic(可选 Base URL 覆盖)
ANTHROPIC_API_KEY=sk-ant-...
ANTHROPIC_BASE_URL=https://your-proxy.example.com  # 可选

# OpenAI-Compatible(必须配 Base URL)
OPENAI_COMPATIBLE_API_KEY=your-key
OPENAI_COMPATIBLE_BASE_URL=https://your-gateway/v1
OPENWIKI_MODEL_ID=your-model-name

# Google Vertex AI (Gemini Enterprise)
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=global  # 可选,默认 global
# 认证用 Google ADC,不设 API Key

# LangSmith 追踪(可选)
LANGSMITH_API_KEY=lsv2_...
LANGCHAIN_PROJECT=openwiki
LANGCHAIN_TRACING_V2=true

# 遥测关闭
OPENWIKI_TELEMETRY_DISABLED=1
# 或
DO_NOT_TRACK=1

使用

两种工作模式

OpenWiki 有两种核心模式,面向不同场景:

Code 模式,为代码仓库生成文档:

openwiki code --init              # 首次生成仓库文档
openwiki code --update            # 更新已有文档
openwiki code "聚焦 API 文档"     # 带指令的更新

Personal 模式,生成个人知识库 wiki(接入多数据源):

openwiki personal --init          # 首次生成个人大脑
openwiki personal --update        # 更新

命令完整参考

# 交互式聊天
openwiki                          # 打开交互 UI
openwiki "总结一下你能做什么"      # 发消息后保持打开

# 文档生成
openwiki code --init [message]    # 生成仓库文档
openwiki personal --init [message] # 生成个人 wiki
openwiki --update [message]       # 刷新已有文档

# 非交互执行
openwiki -p, --print              # 运行一次,输出到 stdout 后退出
openwiki --modelId <id>           # 指定模型
openwiki --model-id <id>          # 同上(kebab-case)
openwiki --dry-run                # 开发模式,不调 Agent
openwiki --help / -h              # 帮助

# 连接器管理
openwiki auth                     # 列出所有 auth provider 状态
openwiki auth <provider>          # OAuth 登录(gmail/notion/slack/x)
openwiki auth configure <provider> [--force]  # 创建连接器配置
openwiki auth tools <provider>    # 列出 MCP 工具(如 notion)

# 摄取
openwiki ingest [target]          # 运行数据源摄取(all / 单个 / 具体实例)

# 定时任务(macOS)
openwiki cron list                # 查看调度状态
openwiki cron pause <source|all>  # 暂停
openwiki cron resume <source|all> # 恢复
openwiki cron delete <source|all> # 删除

# Slack OAuth 隧道
openwiki ngrok start [url] [--port <port>]

自动退出行为

--init--update 在 TTY 终端下执行成功后会自动退出(exit code 0)。这意味着你可以同一个命令既在本地交互使用,又在 CI 里跑。--print 模式不受影响,始终输出到 stdout 后退出。

交互 UI 支持的斜杠命令

在交互模式下:

  • /init:启动文档初始化
  • /update:启动文档更新
  • /provider:切换 Provider
  • /model:切换模型
  • /exit:退出

Agent 工作流

OpenWiki 运行流程

非 chat 运行的完整流程(src/agent/index.ts):

  1. 加载环境:把 ~/.openwiki/.env 合并到 process.env,已有进程级变量优先
  2. 解析 ProviderresolveConfiguredProvider() 按优先级确定 Provider,检查 API Key 存在性
  3. 收集 Git 证据:当前 HEAD、工作树状态、变更窗口(init 取最近 20 条 commit;update 优先用上次 gitHead 做精确范围,回退到时间戳范围)
  4. 内容快照(前) :对 openwiki/ 目录做 SHA-256 哈希(排除 .last-update.json
  5. 构建 Prompt:系统提示(行为准则 + 文件系统约定)+ 用户提示(Git 摘要 + 指令)
  6. 创建模型:按 Provider 分支创建 ChatOpenAI / ChatAnthropic / ChatOpenRouter
  7. DeepAgents 执行LocalShellBackend 虚拟模式,根目录为仓库路径,maxOutputBytes: 100_000,120s 超时
  8. 内容快照(后) :再次哈希
  9. 元数据写入:仅当前后快照不同时写入 .last-update.json,记录 updatedAt / command / gitHead / model

Git 证据收集策略

这是 OpenWiki 设计里比较聪明的一步:在 Agent 启动前由宿主进程收集 Git 上下文,而不是让 Agent 自己跑 git 命令。

场景Git 命令
Initgit log --max-count=20 --name-status --oneline
Update(有 gitHead)git log <lastHead>..HEAD --name-status --oneline
Update(仅有 updatedAt)git log --since <updatedAt> --name-status --oneline
通用git status --short + git rev-parse HEAD + git diff --name-status HEAD

内容快照防循环

给 CI 设计的机制。定时更新任务可能跑了很多次但代码没变,Agent 也不会改文档。如果前后 SHA-256 相同,不写 .last-update.json,不触发 PR。避免"元数据只有时间戳变了"这种无意义 PR。

写保护机制

OpenWikiLocalShellBackend 继承 DeepAgents 的 LocalShellBackend,加了 docs-only 写保护:文档模式下 Agent 只能写 openwiki/ 目录下的文件,不能改仓库源码。Agent 有文件系统访问能力,但被限制在文档目录内。

Prompt 策略

系统提示要求 Agent:

  • 只写 openwiki/ 目录下的文档
  • 用文件系统探索和 git history,不能编造事实
  • 保持 wiki 聚焦可导航,不要生成一堆 stub 页面
  • 同时为人类和未来的 Agent 读者服务
  • 不读 .env 和密钥文件
  • 仓库根目录是唯一作用域
  • AGENTS.mdCLAUDE.md 中插入/刷新标准 OpenWiki 引用段落

连接器系统

OpenWiki 内置 7 个连接器,主要用于 Personal 模式:

连接器后端需要凭证Agent 发现拉取内容
git-repolocal-git本地仓库的 branch/HEAD、log(最近20条)、status、diff
google (Gmail)direct-apiGmail OAuth tokenGmail API v1,默认 newer_than:1d,写 gmail-messages.json
hackernewsdirect-apiHN Firebase feeds + Algolia 搜索
notionMCP (stdio/HTTP)OPENWIKI_NOTION_MCP_ACCESS_TOKEN托管 Notion MCP server,发现工具或执行只读操作
slackdirect-apiSlack user tokensearch.messagesconversations.list/historyassistant.search
web-searchdirect-apiTAVILY_API_KEYTavily 搜索,按配置 query 执行
xdirect-apiX OAuth tokenhome_timelineuser_postsmentionsbookmarkslist_posts

架构设计:确定性摄取 + LLM 合成

连接器系统的设计原则是把网络调用排除在 Agent 控制路径之外:

  1. 确定性摄取:连接器用自己的代码调 API,把原始数据写到 ~/.openwiki/connectors/<id>/raw/<runId>/
  2. LLM 合成:Agent 只读 raw 目录下的文件,不直接调外部 API

这样设计的好处:凭证不暴露给模型,网络错误可重试不消耗 token,原始数据有审计痕迹。

MCP 只读策略

Notion 连接器走 MCP 协议,但加了严格的只读策略(src/connectors/mcp-runtime.ts):

  • 工具必须在 allowedTools 白名单里
  • 或 MCP server 自己标注 readOnlyHint: true
  • 或工具名/描述匹配只读启发式(search/retrieve/get/list/query/read/fetch/find/lookup/load/children)

即使底层 MCP server 暴露了写工具,OpenWiki 也不会调用。

X 连接器的增量游标

每个流(除了 bookmarks)都在 state 里维护 since_id 游标,重复摄取时只拉新内容。list_posts 会按配置的 listIds 扇出。

Slack 的"最新消息"可靠性

my-recent-messages.json 有个 definitiveForLatestMessage 标志:

  • true:通过 search.messages 解析(需要 search:read 权限),可靠
  • false:回退到 conversations.history 扫描,不可靠

用 Agent 回答"我在 Slack 上最后说了什么"时,必须检查这个标志。


CI 自动化部署

OpenWiki 支持 GitHub Actions、GitLab CI、Bitbucket Pipelines 三个平台,套路一致:定时跑 openwiki code --update --print,有变更就自动创建 PR/MR。

GitHub Actions

仓库提供了 examples/openwiki-update.yml,核心配置:

name: OpenWiki Update

on:
  workflow_dispatch:
  schedule:
    - cron: "0 8 * * *"  # 每天 08:00 UTC

permissions:
  contents: write
  pull-requests: write

jobs:
  update:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          persist-credentials: true

      - uses: actions/setup-node@v4
        with:
          node-version: "22"

      - name: Install OpenWiki
        run: npm install --global openwiki

      - name: Run OpenWiki
        run: openwiki code --update --print
        env:
          OPENWIKI_PROVIDER: openrouter
          OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
          OPENWIKI_MODEL_ID: z-ai/glm-5.2
          LANGSMITH_API_KEY: ${{ secrets.LANGSMITH_API_KEY }}
          LANGCHAIN_PROJECT: openwiki
          LANGCHAIN_TRACING_V2: "true"

      - name: Create PR
        uses: peter-evans/create-pull-request@v7
        with:
          add-paths: |
            openwiki
            AGENTS.md
            CLAUDE.md
            .github/workflows/openwiki-update.yml
          branch: openwiki/update
          commit-message: "docs: update OpenWiki"
          title: "docs: update OpenWiki"
          body: "Automated OpenWiki documentation update."

关键点

  • --update --print 在 CI 中是幂等的,没内容变化时不写元数据,peter-evans/create-pull-request 检测到无 diff 就不创建 PR
  • 把这个 yml 文件也加到 add-paths 里,这样首次运行会自动把 workflow 文件本身也提交进去
  • 建议在 GitHub Secrets 里配 OPENROUTER_API_KEY(或你选的 Provider 的 Key)和 LANGSMITH_API_KEY

GitLab CI

examples/openwiki-update.gitlab-ci.yml

openwiki_update:
  image: node:22
  stage: deploy
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
    - if: '$CI_PIPELINE_SOURCE == "web"'
  before_script:
    - apt-get update && apt-get install -y git curl
    - npm install --global openwiki
    - git config user.name "${GITLAB_USER_NAME:-OpenWiki Bot}"
    - git config user.email "${GITLAB_USER_EMAIL:-openwiki@example.com}"
  script:
    - openwiki code --update --print
    - |
      if git diff --quiet -- openwiki AGENTS.md CLAUDE.md .github/workflows/openwiki-update.yml; then
        echo "OpenWiki is already up to date."
        exit 0
      fi
    - export OPENWIKI_BRANCH="openwiki/update-${CI_PIPELINE_ID}"
    - git checkout -b "$OPENWIKI_BRANCH"
    - git add openwiki AGENTS.md CLAUDE.md .github/workflows/openwiki-update.yml
    - git commit -m "docs: update OpenWiki"
    - git push "https://oauth2:${OPENWIKI_GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" "$OPENWIKI_BRANCH"
    - |
      curl --fail --request POST \
        --header "PRIVATE-TOKEN: ${OPENWIKI_GITLAB_TOKEN}" \
        --form "source_branch=${OPENWIKI_BRANCH}" \
        --form "target_branch=${CI_DEFAULT_BRANCH}" \
        --form "title=docs: update OpenWiki" \
        --form "description=Automated OpenWiki documentation update." \
        "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests"
  variables:
    OPENWIKI_PROVIDER: openrouter
    OPENWIKI_MODEL_ID: z-ai/glm-5.2

GitLab 配置要点

  • 在 Repository Settings > Pipelines > Schedules 创建定时触发
  • Protected CI/CD Variables 里配 OPENROUTER_API_KEYOPENWIKI_GITLAB_TOKEN
  • OPENWIKI_GITLAB_TOKEN 需要推送分支和创建 MR 的权限

Bitbucket Pipelines

examples/openwiki-update.bitbucket-pipelines.yml 套路相同:

  • 在 Repository settings > Pipelines > Schedules 配制定时
  • Repository variables 里配 OPENROUTER_API_KEYOPENWIKI_BITBUCKET_TOKEN
  • Token 需要 write 权限和创建 PR 权限

本地定时(macOS)

openwiki cron 系列命令管理 macOS LaunchAgent 定时任务:

  • 安装在 ~/Library/LaunchAgents/com.openwiki.<source>.plist
  • 日志在 ~/.openwiki/logs/
  • 复杂 cron 表达式如不能精确转为 StartCalendarInterval,会保存元数据但只给警告不安装不准确的计划
  • pmset 唤醒窗口:取所有调度的最早时间前 2 分钟唤醒,最晚时间后 30 分钟休眠

输出结构

一次成功的 code --init 运行后,仓库里会多出来:

your-repo/
├── openwiki/
│   ├── quickstart.md           # 快速入门
│   ├── index.md                # 目录索引(自动生成)
│   ├── architecture/
│   │   ├── index.md
│   │   └── overview.md         # 架构概览
│   ├── cli/
│   │   ├── index.md
│   │   └── usage.md            # CLI 参考
│   ├── agent/
│   │   ├── index.md
│   │   └── workflow.md         # Agent 工作流
│   ├── integrations/
│   │   ├── index.md
│   │   └── connectors.md       # 连接器文档
│   ├── operations/
│   │   ├── index.md
│   │   └── credentials-and-updates.md
│   ├── INSTRUCTIONS.md         # 仓库级 wiki 指令
│   └── .last-update.json       # 更新元数据(不提交也行)
├── AGENTS.md                   # Agent 引用段落(自动插入)
├── CLAUDE.md                   # Claude Code 引用段落(自动插入)
└── .github/workflows/
    └── openwiki-update.yml     # CI workflow(openwiki code 自动写入)

AGENTS.md / CLAUDE.md 自动维护

Agent 会在仓库根目录的 AGENTS.mdCLAUDE.md 里插入一个标准段落,标记为 <!-- OPENWIKI:START --><!-- OPENWIKI:END -->,内容是"这个仓库用 OpenWiki,从 openwiki/quickstart.md 开始读"。这个段落每次运行时会自动刷新,不要手动改。

.last-update.json

{
  "updatedAt": "2026-07-17T10:30:00.000Z",
  "command": "update",
  "gitHead": "abc123def456...",
  "model": "z-ai/glm-5.2"
}

这个文件只在 openwiki/ 内容确实变化时才更新。下次 --update 会用 gitHeadgit log <lastHead>..HEAD 精确范围,没有 gitHead 就回退到 --since <updatedAt> 时间范围。


遥测

OpenWiki 发送匿名可靠性遥测数据(通过 PostHog),包含:

  • 安装 ID(随机生成,不关联个人信息)
  • 运行命令和成功/失败状态
  • Provider 和模型 ID
  • 运行耗时
  • 错误类型(不含堆栈和敏感信息)

关闭方式

export OPENWIKI_TELEMETRY_DISABLED=1
# 或
export DO_NOT_TRACK=1

永久关闭加到 ~/.openwiki/.env。CI 里设到 workflow 环境变量。

查看具体发了什么

openwiki code --update --print --telemetry-file=./telemetry.json

开发者指南

项目结构

src/
├── cli.tsx                      # Ink 终端 UI + 运行生命周期
├── commands.ts                  # CLI 解析和帮助文本
├── credentials.tsx              # 交互式凭据引导
├── env.ts                       # ~/.openwiki/.env 读写
├── constants.ts                 # Provider 配置(12个)、模型列表、校验
├── ingestion.ts                 # 连接器摄取编排
├── onboarding.ts                # 首次运行向导
├── schedules.ts                 # macOS LaunchAgent 管理
├── code-mode.ts                 # openwiki code 模式初始化
├── diagnostics.ts               # 凭据诊断
├── agent/
│   ├── index.ts                 # Agent 运行时入口
│   ├── prompt.ts                # 系统提示和用户提示构建
│   ├── utils.ts                 # Git 证据 + 内容快照
│   ├── types.ts                 # 共享类型
│   ├── docs-only-backend.ts     # DeepAgents 后端 + 写保护
│   ├── openai-chatgpt-oauth.ts  # ChatGPT OAuth 流程
│   ├── vertex-surface.ts        # Vertex AI 路由
│   ├── frontmatter-validator.ts # YAML frontmatter 校验
│   ├── skills.ts                # Agent 技能加载
│   └── index-middleware.ts      # Agent 中间件
├── auth/                        # 连接器 OAuth 系统
│   ├── oauth.ts                 # 通用 OAuth runner
│   ├── providers.ts             # Provider 配置
│   ├── configure.ts             # openwiki auth configure
│   ├── ngrok.ts                 # Slack HTTPS 隧道
│   ├── tokens.ts                # Token 刷新
│   └── types.ts
├── connectors/                  # 7 个连接器
│   ├── types.ts                 # ConnectorId 联合类型
│   ├── registry.ts              # 注册表
│   ├── tools.ts                 # Agent 可调用工具
│   ├── mcp-client.ts            # MCP JSON-RPC 客户端
│   ├── mcp-runtime.ts           # MCP 只读策略
│   ├── io.ts                    # 文件 IO 辅助
│   └── sources/                 # 各连接器实现
│       ├── git-repo.ts
│       ├── gmail.ts
│       ├── hackernews.ts
│       ├── mcp.ts               # Notion (MCP 工厂)
│       ├── slack.ts
│       ├── web-search.ts
│       └── x.ts
└── telemetry/                   # 遥测系统
    ├── client.ts
    ├── config.ts
    ├── gates.ts
    ├── senders.ts
    └── ...

添加新 Provider

  1. src/constants.tsOpenWikiProvider 类型加新值
  2. PROVIDER_CONFIGS 加配置项(apiKeyEnvKeybaseURLmodelOptions 等)
  3. 加到 SELECTABLE_OPENWIKI_PROVIDERS 数组
  4. src/agent/index.tscreateModel() 加分支
  5. src/env.tsmanagedEnvKeys 加新环境变量
  6. 如果用 OAuth,在 src/auth/ 加 token 刷新流程

添加新连接器

仓库有现成的 skill 指导:skills/write-connector/SKILL.md。核心步骤:

  1. src/connectors/types.tsConnectorId 加新值
  2. src/connectors/sources/ 下新建 <connector>.ts
  3. 实现 ConnectorRuntime(id、displayName、requiredEnv、ingest())
  4. src/connectors/registry.ts 注册
  5. src/credentials.tsxSOURCE_OPTIONS 加选项

安全铁律

  • 永远不读、不打印、不日志、不硬编码密钥值
  • 密钥只存在 ~/.openwiki/.env,配置文件里只引用环境变量名
  • 原始数据写入 ~/.openwiki/connectors/<id>/raw/<run-id>/
  • 状态文件在 ~/.openwiki/connectors/<id>/state.json
  • 如果走 MCP,只调白名单里的只读操作

本地开发

pnpm install
pnpm run build          # TypeScript 编译
pnpm run dev            # 用 tsx 直接跑 src/cli.tsx
pnpm test               # Vitest 测试
pnpm run coverage       # 覆盖率
pnpm run format         # Prettier 格式化
pnpm run lint           # ESLint

PR 规范:一个 PR 只做一个改动。不要把无关的修改捆在一起。


总结

适合什么场景

  • 中大型代码仓库缺文档,或者文档严重过时,需要从零生成或大幅刷新
  • 快速迭代的项目,代码变得快文档跟不上,用 CI 定时跑保持同步
  • 团队知识沉淀,新人入职读 openwiki/quickstart.md 比读源码快得多
  • 个人知识管理,Personal 模式接入 Gmail/Slack/Notion 等数据源合成知识库

设计亮点

  1. Git-grounded:Agent 不编造,所有结论基于 git history 和文件系统实际内容
  2. 内容快照防循环:SHA-256 对比确保无意义更新不产生 PR
  3. 写保护:Agent 只能写 openwiki/ 目录,不碰源码
  4. 确定性摄取 + LLM 合成:网络调用不经过 Agent,凭证不暴露给模型
  5. 12 个 Provider 支持,从 OpenAI 到 AWS Bedrock 都有,还有 OpenAI-Compatible 万能网关
  6. 三平台 CI 模板:GitHub/GitLab/Bitbucket 都有现成 workflow

局限

  • 依赖模型质量:文档质量取决于 LLM 理解代码的能力,弱模型会产出泛泛而谈的内容
  • Token 消耗:大仓库的 init 会消耗大量 token(读很多文件),建议用便宜模型做 init,好模型做 update
  • macOS 偏重:本地定时任务管理(LaunchAgent + pmset)是 macOS 专有的,Linux/Windows 用户得自己用 cron 或 Task Scheduler
  • 连接器仍在早期:7 个连接器里 Notion 和 Slack 需要 OAuth 配置,X 需要 X API 访问权,门槛不低
  • 只支持 Node.js 22+,低版本不行

跟传统文档工具的关系

OpenWiki 不是 Javadoc/Sphinx/TypeDoc 的替代品。那些工具精确地提取 API 签名,OpenWiki 生成的是架构概览和工作流文档。两者互补,用 OpenWiki 生成"这个仓库怎么理解"的高层文档,用传统工具生成 API 参考。


与 Hermes Agent 融合方案

Hermes Agent 仓库:github.com/nousresearc… Hermes 官网:hermes-agent.nousresearch.com License:MIT

两个项目为什么互补

OpenWiki 和 Hermes Agent 都是 Agent 工具,但定位完全不同:

维度OpenWikiHermes Agent
核心能力读代码/git → 生成结构化文档自我进化的个人 Agent,learning loop
Agent 模式一次性任务(init/update)持续运行、跨会话记忆
数据流单向:代码 → 文档双向:感知 → 决策 → 行动 → 记忆
输出openwiki/ 目录的 MarkdownSkills、Memory、Kanban 任务
触发手动或 CI 定时事件驱动 + Cron + IM 消息
多 Agent单 Agent + DeepAgents 后端Kanban 多 Profile 协作

OpenWiki 缺的是持续记忆和任务编排能力,每次运行都是无状态的,不知道上次跑了什么。Hermes 缺的是对代码库的深度理解能力,可以调 git 命令但不会生成结构化文档。把两者接起来,就得到了一个能持续维护项目文档、还能把文档变成可复用知识的系统。

融合架构总览

OpenWiki × Hermes 融合架构

路径 A:Hermes Skill 包装 OpenWiki(最轻量)

把 OpenWiki 的能力封装成一个 Hermes Skill,Hermes Profile 通过 /wiki 斜杠命令调用。推荐先从这个开始。

Skill 定义(放在 ~/.hermes/skills/wiki/SKILL.md):

---
name: wiki
description: >
  使用 OpenWiki 为代码仓库生成或更新文档。支持 init(首次生成)
  和 update(增量更新)两种模式。Agent 通过 shell 调用 openwiki CLI,
  生成结果在仓库的 openwiki/ 目录下。
---

# Wiki Skill

## 何时使用
- 用户说"给这个项目生成文档"或"更新文档"
- 代码大改后需要刷新文档
- 新仓库需要 onboarding 文档

## 执行步骤

### 初始化文档(首次)
```bash
cd /path/to/target/repo
openwiki code --init --print

更新文档(增量)

cd /path/to/target/repo
openwiki code --update --print

带指令更新

openwiki code "聚焦 API 文档和部署指南" --print

参数

  • --init:首次生成,会读最近 20 条 commit 做全量文档
  • --update:增量更新,用 .last-update.json 的 gitHead 做精确范围
  • --print:非交互模式,输出到 stdout 后退出(适合 Agent 调用)
  • --modelId:指定模型(默认用 ~/.openwiki/.env 里的配置)

输出

  • 文档写入 openwiki/ 目录
  • AGENTS.md / CLAUDE.md 自动插入引用段落
  • .last-update.json 记录元数据(仅内容变化时)

注意

  • Agent 不需要读源码,OpenWiki 自己会读
  • --print 模式确保不卡在交互 UI
  • 如果 openwiki 没装,先 npm install -g openwiki

使用方式

# 在 Hermes CLI 里
/wiki 为当前项目生成文档

# 或者带参数
/wiki 更新文档,聚焦部署和配置部分

# Hermes 会调用 openwiki CLI,读输出,然后告诉你结果

进阶:用 /learn 让 Hermes 自己学会这个 Skill

/learn https://github.com/langchain-ai/openwiki 的使用方法,重点放在 code 模式的 init 和 update 命令

Hermes 会抓取 README 和文档,自动生成一个符合标准的 Skill,不用手写。

路径 B:Kanban Worker 分配文档任务(多 Agent 协作)

利用 Hermes Kanban 的多 Profile 协作能力,把文档生成变成一个有 Reviewer 的流水线。

场景:代码 push 后自动触发文档更新,经过 Reviewer 审核后合并。

Kanban 任务设计

# 1. Orchestrator Profile 检测到 git push,创建文档更新任务
hermes kanban create \
  --title "更新 OpenWiki 文档" \
  --body "代码变更涉及 auth 模块和 API 层,需要刷新相关文档" \
  --assignee wiki-worker \
  --tenant project-a

# 2. wiki-worker Profile 拿到任务后执行
# 在 wiki-worker 的 SOUL.md 里配置:
# "你是文档维护专员。拿到任务后 cd 到目标仓库,
#  执行 openwiki code --update --print,
#  读输出确认成功,把变更摘要写到 comment 里,
#  标记任务为需要 review"

# 3. Reviewer Profile 检查文档质量
# hermes kanban show <id> 读 comment
# 检查 openwiki/ 变更是否合理
# 通过 → complete;不通过 → comment 写反馈,block 任务

Kanban 任务流

git push event
  → Orchestrator 创建任务(assignee: wiki-worker)
  → wiki-worker 执行 openwiki code --update --print
  → wiki-worker comment: "已更新 auth.md 和 api.md,变更摘要:..."
  → Orchestrator 转交 review(assignee: doc-reviewer)
  → doc-reviewer 读 diff,检查文档质量
  → 通过 → kanban complete
  → 不通过 → comment 反馈,block 任务等 wiki-worker 修改

workspace 配置

# 用 dir: 模式指向仓库目录,worker 在仓库里工作
hermes kanban create \
  --title "更新文档" \
  --assignee wiki-worker \
  --workspace dir:/path/to/target/repo

worktree: 模式更安全,Kanban 会创建 git worktree,worker 在隔离分支上工作:

hermes kanban create \
  --title "更新文档" \
  --assignee wiki-worker \
  --workspace worktree

路径 C:MCP 连接器双向数据流(深度集成)

OpenWiki 本身支持 MCP 连接器(Notion 就是走 MCP 的),可以写一个自定义 MCP server 把 OpenWiki 的能力暴露给 Hermes。

OpenWiki MCP Server(TypeScript,放在 ~/.openwiki/mcp-server/):

// mcp-server.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new Server({
  name: "openwiki-mcp",
  version: "0.1.0",
}, {
  capabilities: { tools: {} }
});

// 只读工具:让 Hermes Agent 读取 OpenWiki 生成的文档
server.setRequestHandler("tools/list", async () => ({
  tools: [
    {
      name: "read_wiki",
      description: "读取仓库的 OpenWiki 文档内容",
      inputSchema: {
        type: "object",
        properties: {
          repo_path: { type: "string", description: "仓库绝对路径" },
          page: { type: "string", description: "页面名,如 quickstart / architecture/overview" }
        },
        required: ["repo_path"]
      }
    },
    {
      name: "list_wiki_pages",
      description: "列出仓库的所有 OpenWiki 页面",
      inputSchema: {
        type: "object",
        properties: {
          repo_path: { type: "string", description: "仓库绝对路径" }
        },
        required: ["repo_path"]
      }
    },
    {
      name: "get_last_update",
      description: "获取文档最后更新信息(gitHead / updatedAt / model)",
      inputSchema: {
        type: "object",
        properties: {
          repo_path: { type: "string", description: "仓库绝对路径" }
        },
        required: ["repo_path"]
      }
    }
    // 注意:不暴露 write/update 工具,保持只读,跟 OpenWiki 的 MCP 策略一致
  ]
}));

// 工具处理:读文件系统,返回 Markdown 内容
server.setRequestHandler("tools/call", async (request) => {
  const { name, arguments: args } = request.params;
  const fs = await import("fs/promises");
  const path = await import("path");

  const wikiDir = path.join(args.repo_path, "openwiki");

  switch (name) {
    case "read_wiki": {
      const filePath = args.page
        ? path.join(wikiDir, `${args.page}.md`)
        : path.join(wikiDir, "quickstart.md");
      const content = await fs.readFile(filePath, "utf-8");
      return { content: [{ type: "text", text: content }] };
    }
    case "list_wiki_pages": {
      // 递归列出 openwiki/ 下所有 .md 文件
      const pages = await listMarkdownFiles(wikiDir);
      return { content: [{ type: "text", text: JSON.stringify(pages, null, 2) }] };
    }
    case "get_last_update": {
      const meta = await fs.readFile(
        path.join(wikiDir, ".last-update.json"), "utf-8"
      ).catch(() => "{}");
      return { content: [{ type: "text", text: meta }] };
    }
  }
});

const transport = new StdioServerTransport();
await server.connect(transport);

Hermes 侧配置

# 在 Hermes 配置里添加 MCP server
hermes mcp add openwiki --stdio "node /path/to/mcp-server.js"

配置后 Hermes Agent 可以直接调用:

# Hermes 对话里
"帮我看看 my-project 项目的架构文档"
→ Hermes 调用 read_wiki(repo_path: "/path/to/my-project", page: "architecture/overview")
→ 读取 OpenWiki 生成的架构文档
→ Hermes 理解后用自己的话回答你

"这个项目文档上次什么时候更新的?"
→ Hermes 调用 get_last_update(repo_path: "/path/to/my-project")
→ 返回 .last-update.json 内容

更进一步的玩法,让 OpenWiki 在生成文档时能读到 Hermes 的 Memory:

// 在 OpenWiki 的 ~/.openwiki/.env 里配置一个自定义连接器
// src/connectors/sources/hermes-memory.ts
// 读取 ~/.hermes/MEMORY.md 和 ~/.hermes/kanban.db 的任务历史
// 写入 ~/.openwiki/connectors/hermes-memory/raw/latest.json
// OpenWiki Agent 生成 personal wiki 时可以引用 Hermes 的记忆

这样 OpenWiki 的 Personal 模式不只能接 Gmail/Slack,还能接 Hermes 的 Memory 和 Kanban 历史,把 Agent 自己的工作经验也合成进知识库。

三条路径对比

维度路径 A:Skill路径 B:Kanban路径 C:MCP
实现难度低(写个 SKILL.md)中(配 Profile + workspace)高(写 MCP server)
数据流Hermes → OpenWiki(单向)双向(任务 + comment)双向(工具调用 + 数据读取)
适合场景个人开发者,偶尔生成文档团队,需要 Review 流程深度集成,Hermes 需要读文档做决策
记忆无(OpenWiki 无状态)有(Kanban 任务历史持久)有(Hermes Memory 持续积累)
触发手动 /wiki 或 Crongit push / 定时 / 手动Hermes 对话中自动调用
Provider 要求各配各的OpenWiki 用自己的 ProviderHermes 的模型 + OpenWiki 的 Provider

渐进式集成路线

第一步(10 分钟) :走路径 A,写一个 wiki Skill,让 Hermes 能通过 /wiki 命令调 OpenWiki。先验证基本流程通不通。

第二步(1 小时) :给 wiki-worker Profile 写 SOUL.md,配一个 Kanban board,把文档更新变成有审核的任务流。加上 git hook 或 Cron 触发。

第三步(半天) :写 OpenWiki MCP Server,让 Hermes 能直接读 openwiki/ 文档内容。再写个反向连接器,让 OpenWiki 能读 Hermes Memory。

第四步(持续) :Hermes Cron 里配定时任务,每天跑一次 OpenWiki update,有变更就创建 Kanban 任务通知 Reviewer,Reviewer 通过后自动合并 PR。Reviewer 的审核经验通过 Hermes Memory 沉淀,下次审核更准。