内容
# 跟踪
 
在文件夹中的文件进行本地检索,适用于代理或您。 跟踪在磁盘上索引文档,并在CLI或MCP服务器上提供搜索、文档获取和诊断。 这允许代理从知识库中提取正确的段落,而无需将整个知识库粘贴到上下文中。
默认的`搜索`是自适应的和BM25优先的。 跟踪信任强烈的词汇匹配,但在关键词证据较弱时跳过它们,并 fallback 到语义或混合搜索。 检索完全在本地进行。 嵌入在设备上运行(默认为ONNX int8);没有任何东西离开机器。
CLI和MCP服务器包装相同的Python基本功能(`WikiIndexer`、`AdaptiveSearch`、`CollectionRegistry`和结果格式化器),因此您可以直接从脚本或库中使用这些功能。
格式:Markdown、PDF、Word、PowerPoint、CSV、SQL、Python、YAML、TypeScript、Jupyter笔记本。
## 安装
跟踪需要Python 3.11+和`uv`。
```bash
uv sync
```
## 使用已提交的Fixture进行演示
此命令搜索`tests/fixtures/eval_kb`中已提交的fixture。
```console
$ KB_PATH=tests/fixtures/eval_kb TOKENIZERS_PARALLELISM=false uv run trace search "BM25 ranking" --top-k 2
找到 2 个结果
## 策略
- **已选:** 关键词
- **已使用Fallback:** 否
- **原因:** BM25 返回了强烈的精确匹配结果
## 上下文
### 1. BM25
- **路径:** `glossary/bm25.md`
- **文件夹:** glossary
- **来源:** 关键词
**片段 1:** BM25
- **匹配证据:** 标题匹配:bm25;路径匹配:bm25;breadcrumb 匹配:bm25
- **匹配术语:** `bm25`, `ranking`
- **最佳引用:** 文档:BM25 文件夹:glossary # BM25 BM25 是一个用于词汇检索的经典**关键词**排名函数...
## 建议的后续操作
- `get_document(path="glossary/bm25.md")`
```
## CLI
在仓库中使用 `uv run trace ...`,或安装后使用 `trace ...`。
```bash
# 单个集合
KB_PATH=/path/to/docs uv run trace search "sample query"
# 命名集合
KB_COLLECTIONS="docs:/path/to/docs,team:/path/to/second-kb" \
uv run trace search "sample query" --collection docs
# 检查设置
KB_PATH=/path/to/docs uv run trace doctor
# 启动 MCP 服务器
KB_PATH=/path/to/docs uv run trace serve
```
如果没有子命令,`uv run trace` 将启动 MCP 服务器。
| 命令 | 描述 |
| --- | --- |
| `trace search "query"` | BM25优先搜索,语义/混合fallback |
| `trace semantic-search "query"` | 向量相似性搜索 |
| `trace keyword-search "term"` | 直接BM25关键词搜索,用于精确术语 |
| `trace hybrid-search "query"` | 语义 + 关键词组合 |
| `trace get-document path/to/doc.md` | 按路径获取文档 |
| `trace list-documents` | 列出文档,可选按文件夹 |
| `trace index-stats` | 显示索引状态 |
| `trace doctor "sample query"` | 诊断配置、可见文档、排除项、索引 |
| `trace reindex` | 增量更新索引; `--force` 重新构建 |
| `trace serve` | 启动 MCP 服务器 |
搜索命令接受 `--top-k`(`keyword-search` 使用 `--max-results`);`list-documents` 接受 `--folder` 和 `--limit`。 搜索命令和 `list-documents` 还接受 `--path-prefix`(可重复)、 `--extensions`(`.md,.py`)和 `--since`(ISO 8601)来限定结果。 识别集合的命令接受 `--collection`。
## MCP 服务器
跟踪通过stdio与MCP通信。 使用`KB_PATH`指向单个集合,或使用`KB_COLLECTIONS`指向多个命名集合。 服务器名称为`trace`;工具以`mcp__trace__<tool>`公开。
### Claude 代码
```bash
claude mcp add trace \
--transport stdio \
--env KB_COLLECTIONS="docs:/path/to/docs,team:/path/to/second-kb" \
-- uv run --directory /path/to/trace trace serve
```
```bash
# 检验
KB_COLLECTIONS="docs:/path/to/docs,team:/path/to/second-kb" \
uv run fastmcp dev src/trace_search/server/trace_server.py
```
工具与CLI一一对应:
| 工具 | 描述 |
| --- | --- |
| `search` | BM25优先搜索,语义/混合fallback(默认) |
| `semantic_search` | 向量相似性搜索 |
| `keyword_search` | 直接BM25关键词搜索,用于精确术语 |
| `search_hybrid` | 语义 + 关键词组合 |
| `get_document` | 按路径获取文档 |
| `list_documents` | 列出文档,可选按文件夹 |
| `index_stats` | 显示索引状态 |
| `doctor` | 诊断配置、可见文档、排除项、索引 |
| `reindex` | 增量更新索引; `force=true` 重新构建 |
在多集合模式下,搜索和文档工具接受可选的`collection`。 搜索工具和`list_documents`接受与CLI相同的`path_prefix` / `extensions` / `since`过滤器;过滤器与AND组合,并在`search`输出中显示为`Active filters`,因此空结果可以自解释。
首先使用`search`。 它报告了哪个策略获胜,按文档分组上下文,包括匹配证据,并建议`get_document(path=...)`后续操作。 当您想要一种模式进行调试或确定性比较时,请使用`keyword_search` / `semantic_search` / `search_hybrid`。
## 配置
| 变量 | 描述 | 默认值 |
| --- | --- | --- |
| `KB_PATH` | 单个集合的路径(`~`展开) | 未设置 |
| `KB_COLLECTIONS` | 以逗号分隔的`name:path`对(`~`展开) | 未设置 |
| `INDEX_PATH` | 索引的根路径(`~`展开) | 未设置 |
| `LOG_LEVEL` | `DEBUG`/`INFO`/`WARNING`/`ERROR`/`CRITICAL`/`NOTSET` | `INFO` |
| `EMBEDDING_MODEL` | `all-MiniLM-L6-v2` 或 `BAAI/bge-base-en-v1.5` | `all-MiniLM-L6-v2` |
| `EMBEDDING_BACKEND` | `onnx`(int8,更快)或 `torch` | `onnx` |
| `RERANKER_ENABLED` | 启用重新排名 | `false` |
`KB_PATH` 和 `KB_COLLECTIONS` 互斥。 同时设置两者会在启动时失败,无效路径、集合名称和日志级别也会导致启动失败。
索引位于每个集合下的 `.mcp-search/indexes/`。 设置 `INDEX_PATH` 将它们存储在其他位置:单集合模式直接写入那里,多集合模式为每个集合使用一个子目录。
## 重新索引
`reindex` 是增量的:跟踪每个文件(SHA-256 + mtime + size),并仅重新处理已添加、更改或删除的内容。 运行 `trace reindex --force`(`force=true` 在MCP上)以删除索引并从头开始构建,模型更改后或从损坏中恢复。
`doctor` 报告下一个重新索引计划和更改摘要:
```text
- 索引状态:过时
- 自上次索引以来,1个已添加,2个已更改,1个已删除。
- 下一个 `reindex` 将对更改的文件进行增量运行。
- 自上次索引以来,源更改:unchanged=27,added=1,changed=2,removed=1
```
当给定示例查询时,`doctor` 仅探测现有索引。 它告诉您重新索引而不是作为副作用构建。 如果它报告未知元数据(较旧的 `v1` 架构),则一次 `reindex` 重新填充模型和新鲜度元数据;该运行是强制的,后续运行是增量的。
## 检索质量
跟踪包含一个小型评估工具包(`tools/eval/`),用于黄金查询检查。 已提交的fixture是一个刻意设计的烟雾测试:24个短Markdown文档和17个查询,包含近似概念、精确令牌查找和释义。
| 模式 | Top-1 (P@1) | Top-5 (Success@5) | MRR | p50 | p95 |
| --- | --- | --- | --- | --- | --- |
| `bm25` | 88% | 94% | 0.912 | 0.16 毫秒 | 2.6 毫秒 |
| `semantic` | 88% | 100% | 0.941 | 6.71 毫秒 | 7.1 毫秒 |
| `hybrid` | 88% | 100% | 0.941 | 7.10 毫秒 | 10.9 毫秒 |
| `adaptive` | 88% | 100% | 0.941 | 7.20 毫秒 | 10.6 毫秒 |
共享的88% Top-1隐藏了实际的权衡。 BM25是最快的,对精确术语很强,但完全错过了一个释义。 语义和混合检索在前5名中恢复了所有查询。 `adaptive`保留BM25用于强词汇命中,并在关键词证据较弱时fallback到向量搜索,与最佳召回率匹配,同时保持词汇查询廉价。
这些是烟雾测试数字,而不是语料库规模的基准声明。 完整的报告位于 [`docs/benchmarks/`](docs/benchmarks/) 中。 使用以下命令重现已提交的门控:
```bash
KB_PATH=tests/fixtures/eval_kb EVAL_GOLDEN_QUERIES=tests/fixtures/eval_golden_queries.yaml \
uv run python -m tools.eval.cli --full --search adaptive --output-dir docs/benchmarks/
```
对于多KB检索战斗套件,请参阅 [`docs/retrieval-modes.md`](docs/retrieval-modes.md)。 它比较了BM25、语义、混合、重新排名和自适应检索在已提交的无秘密fixtures和文档上的表现。
## 开发
```bash
uv run python -m pytest -m "not slow" # 跳过嵌入测试
uv run python scripts/check_module_sizes.py # 没有模块 > 1000 行
uv run ruff check .
uv build
# 针对已提交的fixture进行搜索评估
KB_PATH=tests/fixtures/eval_kb EVAL_GOLDEN_QUERIES=tests/fixtures/eval_golden_queries.yaml \
uv run python -m tools.eval.cli --full --search adaptive
```
要针对您自己的语料库进行评估,请复制 `tools/eval/golden_queries.example.yaml` 到 `tools/eval/golden_queries.yaml`,将 `KB_PATH` 指向匹配的文档,构建索引,然后运行 `uv run python -m tools.eval.cli --quick`。