关于 Knowledge Base MCP Server
Knowledge Base MCP Server 将 Markdown 笔记索引到本地 FAISS 向量库,支持语义搜索和问答。它面向 MCP 客户端及命令行用户,并提供可选的笔记写入和索引管理命令。
主要功能
- 01跨 Markdown 笔记语义搜索
- 02基于索引笔记回答问题
- 03可选写入笔记
- 04本地 FAISS 向量索引
- 05命令行索引与诊断
适用场景
- 01按主题而非精确词语查找笔记
- 02根据个人或工作笔记提问
- 03通过命令行索引并检查知识库
MCP 相关
提供搜索知识库、根据内容回答问题及可选写入笔记的工具。MCP 客户端与 `kb` 命令行工具可访问同一笔记集合。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Knowledge Base MCP 服务
将此服务指向一个存放 Markdown 笔记的文件夹,它就能按含义而非仅按关键词搜索内容——既可以通过 AI 客户端,也可以通过命令行执行。
你可以将笔记作为普通文件保存在自己的磁盘上。服务会读取笔记,将其拆分成文本块,再用你选择的嵌入模型(本地 Ollama 模型、OpenAI 或 HuggingFace)将每个文本块转换为向量,并将这些向量存储在本地 FAISS 索引中。使用本地嵌入模型和本地 LLM 运行时,笔记不会离开你的设备;只有在使用托管服务提供商时,笔记才会经由网络传输。该索引提供两个入口:
- MCP 服务,任何 Model Context Protocol 客户端——Claude Desktop、Codex CLI、Cursor、Continue、Cline——都可以调用它来搜索笔记、根据笔记内容回答问题,以及(可选)写入新笔记。
kb命令行工具,可在终端或 Agent 的命令行中操作同一语料库,还提供 MCP 接口未开放的运维命令:建立索引、运行诊断、评估和整理笔记。
在本文档中,知识库(或 书架)是指笔记根目录下的一个子目录——work/、research/、personal/——你可以单独搜索其中的内容,也可以同时搜索多个目录。
演示
这里展示的是真实输出,没有模拟数据:录制过程使用 kb CLI 搜索本仓库的 docs/ 中整理的小型知识库,并用默认的 Ollama 嵌入模型建立索引。你可以使用 docs/assets/record-demo.sh 重新生成演示。
目录
| 章节 | 适合在何时阅读 |
|---|---|
| 安装 | 将服务或 kb CLI 安装到你的设备上。 |
| 配置 | 选择嵌入服务提供商并整理笔记。 |
| 使用 MCP 服务 | 将 AI 客户端连接到你的知识库。 |
使用 kb CLI | 在命令行中搜索、提问、写入和整理内容。 |
| 调整检索质量 | 启用可选的重排序、门控和安全处理阶段。 |
| 远程传输 | 使用 HTTP 或 SSE 而不是 stdio 提供 MCP 服务。 |
| 基准测试 | 在本地测量检索质量。 |
| 故障排除 | 搜索没有结果,或内容似乎已过时。 |
| 安全 | 在将服务用于不可信内容之前,了解信任边界。 |
| 文档导航 | 查找 docs/ 下更深入的参考文档和操作手册。 |
安装
所有安装方式都需要 Node.js 22 或更高版本,以及 npm。
作为 MCP 服务(一条命令)
npx -y @jeanibarz/knowledge-base-mcp-server@latest
npx 会从 npm 获取软件包并启动 stdio 服务。将 MCP 客户端指向同一条命令,并设置配置中所述的环境变量。docs/clients.md 提供了适用于 Claude Desktop、Codex CLI、Cursor、Continue 和 Cline 的可直接复制粘贴的配置片段。
固定使用
@latest,不要使用未指定版本的形式。npx -y @jeanibarz/knowledge-base-mcp-server(未指定版本)会将解析出的版本无限期缓存到~/.npm/_npx/中——即使发布了新版本,后续启动客户端时仍会使用缓存版本。@latest形式会生成不同的缓存键,并在每次启动时重新解析,因此客户端下次重启时即可获取修复,无需手动清除~/.npm/_npx/。参见 RFC 012 §2.4。
作为 CLI(kb)
全局安装后,即可在任意 shell 中使用 kb 命令——适合交互使用,也可作为供 AI Agent 调用 shell 的工具:
npm install -g @jeanibarz/knowledge-base-mcp-server@latest
kb list # which knowledge bases can I see?
kb doctor # is retrieval actually healthy?
kb search "your query"
操作系统每次调用时都会解析二进制文件,因此 npm i -g …@latest 会立即生效——无需重启已加载 MCP 服务的 AI 客户端。kb 可执行文件读取与 MCP 服务相同的环境变量。完整命令列表请参见使用 kb CLI。
通过 Smithery
要通过 Smithery 为 Claude Desktop 自动安装:
npx -y @smithery/cli install @jeanibarz/knowledge-base-mcp-server --client claude
从源码安装
若要基于此代码库进行开发或固定到尚未发布的提交,请使用此方式。
git clone https://github.com/jeanibarz/knowledge-base-mcp-server.git
cd knowledge-base-mcp-server
npm install
npm run build
然后设置环境变量(参见配置),创建知识库目录,并将 node build/index.js 添加到 MCP 客户端配置中——参见 docs/clients.md。
本地开发
在你积极开发此代码库,并希望全局 kb 和 knowledge-base-mcp-server 命令始终反映当前检出版本时使用此方法——无需 npm publish,也无需每次 git pull 后手动重新安装。
git clone https://github.com/jeanibarz/knowledge-base-mcp-server.git
cd knowledge-base-mcp-server
npm run dev:setup
dev:setup 会执行以下三项幂等操作:
npm install+npm run build— 首次构建,确保链接前命令已生成。npm link— 将kb和knowledge-base-mcp-server符号链接到全局 Node 前缀(设置期间会打印路径,方便你确认链接位置)。此后,每次npm run build都会就地覆盖build/,全局命令会在下次调用时使用新代码。无需重新链接。git config core.hooksPath .githooks— 将 git 指向已跟踪的.githooks/目录,以便每次git pull(合并或变基)和git merge后触发post-merge和post-rewrite钩子。每个钩子都会在package.json发生变化时重新运行npm install,并在任何源文件发生变化时重新运行npm run build;没有相关变化时则保持安静。它会在钩子顺序中最后运行,因此安装或构建失败时,代码库会保持原样。
日常只需运行 git pull(钩子会重新构建),或在编辑后运行 npm run build;全局 kb 会在下次调用时反映这些更改。
为什么使用 npm link,而不是 npm install -g .? npm link 创建的是符号链接,因此重新构建后即可直接使用新版本。npm install -g . 会复制构建快照,所以每次更改都需要重新安装。
钩子范围。 钩子会在 git pull / git merge / git pull --rebase 时触发,但不会在分支间执行 git checkout 时触发——切换分支后请自行运行 npm run build。如果重新构建失败,钩子会打印警告并以状态码 0 退出,因此不会将拉取操作报告为失败。
以下三个开发辅助工具使用临时状态运行,不会触及你的实际知识库和索引:
| 命令 | 功能 |
|---|---|
npm run dev:doctor | 构建当前检出版本,创建一次性临时语料,并验证 CLI、本机 FAISS 依赖、kb list、词法搜索,以及(如果配置的嵌入提供方可访问)密集向量搜索。可用于对新贡献者的 Shell 环境进行快速检查。 |
npm run dev:cli -- search "…" --kb=work | 直接运行 TypeScript CLI 入口并启用源映射,无需重新构建或重新链接即可获取真实堆栈跟踪。它会先将当前生效的 KNOWLEDGE_BASES_ROOT_DIR、FAISS_INDEX_PATH、嵌入提供方和模型打印到标准错误,以便你确认命令将操作哪个知识库和索引。 |
npm run dev:remote -- --transport=http|sse | 初始化一个临时知识库,选择一个空闲的回环端口,生成 MCP_AUTH_TOKEN,打印 curl 示例,针对该临时状态启动 TypeScript 服务,并在退出时将其删除。添加 --keep 可检查生成的文件,添加 --print-env 可输出环境变量和示例,但不启动服务。 |
切换回已发布的 npm 版本(例如用于比较行为):
npm unlink -g @jeanibarz/knowledge-base-mcp-server
npm install -g @jeanibarz/knowledge-base-mcp-server@latest
配置
首先有两项设置很重要:笔记的存放位置以及将笔记转换为向量的嵌入模型。其他设置都有可用的默认值。
KNOWLEDGE_BASES_ROOT_DIR=$HOME/knowledge_bases # one subdirectory per knowledge base
EMBEDDING_PROVIDER=ollama # ollama | openai | huggingface
在 shell 配置文件(.bashrc、.zshrc)或 MCP 客户端的配置中设置这些变量。所有受识别的变量及其默认值、可接受的值和验证约束都列在 docs/reference/configuration.md 中;面向运维人员的检索标志和发布状态说明见 docs/feature-flags.md。本地开发时,将 .env.example 复制为 .env。
运行 kb config validate,在启动前检查配置。它既能发现变量之间的配置错误,也能发现单个变量的值无效;例如,KB_CHUNK_OVERLAP 必须严格小于 KB_CHUNK_SIZE。kb doctor 也会报告同样的问题,并在这两个值不符合要求时以非零状态码退出。
选择嵌入服务提供方
生产环境支持三种服务提供方。第四种 EMBEDDING_PROVIDER=fake 会为测试和离线样例返回确定性向量,但不适用于实际检索。
Ollama(推荐——本地且免费)
在自己的设备上运行嵌入模型,不会将任何笔记内容发送到其他地方。
EMBEDDING_PROVIDER=ollama
OLLAMA_BASE_URL=http://localhost:11434 # default
OLLAMA_MODEL=dengcao/Qwen3-Embedding-0.6B:Q8_0 # default
KNOWLEDGE_BASES_ROOT_DIR=$HOME/knowledge_bases
先安装 Ollama,再拉取模型:ollama pull dengcao/Qwen3-Embedding-0.6B:Q8_0。
选择模型前,请先检查其上下文窗口。 默认分块器会生成约 1000 个字符的分块,通常会超过 256 个 token,因此
all-minilm这类 256-token 模型会拒绝所有请求。请选择至少支持约 500 个 token 的模型:nomic-embed-text(8192)、dengcao/Qwen3-Embedding-0.6B:Q8_0(32K)或任何支持 ≥512 个 token 的模型。
OpenAI
EMBEDDING_PROVIDER=openai
OPENAI_API_KEY=your_api_key_here
OPENAI_MODEL_NAME=text-embedding-3-small
KNOWLEDGE_BASES_ROOT_DIR=$HOME/knowledge_bases
若要连接 OpenAI 兼容端点,而非官方 API(例如可自托管的网关、火山引擎 Ark、OpenRouter),请将 OPENAI_BASE_URL 设为该端点的基础 URL,并包含 API 版本路径(OPENAI_BASE_URL=https://ark.cn-beijing.volces.com/api/v3)。留空则使用默认值 https://api.openai.com/v1。Azure OpenAI 只能通过其 /openai/v1/ API 兼容接口访问(OPENAI_BASE_URL=https://<resource>.openai.azure.com/openai/v1);传统 Azure 部署需要使用 api-key 进行身份验证、添加 api-version 查询参数,并使用每个部署对应的路径,因此不能通过普通基础 URL 访问。
默认模型已更改。 OpenAI 的默认模型现在是
text-embedding-3-small,此前为text-embedding-ada-002。两者都会生成 1536 维向量,但模型名称变更会触发 FAISS 在下次查询时进行一次重建。设置OPENAI_MODEL_NAME=text-embedding-ada-002可保留旧的默认模型。
HuggingFace(回退选项;如果不设置任何内容,则为默认值)
EMBEDDING_PROVIDER=huggingface # optional — this is the default
HUGGINGFACE_API_KEY=your_api_key_here
HUGGINGFACE_MODEL_NAME=BAAI/bge-small-en-v1.5
HUGGINGFACE_PROVIDER=hf-inference # optional router provider for serverless inference
KNOWLEDGE_BASES_ROOT_DIR=$HOME/knowledge_bases
只需一个免费的 HuggingFace API 密钥即可开始使用。
HuggingFace 已于 2025 年弃用旧版 api-inference.huggingface.co/models/... 端点。现在,特征提取请求会通过 Inference Providers 路由器发送至 https://router.huggingface.co/hf-inference/models/<model>/pipeline/feature-extraction。设置 HUGGINGFACE_PROVIDER 可选择其他受支持的提供商:together、replicate、fireworks-ai、sambanova、nebius、novita。HUGGINGFACE_API_KEY 可填写 Hugging Face 令牌或兼容的提供商密钥,具体取决于上游的请求身份验证方式。若要使用自托管或专用 Inference Endpoint,请将 HUGGINGFACE_ENDPOINT_URL 设为完整的 POST URL;指定端点 URL 后,将绕过路由器的提供商选择。
默认模型已更改。 HuggingFace 的默认模型现为
BAAI/bge-small-en-v1.5,此前为sentence-transformers/all-MiniLM-L6-v2。两者都会生成 384 维向量,但模型名称变更会在下次查询时触发一次 FAISS 重建。设置HUGGINGFACE_MODEL_NAME=sentence-transformers/all-MiniLM-L6-v2可保留旧的默认模型。
每种模型支持的默认值、向量维度、任务前缀要求和重新索引注意事项,请参阅 docs/reference/embedding-models.md。
整理知识库
在 KNOWLEDGE_BASES_ROOT_DIR 下为每个知识库创建一个子目录,例如 company/、it_support/、onboarding/,然后将笔记放入其中。子目录可以自由嵌套;服务会递归读取它们。
$HOME/knowledge_bases/
├── work/
│ └── runbooks/deploy.md
├── research/
│ └── papers/retrieval.md
└── .faiss/ # index storage, created for you
会建立索引的内容。 只有扩展名在允许列表中的文件才会被处理:.md、.markdown、.txt、.rst、.html、.htm。隐藏文件和目录(名称以 . 开头的内容)会被跳过,PDF、工作流旁文件(_seen.jsonl、_index.jsonl)、日志和暂存子目录(logs/、tmp/、_tmp/),以及操作系统杂项文件(.DS_Store、Thumbs.db、desktop.ini)也会被跳过。无扩展名文件(例如 README、LICENSE 或 Makefile)不会被嵌入。
若要扩大或缩小范围:
# Comma-separated extensions (case-insensitive; leading dot optional).
INGEST_EXTRA_EXTENSIONS=".json,.yaml"
# Comma-separated minimatch globs relative to the KB root.
INGEST_EXCLUDE_PATHS="drafts/**,scratch.md"
只有在确实需要提取 PDF 内容时才添加 ".pdf"。基础排除规则具有权威性:你可以添加更多排除项,但不能移除内置规则。完整的加载器和扩展名对照表请参阅 docs/reference/loaders.md。
文件如何变得可搜索。 对每个可导入文件,服务都会计算 SHA256 哈希值,并将其存储在文件旁的隐藏 .index/ 子目录中,以便后续检查文件自上次建立索引后是否发生变化。更改后的内容会被拆分为多个块:.md 文件使用可识别标题的 MarkdownTextSplitter,其他文件使用 RecursiveCharacterTextSplitter;两者的参数均为 chunkSize: 1000, chunkOverlap: 200,因此大型 .txt 或 .rst 文件会拆分为多个块,而不是生成一个模糊的嵌入向量。每个块都会被嵌入并添加到 FAISS 索引中。索引会在服务启动时初始化,并在服务发现文件变更时更新。
如何编写便于服务检索的笔记是一个独立主题:docs/authoring-knowledge.md 介绍了便于分块的 Markdown、frontmatter 分类体系、内容边界安全和笔记生命周期。
索引存储
FAISS 索引存放在 FAISS_INDEX_PATH 指定的位置,默认值为 $KNOWLEDGE_BASES_ROOT_DIR/.faiss。每种嵌入模型都会在其中拥有独立的子目录,因此注册第二种模型不会覆盖第一种模型的索引——请参阅比较嵌入模型。
多个进程共享索引路径。 多个 MCP 和 CLI 进程可以共享一个受信任的 FAISS_INDEX_PATH;写入操作会通过按模型设置的锁和带版本的原子保存进行串行处理。请将目录保存在本地可信位置,不要将其放在不受信任的对等方可以写入的文件系统上。请参阅安全性和 docs/architecture/threat-model.md。
日志记录与审计
LOG_FILE=/path/to/logs/knowledge-base.log会将结构化日志同步写入文件。日志详细程度由LOG_LEVEL=debug|info|warn|error设置,默认为info。日志绝不会写入 stdout,因为 stdout 用于传输 JSON-RPC 流。KB_MUTATION_AUDIT_LOG=/path/to/kb-mutations.jsonl会记录每次知识库内容写入,形成仅追加的账本。每行都会记录执行操作的界面(cli.kb-remember、cli.kb-capture、cli.kb-ask、mcp.add_document、mcp.delete_document)、操作、知识库和相对路径、时间戳、before_sha256/after_sha256、是否执行了写入和刷新,以及各界面的决策标记。绝不会存储笔记内容,只记录哈希和元数据。审计日志采用尽力而为的方式写入:写入失败时会向 stderr 记录警告,但绝不会中止正在记录的写入。知识库名称和路径是记录固有的信息,因此请将审计日志视为与知识库目录同等敏感。
自定义 MCP 工具描述
可以在服务启动前覆盖 AI 客户端看到的各个工具描述。如果部署只提供一个特定语料库,并且你希望模型使用恰当的工具,这样做很有用。未设置或留空时,会使用内置默认值。
RETRIEVE_KNOWLEDGE_DESCRIPTION="Search engineering runbooks, RFCs, and postmortems."
ASK_KNOWLEDGE_DESCRIPTION="Answer from engineering runbooks with citations."
LIST_KNOWLEDGE_BASES_DESCRIPTION="List available engineering knowledge bases."
LIST_MODELS_DESCRIPTION="List embedding models registered for engineering retrieval."
KB_STATS_DESCRIPTION="Report engineering KB index and transport health."
使用 MCP 服务
工具
客户端会看到以下工具(在 src/KnowledgeBaseServer.ts 中注册):
| 工具 | 用途 |
|---|---|
list_knowledge_bases | 查找现有哪些知识库,以便 Agent 在后续搜索时限定范围,而不是猜测名称。 |
retrieve_knowledge | 核心语义搜索工具——返回与查询最相关的段落,让 Agent 能基于你的文档生成回答,而不是依赖模型已有的知识。如果提供了 knowledge_base,则只搜索一个知识库;否则搜索所有知识库。默认最多返回 10 个分块。threshold 限定匹配结果与查询之间的最大距离(这是一个距离值,因此数值越低越接近);默认值 2 位于量表的最宽松一端,单独使用时很少排除任何结果——调低该值可收紧检索条件;也可参见相关性门控,了解专为此目的设计的阶段。在混合模式下不会应用阈值,因为融合前会对两路结果进行过量获取。 |
ask_knowledge | 检索内容,然后由已配置的本地或兼容 OpenAI 的 LLM 撰写带引用的回答——一次调用即可完成,无需先检索再输入提示词。 |
list_models | 列出已注册的嵌入模型及当前启用的模型。 |
kb_stats | 只读地查看语料库、索引、模型、缓存和传输统计信息——无需触及索引即可进行健康检查。 |
diff_index | 比较两个已持久化索引版本的检索结果,查看重建实际带来了哪些变化。 |
add_document | 通过受保护的变更路径向知识库写入文本文档。 |
delete_document | 通过受保护的变更路径删除知识库中的相对路径文档。 |
reindex_knowledge_base | 强制全局重建,并可选择先验证指定的知识库。 |
精确的输入架构、类型和取值范围由随附的工具注册表生成,详见 docs/reference/mcp-tools.md。
关闭写入(
KB_INGEST_ENABLED)。 最后 3 个工具——add_document、delete_document、reindex_knowledge_base——仅在KB_INGEST_ENABLED设为on时注册,该值默认为on。将其设为off可移除这 3 个工具,只保留严格只读的工具接口。对于共享或只读部署,如果 Agent 意外写入会造成严重后果,请这样设置。
资源
需要直接枚举和读取源文档,而不是搜索文档的客户端,可以使用 MCP 资源。resources/list 会为 KNOWLEDGE_BASES_ROOT_DIR 下每个可摄取且未隔离的文件返回 kb://<knowledge-base>/<encoded-relative-path> URI;resources/read 会以文本形式返回原始文档,或者在选择摄取 .pdf 文件时返回 base64 PDF 数据块。有关 URI、MIME 类型和百分号编码的详情,请参阅 docs/mcp-resources.md。
日志记录
该服务会声明标准 MCP logging 能力。HTTP 和 SSE 客户端可以调用 logging/setLevel,为其会话选择最低通知级别;stdio 会将此请求作为无操作处理。这与 KB_LOG_FORMAT 和 LOG_FILE 无关。请参阅 docs/mcp-logging.md。
结果示例
retrieve_knowledge 会返回一个 Markdown 字符串,每条匹配结果各占一个块:
## Semantic Search Results
**Result 1:**
[Content of the most similar chunk]
**Source:**
```json
{
"source": "[Path to the file containing the chunk]"
}
```
---
**Result 2:**
[Content of the second most similar chunk]
**Source:**
```json
{
"source": "[Path to the file containing the chunk]"
}
```
> **Disclaimer:** The provided results might not all be relevant. Please cross-check the relevance of the information.
每条结果都包含分块内容、源文件和相似度分数。当分块元数据包含行号时,源文件头会将稳定的分块句柄(例如 alpha/docs/deploy.md#L42-L78)链接到匹配的 kb://alpha/docs/deploy.md#L42-L78 资源 URI。在启动服务前,将 KB_EDITOR_URI 设为 vscode、cursor 或 file,还会生成包含本地绝对路径的编辑器打开链接;默认值 none 会让响应中不包含绝对路径。
错误代码
工具错误会以 isError: true 和 JSON 文本负载的形式返回,因此客户端可以根据稳定的代码分支处理,而不必匹配子字符串:
{
"error": {
"code": "PROVIDER_AUTH",
"message": "OPENAI_API_KEY environment variable is required when using OpenAI provider"
}
}
| 代码 | 含义 | 典型客户端操作 |
|---|---|---|
INDEX_NOT_INITIALIZED | FAISS 索引尚不可用时执行了搜索。 | 初始化完成后重试,或触发刷新。 |
PROVIDER_UNAVAILABLE | 嵌入提供方暂时不可用。 | 退避后重试。 |
PROVIDER_TIMEOUT | 嵌入提供方超时。 | 退避后重试。 |
PROVIDER_AUTH | 缺少提供方凭据或凭据无效。 | 请用户配置有效的 API 密钥。 |
KB_NOT_FOUND | 请求的知识库不存在。 | 提示选择列出的知识库之一。 |
PERMISSION_DENIED | 服务无法读取或写入所需的本地路径。 | 向操作员/管理员显示此错误。 |
CORRUPT_INDEX | 持久化的 FAISS 索引已损坏或无法读取。 | 重建或恢复索引。 |
VALIDATION | 调用方提供的参数未通过验证。 | 修正请求后重试。 |
INTERNAL | 发生了未分类的服务端错误。 | 显示错误信息和日志以供排查。 |
完整的错误分类(包括 CLI 本地错误代码)已生成到 docs/reference/error-codes.md。
使用 kb CLI
kb 读取与 MCP 服务相同的环境变量(KNOWLEDGE_BASES_ROOT_DIR、FAISS_INDEX_PATH、EMBEDDING_PROVIDER、OLLAMA_*、OPENAI_*、HUGGINGFACE_*),因此 MCP 服务运行正常后,CLI 也能正常运行。它面向两类用户:在终端操作的人,以及拥有 shell 工具但无法连接 MCP 的 AI Agent。
每条命令都有完整的生成式参考文档,见 docs/reference/cli.md — 下方的概览仅供了解,并不完整。
命令速查
| 任务 | 命令 |
|---|---|
| 查看现有内容 | kb list · kb stats · kb tags · kb where "<topic>" |
| 搜索 | kb search · kb open · kb related · kb explain |
| 使用大模型作答 | kb llm · kb ask |
| 收集证据 | kb research plan · kb research collect |
| 编写和整理笔记 | kb remember · kb capture · kb import-url · kb tag · kb promote · kb superseded · kb stale-check · kb quarantine · kb cite |
| 管理嵌入模型 | kb models · kb compare |
| 衡量质量 | kb feedback · kb eval · kb eval-gate |
| 运维和诊断 | kb doctor · kb config validate · kb serve · kb reindex · kb logs · kb diagnose · kb cache · kb verify |
| Shell 集成 | kb --help · kb help <command> · kb completion bash|zsh|fish |
搜索
kb search 默认为只读:它会加载现有索引,但不会重新扫描文件。想让它先检测编辑内容时,请传入 --refresh。输出末尾会显示新鲜度页脚,告知索引相对于文件修改时间是否为最新。
kb search "your query" # dense (semantic) search over all shelves
kb search "your query" --kb=work --k=5 # scope to one shelf, cap results
kb search "your query" --refresh # re-scan KB files first (this writes)
kb search "your query" --timing # per-stage elapsed milliseconds
kb search "your query" --explain-empty # deep diagnostics when nothing comes back
选择检索模式。 语义(“dense”)搜索会查找与你的查询含义相同的段落,这正是你提出自然语言问题时所需要的。它对精确令牌的检索能力较弱——例如文件路径、标志名称、错误代码——因为这些内容对嵌入模型来说几乎没有含义。--mode 用于选择策略:
| 模式 | 排序方式 | 适用场景 |
|---|---|---|
dense(默认) | 基于 FAISS 索引进行向量相似度匹配。 | 你用自然语言提出问题时。 |
lexical | BM25,即搜索引擎使用的经典关键词/词频排序方式。 | 你知道确切的字符串时——INDEX_NOT_INITIALIZED、src/cli.ts。 |
hybrid | 同时运行两种模式,并使用 RRF(倒数排名融合)合并两个排序列表。RRF 根据结果在各列表中的位置而非原始分数进行评分,因此无需对不可比的分数尺度进行归一化。 | 你想召回精确令牌,同时不放弃语义匹配时。 |
auto | 启发式策略:自然语言查询使用 dense;形似代码、路径、标志、错误代码或问题引用的查询使用 hybrid。 | 你不想费心选择时。 |
kb search "INDEX_NOT_INITIALIZED" --mode=lexical
kb search "retrieval benchmarks" --mode=lexical --lexical-unit=source # rank whole files, not chunks
kb search "INDEX_NOT_INITIALIZED" --mode=hybrid
kb search "src/cli-search.ts" --mode=auto
扩展匹配上下文。 一个分块大约有一千个字符,因此不错的匹配通常只是较长内容中的一部分。--context-before、--context-after 和 --context-window 会为每个 dense 匹配附加同一来源中相邻的分块——可阅读的内容更多,但后续查询更少。JSON 格式和权衡取舍请参阅 docs/search-neighbor-context.md。
kb search "runbook rollback" --context-window=1
调整结果集。 这些运算符都是附加式且只读的;每个运算符针对纯 top-k 结果可能不尽如人意的不同情况:
| 运算符 | 适用场景 |
|---|---|
--diverse | 你的排名靠前结果是来自同一文件的近似重复项,而你更希望看到不同来源的内容。它会对有限范围内的 dense 候选项重新排序,让结果覆盖更多来源文件。 |
--anti-query="<text>" | 你想让结果避开一个已知无关的相邻主题。与负向查询接近的候选项会受到惩罚,但仅限于正向查询本身已支持的候选项。 |
--plus="<text>" / --minus="<text>" | 你想调整查询本身,在查询向量中添加正向和负向成分,而不是事后筛选。 |
kb search "agent evidence" --diverse --format=json
kb search "agent evidence" --anti-query="frontend styling"
kb search "queue debt" --plus="slow loop" --minus="UI layout" --format=json
JSON 输出包含一个 advanced_retrieval 区块,用于说明模式、约束、查询成分和每个结果的评分信号,让你了解结果为何排在当前位置。
输出格式。
| 标志 | 格式 |
|---|---|
--format=md(默认) | 易于阅读的 Markdown 区块。 |
--format=json | 完整封装,包含分数、元数据和 advanced_retrieval 说明。 |
--format=compact | 每个命中项占一行,格式为 score|kb|path:line,适用于简洁的运维结果列表。 |
--format=vimgrep | 每个命中项占一行,格式为 path:line:col:preview,适用于编辑器快速修复列表。 |
--batch-jsonl | 从标准输入读取 {"query":"…","kb":"…","k":N} 记录,并为每行输出一个 JSON 封装。 |
printf '{"query":"q1"}\n{"query":"q2"}\n' | kb search --batch-jsonl
追溯结果来源。 只要分块包含 KB、路径和行范围,JSON 结果就会携带稳定的 chunk_id,例如 alpha/docs/deploy.md#L42-L78;缺少行元数据的分块则回退为 #chunk-N。
kb open alpha/docs/deploy.md#L42-L78 # resolve a chunk id, kb:// URI, or result path to a source file
kb related alpha/docs/deploy.md#L42-L78 # find dense neighbors of an existing result chunk
kb open 会根据 KB 根目录验证路径并将其打印出来;添加 --json 可获取引用的行范围和 editorUri。kb related 会根据句柄获取已索引的种子分块,以其文本进行搜索;除非传入 --include-self,否则会排除种子本身。
询问:从本地大模型获取答案
kb ask 保持检索过程确定,并在此基础上增加聊天步骤:先检索,再让兼容 OpenAI 的大模型生成带引用的答案。它接受与 kb search 相同的 --mode 值,以及 --rerank。
端点按以下顺序确定:--endpoint、KB_LLM_ENDPOINT、--llm-profile、当前启用的 kb llm 配置,最后是 127.0.0.1:8080 上的默认 local-research-agent 地址。(local-research-agent 是一个独立项目,用于运行本地 llama-server;kb 可以复用已运行的服务,也可以自行管理——见下文。)
kb llm use-endpoint http://127.0.0.1:8080/v1/chat/completions --profile=local-research-agent
kb llm status
kb ask "Which notes discuss reboot recovery?" --kb=operating-environment
kb ask "why does src/cli.ts throw?" --mode=hybrid --rerank
kb ask "what changed in the daemonization notes?" --timing
在 REPL 中迭代。 --interactive(-i)会启动多轮会话,而不是只回答一次:第一个问题会检索证据,后续问题会复用相同证据——不会重新检索——直到你要求重新扫描。对于深入探讨某个主题,这是更便捷的方式,因为每个后续问题都会跳过检索往返。在会话中可使用以下命令:
/sources— 显示上一个答案的引用。/kb <name>— 将检索范围限定为某个 KB 并重新检索;不带参数的/kb会显示当前范围。/refresh— 丢弃缓存的证据,以便下一个问题重新扫描并检索。/save [title]— 将上一次问答保存为转录笔记(需要通过--kb或/kb指定 KB)。/reset— 清除缓存的证据和对话历史。/help、/exit(别名/quit)。
交互模式需要 TTY;如果 stdin 通过管道传入或被重定向,则会退回为单次回答(并在 stderr 上显示提示)。
kb ask -i --kb=operating-environment
# > Which notes discuss reboot recovery? # first question retrieves evidence
# > What do they say about the watchdog timer? # follow-up reuses the same evidence
# > /refresh # drop cached evidence; next question re-retrieves
# > /exit
将答案保存为笔记。 --save-transcript --kb=<name> --yes 会将答案作为新的 Markdown 笔记写入该 KB,记录问题、答案、引用、来源块 ID、大模型端点/配置/模型、检索模型,以及在启用 --timing 时记录的计时元数据。--title=<title> 用于设置笔记标题和 slug。已有的转录笔记绝不会被覆盖。
kb ask "what changed?" --kb=work --save-transcript --title="Ask - daemon changes" --yes
避免在大模型提示词中使用某条笔记。 如果笔记的 frontmatter 包含 kb_policy: { no_llm_context: true },它仍会出现在搜索结果中,但 kb ask 和 MCP ask_knowledge 会在调用大模型前将其过滤,并在 context_packing.policy_filtered_chunks 中报告数量。摄取时的上下文前缀和相关性门控评估也会将其排除,但仍将该块保留为普通检索数据。
离线开发。 KB_LLM_FAKE=on 会将 kb ask、相关性门控评估和上下文前缀生成导向确定性的进程内伪造大模型——无需端点。如果客户端需要真正兼容 OpenAI 的本地主机端点,则运行 npm run dev:mockllm -- --port=18080。规则可通过 KB_LLM_FAKE_RULES 自定义;详见 docs/testing/fake-llm.md。
管理预热模型。 如果你希望 kb 管理模型进程,而不是复用他人运行的模型:
kb llm install --profile=qwen --runner=llama-server \
--bin=/path/to/llama-server --model=/path/to/model.gguf --port=8091
kb llm start --profile=qwen
kb llm set-model --profile=qwen --model=/path/to/other-model.gguf --start
kb llm uninstall --profile=qwen
外部配置仅供复用:kb llm stop、restart、uninstall 和 reap 不会停止由 local-research-agent 管理的服务。受管理的配置会使用 kb-llm@<profile>.service 作为命名空间,绑定到 127.0.0.1,并在用户状态目录下写入租约,因此可以回收已失效的受管理模型,而不是让它们永远驻留。
为一个宽泛的问题收集证据
kb research 是一项只读工作流,适用于需要先广泛收集证据,再撰写答案、RFC、评估计划或议题的 Agent shell。它刻意不调用大模型、不启动模型、不刷新索引,也不写入笔记——只读取并整理检索已有的信息。
先运行 plan,检查确定性的资料架和查询计划,然后运行 collect,将结果收集到运行目录中:
kb research plan "synthesize an end-to-end approach for autonomous research agents and evals" --format=json
kb research collect "synthesize an end-to-end approach for autonomous research agents and evals" \
--run-dir /tmp/kb-research-autonomous-agents-evals-20260521 \
--format=json
然后阅读生成的 evidence_packet.md,自行综合整理。运行目录中还包含 run.json、plan.json、ledger.json 和 events.jsonl:ledger.json 保留完整信息,便于审计和调试;而 evidence_packet.md 则是便于人工浏览的视图。JSON 契约和稳定的产物字段见 docs/cli-json-contracts.md;更详细的操作指南——包括何时使用、如何阅读数据包,以及下游的 kb ask 和 kb feedback 流程——见 docs/operations/research-workflow.md。
编写和整理笔记
这些命令允许 Agent shell 谨慎地为知识库补充内容。完整的任务导向工作流(从收集到标记、审阅和提升)见 docs/authoring-knowledge.md;机器可读的命令格式见 docs/cli-json-contracts.md。
kb remember — 创建或追加笔记。 --suggest 是安全的第一步:它会根据笔记文件名和标题列出可能的现有目标,不读取 stdin,也不写入笔记(但可能会刷新小型 .index 标题缓存)。实际写入需要同时指定 --stdin 和 --yes。创建时会使用 slug 化的 .md 文件名,并拒绝覆盖;追加时只接受知识库相对路径。追加操作会按目标串行执行,并通过临时文件、fsync 和原子重命名提交。
kb remember --suggest --kb=work --title="Quarterly plan"
printf '# Quarterly plan\n\n...' | kb remember --kb=work --title="Quarterly plan" --stdin --yes
printf '\nFollow-up note.\n' | kb remember --kb=work --append=quarterly-plan.md --stdin --yes
kb capture 会运行命令,并将其 stdout 以围栏代码块的形式追加到笔记中。默认情况下,它会同时对捕获的输出和显示的命令行中的常见凭据格式进行脱敏——只有确实需要原始文本时,才传入 --no-redact。成功写入后,可为任一命令添加 --refresh,以重新索引受影响的知识库。
kb import-url — 将网页或 PDF 快照为带来源信息的笔记。 它通过 http(s) 获取内容,并使用索引器采用的同一套加载器处理 HTML 和 PDF 响应;写入一篇笔记,其 YAML frontmatter 会记录 source_url、fetched_at、content_sha256、content_type、http_status 和 byte_count。
kb import-url --kb=research https://example.com/article
获取过程受到严格限制,因为 URL 是由攻击者控制的输入:只允许 http 和 https 协议;手动跟随重定向,并在每次跳转时重新验证(--max-redirects,默认值为 5);限制响应大小(--max-bytes,默认值为 8 MiB)和耗时(--timeout,默认值为 30000 ms);除非传入 --allow-local-network,否则拒绝私有、环回和链路本地地址(SSRF 防护)。笔记路径默认使用页面标题的 slug;使用 --note=<path.md> 指定路径,使用 --title 覆盖标题,使用 --refresh 在之后重新索引。若笔记已存在,则拒绝覆盖。
kb tag — 管理单篇笔记的 frontmatter 标签。 默认执行试运行;可重复使用 --add 或 --remove 指定多个标签,并传入 --yes,通过原子写入器和知识库的 .kb-policy.json 修改策略提交。笔记正文会逐字节保留;写入前会拒绝格式错误的 frontmatter。
kb tags --kb=work # list facet values (tags/status/type) with counts
kb tags --facet=status --format=json # discover the vocabulary for kb search --status filters
kb tag work/runbooks/deploy.md --add=verified # dry run
kb tag work/runbooks/deploy.md --add=verified --yes # commit
kb tags 会直接读取笔记文件,但现有索引只有在执行 kb search --refresh 后才会获知新增的标签值。
kb superseded — 查找已过时的笔记。 这是一项只读的“主动遗忘”审查:它会扫描 frontmatter,查找明确矛盾、已弃用或休眠的生命周期状态、过时的验证日期以及置信度较低的活动笔记;随后使用语义索引,在有依据时补充保守的新近邻证据。--format=json 适用于 Agent 工作流;--include-clean 会提供完整清单。
kb superseded --kb=work
kb promote alpha/docs/deploy.md # review and update lifecycle frontmatter on one note
kb stale-check --kb=work # find path / URL references that no longer resolve
kb quarantine list --kb=work # inspect per-file ingest quarantine entries
kb cite alpha/docs/deploy.md # export BibTeX or CSL-JSON from note frontmatter
比较嵌入模型
你可以并行保留多个嵌入模型,并按 ID 查询每个模型——无需丢弃现有可信索引,即可对比检索质量。
# List registered models. The * marks the active one.
kb models list
# Add a second model — embeds your KB once under the new model.
# For paid providers, prints an estimated cost and prompts before any HTTP traffic.
kb models add ollama nomic-embed-text # local, free
kb models add openai text-embedding-3-small # paid; estimate first
kb models add huggingface BAAI/bge-small-en-v1.5
kb models add ollama nomic-embed-text --index-type=sq8 # FAISS scalar quantization
kb models add ollama nomic-embed-text --index-type=hnsw # HNSW approximate search backend
# Query a specific model without changing the default.
kb search "your query" --model=openai__text-embedding-3-small
# Side-by-side comparison: unified rank/score table over both models' top-k.
kb compare "your query" ollama__nomic-embed-text-latest openai__text-embedding-3-small
# Switch the default model.
kb models set-active openai__text-embedding-3-small
# Remove a model (refuses to remove the active one).
kb models remove huggingface__BAAI-bge-small-en-v1.5
模型 ID 及其存储路径的生成方式:
- ID 格式 —
<provider>__<filesystem-safe-slug>,根据(provider, model_name)确定性生成,且严格保留你输入的内容。OLLAMA_MODEL=nomic-embed-text:latest会变为ollama__nomic-embed-text-latest。 - 磁盘路径 — 每个模型存储在
${FAISS_INDEX_PATH}/models/<id>/。 - 活动模型 — 记录在
${FAISS_INDEX_PATH}/active.txt中;可通过KB_ACTIVE_MODEL按进程覆盖。 - 索引类型 — 使用
KB_INDEX_TYPE或kb models add --index-type=flat|sq8|hnsw设置,详见 docs/operations/index-quantization.md。
支持的默认值、向量维度、任务前缀要求和重新索引注意事项,请参阅 docs/reference/embedding-models.md;设计方案请参阅 RFC 013。
从单模型布局升级。 首次启动服务或
kb时会自动迁移:现有的单模型索引会移至${FAISS_INDEX_PATH}/models/<derived_id>/,并写入active.txt。并发启动通过${FAISS_INDEX_PATH}/.kb-migration.lock协调。如果需要回滚,请备份原来的${FAISS_INDEX_PATH}。在 MCP 侧,此变更是增量式的:retrieve_knowledge新增了可选的model_name,新增了list_models,而kb_stats现在会在last_index_update下报告进程内最近一次updateIndex的摘要。不传递model_name的工具行为完全不变——线缆格式与 0.2.x 逐字节相同。
衡量检索质量
kb feedback — 记录评估结果,再将其转化为测试。 每条评估结果都会追加到每个 KB 专属的记录文件 <kb>/.index/relevance-feedback.jsonl 中。promote 会将某个查询的所有记录行转换为检索评估用例,让累积的人类评估结果成为回归覆盖,而不是随时间流失。
kb feedback add --kb=work --query="rollback procedure" \
--source=runbooks/deploy.md --verdict=relevant # also: irrelevant | stale | misleading
kb feedback add --kb=work --query="rollback procedure" \
--source=runbooks/deploy.md --verdict=relevant \
--relevance=3 --chunk-id=work/runbooks/deploy.md#L42-L78 # graded 0..3, pinned to one chunk
kb feedback list --kb=work
kb feedback promote --kb=work --query="rollback procedure" \
--fixture=docs/testing/feedback-fixture.yml --yes
请参阅 docs/operations/feedback-workflow.md。
kb eval — 运行由固定用例驱动的检索检查。 用例可以设置 query,并可选设置 kb、required_sources、forbidden_sources、expected_metadata、max_duplicate_groups、stale_policy 和 gate。用例的 gate 字段与相关性门控无关——这里表示“此用例失败是否应导致构建失败”。未设门控的用例失败时会打印警告并以状态码 0 退出;设有门控的用例失败时会以状态码 1 退出,因此可用于 CI。
gate: false
cases:
- name: deployment runbook
query: rollback procedure
kb: work
gate: true
required_sources: [runbooks/deploy.md]
forbidden_sources: [archive/old-deploy.md]
expected_metadata:
frontmatter.status: approved
max_duplicate_groups: 1
stale_policy: fresh
kb eval-gate — 在信任相关性门控前对其进行验证。 使用带标签查询的固定用例端到端运行门控(包含一个统计下限,以及可选的大模型裁判),并报告各阶段的精确率、召回率和空结果率。每当更改 KB_GATE_* 调优参数或裁判提示词时,都应运行此命令。
kb eval retrieval-eval.yml
kb eval-gate docs/testing/fixtures/rfc-018-gate-eval/queries.yml
请参阅 docs/operations/eval-gate-harness.md。
运维与诊断
kb doctor # availability snapshot: index, embedding backend, LLM
kb config validate # static env-var schema validation before startup
kb serve # loopback daemon for warm reads; --warm pre-loads indexes
kb serve status # daemon liveness and degraded-mode diagnostics
kb reindex --with-context # rebuild the index with contextual prefaces
kb reindex status --format=json # ledger of recent and in-flight reindex passes
kb logs show --request-id=<id> # read canonical request logs by id
kb logs recent --limit=20 --format=json
kb diagnose --request-id=<id> --repro-bundle=/tmp/kb-diag
kb cache list # inspect local cache surfaces
kb cache prune # prune stale cache entries
kb verify # slow integrity checks for persisted indexes and sidecars
kb serve 会运行一个环回守护进程,供使用 --daemon 的客户端执行热读取,避免每次调用查询时都要等待模型和索引加载。运行 kb serve [--host=127.0.0.1] [--port=17799] [--idle-timeout-ms=300000] [--warm] 即可启动;--warm(或 KB_DAEMON_PREWARM=on)会预加载当前活动模型、FAISS 索引和词法索引,然后报告就绪。kb serve status [--json] 会在 KB_DAEMON_URL(默认值为 http://127.0.0.1:17799)处报告可达性、pid、空闲超时、支持的命令、预热状态,以及(守护进程提供此信息时)准入负载——进行中的请求数、拒绝数、并发上限和队列大小。发送 SIGINT 或 SIGTERM 即可停止守护进程;如果守护进程无法访问,CLI 命令会退回到进程内直接执行。请参阅 docs/operations/daemon-lifecycle.md。
kb reindex 会重建索引。--with-context 会添加上下文前缀(需要设置 KB_CONTEXTUAL_RETRIEVAL=on 和 KB_LLM_ENDPOINT)。kb reindex status 会读取持久化的运行状态和各来源的 sidecar 记录,报告运行状态、符合条件的已索引文件、sidecar 覆盖情况、待处理文件、已解析和失败的分块,以及失败代码。请注意,--kb=<name> 仅作为保护条件和估算提示——重建始终会覆盖整个按模型单索引的布局(RFC 017 §5)。
kb logs 会读取在 KB_LOG_FORMAT=canonical 或 both 下生成的结构化请求日志。kb logs show --request-id=<id> 会提取一次检索的所有日志行;--query-sha=<hash> 可追踪重复查询;kb logs recent --limit=<n> 会显示最新条目。--format=json 会输出报告封装;--format=csv|tsv|ndjson 会输出扁平事件行,供下游工具使用。
kb diagnose 会将某个请求的规范事件打包为经过脱敏的私密文件包,以便在问题报告中分享。规范日志不会存储原始查询文本,因此,如果还希望使用从日志事件推断出的模型、知识库范围、k 值和阈值提示,通过 kb explain --repro-bundle 重放查询,请传入 --query、--query-file 或 --stdin。
调整检索质量
纯稠密检索是默认模式,无需配置。它周围还设有五个阶段。其中四个默认关闭,因为每个阶段都需要付出一定代价才能提升精确率或安全性,应由你审慎决定是否启用;第五个阶段——不可信内容防护——默认开启。完整的标志矩阵(包括默认值、单次调用覆盖项、推出状态和验证命令)请参阅 docs/feature-flags.md。
入库时添加上下文前缀
将笔记分块后,会拆成约 1000 个字符的片段,嵌入模型会单独处理每个片段。因此,一段这样的内容:
“我们将它固定到 CPU 上,因为这张 24 GB 显卡已经被门控模型占满了。”
并未包含让它易于检索的关键信息:固定的是哪个服务、哪张显卡、哪个模型。它的向量会靠近其他关于“固定”的段落,而不是靠近运维人员实际会输入的 GPU 资源争用问题。笔记虽然已建立索引,但实际上仍然无法检索到。
上下文前缀可以在入库时解决这个问题,而不是等到查询时再处理。在嵌入片段之前,大模型会生成一段简短文字(约 50–100 个 token),描述该片段在文档中的位置,并将这段文字加到待向量化文本的开头。这样,片段嵌入所表达的就是它讨论的内容,而不只是它字面上写了什么。发布这项技术的 Anthropic 在一个代码与散文基准测试中测得,前 5 项检索失败率降低了 49%。
启用前有两点值得了解。返回给调用方的文本不会改变——前缀只会影响向量,不会影响 retrieve_knowledge 或 kb search 返回的内容。此外,这确实会产生开销:每个片段在入库时都要调用一次大模型。生成的前缀会缓存在每个来源对应的 sidecar 文件中,因此重新建立索引时,只需为实际发生变化的片段付费。
KB_CONTEXTUAL_RETRIEVAL=on # plus a KB_LLM_ENDPOINT to generate against
kb reindex --with-context # backfill existing shelves
kb reindex status # sidecar coverage, pending files, failures
设计和发布详情见 RFC 017。
交叉编码器重排序
密集检索会分别计算查询和每个片段的得分,然后比较两个向量——这很快,因为片段向量在建立索引时只计算一次,但模型从未同时看到查询和片段。交叉编码器则会同时读取二者,并直接为匹配度评分,因此精度明显更高,但在整个语料库上运行又太慢。重排序兼得两者之长:先用密集检索(或混合检索)选出候选短名单,再用交叉编码器仅对这份短名单重新排序。
设置 KB_RERANK=on 可启用此功能,也可在每次调用时使用 kb search --rerank / kb ask --rerank。每次查询会增加少量延迟。
| Env var | Description | Default |
|---|---|---|
KB_RERANK | 启用交叉编码器重排序阶段。 | off |
KB_RERANK_MODEL | 用于重排序的交叉编码器模型 ID。 | (内置默认值) |
KB_RERANK_TOP_N | 提交给重排序器的候选项数量。 | (内置默认值) |
KB_RERANK_SKIP_DOMAINS | 以逗号分隔的知识库域名列表;这些域名将跳过重排序。 | (无) |
KB_RERANK_DEVICE(cuda、cpu)和 KB_RERANK_DTYPE(fp32、……)是可选的 Transformers.js / ONNX Runtime 覆盖设置,用于控制交叉编码器的执行方式——需要针对特定运行时进行加速或控制数据类型时,可设置这些变量。两者均列在 kb config show 的输出中,并由 kb config validate 验证。设计详情见 RFC 019。
相关性门控
检索总会返回一些内容:询问笔记未涵盖的主题,仍然会得到匹配度最低的十个片段。检索时的相似度阈值帮不上忙——它默认处于距离尺度的最远端,很少排除任何内容(参见 retrieve_knowledge)。这些片段传给大模型后,会被视为权威上下文,悄然影响答案。相关性门控会在检索和使用之间增加一道检查——先设置统计评分下限,然后可选用大模型评判——丢弃与任务实际不匹配的片段;必要时宁可什么都不返回,也不返回错误内容。
这确实存在取舍:门控也可能丢弃真正相关的片段,以提高精确率为代价降低召回率。因此,除非你选择启用,否则它默认关闭。
KB_RELEVANCE_GATE=on # enable for a whole process
kb search "…" --gate # enable for one call
kb search "…" --no-gate # bypass in a process where it is enabled
评判器会从 --task-context=<text> / --task-context-file=<path>(MCP:task_context)获取任务描述,并读取 KB_GATE_LLM_ENDPOINT / KB_GATE_LLM_MODEL;若未设置,则回退到 KB_LLM_ENDPOINT / KB_LLM_MODEL。MCP 调用方可以传入 gate: "off" 以绕过门控。
| 环境变量 | 含义 | 默认值 |
|---|---|---|
KB_GATE_SCORE_FLOOR | 片段必须达到的统计评分下限。 | 0.95 |
KB_GATE_JUDGE_INPUT | 送交大模型评判器的剩余片段数量。 | 10 |
KB_GATE_LLM_TIMEOUT_MS | 评判调用超时时间。 | 8000 |
KB_GATE_MIN_TASK_TOKENS | 启动评判所需的任务上下文最小长度。 | 8 |
KB_GATE_EMPTY_VERDICT | 允许门控不返回任何上下文。 | off |
只有在你能接受调用方收到零条检索上下文后,才启用 KB_GATE_EMPTY_VERDICT。在依赖任何调优改动之前,先用 kb eval-gate 进行验证;设计说明见 RFC 018。
摄取时的密钥扫描
从终端和日志中捕获的笔记有时会包含凭据。设置 KB_INGEST_SECRET_SCAN=on,即可在嵌入之前扫描片段文本和 frontmatter 中类似凭据的内容。命中项会以原因 secret_detected 隔离,并在任何 FAISS 写入前跳过,因此密钥不会进入索引。
kb quarantine list --reason=secret_detected
仅对有意存储凭据示例的知识库使用 KB_SECRET_SCAN_BYPASS_KBS=trusted-kb,...。参见 摄取时的密钥扫描。
不可信内容防护
检索到的任何内容都会被粘贴到大模型的上下文中,因此,包含“忽略之前的指令”的笔记可能成为注入向量,攻击提出问题的 Agent。每个检索到的片段都会经过不可信内容防护;该防护会扫描提示词注入信号——系统角色标记、覆盖指令的措辞、Unicode 双向 / 零宽 / 标签控制字符——并标记检测到的内容。
与其他三个阶段不同,此阶段默认开启(KB_INJECTION_GUARD=tag):
| 值 | 行为 |
|---|---|
tag(默认) | 在片段元数据中标注检测到的内容。 |
wrap | 用哨兵字符串围住内容,以便下游提示词能够区分数据和指令。 |
both | 同时执行以上两项。 |
off | 不进行扫描。 |
仅对你完全掌控的知识库设置 off;或者使用 KB_INJECTION_GUARD_BYPASS_KBS=trusted-kb,... 豁免特定知识库,而不削弱全局默认设置。
远程传输(可选)
默认情况下,服务通过 stdio 使用 MCP——每个受支持的客户端(Claude Desktop、Codex、Cursor、Continue、Cline)都会将其作为子进程启动,这种方式适合单用户本地工具。RFC 008 增加了可选的 SSE 和 streamable HTTP 传输方式,供基于浏览器的客户端、Smithery 远程模式和共享部署使用。除非设置 MCP_TRANSPORT,否则 stdio 行为保持不变。
export MCP_TRANSPORT=http # stdio (default), sse, or http
export MCP_AUTH_TOKEN="$(openssl rand -base64 32)" # must be ≥32 characters; shorter tokens abort startup
# Or MCP_AUTH_TOKEN_FILE=/run/secrets/kb-mcp-token to read the token from a file; takes precedence over MCP_AUTH_TOKEN
export MCP_ALLOWED_ORIGINS="http://localhost:5173" # comma-separated; unset denies all browser origins
export MCP_PORT=8765 # default
export MCP_BIND_ADDR=127.0.0.1 # default — loopback only
export MCP_AUTH_BACKOFF_THRESHOLD=5 # failed bearer attempts before backoff; 0 disables
export MCP_AUTH_BACKOFF_MS=30000 # Retry-After window for auth backoff
node build/index.js
此模式下的端点:
| 端点 | 身份验证 | 用途 |
|---|---|---|
GET /health | 无 | 存活探针。返回 200 {"status":"ok"},不包含其他内容——对于匿名调用者,不提供版本、运行时间或文件系统指纹(RFC 008 §6.8)。 |
GET /ready | bearer | 面向运维人员和反向代理的就绪探针。当活动模型解析成功、活动索引文件存在,且嵌入后端能响应一条简短的冒烟测试查询时返回 200;否则返回 503,仅列出未通过检查的名称。 |
GET /sse + POST /messages?sessionId=<uuid> | bearer | MCP_TRANSPORT=sse:长连接流,以及该会话的 JSON-RPC 消息。 |
POST /mcp | bearer | MCP_TRANSPORT=http:streamable HTTP。服务会在初始化期间返回 Mcp-Session-Id;客户端必须在后续的 GET、POST 和 DELETE /mcp 请求中发送该标识。 |
除健康检查端点外,所有端点(包括 /ready)都需要 Authorization: Bearer <token>。MCP_AUTH_TOKEN_FILE 会从挂载的密钥文件读取令牌——读取的内容会去除首尾空白,长度仍须至少为 32 个字符,且优先级高于 MCP_AUTH_TOKEN。来自同一远程地址的重复 bearer 身份验证失败会触发有界的内存退避,并收到 Retry-After;身份验证成功后会清除此地址的状态。在反向代理后,退避键使用代理的套接字地址,而非 X-Forwarded-For,因此对于任何面向互联网的部署,请在代理侧配置限流。
安全默认设置。 在 SSE 或 HTTP 模式下,如果未设置 MCP_AUTH_TOKEN 或 MCP_AUTH_TOKEN_FILE,服务将拒绝启动;服务仅绑定到环回地址,并以恒定时间比较 bearer 令牌。若要将其暴露给主机之外的访问者,请设置 MCP_BIND_ADDR=0.0.0.0 并且在反向代理中终止 TLS——TLS 不在本服务的范围内。
开发期间如需临时试验环境,请使用 npm run dev:remote(参见本地开发)。
基准测试
npm run bench:beir 会运行本地 BEIR 检索基准测试,使用无需凭据的词法检索,让你可以衡量分块或排序的改动,而不是靠猜测:
npm run bench:beir -- --dataset=scifact --split=test --mode=lexical --lexical-unit=source --output-dir=/tmp/kb-beir-scifact
运行器会构建一个临时 KB 根目录,并输出指标 JSON 和 TREC 运行文件,以及复现所需的元数据:git SHA、命令、数据集校验和、运行时版本、分块配置和延迟百分位数。这些是本地产物,不是官方 BEIR 排行榜提交——词法来源路径按文档级别评分,与 kb search --mode=lexical --lexical-unit=source 一致。有关冒烟测试命令和注意事项,请参见 benchmarks/README.md;已归档的 SciFact 运行结果请参见 benchmarks/results/README.md。
要端到端复现已提交的 dense / small-model 数值(使用 Ollama 上的 nomic-embed-text,涵盖 BEIR、MTEB 和 BRIGHT),请按照 benchmarks/REPRODUCE.md 中的分步操作指南进行。
Optuna 调优是可选的,仅在你主动调用时运行。它会扫描词法分块参数,并写入可重放的最佳配置文件:
npm run bench:tune -- \
--trials=12 \
--direction=maximize \
--metric=metrics.ndcgAt10 \
--study-name=scifact-lexical \
--best-config-out=/tmp/kb-scifact-lexical-best.json \
--param-int=KB_CHUNK_SIZE=256:1024:128 \
--param-int=KB_CHUNK_OVERLAP=0:128:32 \
-- npm run bench:beir -- --dataset=scifact --split=test --mode=lexical --max-queries=25 --output-dir=/tmp/kb-scifact-tune
重放最佳试验无需安装 Optuna:
npm run bench:tune -- --replay-config=/tmp/kb-scifact-lexical-best.json
故障排查
请先查看以命令为导向的操作手册 docs/troubleshooting-local-kb.md——其中涵盖结果为空、索引过期页脚、关联检出与全局二进制文件不一致、缺少活动模型、后端可用性以及刷新锁竞争。处理实时故障时,请按症状查阅 docs/operations/incident-response.md。有关 Ollama、llama-server、n8n、systemd 用户单元、远程传输或 kb serve,请参阅本地服务操作手册。
从 kb doctor 开始
当 kb search(或 MCP retrieve_knowledge 工具)没有返回结果时,请先运行只读的 kb doctor。它是检索可用性的权威检查,也会报告 kb ask 的本地 LLM 就绪情况。
kb doctor # human-readable report
kb doctor --format=json # machine-readable, for agent shells
完整报告涵盖四个方面:
- 检索就绪情况——活动模型解析、FAISS 索引版本和 mtime、最新的进程内索引更新摘要,以及各知识库的过期计数。
- 后端可达性——嵌入提供方(Ollama / HuggingFace / OpenAI),以及
kb ask和相关性门控的 LLM 端点。 - LLM 使用计数器,按操作细分——调用次数、错误数、p95 延迟、报告的令牌总数、尝试次数和重试次数、缓存命中结果,以及答案实际因此发生变化的频率。提供方和模型的归属统计设有上限:只按名称跟踪使用最多的少数几项,因此长尾模型不会让计数器集合无限增长。
- 本地安装状态——CLI 版本和本地 git 状态,可用于发现指向过期检出目录的全局
kb二进制文件。
必需的检索检查失败时,命令会以非零状态码退出——例如活动模型无法解析、索引缺失或后端不可达。LLM 端点故障只会显示为 WARN 行,因为搜索完全可能运行正常,而 kb ask 或可选门控尚未就绪。
四种专用模式可回答范围更窄的问题,无需加载完整的运行状况报告:
| 命令 | 适用场景 |
|---|---|
kb doctor --endpoints | 只需确认已配置的本地端点是否可达,以便启动客户端或进行连接配置。检查 MCP 绑定地址/端口是否可用、KB_DAEMON_URL 的运行状况、Ollama 嵌入可达性、KB_LLM_ENDPOINT 或活动 LLM 配置,以及启用门控时的 KB_GATE_LLM_ENDPOINT。门控已禁用、未设置其端点或正在使用虚假评估器时,会跳过门控行。 |
kb doctor --locks | 刷新或模型写入操作报告锁竞争时使用。扫描各模型的 .kb-write.lock 路径,并报告锁定时长、新锁记录的所有者 PID 和命令、疑似过期状态以及保守的后续操作建议——绝不会删除锁文件。 |
kb doctor --kb-symlinks | 审查知识库内容根目录时使用。通过 lstat 扫描,不跟随符号链接目录,并将目标分类为根目录内、越出根目录、失效或循环/错误,同时限制示例数量。 |
kb doctor --bug-report=/tmp | 准备提交问题或向其他运维人员提供诊断信息时使用。会生成一个带时间戳的目录,其中包含经过脱敏的 doctor.json、stats.json、近期规范日志摘要、运行时和环境元数据,以及 README。不会包含笔记内容和原始 API 密钥,但知识库名称、路径、模型名称和日志元数据仍可能包含敏感信息。 |
了解搜索失败
kb search 失败分为六类,帮助你或 Agent 无需阅读堆栈跟踪即可判断需要修复什么。每种失败都包含一个稳定的 code、一个 category、一条易读的 message,以及具体的 next_action。
| 类别 | 常见代码 | 建议尝试 |
|---|---|---|
configuration | PROVIDER_AUTH、KB_NOT_FOUND、ACTIVE_MODEL_UNRESOLVED | 设置缺失的 API 密钥,运行 kb list / kb models list,或运行 kb models set-active <id>。 |
indexing | INDEX_NOT_INITIALIZED、CORRUPT_INDEX | 使用 kb search --refresh 创建或重建索引。 |
provider | PROVIDER_UNAVAILABLE、PROVIDER_TIMEOUT | 确认嵌入后端可访问(ollama serve、提供商状态页)。 |
permissions | PERMISSION_DENIED | 授予 $FAISS_INDEX_PATH 和每个知识库的 .index/ 写入权限。 |
input | VALIDATION | 调整消息中指出的被拒绝字段。 |
lock | REFRESH_LOCK_BUSY | 稍后重试;每个模型同时只能有一个 kb search --refresh 写入进程运行。 |
使用 --format=md 时,错误会输出到 stderr,格式为 kb search: <message>,后面跟着 category: 和 next: 行。使用 --format=json 时,错误会输出到 stdout,格式为 {"error":{"code","category","message","next_action",...}},Agent 可以据此按类别分支处理。如果原因不明确,next_action 会回退为 kb doctor。退出代码遵循 CLI 约定:配置和输入问题(无需重试即可修复)返回 2;运行时、索引、提供商、权限和锁问题返回 1。
其他提示
- 设置
LOG_FILE以记录结构化日志。JSON-RPC 通信仍使用 stdout,因此这对诊断 MCP 握手错误尤其有用——所有诊断消息都会发送到 stderr 和可选的日志文件。 - 创建或更新索引时发生的权限错误会在控制台和日志文件中明确显示。请确认进程可以写入
FAISS_INDEX_PATH,以及每个知识库内的.index/目录。 npm test会构建项目,先运行带有--maxWorkers=4的并行 Jest 项目,再运行带有--runInBand的串行项目。测试套件涵盖日志记录器回退行为和 FAISS 权限处理。
安全性
此服务旨在作为本地工具运行:单个用户、单台机器、一个可信终端。在实际使用中,有两个信任边界需要注意。
$FAISS_INDEX_PATH 是代码执行边界。 FaissStore.load 会通过 pickleparser 反序列化 docstore,因此该目录中只能包含此服务写入的文件——不得放入不可信的备份,也不得使用共享写入挂载。多个 MCP 和 CLI 进程可以共用一个可信索引路径;写入操作通过每模型锁和原子保存进行协调。
$KNOWLEDGE_BASES_ROOT_DIR 是内容边界。 其中的内容会被嵌入,并原样返回给 MCP 客户端,因此来自不可信来源的 Markdown 可能对使用结果的 Agent 构成提示注入风险。不可信内容防护机制默认会缓解此风险,但无法彻底消除风险。
完整说明——包括提供商密钥处理、路径验证、远程传输策略和并发处理——请参阅 docs/architecture/threat-model.md。
文档导航
docs/ 中有完整索引。以下是最常用的文档:
| 如果你想…… | 请阅读 |
|---|---|
| 配置特定的 MCP 客户端 | docs/clients.md |
| 编写便于检索的笔记 | docs/authoring-knowledge.md |
| 查找任何命令、标志、环境变量、工具、指标或错误代码 | docs/reference/ — 根据源代码生成,因此内容始终保持同步 |
| 查看所有检索标志及其默认值和发布状态 | docs/feature-flags.md |
| 根据 CLI JSON 输出编写脚本 | docs/cli-json-contracts.md |
| 运行或恢复部署 | docs/operations/ |
| 了解系统的构建方式 | docs/architecture/ |
| 了解采用这种构建方式的原因 | docs/rfcs/ 和 docs/architecture/adr/ |
关于“RFC NNN”的说明。 本项目中重要的设计决策会以编号 RFC 的形式记录在
docs/rfcs/下——这是本仓库自己的设计文档系列,并非 IETF 文档。上文引用某个 RFC 时,指的是某项功能背后的完整设计依据,而不是使用该功能所必读的内容。
贡献
贡献流程请参阅 CONTRIBUTING.md,有关架构、约定和验证步骤的面向 Agent 指南请参阅 CLAUDE.md。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。