内容
<img width="1469" height="842" alt="Screenshot from 2026-07-09 22-06-41" src="https://github.com/user-attachments/assets/88c10be3-36cc-4173-b298-07163019cf17" />
# 代码知识库
一组相关代码项目的独立、只读知识层(例如,Laravel API 和 Vue 前端)。它构建 **一个合并的代码连接图** — 包括跨仓库的边,它们将前端 API 调用链接到为它们提供服务的 Laravel 控制器 — 以及一个 **向量化搜索索引**,用于项目文档。默认情况下,所有操作都在设备上运行 **无需 API 密钥**(`none` 和 `llama` 嵌入后端);只有可选的 `other` 后端可以访问外部服务。
构建在两个现有工具之上:[**graphify**](https://github.com/Graphify-Labs/graphify)(AST 代码图)和 [**qmd**](https://github.com/tobi/qmd)(设备端 Markdown 向量搜索)。
## 需求
这些是外部依赖项 — 未被供应商管理。安装它们并确保在运行构建之前它们位于您的 `PATH` 中:
| 工具 | 版本(已测试) | 用途 |
| --- | --- | --- |
| [**graphify**](https://github.com/Graphify-Labs/graphify) | `>= 0.9.25` | AST 代码图(`update`、`merge-graphs`、`cluster-only`、`query`、`path`、`explain`、`affected`)。构建和 `bin/kb-mcp` shell 调用它。 |
| **qmd** | `>= 2.5.3`(`query`/`search`/`vsearch` CLI) | 设备端 Markdown 向量 + BM25 文档搜索。**必须是现代血统**:`bin/kb-mcp` 和文档使用 `qmd query`。较旧的 `qsearch` 血统(例如 0.3.x)具有不兼容的命令集,将破坏文档搜索 — 请参见下面的注释。 |
| **python3** | `>= 3.10` | `bin/` 中的丰富脚本(仅标准库 — 无包)。 |
| **rsync** | 任意近期版本 | 将索引项目的代码仅复制到 `repos/` 中。 |
| **php** + **artisan** | 索引应用的版本 | 仅当项目设置 `routes` 时需要 — `bin/kb` 运行 `php artisan route:list --json` 以构建跨仓库 `http_request` 边。 |
默认情况下,所有操作都在设备上运行 **无需 API 密钥**(参见配置下的嵌入后端选择)。检查已安装的内容:
```bash
graphify --version && qmd --version && python3 --version
qmd query --help >/dev/null 2>&1 && echo "qmd: query CLI ok" || echo "qmd: 错误的血统(无 'query' 命令)"
```
> **qmd 版本兼容性。** 本知识库针对现代 qmd CLI(`query`/`search`/`vsearch`,2.5.3+)。不同的旧血统使用 `qmd qsearch --no-rerank --no-expand` 代替,缺少 `query`;`bin/kb-mcp` 的 `docs_search` 将失败。 如果您在多个机器上共享一个知识库,**在所有机器上安装相同的 qmd 血统** — 基于 `query` 的 checkout 和基于 `qsearch` 的 checkout 不能同时从同一个 `bin/kb-mcp` 工作。
## 快速开始
```bash
make build # 构建合并图 + qmd 文档索引
make open # 打开类型化/域可视化(kb-graph.html)
qmd query "身份验证如何工作" -c kb
graphify path "useAuthFlow.js" "AuthMethodsController" --graph graphify-out/graph.json
```
qmd 集合名称默认为 `kb`;在构建之前通过设置 `KB_COLLECTION` 来覆盖它。
## 您得到的内容
- `graphify-out/graph.json` — 合并图:每个节点都标有其 `repo`;`http_request` 边连接前端调用站点到后端控制器,跨仓库。
- `graphify-out/kb-graph.html` — **主要** 可视化:类型化/域视图(形状 = 类型,颜色 = 域),分层且延迟加载。此处是 `make open` 打开的内容。分层延迟加载(域超级节点按需展开,边重新路由)旨在保持 **大型代码库 — 5k+ 文件没问题**;它永远不会一次渲染整个图。
- `graphify-out/graph.html` — graphify 的完整交互式可视化(备用)。
- `graphify-out/GRAPH_REPORT.md` — 易读的架构报告,包含社区。
- qmd `kb` 集合(`.qmd/`)— 所有文档的混合 BM25 + 向量搜索。
## 配置
复制 `kb.projects.toml.example` 到 `kb.projects.toml` 并编辑它以添加/删除项目或更改扫描/索引的路径。**不支持符号链接** — 路径是显式的。`.graphifyignore` 控制 graphify 排除的内容。
### qmd 嵌入后端
第一次构建会询问 **qmd 的嵌入位置** 并在 `.kb.local` 中记住选择(gitignored):
| 选择 | 它执行的操作 |
| --- | --- |
| `none` | 完全跳过向量 — 仅 BM25 关键词搜索。无需模型下载。 |
| `llama` | 设备端 llama.cpp 嵌入(qmd 的默认值;下载小型 GGUF 模型)。 |
| `other` | 自带嵌入器:运行 `$KB_QMD_EMBED_CMD`(如果设置),否则直接 `qmd embed`,以便您可以通过其环境变量将 qmd 指向自己的模型/端点。 |
跳过提示,设置 `KB_QMD_BACKEND=none|llama|other`(例如,在 CI 中)。稍后使用 `make qmd-backend`(或 `bin/kb qmd-backend`)更改。
## 安装到项目中
每个使用知识库的项目都需要两件事:**MCP 服务器配置**,以便其代理可以查询知识库,以及 **`kb` 技能**,以便代理知道何时/如何使用它。两者都指向此处 — 此仓库是唯一的真实来源。
### 1. MCP 服务器配置
将 `kb` 服务器添加到项目的 `.mcp.json`(`mcpServers` 对象)。无需环境变量,无需安装 — 它是一个零依赖的 stdio 服务器(使用此签出的绝对路径):
```json
{
"mcpServers": {
"kb": { "command": "/path/to/kb/bin/kb-mcp" }
}
}
```
重启代理会话以加载它。它公开 `graph_query`、`graph_path`、`graph_explain`、`graph_affected`、`docs_search`、`docs_get`。(此仓库自己的 `.mcp.json` 仅注册 `qmd`,`kb-mcp` 在内部调用它 — 项目 **不需要** `qmd` 条目。)
### 2. `kb` 技能
规范技能位于此处 [`skills/kb/SKILL.md`](skills/kb/SKILL.md)。通过符号链接将其安装到项目中,以便此处更新传播到所有地方:
```bash
# Laravel 项目在 .ai/skills 中保留技能,并使用 .claude/skills 符号链接:
ln -s /path/to/kb/skills/kb /path/to/project/.ai/skills/kb
ln -s ../../.ai/skills/kb /path/to/project/.claude/skills/kb
# 或者,对于直接从 .claude/skills 读取技能的项目:
ln -s /path/to/kb/skills/kb /path/to/project/.claude/skills/kb
```
匹配每个项目的现有技能布局(检查兄弟技能:有些使用 `.ai/skills` + `.claude/skills` 符号链接,其他直接使用 `.claude/skills`)。重启会话以获取它。如果您更喜欢自包含的副本而不是符号链接,请改为 `cp -r` 目录。
### 3. 自动提醒钩子(推荐)
**跳过此步骤,安装可靠性会降低。** 技能仅在代理自己的判断下触发,而 `kb` MCP 工具在具有许多 MCP 服务器的项目中可能会 **延迟** 搜索索引 — 因此代理可能会在“如何工作/连接什么/影响”提示下默认使用 `grep`/`Explore`,并且永远不会到达图(正是此钩子防止的失败)。`UserPromptSubmit` 钩子弥补了这一空白:它扫描提示中的连接/影响触发词,并注入一行提醒,使用 `kb` 图形工具。
在使用的项目中添加它(不是此处 — 此仓库是只读的,并且不是 Claude Code 项目)。一个现成的匹配器模板位于 [`skills/kb/install/kb-reminder.py`](skills/kb/install/kb-reminder.py)(EN + RU 触发器;用团队语言扩展 `TRIGGERS`):
```bash
# 1. 复制匹配器模板(不要符号链接 — 项目扩展其 TRIGGERS 列表)
mkdir -p /path/to/project/.claude/hooks
cp /path/to/kb/skills/kb/install/kb-reminder.py /path/to/project/.claude/hooks/
# 2. 在 .claude/settings.json 中连接它(合并 — 永远不要覆盖现有钩子/键)
```
```json
{
"hooks": {
"UserPromptSubmit": [
{ "hooks": [ { "type": "command",
"command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/kb-reminder.py\" 2>/dev/null || true",
"statusMessage": "Checking for kb-graph relevance" } ] }
]
}
}
```
脚本读取 stdin 上的钩子 JSON,打印
`{"hookSpecificOutput": {"hookEventName": "UserPromptSubmit", "additionalContext": "<reminder>"}}`
在触发时,并保持沉默 + 退出 0 否则,以免阻塞提示。此外,请添加一个 **项目指南行**(“对于 how-does-X / what-connects / impact 问题,请在使用 grep 之前使用 `kb` 技能,并告诉委托的子代理也这样做”)。参见 SKILL.md “如何有效地使用它”第 5-6 点,说明其原因。
### 4. 验证安装
从项目根目录运行 — 每行都应报告存在/是:
```bash
# 1. MCP 服务器已注册且二进制文件可运行
python3 -c "import json;print('kb cmd:',json.load(open('.mcp.json'))['mcpServers']['kb']['command'])"
test -x "$(python3 -c "import json;print(json.load(open('.mcp.json'))['mcpServers']['kb']['command'])")" && echo "kb-mcp executable: YES"
# 2. 技能可达(无论项目使用哪种布局)
test -f .claude/skills/kb/SKILL.md && echo "skill: YES"
# 3. 钩子存在、有效且实际上会在示例提示上触发
test -f .claude/hooks/kb-reminder.py && echo "hook script: present"
jq -e '.hooks.UserPromptSubmit' .claude/settings.json >/dev/null && echo "hook wired: YES"
echo '{"prompt":"how does auth work"}' | python3 .claude/hooks/kb-reminder.py | jq -e .hookSpecificOutput >/dev/null && echo "hook fires: YES"
# 4. qmd 是兼容的血统(kb-mcp 的 docs_search 需要 `qmd query`)
qmd query --help >/dev/null 2>&1 && echo "qmd query CLI: YES" || echo "qmd query CLI: NO — wrong qmd lineage"
```
然后 **重启代理会话**(或打开 `/hooks` 一次),以便它加载新的 `.mcp.json` 服务器、技能和新创建的 `settings.json` — 设置观察器仅跟踪 `.claude/`,如果在会话启动时那里存在设置文件。
## 项目如何连接
`bin/link_http.py` 读取每个 Laravel 应用的 `php artisan route:list --json` 并将其与前端的 API 调用站点进行匹配,注入 `http_request` 边。它识别常见形状 — 点客户端 (`api.<verb>('<path>')`),ofetch/fetch 包装器,其中动词位于选项对象中 (`$api(...)`、`apiFetch(...)`,以及原始 `fetch(\`${API_BASE}/…\`)`) — 并容忍前端省略基本前缀,而基本 URL 提供(例如 Laravel 的 `api/`)。这就是 `graphify path` 可以遍历从 Vue/React 文件到提供其请求的控制器的原因。
## 路线图
- [ ] **`bin/link_http.py` 的突变测试。** 匹配器有单元测试
(`make test`),但测试可以通过同时对现实回归保持盲目。添加一个
突变传递 — 翻转正则表达式,交换 GET 默认值改为 POST,逆转一个
`endswith`,删除最短后缀排序 — 并确认套件 *失败* 在
每个(每个突变体都被杀死)。保持依赖关系轻(小型标准库测试 +
`make mutation`)或在虚拟环境中连接 `mutmut`。
## 足迹
索引项目 **从未被修改**。它们的代码被复制(仅代码)到 `repos/`
(gitignored)进行扫描;所有输出都位于此仓库中。
参见 `CLAUDE.md` 以获取代理查询工作流程。
## 许可证
[GPL-3.0-or-later](LICENSE) — 免费软件:使用、研究、分享和修改它。版权所有 (C) 2026 Romans Sereda。派生作品也必须在 GPL 下许可(版权共享)。