stm32-rag-mcp
# STM32 RAG MCP
一个以 **Claude Code 插件** 形式交付的 STM32 文档知识库。它从本地 datasheet 和 reference manual 中检索原文证据,通过 MCP 返回文档、revision、PDF 页码、章节、寄存器和 source SHA-256,再由 Claude 基于证据回答或生成代码。
> 当前版本是 evidence-first、lexical-first RAG:本地检索无需 embedding 模型或远程向量库;Claude Code 仍负责最终自然语言回答。证据不足时系统明确 abstain,不猜寄存器、地址或页码。
## 当前语料
| 系列 | 类型 | 文档 | 文件 | 页数 |
|---|---|---|---|---:|
| STM32F1 | datasheet | STM32F103C8 | `reference_manual/datasheet/STM32F1/STM32F103C8.pdf` | 117 |
| STM32F1 | reference manual | RM0008 Rev 21 | `reference_manual/STM32F1/RM0008.pdf` | 1,136 |
| STM32F4 | datasheet | STM32F405/407 | `reference_manual/datasheet/STM32F4/STM32F405_407.pdf` | 203 |
| STM32F4 | reference manual | RM0090 Rev 9 | `reference_manual/STM32F4/RM0090.pdf` | 1,718 |
本地验证语料合计 4 份 PDF、3,174 页、42,839,844 bytes。`download_manifest.csv` 保存 SHA-256、实际镜像来源和 ST 官方文档页面。当前 PDF 来自公开镜像,索引不会把它们描述成“自动同步的最新版”;更新文档后必须重新校验 revision、SHA 和 citation。
> **仓库语料说明:** 当前公开仓库已经包含上述 4 份 PDF,方便首次安装直接构建索引。PDF 仍应视为 ST 文档的再分发内容;更新或替换文件前请确认其来源和再分发许可。SQLite 索引是可再生构建产物,不提交到仓库。
## 架构
```text
STM32 PDF
-> SHA/provenance registry
-> PyMuPDF page/block parser
-> TOC + model-scope propagation
-> section/register-aware chunks
-> SQLite metadata + FTS5 BM25
-> exact technical-token rerank + abstention
-> MCP evidence tools
-> Claude Code answer with citations
```
核心特点:
- page-first:保留 physical PDF page、PDF label、可见页脚和异常标记;
- scope-aware:区分 RM0090 的 F42/F43 RCC 章节与 F405/F407 RCC 章节;
- register-aware:支持 `GPIO_MODER` / `GPIOA_MODER` 到 `GPIOx_MODER` 的规范化,同时区分 F1 的 `GPIOx_CRL/CRH`;
- deterministic:SQLite FTS5 `unicode61 tokenchars '_'`、固定重排和 index fingerprint;
- fail loud:PDF、schema、parser、chunker 或 corpus fingerprint 变化时拒绝旧索引;
- read-only MCP:运行时不下载、不建库、不修改 PDF。
## 安装依赖
项目使用 `uv.lock` 固定依赖。已验证运行时:CPython 3.13.13、PyMuPDF 1.28.2、MCP 2.1.1。
```bash
uv sync --frozen --extra dev
```
## 准备 PDF 与构建索引
克隆仓库后,4 份验证语料位于 `reference_manual/`,可先校验路径、大小和 SHA-256:
```bash
uv run stm32-rag doctor --corpus reference_manual --manifest download_manifest.csv --json
```
预期输出 `ok: true`,包含 4 documents、3,174 pages 和 42,839,844 bytes。manifest 中的 `source` 是原始镜像地址,`official_page` 是 ST 官方文档页;它们用于 provenance 记录,不会在正常启动时自动访问网络。
如果需要重新下载或替换 PDF,下载器只会在显式执行时联网,并将结果写入被 `.gitignore` 排除的 `download_results.csv`:
```bash
uv run python download_stm32_docs.py
```
下载完成后必须重新校验 manifest 中记录的文件路径、字节数和 SHA-256;下载器报告 `failed` 时会以非零状态退出。确认语料完整后,构建本地 SQLite FTS5 索引:
```bash
uv run stm32-rag index \\
--corpus reference_manual \\
--manifest download_manifest.csv \\
--db assets/stm32-index.sqlite3 \\
--index-manifest assets/index-manifest.json \\
--json
```
索引构建会在临时数据库中完成 integrity check 和 fingerprint 校验,成功后才原子替换 `assets/stm32-index.sqlite3`。索引不会提交到 GitHub;更新 PDF、parser、chunker 或 retrieval policy 后都应重新构建。
构建完成后再次检查索引:
```bash
uv run stm32-rag doctor \\
--corpus reference_manual \\
--manifest download_manifest.csv \\
--db assets/stm32-index.sqlite3 \\
--json
```
## CLI 查询
```bash
uv run stm32-rag search --db assets/stm32-index.sqlite3 --corpus reference_manual --manifest download_manifest.csv --chip STM32F407 --query GPIO_MODER --json
```
```bash
uv run stm32-rag search --db assets/stm32-index.sqlite3 --corpus reference_manual --manifest download_manifest.csv --chip STM32F407 --query "USART_CR1 TE bit" --json
```
不存在或跨系列不兼容的寄存器会返回 `abstained: true`,不会静默取消 chip filter。
## 重建索引
更新 PDF、parser 或 chunker 后运行:
```bash
uv run stm32-rag index --corpus reference_manual --manifest download_manifest.csv --db assets/stm32-index.sqlite3 --index-manifest assets/index-manifest.json --json
```
index builder 在临时 SQLite 中完成事务、integrity check 和 fingerprint 校验后再原子替换目标文件;失败不会破坏旧索引。
## Claude Code 插件
插件组件:
- `.claude-plugin/plugin.json`
- `.mcp.json`
- `skills/stm32-docs/SKILL.md`
- MCP tools:`search_stm32_docs`、`get_register`、`search_peripheral`
验证插件:
```bash
claude plugin validate C:/Users/Administrator/rag_embedding --strict
```
本地开发加载:
```bash
claude --plugin-dir C:/Users/Administrator/rag_embedding
```
启动后在 Claude Code 中检查 `/mcp`,技能命令为:
```text
/stm32-rag:stm32-docs
```
`.mcp.json` 使用 `${CLAUDE_PLUGIN_ROOT}` 定位只读 corpus/index,使用 `${CLAUDE_PLUGIN_DATA}` 保存 uv 环境/cache。首次在新安装位置启动时,uv 可能从 lockfile 安装 Python 依赖;它不会自动下载 STM32 PDF、生成 SQLite 索引或下载 embedding 模型。公开仓库中的 `.mcp.json` 需要在本地语料和索引准备完成后使用。
## MCP 工具
### `search_stm32_docs`
综合查询,可传:`query`、`chip`、`family`、`document_type`、`peripheral`、`register`、`top_k`。
### `get_register`
精确寄存器查询,必须传 `chip` 和 `register`。适合地址 offset、reset value、bit field 和清除语义。
### `search_peripheral`
外设范围查询,必须传 `chip` 和 `peripheral`,可附加具体问题。
三个工具都只返回 evidence/citations,不返回一个伪装成权威的本地生成答案。
## Citation 语义
每条 evidence 包含:
- document / DocID / revision / type / family;
- source path、SHA-256、mirror URL、ST official page;
- physical PDF pages、PDF labels、source footers;
- section path、register、chip scope;
- warnings 和 page anomalies。
RM0008 p.67–80 是重要异常:PDF physical/page label 仍为 67–80,但可见页脚错误写成 `67/80`…`80/80`。系统保留 canonical page 与 source footer,并标记 `embedded_total_mismatch`。
## 评测与测试
```bash
uv run pytest -q
```
当前测试覆盖:
- corpus 路径、SHA、页数和 downloader 无副作用 import;
- RM0008 页码异常;
- RM0090 scope 与无效 TOC anchor;
- F4 datasheet 横向页;
- register chunk 跨页与确定性 ID;
- SQLite schema、FTS5、只读和 stale-index 防护;
- CLI、MCP in-memory client 和真实 stdio 子进程;
- `eval/golden_queries.json` 的 20 个正例 + 5 个负例 hard gate。
正例要求 Recall@5 / citation hit 至少 90%;当前 20/20 正例首条命中定义页,5/5 负例 abstain。
## 已知限制
- 当前检索模式为 `lexical`,未打包 embedding 模型或 learned reranker;接口扩展点已保留,但响应不会谎称 hybrid。
- F4 datasheet p.14–15、62–70 为旋转横向表格。系统保留原文/rotation 并标记 `table_layout_degraded`;精确 pin/Alternate Function 查询会优先匹配非降级 pinout 表,无法建立可靠映射时显式 abstain。
- 尚未加入 SVD 结构化寄存器数据库、Errata、Application Note、HAL/LL、示例代码或其他 STM32 family。
- `download_stm32_docs.py` 只在显式执行时联网,并写 `download_results.csv`;它不会覆盖 verified corpus manifest。MVP 正常运行不调用 downloader。
## 项目计划
完整背景和后续路线见 `STM32_RAG_MCP_Project_Plan.md`。本版优先兑现计划中的核心目标:从 STM32 文档找到可靠证据、保留页码和来源,并通过 MCP 供 Claude 主动查询。
TDQS
Scored across 3 tools
General search_stm32_docs overlaps semantically with get_register and search_peripheral, since a broad docs search could return register or peripheral content. The specialized tools are clearly scoped, but agents may still hesitate between the general and resource-specific search paths.
All tool names follow a consistent verb_noun snake_case pattern: search_stm32_docs, get_register, and search_peripheral. The two search tools share a predictable prefix, and get_register fits the same structural style.
Three tools is compact but well-scoped for a documentation RAG server: general docs search, register lookup, and peripheral search. Each tool covers a distinct retrieval need without unnecessary padding.
Core retrieval workflows are covered: broad documentation search, register-level lookup, and peripheral-scoped search with citations. Minor gaps exist around discovering available chip models or document lists, but agents can likely work around them using the general search tool.