关于 rag
FieldCure MCP RAG Server 用于索引本地文档集合,并在多个知识库中提供关键词与语义混合搜索。它支持多种文档格式,也可选择使用 AI 上下文化处理和向量嵌入。
主要功能
- 01BM25 与向量混合搜索
- 02索引多个本地知识库
- 03提取办公文件和 PDF 文本
- 04对扫描 PDF 执行 OCR 并转录音频
- 05使用 AI 为文本块补充上下文
- 06重试待处理文本块的向量嵌入
适用场景
- 01跨知识库搜索项目文档
- 02使用 OCR 索引扫描版 PDF
- 03通过转录文本搜索音频记录
- 04索引期间继续执行搜索
MCP 相关
stdio MCP 服务提供跨知识库的只读搜索,可通过 `kb_id` 选择知识库。它还提供 `start_reindex` 工具来提交索引请求。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
FieldCure MCP RAG Server
一个用于索引和搜索本地文档集合的 Model Context Protocol (MCP) 服务。支持 DOCX、HWPX、PDF(含 OCR)、Excel、PowerPoint 和音频(Whisper 转录,仅限 Windows),并提供针对韩语和英语优化的关键词与语义混合搜索。
使用 C# 和官方 MCP C# SDK 构建。
命令
fieldcure-mcp-rag
├── serve --base-path <path> # Multi-KB MCP search server (stdio)
├── exec --path <kb-path> [--force] [--partial ...] # Headless indexing for a single KB
├── exec-queue --queue-file <path> [--sweep-all] # Process deferred indexing queue
├── prune-orphans --base-path <path> # Delete orphan KB folders
└── smoke-ocr --pdf <scanned.pdf> # Self-test: OCR a scanned PDF (Windows)
- serve — 以只读模式提供基础路径下的所有知识库。单个进程通过
kb_id参数处理多个知识库。可在 exec 执行索引时运行(SQLite WAL)。 - exec — 扫描源文件夹、切分文档、使用 AI 添加上下文、生成嵌入并存储到 SQLite。
--partial会在模型变更时仅重新运行下游阶段,并保留 OCR 输出。 - exec-queue — 顺序协调器,负责处理延迟索引队列。每次处理一个条目,不会争用 GPU。
--sweep-all也会处理延迟条目(用于应用关闭时)。 - prune-orphans — 删除孤立的知识库文件夹(以 GUID 命名且没有 config.json)。受保护的文件夹(以
.、_为前缀或包含-backup-)不会被处理。 - smoke-ocr — 诊断模式。通过 OCR 回退解析器加载扫描版 PDF,将识别文本输出到 stdout,并在结果非空时以
0退出。会单独显示DllNotFoundException/BadImageFormatException,以便立即发现原生库缺失或架构不匹配的问题。可用于验证给定主机上的 OCR 原生库路径是否正确配置(尤其是 win-arm64 dnx 安装)。
功能
搜索
- 混合 BM25 + 向量搜索,并使用 Reciprocal Rank Fusion (RRF)
- 未配置嵌入提供方时回退为仅 BM25 搜索
- 针对韩语优化的分块(句子边界、小数保护、括号感知)
- 通过
System.Numerics.Vector加速 SIMD 余弦相似度计算 - 使用 FTS5 三元组索引进行子串和适用于 CJK 的关键词匹配
索引
- 通过 SHA256 变更检测实现增量索引
- 使用 AI 为分块添加上下文,并进行双语关键词增强(参见分块上下文增强)
- 两阶段提交管道可在嵌入失败时保留上游的高开销工作(参见索引工作原理)
- 从 DOCX/HWPX 中提取数学公式,并转换为
[math: LaTeX]块 - PDF 的 OCR 回退功能(对扫描页面使用 Tesseract eng+kor)
- 通过 Whisper.net 转录音频(
.mp3、.wav、.m4a、.ogg、.flac、.webm)——仅限 Windows。启动时会根据检测到的 GPU/RAM/核心数自动选择模型大小(Tiny→Large);每个转录分块都会记录audio.model_size和audio.transcribed_at,便于日后审核重新索引 - 跨进程索引锁,自动清理过期 PID
- 清理已删除文件的孤立数据
队列协调器
- 所有索引请求都通过
start_reindexMCP 工具处理——不会直接启动 exec - 范围合并规则:full ⊃ contextualization ⊃ embedding(重复请求会升级范围,而非重复执行)
- 基于 PID 的协调器锁,并带有复用防护(
orchestrator.lock) - 逻辑删除知识库(移除 config.json)+ 使用
prune-orphans进行物理清理 - 延迟索引,用于应用关闭时批量处理(
--sweep-all)
运维
- 多知识库服务:单个进程提供基础路径下的所有知识库,并按需加载每个知识库
- SQLite WAL 模式允许在索引期间进行搜索
- 通过
cancel文件实现优雅关闭 - 每个知识库都使用
config.json配置提供方
集成
- Ollama 原生集成 — 通过
/api/embed生成嵌入,通过/api/chat进行上下文化,支持keep_alive和num_ctx。需要 Ollama 0.4.0+。 - 兼容 OpenAI — 通过
/v1/embeddings生成嵌入,通过/v1/chat/completions进行上下文化。适用于 OpenAI、Azure OpenAI、Groq、LM Studio、Together AI。 - Gemini 原生集成 — 通过
/v1beta/models/{model}:embedContent生成嵌入,支持task_type非对称检索(RETRIEVAL_DOCUMENT/RETRIEVAL_QUERY)和 Matryoshka 维度截断(768 / 1536 / 3072)。gemini-embedding-2,支持多语言,输入上限为 8k token。 - Anthropic — 通过
/v1/messages进行上下文化。 - 通过环境变量设置 API 密钥 —
OPENAI_API_KEY、ANTHROPIC_API_KEY等。批量索引命令(exec、exec-queue)仅支持环境变量。交互式 MCP 搜索可在客户端支持的情况下回退到 MCP 信息征询。 - 标准 MCP stdio 传输(通过 stdin/stdout 传输 JSON-RPC)
分块上下文化
标准 RAG 分块会丢失上下文——从周围段落中截取的关于“该协议”的句子会变得含义模糊。此服务通过统一分块上下文化解决这一问题:每个分块仅调用一次大模型,一次性生成上下文说明和双语(韩语 + 英语)关键词。
结果与原始分块文本一并存储:
- 保留原始文本,以便准确显示检索结果
- 上下文化文本用于生成嵌入并编入 BM25 索引
- 双语关键词支持跨语言搜索——韩语查询可以检索到英文文档,反之亦然
在 config.json 中设置 contextualizer 即可启用此功能。如果偏好对原始分块直接编制索引,也可以禁用此功能(将 provider/model 设置为空)。
索引工作原理
exec 命令会对每个文件运行 5 阶段流水线:
- 提取 — 从文档中提取文本(DOCX、PDF OCR、音频转录等)
- 分块 — 拆分为约 1000 字符的窗口
- 上下文化 — 由大模型丰富内容(可选,参见上文)
- 生成嵌入 — 通过 API 生成向量嵌入
- 持久化 — 保存到 SQLite
对于大型文件,仅阶段 1 就可能耗时 20 分钟以上——例如对 596 页的扫描版 PDF 进行 OCR,或转录数小时的音频。每个知识库中的首个音频文件还需要一次性下载 ggml 模型(缓存于 {UserProfile}/.fieldcure/whisper-models/)。为避免后续阶段失败时丢失耗费大量资源的上游处理结果,流水线采用两次提交模型:
Stages 1-3 (Extract → Chunk → Contextualize)
↓
[Commit 1] chunks saved as PendingEmbedding
↓
Stage 4 (Embed)
├─ success → [Commit 2a] promote chunks to Indexed
└─ failure → chunks remain PendingEmbedding (retry next exec)
重要性:25 分钟的 OCR 结果会在调用任何嵌入 API 之前持久化到磁盘。如果阶段 4 失败(网络错误、速率限制、token 限制、进程崩溃,甚至断电),分块仍会保留。下一次运行 exec 时会根据哈希跳过该文件(不再重新运行 OCR),并由延迟重试流程仅重试阶段 4。
分块级故障隔离(二分拆分)
如果文件中的某个分块超出嵌入模型的 token 限制(例如,教科书中数学内容密集的页面),二分拆分算法会隔离该分块:
EmbedBatch([0..1249]) → 400 "input[846] too long"
├─ EmbedBatch([0..624]) → OK (promote 625)
└─ EmbedBatch([625..1249]) → 400
├─ EmbedBatch([625..937]) → 400
│ ... (binary search narrows toward chunk 846)
│ └─ EmbedBatch([846..846]) → 400 (mark chunk 846 Failed)
└─ EmbedBatch([938..1249]) → OK (promote 312)
结果:1249 个分块已编入索引,只有第 846 个分块被标记为 Failed。文件状态变为 Degraded——内容仍可部分搜索,而非完全不可用。
延迟重试流程
每次 exec 结束时,都会重试之前运行中仍处于 PendingEmbedding 状态的分块:
- 从 DB 读取已丰富的文本——不重新运行 OCR 或上下文化
- 仅调用嵌入 API——通常只需几秒,而非几分钟
- 每个分块最多重试 3 次;重试次数耗尽后,该分块会被标记为
Failed - 遇到认证错误(401/403)时,会将 provider 标记为不可用,并跳过本轮剩余重试
文件状态
| 状态 | 含义 | 跳过哈希匹配文件的行为 |
|---|---|---|
Ready | 已完成索引 | 哈希匹配时跳过 |
Degraded | 部分分块失败(已通过二分拆分隔离) | 哈希匹配时跳过 |
PartiallyDeferred | 分块等待重试嵌入 | 主循环跳过;延后处理阶段会接手 |
Failed | 提取失败或嵌入多次失败 | 跳过;需要使用 --force 重试 |
NeedsAction | 需要用户干预 | 跳过,并单独计数 |
架构版本控制
每个知识库数据库都带有 PRAGMA user_version 标记。exec 命令会在 InitializeSchema() 过程中自动迁移旧架构。serve 命令以只读方式打开数据库,绝不会触发迁移——旧架构的知识库仍可正常提供搜索查询,其新功能列则保持未使用状态。
安装
dotnet tool(推荐)
dotnet tool install -g FieldCure.Mcp.Rag
从源代码安装
git clone https://github.com/fieldcure/fieldcure-mcp-rag.git
cd fieldcure-mcp-rag
dotnet build
要求
- .NET 8.0 Runtime 或更高版本
- OCR:仅限 Windows x64 — 扫描版 PDF 的 Tesseract OCR 会在首次使用时延迟加载(仅限 Windows)。在其他平台上,含有嵌入文本的 PDF 可正常处理;没有文本层的扫描页面会被静默跳过。
- 嵌入提供商(Ollama、OpenAI 等)——可选;没有它也可使用 BM25 搜索
- Ollama 0.4.0 或更高版本(如果使用 Ollama 进行嵌入或上下文补充)
快速开始
为文件夹编制索引并搜索,无需任何嵌入配置(仅使用 BM25):
# 1. Install
dotnet tool install -g FieldCure.Mcp.Rag
# 2. Create a minimal config
$kbPath = "$env:LOCALAPPDATA\FieldCure\Mcp.Rag\demo"
New-Item -ItemType Directory -Force -Path $kbPath
@'
{
"id": "demo",
"name": "Demo KB",
"sourcePaths": ["C:\\my-docs"]
}
'@ | Set-Content "$kbPath\config.json"
# 3. Index
fieldcure-mcp-rag exec --path $kbPath
# 4. Start the search server
fieldcure-mcp-rag serve --base-path "$env:LOCALAPPDATA\FieldCure\Mcp.Rag"
如需通过语义搜索和上下文补充获得完整的检索质量,请在 config.json 中添加 embedding 和 contextualizer 配置块——请参阅下方的用法。
用法
1. 创建知识库文件夹
%LOCALAPPDATA%\FieldCure\Mcp.Rag\{kb-id}\config.json
{
"id": "my-kb-001",
"name": "Project Docs",
"created": "2026-04-03T00:00:00Z",
"sourcePaths": ["C:\\Users\\me\\Documents\\project-docs"],
"contextualizer": {
"provider": "anthropic",
"model": "claude-haiku-4-5-20251001",
"apiKeyPreset": "Claude"
},
"embedding": {
"provider": "openai",
"model": "text-embedding-3-small",
"apiKeyPreset": "OpenAI"
}
}
API 密钥从环境变量中读取:apiKeyPreset: "OpenAI" → OPENAI_API_KEY,"Claude" → ANTHROPIC_API_KEY,"Gemini"(或 "Google")→ GEMINI_API_KEY。
Gemini 嵌入示例——采用非对称检索和 1536 维 Matryoshka 截断(仅占完整 3072 维存储空间的 50%,且 MTEB 分数相同):
"embedding": {
"provider": "gemini",
"model": "gemini-embedding-2",
"apiKeyPreset": "Gemini",
"dimension": 1536
}
| 维度 | MTEB | 存储空间 | 用途 |
|---|---|---|---|
| 768 | 67.99 | 25% | 存储空间受限 |
| 1536 | 68.17 | 50% | 推荐默认值 |
| 3072 | 68.17 | 100% | 最高质量(预归一化) |
在 serve 模式下,如果客户端支持 MCP elicitation,search_documents 也可通过 MCP elicitation 提示用户。在 exec 和 exec-queue 模式下,必须通过环境变量提供缺失的密钥。 |
2. 为文档编制索引
fieldcure-mcp-rag exec --path "C:\Users\me\AppData\Local\FieldCure\Mcp.Rag\my-kb-001"
3. 启动 MCP 搜索服务
fieldcure-mcp-rag serve --base-path "C:\Users\me\AppData\Local\FieldCure\Mcp.Rag"
单个 serve 进程可处理基础路径下的所有知识库。工具接受 kb_id 参数,以指定目标知识库。
Claude Desktop
将以下内容添加到 claude_desktop_config.json:
{
"mcpServers": {
"rag": {
"command": "fieldcure-mcp-rag",
"args": ["serve", "--base-path", "C:\\Users\\me\\AppData\\Local\\FieldCure\\Mcp.Rag"],
"env": {
"OPENAI_API_KEY": "sk-...",
"ANTHROPIC_API_KEY": "sk-ant-..."
}
}
}
}
config.json 参考
| 字段 | 描述 |
|---|---|
id | 知识库标识符 |
name | 显示名称 |
sourcePaths | 要编制索引的文件夹列表(支持多个) |
contextualizer.provider | "anthropic"、"openai"、"ollama",或留空以禁用 |
embedding.provider | "openai"、"ollama"、"gemini",或留空以禁用 |
embedding.dimension | 输出维度。0 = 提供方默认值。Gemini 支持 MRL 截断:768 / 1536 / 3072。 |
contextualizer.model | 模型 ID,或留空以禁用上下文化处理 |
contextualizer.apiKeyPreset | 映射到环境变量:"OpenAI" → OPENAI_API_KEY,"Claude" → ANTHROPIC_API_KEY |
contextualizer.baseUrl | API 基础 URL 覆盖值(null = 提供方默认值) |
embedding.* | 结构与 contextualizer 相同 |
embedding.maxChunkChars | 预拆分前每个分块的最大字符数(默认值:4000) |
embedding.batchSize | 每次嵌入 API 调用的最大分块数(默认值:根据提供方表自动确定) |
embedding.keepAlive | 仅限 Ollama:VRAM 保留时长(默认值:"5m") |
embedding.numCtx | 仅限 Ollama:上下文窗口令牌数(默认值:8192)。仅限 contextualizer。 |
systemPrompt | 用于上下文化处理的自定义系统提示词(null = 内置默认值) |
工具
除 list_knowledge_bases 外,所有工具都需要 kb_id 参数来指定目标知识库。
| 工具 | 描述 |
|---|---|
list_knowledge_bases | 列出所有可用的 KB 及其状态(文件/分块数量、索引状态) |
search_documents | BM25 + 向量混合搜索,使用 RRF。支持 search_mode:auto、bm25、vector |
get_document_chunk | 按 ID 获取特定分块的完整内容 |
start_reindex | 将索引请求加入队列。支持范围合并、强制/延迟标志、编排器自动启动 |
cancel_reindex | 移除待处理(尚未开始)的队列条目 |
get_index_info | 索引元数据、队列状态(状态/位置/延迟/last_error)、上下文化处理健康状况 |
check_changes | 试运行文件系统扫描。轻量级,不调用 API |
搜索模式
search_mode | 行为 |
|---|---|
auto | 有可用嵌入时使用混合搜索,否则使用 BM25。推荐 |
bm25 | 仅关键词搜索(FTS5)。不调用嵌入 API |
vector | 仅语义搜索。未配置嵌入提供方时会报错 |
支持的格式
文档格式由 FieldCure.DocumentParsers 提供:
- DOCX — Microsoft Word(支持数学公式提取)
- HWPX — 韩国标准文档(OWPML,支持数学公式提取)
- XLSX — Excel 电子表格
- PPTX — PowerPoint 演示文稿
- PDF — 提取 PDF 文本并添加
## Page N标题;扫描页面使用 OCR 回退(Tesseract,eng+kor) - TXT, MD — 纯文本 / Markdown
项目结构
src/FieldCure.Mcp.Rag/
├── Program.cs # CLI entry (exec | exec-queue | serve | prune-orphans)
├── MultiKbContext.cs # Multi-KB manager (lazy load, Classify, lazy unload)
├── ExecQueueRunner.cs # Deferred queue orchestrator
├── OrphanCleanupRunner.cs # prune-orphans CLI
├── Configuration/
│ ├── RagConfig.cs # config.json model (KeepAlive, NumCtx fields)
│ └── OllamaDefaults.cs # Shared defaults (KeepAlive="5m", NumCtx=8192)
├── Indexing/
│ ├── IndexingEngine.cs # 5-stage pipeline (2-commit model)
│ └── EmbeddingBatchSplitter.cs # Binary-split per-chunk failure isolation
├── Contextualization/
│ ├── IChunkContextualizer.cs
│ ├── OpenAiChunkContextualizer.cs # /v1/chat/completions
│ ├── OllamaChunkContextualizer.cs # /api/chat (keep_alive + num_ctx)
│ ├── AnthropicChunkContextualizer.cs
│ └── NullChunkContextualizer.cs
├── Embedding/
│ ├── IEmbeddingProvider.cs
│ ├── OpenAiCompatibleEmbeddingProvider.cs # /v1/embeddings
│ ├── OllamaEmbeddingProvider.cs # /api/embed (keep_alive)
│ ├── NullEmbeddingProvider.cs
│ └── EmbeddingBatchSizes.cs
├── Storage/
│ └── SqliteVectorStore.cs # SQLite + FTS5 + SIMD cosine similarity
├── Search/
│ ├── HybridSearcher.cs # BM25 + Vector → RRF
│ └── RrfFusion.cs
├── Chunking/
│ ├── TextChunker.cs
│ └── ChunkLimits.cs
└── Tools/
├── ListKnowledgeBasesTool.cs
├── SearchDocumentsTool.cs
├── GetDocumentChunkTool.cs
├── StartReindexTool.cs # Queue entry point + orchestrator spawn
├── CancelReindexTool.cs # Remove pending queue entry
├── GetIndexInfoTool.cs # Includes queue state
└── CheckChangesTool.cs
数据存储
知识库数据存储在 %LOCALAPPDATA%\FieldCure\Mcp.Rag\{kb-id}\:
config.json— 知识库配置rag.db— SQLite 数据库(分块、嵌入、FTS5 索引、文件哈希、索引锁)
队列和锁文件位于 %LOCALAPPDATA%\FieldCure\Mcp.Rag\:
.deferred-queue.json— 待处理的索引请求orchestrator.lock— 队列编排器的 PID 锁
开发
# Build
dotnet build
# Test
dotnet test
# Pack as dotnet tool
dotnet pack src/FieldCure.Mcp.Rag -c Release
另请参阅
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。