内容
# rag-paper
**本地优先的RAG论文库,用于PDF研究工作流。**
rag-paper帮助您从PDF文件中建立一个私有的、本地的、可搜索的论文库。它解析PDF,分割论文文本,创建嵌入,存储向量在本地Chroma中,并通过CLI和MCP服务器为Codex CLI和Claude Code等工具提供检索功能。
它专为希望高效阅读论文同时节省令牌并使用经济实惠的模型的科研人员、学生、工程师和LLM高级用户设计,例如DeepSeek、Qwen、本地Ollama嵌入或OpenAI兼容的嵌入服务。
[中文 README](./README.zh-CN.md)
## 关键词
论文 RAG,本地 RAG,PDF RAG,学术搜索,Chroma,MCP 服务器,Codex CLI,Claude Code,Zotero,Obsidian,引用图,Mermaid,DOI 增强,CrossRef,OpenAlex,语义重复删除,本地向量数据库,研究助手,低成本 LLM 工作流
## 为什么选择 rag-paper
- **高效的论文阅读**:仅检索相关片段,而不是将整个 PDF 发送给 LLM。
- **本地优先存储**:向量和元数据存储在本地 Chroma 中。
- **MCP 准备**:为 Codex CLI、Claude Code 和其他 MCP 客户端提供论文搜索工具。
- **低成本模型友好**:默认使用本地 Ollama 嵌入,或使用 OpenAI 兼容的嵌入端点。
- **Zotero 友好**:将 `root_path` 指向一个或多个 Zotero 存储/导出目录。
- **Obsidian 友好**:导出引用图为 Mermaid Markdown。
- **隐私控制**:使用 `skip_marker_file` 防止敏感文件夹被索引。
## 要求
- Python **3.10+**
- 本地或远程嵌入提供商
- 默认嵌入设置:Ollama with `qwen3-embedding:4b`
```bash
ollama pull qwen3-embedding:4b
```
## 安装
```bash
git clone https://github.com/your-name/rag-paper.git
cd rag-paper
python -m venv .venv
source .venv/bin/activate
pip install -e .
```
Windows PowerShell:
```powershell
git clone https://github.com/your-name/rag-paper.git
Set-Location rag-paper
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e .
```
## 快速开始
创建配置文件:
```bash
rag-paper init-config --path ./config.json
```
将 PDF 文件放在 `./papers` 下,或编辑 `config.json` 并将 `papers[].root_path` 指向您自己的目录。
索引 PDF 文件:
```bash
rag-paper index
```
本地搜索:
```bash
rag-paper search "检索增强生成评估" --top-k 5
```
查看索引论文:
```bash
rag-paper list-indexed-papers
rag-paper show-indexed-paper "注意力" --limit 3
```
删除错误的索引记录:
```bash
rag-paper delete-indexed-paper "10.55277/researchhub.x9vnpm0y.1"
rag-paper build-citation-graph
```
启动 MCP 服务器:
```bash
rag-paper serve
```
## 技术栈
- **PyMuPDF**:PDF 文本提取和 PDF 元数据读取。
- **ChromaDB**:本地持久向量数据库,用于论文片段。
- **Rank BM25**:混合搜索的关键词检索路径。
- **MCP Python SDK**:为 Codex CLI、Claude Code 和其他 MCP 客户端提供论文搜索和检查工具。
## 模块
### 索引
`rag-paper index` 扫描配置的 PDF 根目录,尊重 `skip_marker_file`,提取文本,分割论文,创建嵌入,并将片段写入 Chroma。在向量化之前,它显示文件数量和根路径,除非启用 `--yes` 或 `indexing.assume_yes`。
索引是增量式的。rag-paper 在清单中存储 `size + mtime_ns`,仅在快速文件签名更改时计算 SHA256。失败的文件记录在 JSONL 日志中,可以使用 `rag-paper index --retry-failed` 重新尝试。
### 搜索和检索
`rag-paper search` 对索引片段执行本地混合检索。它将 Chroma 的向量相似性与 BM25 关键词匹配相结合,然后返回适合发送给 LLM 而不是整个 PDF 的紧凑的源感知摘录。
搜索支持作者、年份、标签和文件名等过滤器。相同的检索引擎为 MCP 工具提供支持。
### 索引论文检查
`rag-paper list-indexed-papers` 以终端表格形式显示当前 Chroma 库,包括论文总数、片段数量、标题、DOI、年份和源路径。
`rag-paper show-indexed-paper` 支持标题、文件名、源路径和 DOI 的模糊选择器。它显示合并的元数据和前 5 个片段 ID;使用 `--all-chunks` 显示每个片段 ID。
`rag-paper delete-indexed-paper` 从 Chroma 和索引清单中删除匹配的论文。没有 `--yes`,每个匹配的论文必须在删除前一一确认。删除索引论文后,运行 `rag-paper build-citation-graph` 以刷新引用图导出。
### 元数据增强
`rag-paper enrich-metadata` 使用 DOI 和书目元数据增强索引论文。它支持 CrossRef 和 OpenAlex,提供商回退,速率限制,自定义 User-Agent,联系邮箱和 HTTP/HTTPS/SOCKS5 代理。
增强模块与向量化分离。它可以按索引文件运行,在索引完成后运行或手动运行。结果写入 `paper_metadata.json`,提供商响应缓存在 SQLite 中。
标题质量检查拒绝明显的垃圾邮件,URL,广告样字符串和符号丰富的 PDF 元数据标题。当 PDF 标题不受信任时,rag-paper 更喜欢从第一页推断出的标题,提供商标题或文件名。
### 重复删除
`rag-paper dedupe-papers` 在索引前报告重复候选者。它可以比较 DOI/标题-年份元数据和从论文文本或摘要构建的语义签名。根据配置,可以报告或跳过重复项。
### 引用图
`rag-paper build-citation-graph` 从丰富的 DOI/OpenAlex 元数据构建图,并导出 JSON 和 Mermaid Markdown。Mermaid 输出设计用于 Obsidian 以浏览论文关系。
### MCP 服务器
`rag-paper serve` 启动 MCP 服务器,以便外部工具可以查询本地论文库。MCP 客户端可以导入论文,搜索片段,列出索引论文,检查元数据,删除索引记录,增强元数据,重复删除论文,获取特定片段,导出上下文和构建引用图。
## 典型工作流
### 与 Zotero 结合使用
`root_path` 是一个数组,因此您可以将 rag-paper 指向多个论文文件夹,包括 Zotero 存储/导出文件夹:
```json
{
"papers": [
{
"root_path": [
"D:/Zotero/storage",
"D:/Zotero/exports/LLM"
],
"skip_marker_file": ".rag-paper-skip",
"tags": ["zotero"]
}
]
}
```
rag-paper 递归扫描这些根目录,只索引 `.pdf` 文件。
### 使用 `skip_marker_file` 保护私有文件夹
如果目录包含配置的标记文件,rag-paper 将跳过该目录及其所有子目录。
这对于隐私保护很有用。例如,您可以在包含未发表论文、私人笔记或不应通过 MCP 搜索公开的论文的文件夹中放置 `.rag-paper-skip`。
```json
{
"papers": [
{
"root_path": ["./papers"],
"skip_marker_file": ".rag-paper-skip"
}
]
}
```
当检测到标记时,rag-paper 显示警告并询问是否继续,除非启用 `--yes` 或 `indexing.assume_yes`。
### 备份和恢复工作
默认情况下,核心运行时数据存储在:
```text
rag_paper_data/
chroma_db/
paper_metadata.json
cache/
citation_graph/
logs/
```
复制 `rag_paper_data/` 足以备份本地 Chroma 向量、元数据、缓存、失败日志、检索统计和引用图导出。
在另一台设备上恢复工作:
1. 安装 rag-paper。
2. 将 `rag_paper_data/` 复制到项目目录中。
3. 如果您自定义了路径,请复制您的 `config.json`。
4. 运行 `rag-paper list-indexed-papers` 以验证恢复的索引。
### 为 Obsidian 构建引用图
元数据增强后,构建引用图:
```bash
rag-paper build-citation-graph
```
rag-paper 导出:
- JSON 图:`rag_paper_data/citation_graph/citation_graph.json`
- Mermaid Markdown:`rag_paper_data/citation_graph/citation_graph.md`
Mermaid 文件可以直接在 Obsidian 或任何支持 Mermaid 的 Markdown 工具中打开。
## 元数据增强
rag-paper 可以使用 DOI 和书目元数据增强索引论文。
支持的提供商:
- CrossRef
- OpenAlex
默认顺序:
```json
{
"metadata_enrichment": {
"providers": ["crossref", "openalex"]
}
}
```
如果第一个提供商失败或返回没有匹配,rag-paper 将回退到下一个提供商。
手动运行增强:
```bash
rag-paper enrich-metadata
```
刷新现有元数据:
```bash
rag-paper enrich-metadata --force
```
刷新索引的 PDF:
```bash
rag-paper enrich-metadata --file /path/to/paper.pdf --force
```
`--file` 首先检查 PDF 是否已在本地 Chroma 中索引。如果没有,rag-paper 退出并要求您先索引它。
元数据增强默认使用 SQLite 缓存:
```text
rag_paper_data/cache/metadata_enrichment.sqlite3
```
这避免了对相同的 DOI 或标题查询重复调用 CrossRef/OpenAlex。
## MCP 用法
启动 MCP 服务器:
```bash
rag-paper serve
```
可用于流式 HTTP 配置示例:
```json
{
"mcpServers": {
"rag-paper": {
"url": "http://127.0.0.1:8765/mcp"
}
}
}
```
stdio 配置示例:
```json
{
"mcpServers": {
"rag-paper": {
"command": "rag-paper",
"args": ["serve"]
}
}
}
```
可用的 MCP 工具包括:
- `service_info`
- `import_papers`
- `list_indexed_papers`
- `show_indexed_paper`
- `delete_indexed_paper`
- `search_papers`
- `search_by_metadata`
- `get_chunk`
- `export_context`
- `enrich_paper_metadata`
- `dedupe_papers`
- `build_paper_citation_graph`
## CLI 命令
```bash
rag-paper init-config
rag-paper index
rag-paper index --force
rag-paper index --file /path/to/paper.pdf
rag-paper index --only-new
rag-paper index --retry-failed
rag-paper enrich-metadata
rag-paper list-indexed-papers
rag-paper show-indexed-paper "选择器"
rag-paper delete-indexed-paper "选择器"
rag-paper search "查询"
rag-paper dedupe-papers
rag-paper build-citation-graph
rag-paper serve
```
## 索引注意事项
rag-paper 将索引状态存储在:
```text
rag_paper_data/chroma_db/index_manifest.json
```
它使用两阶段更改检查:
1. 比较 `size + mtime_ns`。
2. 仅当快速检查更改时计算 SHA256。
如果索引失败,rag-paper 记录失败:
```text
rag_paper_data/logs/index_failed.jsonl
```
重试失败的文件:
```bash
rag-paper index --retry-failed
```
如果您按 `Ctrl+C`,已完成的文件已持久存储在 Chroma 和清单中,因此下一次运行将从剩余的文件继续。
## 开发
```bash
pip install -e ".[dev]"
python -m pytest -q
```
## 许可证
该项目根据 MIT 许可证授权。参见 [LICENSE](./LICENSE)。
## 配置参考
常见选项:
- `data_dir`:核心运行时数据目录。默认值:`./rag_paper_data`
- `papers[].root_path`:PDF 根目录数组。与 Zotero 文件夹一起使用很有用。
- `papers[].skip_marker_file`:用于跳过私有目录的标记文件名。
- `papers[].tags`:根路径下论文的默认标签。
- `chroma.persist_dir`:Chroma 持久性目录。
- `indexing.metadata_path`:论文元数据 JSON 路径。
- `indexing.assume_yes`:跳过交互式确认。
- `indexing.max_files`:要索引的最大 PDF 文件数。
- `indexing.failed_path`:索引失败的 JSONL 路径。
- `metadata_enrichment.enabled`:启用 DOI 和元数据增强。
- `metadata_enrichment.providers`:提供商顺序,例如 `["crossref", "openalex"]`。
- `metadata_enrichment.timing`:`per_file`、`after_index` 或 `manual`。
- `metadata_enrichment.user_agent`:CrossRef/OpenAlex 请求的 User-Agent。
- `metadata_enrichment.mailto`:提供商礼仪的联系邮箱。
- `metadata_enrichment.openalex_email`:OpenAlex 邮箱参数。
- `metadata_enrichment.requests_per_second`:提供商请求速率限制。
- `metadata_enrichment.http_proxy`:HTTP 代理。
- `metadata_enrichment.https_proxy`:HTTPS 代理。
- `metadata_enrichment.socks5_proxy`:SOCKS5 代理。
- `metadata_enrichment.cache_path`:SQLite 增强缓存路径。
- `dedup.enabled`:启用重复报告前索引。
- `dedup.action`:`report` 或 `skip`。
- `dedup.similarity_threshold`:语义重复阈值。
- `citation_graph.path`:引用图 JSON 输出。
- `citation_graph.mermaid_path`:Obsidian 的 Mermaid Markdown 输出。
- `display.datetime_timezone`:`metadata_enriched_at` 的显示时区。
- `display.datetime_format`:显示的 datetime 的 `strftime` 格式。
- `logging.level`:日志级别。
- `logging.stats_path`:检索统计的 JSONL 路径。