独立知识库 RAG 插件(Claude Code / CodeBuddy),同时作为 specode
distill的可选下游消费者。
ragkit 提供向量 + 词汇 + 元数据三路召回,RRF 融合后返回定位卡片。核心仅依赖 stdlib + numpy;向量路按需接入本地模型(via uv sidecar)或第三方 OpenAI 兼容 API,无后端时自动降级。
- 独立 RAG:脱离 specode 独立使用,直接对任意
cases/*.md + navigation/*.md结构的知识库做检索。 - specode 可选消费:specode
distill产出的knowledge-base/目录即是 ragkit 的输入。安装 ragkit 并构建索引后,specode 会在 requirements / design 阶段的 Tier-0 RagKit gate 自动调用ragkit:query多路召回,注入知识点定位指针;未安装或未建索引时零成本跳过。 - 零重型依赖:词汇 + 元数据路仅需 stdlib + numpy,
embed返回退出码 3 时仍可完整使用这两路;向量路按后端可用情况自动激活。
ragkit 脚本头部声明了 PEP 723 内联依赖(# dependencies = ["numpy"]),可直接用 uv run 免安装虚拟环境:
# 词汇/元数据路 + 索引操作(只需 numpy)
uv run plugins/ragkit/scripts/ragkit.py embed --kb <知识库路径>安装约 1.2GB 的本地 embedding 模型(默认 Qwen/Qwen3-Embedding-0.6B):
uv run plugins/ragkit/scripts/ragkit_local_embed.py install
# 直连超时再尝试镜像(若镜像报 connect 错误,去掉该变量直连——
# 镜像 308 跳转与新版 huggingface_hub 不兼容,install 会自动直连重试)
export HF_ENDPOINT=https://hf-mirror.com
uv run plugins/ragkit/scripts/ragkit_local_embed.py installuv run plugins/ragkit/scripts/ragkit.py backend set \
--provider qwen --kb <知识库路径>
export DASHSCOPE_API_KEY=<你的密钥>内置 preset(--provider 可选值):
| preset | model | key_env | 单请求上限 |
|---|---|---|---|
openai |
text-embedding-3-small | OPENAI_API_KEY |
高(可调大 batch_size) |
qwen |
text-embedding-v4 | DASHSCOPE_API_KEY |
10 条/请求(硬上限) |
zhipu |
embedding-3 | ZHIPUAI_API_KEY |
视文档 |
voyage |
voyage-3 | VOYAGE_API_KEY |
视文档 |
azure |
text-embedding-3-small | AZURE_OPENAI_API_KEY |
高 |
自定义端点:--base-url <url> --model <model> --key-env <ENV_VAR>(任何 OpenAI 兼容接口均可)。
密钥只通过环境变量传入,不落盘。
密钥读取自 key_env 指定的环境变量。临时(仅当前终端会话有效):
# macOS / Linux (bash/zsh)
export DASHSCOPE_API_KEY=<你的密钥># Windows PowerShell
$env:DASHSCOPE_API_KEY = "<你的密钥>"永久 / 全局(新开终端也生效,推荐):
# Windows —— 写入用户环境变量,设完需【新开】终端才生效
setx DASHSCOPE_API_KEY "<你的密钥>"# macOS / Linux —— 追加到 shell 配置后 source 生效
echo 'export DASHSCOPE_API_KEY=<你的密钥>' >> ~/.zshrc && source ~/.zshrc
⚠️ 未设置密钥时后端解析会跳过云端;若本地模型也未缓存则降级为词汇+元数据路。 query 时云端调用失败(密钥失效/网络异常)不再崩溃,自动降级并在 stderr 提示。
后端解析优先级为「本地已缓存 > 云端」。若本地已装过模型、但想强制用云端,在 <知识库路径>/.ragkit/config.json 显式指定:
{
"backend": "cloud",
"cloud": { "provider": "qwen", "base_url": "...", "model": "text-embedding-v4", "key_env": "DASHSCOPE_API_KEY" }
}云端每次请求最多上传 batch_size 条文本,默认 10(DashScope text-embedding-v4 兼容模式硬上限,超出返回 400 InvalidParameter)。OpenAI 等端点上限更高,可在 cloud 配置里加 "batch_size": 64 减少请求次数、加快 embed:
{ "cloud": { "provider": "openai", "...": "...", "batch_size": 64 } }切换后端或改 batch 后,需
embed --rebuild重建索引(向量维度/模型空间不同,旧向量不可混用)。
仅需 numpy,可用系统/项目虚拟环境回退:
pip install numpy
python plugins/ragkit/scripts/ragkit.py embed --kb <知识库路径>注意:无 uv 时本地模型路不可用(sidecar 需 uv run);向量路请改用第三方 API。
uv run plugins/ragkit/scripts/ragkit.py embed --kb <知识库路径> [--rebuild]- 默认增量:只重嵌变更 chunk;模型/后端切换或索引损坏时加
--rebuild全量重建。 - 索引写入
<知识库路径>/.ragkit/;knowledge-base/.gitignore应包含.ragkit/(embed 自动写入)。 - 退出码 3 = 无向量后端:词汇 + 元数据索引已建好,
query可降级使用;stdout 的 ╭─ RagKit ─╮ 提示块原样转述给用户(不改写、不省略),含本地模型安装命令与第三方配置步骤。
插件调用(Claude Code / CodeBuddy):
/ragkit:embed [--rebuild]
uv run plugins/ragkit/scripts/ragkit.py query '<检索词>' \
--kb <知识库路径> [--top N] [--channels lexical,metadata] [--json]- 三路(向量 + 词汇 + 元数据)RRF 融合,返回定位卡片。
--channels lexical,metadata强制走词汇 + 元数据路(无向量基线场景)。--json输出结构化 JSON,适合程序化消费;默认输出 Markdown 卡片。- 卡片是定位指针,非事实来源——命中后用「路径」读原文再验证。
插件调用:
/ragkit:query <检索词>
uv run plugins/ragkit/scripts/ragkit.py status \
--kb <知识库路径> [--json]关键字段解读:
| 字段 | 含义 |
|---|---|
n_docs_on_disk |
磁盘上 cases/ + navigation/ 的 md 文件总数 |
n_docs_indexed |
当前索引覆盖文档数 |
index_stale |
true = 有文档比索引新,建议重跑 embed |
drift.missing_from_index |
磁盘有但索引没有的文档(需 embed 补录) |
backend_resolved |
当前解析到的后端(local / cloud / none) |
插件调用:
/ragkit:status
uv run plugins/ragkit/scripts/ragkit.py eval \
--kb <知识库路径> [--evalset <file>] [--top N] [--channels lexical,metadata] [--json]- 默认读内置
scripts/rag/evalset.json(16 条 golden 问题,12 case + 4 navigation)。 - 输出:
recall@top(top-N 召回率)和MRR(平均倒数排名)整体 + 按 bucket 分项。 --channels lexical,metadata= 无向量基线;与全通道(lexical,metadata,vector)对比即向量路增益。
插件调用:
/ragkit:eval [--channels lexical,metadata]
# 设置第三方 API preset
uv run plugins/ragkit/scripts/ragkit.py backend set \
--provider qwen --kb <知识库路径>
# 查看当前配置
uv run plugins/ragkit/scripts/ragkit.py backend show --kb <知识库路径>
# 清除配置,回到自动解析
uv run plugins/ragkit/scripts/ragkit.py backend reset --kb <知识库路径>固定优先级(由高到低):
显式 cfg["backend"] > 本地模型已缓存 > 云端 API 已配置+密钥可读 > none(降级)
- 显式:
backend.set写入.ragkit/config.json的backend字段,强制走指定路。 - 本地:
~/.cache/huggingface/hub/models--<model>/snapshots/存在即视为已缓存。 - 云端:
cloud.base_url非空且对应key_env环境变量已设置。 - none:三条均不满足时降级,embed 返回退出码 3,query 走词汇 + 元数据路。
双后端并存时固定走本地(本地优先于云端,无需手动选择)。
内置 16 条 golden 问题(scripts/rag/evalset.json,12 case + 4 navigation),覆盖
收付系统、加密任务、授权页面等典型检索场景。
扩充 golden 集方法:
- 在
evalset.json中追加{"query": "...", "expect": ["<knowledge_id>"], "bucket": "case|navigation"}条目。 knowledge_id即cases/<name>.md或navigation/<name>.md的文件名(不含后缀)。- 跑
eval查看新增条目的命中情况;MISS 列表给出 got 前三名,辅助调试。
| 指标 | 含义 | 目标 |
|---|---|---|
recall@5 |
预期文档出现在 top-5 结果中的比例 | ≥0.85 为健康 |
MRR |
平均倒数排名(越高越靠前) | ≥0.70 为健康 |
# 先跑词汇+元数据基线
uv run plugins/ragkit/scripts/ragkit.py eval \
--kb <知识库路径> --channels lexical,metadata
# 配好向量后端并重跑 embed 后,对比全通道数字
uv run plugins/ragkit/scripts/ragkit.py eval \
--kb <知识库路径>两组数字之差即向量路的增益;调整分词权重或 RRF 参数前后均应留对照数字。
n=16 recall@5=0.9375 mrr=0.8125
[case] n=12 recall=0.9167 mrr=0.8125
[navigation] n=4 recall=1.0 mrr=0.8125
MISS: 按收付登记号查询授权的后端三步链路
→ got ['121659-premium-query-paymentno-dialog-chain',
'123000-cod-authority-new-components',
'123000-cod-authority-save-three-table-sync']
全通道(向量)验收数字待配置向量后端后补录(本机无 uv/模型缓存/API key)。
ragkit 只认以下结构(与 specode distill 产出格式一致):
knowledge-base/
cases/ ← 经验案例,每个 .md 对应一个知识点
navigation/ ← 导航地图,指向代码位置
MEMORY.md ← 索引摘要(可选,给语言模型快速预览)
.ragkit/ ← ragkit 索引目录(应加入 .gitignore)
config.json
chunks.json
vectors.npy
manifest.json
model_id.txt
安装 ragkit 且 knowledge-base/.ragkit/ 已构建后,specode 的 Tier-0 RagKit gate 自动生效:
- 会话可用 skills 中存在
ragkit:query knowledge-base/.ragkit/目录存在
两个条件均满足时,specode requirements / design 阶段的经验检索自动切换为 ragkit:query 多路召回;否则零成本跳过。
| 退出码 | 含义 |
|---|---|
| 0 | 成功(含 query/status 降级场景) |
| 1 | embed:知识库目录不存在或 0 chunks |
| 2 | argparse 参数错误(argparse 默认行为) |
| 3 | embed 成功但无向量后端(词汇/元数据索引已建好) |