Token导航 LogoToken导航TokenDH.com
Staged Rag MCP logo
搜索检索stdio官方级别未说明来源级核验

Staged Rag MCP

MCP Server

一个基于模型上下文协议(MCP)的两阶段检索增强生成系统,通过先检索摘要再选择性扩展文档的方式提高检索效率和准确性。

工具数

17

提示词数

0

GitHub Stars

0

资源数

0
检索增强生成搜索PythonClaude文档检索Claude DesktopClaudeVS Code

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

smechello

提供方

smechello

最后核验

2026/5/17 20:19

运行时

Python

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

python -m venv .venv

详细介绍

Staged RAG MCP Server

A production-grade, two-level Retrieval-Augmented Generation server built on the Model Context Protocol (MCP)

Search smart. Retrieve less. Answer better.

Created by Shashidhar Reddy Nalamari • nalamarishashidharreddy@gmail.com

______________________________________________________________________

目录

- 系统架构图 - 两级检索管道 - 数据流 - 组件架构

- 基本安装 - 使用可选提供程序进行安装 - 开发安装

- 配置文件 - 服务器配置 - 嵌入配置 - 发电配置 - 分块配置 - 检索配置 - 存储配置 - 摄入配置 - 日志记录配置 - 知识库配置 - 环境变量 - 完整配置参考

- 标准模式(流式HTTP) - STDIO模式 - 使用知识库监视器

- 谷歌双子座(默认) - 开放人工智能 - Ollama(当地) - 拥抱脸 - Azure OpenAI - 一起AI - LM工作室(本地) - 切换提供商 - 确定性回退

- 检索工具 - 搜索_总结 - get_文档 - get_document_chunk - 高级搜索工具 - 混合搜索 - 多查询搜索 - find_类似物 - 文档管理工具 - ingest_文档 - ingest_batch - update_document - 删除文档 - 元数据工具 - get_document_metadata - 观察性工具 - collection_stats - list_collections - 解释检索 - 检索日志 - 知识库工具 - kb_status - 惊讶

- 概述 - 运作原理 - 支持的文件类型 - 自动生成的标签 - PDF支持 - 清单跟踪 - 文件夹组织 - 初始同步与后台监视器

- 数据摄取管道 - 文档模型 - 分块策略 - 摘要生成 - 嵌入和索引

- 语义搜索 - BM25关键字搜索 - 混合搜索 - 多查询融合 - 相似性搜索 - 及排名

- 什么是收藏 - 创建收藏 - 多重收集策略 - 收款统计

- 文档存储(JSON) - 矢量索引(NumPy) - BM25索引(内存中) - 审核日志(jsonl) - KB清单(JSON)

- 审计日志 - 检索说明 - 收集监控

- - 克劳德桌面版 - 自定义MCP客户端

- 系统提示 - 评估摘要提示 - 深度分析提示

- 运行测试 - 测试结构 - 编写新测试

- 速率限制 - 代币预算管理 - 嵌入缓存 - 指标表现

- API密钥管理 - 数据隐私 - 访问控制

______________________________________________________________________

概述

分级RAG MCP服务器 是一个复杂的检索增强生成系统,通过 模型上下文协议(MCP)与将整个文档转储到LLM上下文窗口的传统RAG系统不同,Staged RAG使用 搜索然后展开 策略:首先检索轻量级摘要以识别相关文档,然后选择性地仅获取重要文档的完整内容。

这种方法大大减少了令牌消耗,提高了响应质量,并提供了每个检索决策的完全可审计性。

为什么要分阶段进行RAG?

传统的RAG系统有一个根本问题:它们检索K个文档,并将所有文档推送到LLM上下文中,无论每个文档是否真正相关。这导致:

  • 浪费的代币:无关文档占用了昂贵的上下文窗口空间
  • 分散注意力:重要信息在噪音中丢失
  • 不透明:用户看不到为什么选择某些文档
  • 更高的延迟:处理不必要的文本会减慢响应速度

分段RAG通过引入两级检索管道来解决这些问题:

Level 1: Search Summaries    →    Compact summaries + scores (cheap)
         ↓ (evaluate)
Level 2: Get Full Documents   →    Complete text + chunks (selective)
         ↓ (optional)
Level 2.5: Get Specific Chunk →    Single chunk (surgical)

LLM(或用户)检查1级结果,并决定哪些文件需要完全扩展。这意味着您只需为实际需要的代币付费。

关键差异

功能传统RAG分级RAG MCP
检索策略单遍:检索和注入双遍:总结→ 扩展
令牌效率低--上下文中的所有K个文档高--仅扩展了相关文档
透明度黑框每次检索的完整审计跟踪
搜索模式通常为一种(语义)语义、BM25、混合、多查询
协议自定义APIMCP标准-适用于任何MCP客户端
知识库仅手动摄取使用文件监视器自动同步文件夹
嵌入提供商通常一个7个提供商:Gemini、OpenAI、Ollama、HuggingFace、Azure、Together、LM Studio

______________________________________________________________________

主要特点

岩芯回收

  • 两级分阶段检索 --首先搜索摘要(级别1),然后展开所选文档(级别2),可选单块检索(级别2.5)
  • 语义搜索 --使用最先进的嵌入模型进行向量相似性搜索
  • BM25关键字搜索 --通过Okapi BM25进行基于TF IDF的经典关键字匹配
  • 混合搜索 --语义和关键字分数与归一化权重的可配置混合
  • 多查询融合 --使用交互排名融合(RRF)或最大分数聚合运行多个查询并合并结果
  • 类似文档发现 --查找语义上与参考文档相似的文档

文档管理

  • 单文档摄入 --添加带有标题、文本、标签、元数据和可选预先计算的摘要的文档
  • 批量摄取 --在一次操作中批量摄取多达50个文档
  • 文档更新 --修改元数据、标签或全文(触发自动重分块和重嵌入)
  • 文档删除 --通过自动索引清理(矢量索引+BM25重建)删除文档
  • 令牌计数 --用于预算管理的自动令牌计数

知识库(自动同步文件夹)

  • 文件夹监视器 --基于后台轮询的文件监视器(无特定于操作系统的事件依赖关系)
  • 自动摄入 --将文件放入 knowledge_base/ 它们会立即被编入索引
  • 变化检测 --基于SHA-256哈希的变化检测;修改后的文件会自动重新索引
  • 删除跟踪 --删除的文件会自动从矢量存储中清除
  • PDF支持 --通过以下方式提取完整PDF文本 pypdf 具有元数据标题提取功能
  • 清单跟踪 --持久JSON清单在服务器重启时将文件映射到文档ID
  • 自动标记 --文件会自动按扩展名、源和子文件夹位置标记
  • 文本清理 --智能清理PDF工件:页码、CamelCase连接、过多空白

嵌入提供者

  • 谷歌双子座 --默认提供程序使用 gemini-embedding-001 (3072个尺寸)
  • 开放人工智能text-embedding-3-small / text-embedding-3-large
  • 奥拉玛 --本地模型,如 nomic-embed-text (不需要API密钥)
  • 拥抱脸 --本地 sentence-transformers 或HuggingFace推理API
  • Azure OpenAI --企业Azure OpenAI部署
  • 一起AI --共同嵌入AI模型
  • LM工作室 --通过LM Studio进行本地OpenAI兼容嵌入
  • 确定性回退 -当没有API可用时,基于SHA-256的确定性向量

可观测性

  • 审计日志 --每个工具调用都记录到JSONL中,并带有时间戳、参数、结果计数、文档ID和延迟
  • 检索说明 --检查任何查询文档对的余弦相似度、BM25分数和术语重叠
  • 收款统计 --文档计数、令牌总数、标签/源分布、索引大小
  • 检索日志 --使用工具和会话筛选器查询最近的审核条目
  • 速率限制 -内置请求调步(80 RPM)以保持在API免费层内

建筑

  • MCP标准 --通过FastMCP建立在模型上下文协议之上;适用于VS Code、Claude Desktop和任何MCP客户端
  • 提供商无关嵌入 --工厂模式与懒惰的进口;仅在选中时加载可选依赖项
  • 线程安全 --所有存储、索引和记录器都使用线程锁来实现并发安全
  • 防撞工具 --每个MCP工具都被包裹在错误捕获装饰器中;服务器永远不会因工具故障而崩溃
  • 可通过YAML配置 --基本配置+本地覆盖;机密的环境变量
  • 零外部服务 --不需要数据库服务器;所有内容都存储为本地JSON+NumPy文件

______________________________________________________________________

建筑

系统架构图

┌──────────────────────────────────────────────────────────────────────────┐
│                          MCP CLIENT                                      │
│                  (VS Code / Claude / Custom)                             │
└──────────────────────────┬───────────────────────────────────────────────┘
                           │  MCP Protocol (HTTP / STDIO)
                           ▼
┌──────────────────────────────────────────────────────────────────────────┐
│                        MCP SERVER (FastMCP)                              │
│  ┌────────────────────────────────────────────────────────────────────┐  │
│  │                    server.py — Tool Registry                       │  │
│  │                                                                    │  │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────────┐  │  │
│  │  │  Retrieval   │  │  Management  │  │  Observability           │  │  │
│  │  │  Tools       │  │  Tools       │  │  Tools                   │  │  │
│  │  │              │  │              │  │                          │  │  │
│  │  │ search_      │  │ ingest_      │  │ collection_stats         │  │  │
│  │  │  summaries   │  │  document    │  │ list_collections         │  │  │
│  │  │ get_         │  │ ingest_batch │  │ explain_retrieval        │  │  │
│  │  │  documents   │  │ update_      │  │ retrieval_log            │  │  │
│  │  │ get_document │  │  document    │  │                          │  │  │
│  │  │  _chunk      │  │ delete_      │  │                          │  │  │
│  │  │ hybrid_      │  │  document    │  │                          │  │  │
│  │  │  search      │  │              │  │                          │  │  │
│  │  │ multi_query  │  │              │  │                          │  │  │
│  │  │  _search     │  │              │  │                          │  │  │
│  │  │ find_similar │  │              │  │                          │  │  │
│  │  └──────────────┘  └──────────────┘  └──────────────────────────┘  │  │
│  └────────────────────────────────────────────────────────────────────┘  │
└──────────────────────────┬───────────────────────────────────────────────┘
                           │
                           ▼
┌──────────────────────────────────────────────────────────────────────────┐
│                      SERVICE LAYER (service.py)                          │
│                                                                          │
│  ┌────────────────┐  ┌────────────────┐  ┌────────────────────────────┐  │
│  │ RAGService     │  │ KBManager      │  │ SummaryGenerator           │  │
│  │ (Singleton)    │  │ (Singleton)    │  │ (Gemini / Local Fallback)  │  │
│  └───────┬────────┘  └───────┬────────┘  └────────────────────────────┘  │
│          │                   │                                           │
└──────────┼───────────────────┼───────────────────────────────────────────┘
           │                   │
           ▼                   ▼
┌──────────────────────────────────────────────────────────────────────────┐
│                         CORE LAYER                                       │
│                                                                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐  ┌─────────────┐   │
│  │ DocumentStore│  │ VectorIndex  │  │ BM25Scorer   │  │ ChunkManager│   │
│  │ (JSON)       │  │ (NumPy)      │  │ (rank-bm25)  │  │ (Sentence)  │   │
│  └──────┬───────┘  └──────┬───────┘  └──────────────┘  └─────────────┘   │
│         │                 │                                              │
│  ┌──────┴─────────────────┴──────────────────────────────────────────┐   │
│  │                    EmbeddingEngine                                │   │
│  │  ┌─────────┐ ┌────────┐ ┌────────┐ ┌────────────┐ ┌────────────┐  │   │
│  │  │ Gemini  │ │ OpenAI │ │ Ollama │ │ HuggingFace│ │ Together   │  │   │
│  │  └─────────┘ └────────┘ └────────┘ └────────────┘ └────────────┘  │   │
│  │  ┌──────────────┐ ┌──────────┐ ┌──────────────────────────────┐   │   │
│  │  │ Azure OpenAI │ │ LMStudio │ │ Deterministic Fallback       │   │   │
│  │  └──────────────┘ └──────────┘ └──────────────────────────────┘   │   │
│  └───────────────────────────────────────────────────────────────────┘   │
│                                                                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────────────┐    │
│  │ FileWatcher  │  │ KBManifest   │  │ AuditLogger                  │    │
│  │ (Polling)    │  │ (JSON)       │  │ (JSONL)                      │    │
│  └──────────────┘  └──────────────┘  └──────────────────────────────┘    │
│                                                                          │
└──────────────────────────────────────────────────────────────────────────┘
           │                 │                            │
           ▼                 ▼                            ▼
┌──────────────┐  ┌──────────────┐             ┌──────────────────┐
│ data/store/  │  │ data/index/  │             │ data/logs/       │
│ *.json       │  │ *.npz        │             │ audit.jsonl      │
└──────────────┘  └──────────────┘             └──────────────────┘

两级检索管道

Staged RAG的核心创新是两级检索管道:

                    User Query
                        │
                        ▼
              ┌─────────────────┐
              │  LEVEL 1:       │
              │  search_        │     Lightweight — returns only
              │  summaries()    │     summaries + similarity scores
              └────────┬────────┘
                       │
                       ▼
              ┌─────────────────┐
              │  EVALUATE:      │     LLM or user inspects summaries
              │  Inspect scores │     and decides which docs to expand
              │  & summaries    │
              └────────┬────────┘
                       │
            ┌──────────┼──────────┐
            │          │          │
            ▼          ▼          ▼
     ┌──────────┐ ┌──────────┐ ┌──────────┐
     │ SKIP     │ │ LEVEL 2: │ │ LEVEL 2: │     Selective — only fetch
     │ (low     │ │ get_     │ │ get_     │     documents that scored
     │  score)  │ │ documents│ │ documents│     above threshold
     └──────────┘ └────┬─────┘ └────┬─────┘
                       │            │
                       ▼            ▼
              ┌─────────────────┐
              │  LEVEL 2.5:     │     Surgical — retrieve specific
              │  get_document_  │     chunks within a document
              │  chunk()        │     by index or semantic query
              └────────┬────────┘
                       │
                       ▼
              ┌─────────────────┐
              │  SYNTHESIZE:    │     Generate answer using only
              │  Answer with    │     the relevant retrieved content
              │  citations      │
              └─────────────────┘

数据流

Document Ingestion Flow:
─────────────────────────

  Input Text ──→ Token Count Check ──→ Chunking (sentence-based)
       │                                      │
       ▼                                      ▼
  Summary Generation ──────────────→  Document Model (Pydantic)
       │                                      │
       ▼                                      ▼
  Embedding (provider) ───────────→  Vector Index (NumPy cosine)
       │                                      │
       ▼                                      ▼
  BM25 Index (rebuild) ───────────→  JSON Document Store
       │                                      │
       ▼                                      ▼
  Audit Log Entry ────────────────→  Return doc_id + metadata

Search Flow:
────────────

  Query ──→ Embedding (provider) ──→ Vector Index Search (cosine)
       │                                      │
       ▼                                      ▼
  (Optional) BM25 Score ──────────→  Score Fusion (weighted)
       │                                      │
       ▼                                      ▼
  Filter (tags, min_score) ───────→  Ranked SummaryResults
       │                                      │
       ▼                                      ▼
  Audit Log Entry ────────────────→  Return SearchResponse

组件架构

组件文件责任
MCP服务器server.py工具注册、错误包装、服务器生命周期
RAG服务service.py核心编排:摄取、搜索、更新
配置config.pyYAML加载、设置数据类、合并逻辑
文档存储core/document_store.pyJSON支持的每个集合文档持久性
向量索引core/vector_index.py基于NumPy的具有NPZ持久性的余弦相似性指数
BM25评分器core/bm25.pyOkapi BM25关键字评分使用 rank-bm25
区块管理器core/chunk_manager.py基于句子的重叠文本分块
嵌入引擎core/embeddings.py具有速率限制和回退功能的多提供商嵌入
摘要生成器core/summary_generator.py基于Gemini的摘要,具有提取回退功能
键盘管理core/kb_manager.py文件监视器编排、摄取、重新同步
文件监视器core/file_watcher.py基于轮询的目录监视器,具有哈希跟踪功能
KB清单core/kb_manifest.py文件到文件id映射持久化
审计记录器logging/audit.py具有自动截断功能的线程安全JSONL审计日志
嵌入器工厂embeddings/factory.py懒惰的进口供应商工厂
提示prompts.py分阶段检索工作流的提示模板
工具集utils.py文本清理、句子分割、分块、向量运算

______________________________________________________________________

项目结构

staged-rag-mcp/
│
├── LICENSE                          # Custom license (free use, no false ownership claims)
├── README.md                        # This file — comprehensive project documentation
├── HOWTOUSE.md                      # Detailed usage guide with examples
├── pyproject.toml                   # Python project metadata and dependencies
├── config.yaml                      # Base configuration (version controlled)
├── config.local.yaml                # Local overrides (not version controlled)
├── .env                             # Environment variables (API keys — not committed)
│
├── src/
│   └── staged_rag/                  # Main package
│       ├── __init__.py              # Package version and exports
│       ├── server.py                # MCP server: tool registration, lifecycle
│       ├── service.py               # RAG service: core business logic
│       ├── config.py                # Configuration loading and dataclasses
│       ├── prompts.py               # Prompt templates for staged retrieval
│       ├── utils.py                 # Text processing utilities
│       │
│       ├── core/                    # Core engine components
│       │   ├── __init__.py
│       │   ├── document_store.py    # JSON-backed document persistence
│       │   ├── vector_index.py      # NumPy cosine similarity index
│       │   ├── bm25.py              # BM25 keyword scorer
│       │   ├── chunk_manager.py     # Sentence-based text chunking
│       │   ├── embeddings.py        # Multi-provider embedding engine
│       │   ├── summary_generator.py # AI summary with local fallback
│       │   ├── kb_manager.py        # Knowledge base folder orchestrator
│       │   ├── kb_manifest.py       # File → doc_id manifest tracker
│       │   └── file_watcher.py      # Polling-based file system watcher
│       │
│       ├── embeddings/              # Embedding provider implementations
│       │   ├── __init__.py
│       │   ├── base.py              # Abstract base class (EmbeddingBase)
│       │   ├── configs.py           # Provider configuration dataclasses
│       │   ├── factory.py           # Lazy-import provider factory
│       │   ├── gemini.py            # Google Gemini provider
│       │   ├── openai.py            # OpenAI provider
│       │   ├── ollama.py            # Ollama local provider
│       │   ├── huggingface.py       # HuggingFace (local + API)
│       │   ├── azure_openai.py      # Azure OpenAI provider
│       │   ├── together.py          # Together AI provider
│       │   └── lmstudio.py          # LM Studio local provider
│       │
│       ├── models/                  # Pydantic data models
│       │   ├── __init__.py
│       │   ├── document.py          # Document and DocumentChunk models
│       │   ├── search.py            # SearchResponse and SummaryResult models
│       │   └── audit.py             # AuditLogEntry model
│       │
│       ├── tools/                   # MCP tool implementations
│       │   ├── __init__.py          # Tool re-exports
│       │   ├── retrieval.py         # search_summaries, get_documents, get_document_chunk
│       │   ├── advanced.py          # hybrid_search, multi_query_search, find_similar
│       │   ├── management.py        # ingest, update, delete, kb_status, kb_resync
│       │   ├── metadata.py          # get_document_metadata
│       │   └── observability.py     # collection_stats, explain_retrieval, retrieval_log
│       │
│       ├── resources/               # MCP resource providers
│       │   ├── __init__.py
│       │   └── providers.py         # Document and collection resource URIs
│       │
│       └── logging/                 # Logging and audit
│           ├── __init__.py
│           └── audit.py             # Thread-safe JSONL audit logger
│
├── data/                            # Runtime data directory
│   ├── store/                       # Document store (JSON per collection)
│   │   └── default.json
│   ├── index/                       # Vector indexes (NPZ per collection)
│   │   └── default.npz
│   ├── logs/                        # Audit logs
│   │   └── audit.jsonl
│   ├── mock/                        # Mock data for testing
│   │   └── documents.json
│   └── kb_manifest.json             # Knowledge base manifest
│
├── knowledge_base/                  # Drop files here for auto-ingestion
│   └── README.md
│
├── scripts/                         # Utility scripts
│   ├── seed_mock_data.py            # Seed document store with sample data
│   ├── full_test.py                 # Run comprehensive test suite
│   ├── inspect_state.py             # Inspect current data store state
│   ├── run_eval.py                  # Run retrieval evaluation
│   ├── test_mcp_search.py           # Test MCP search functionality
│   └── test_search.py              # Test search functionality
│
└── tests/                           # Automated tests
    ├── test_agent_flow.py           # End-to-end agent flow tests
    ├── test_document_store.py       # Document store unit tests
    ├── test_embeddings.py           # Embedding provider tests
    ├── test_tools.py                # Tool function tests
    └── test_vector_index.py         # Vector index unit tests

______________________________________________________________________

先决条件

要求最低版本注意事项
python3.11+用途 match 声明, `X \Y` 类型工会
21.0+适用 pyproject.toml 支持
API密钥-至少有一个嵌入提供程序API密钥(请参阅 嵌入提供者)

可选先决条件

工具安装所需
奥拉玛本地嵌入模型奥拉玛
LM工作室本地LM工作室嵌入lmstudio.ai
Git版本控制git-scm.com

______________________________________________________________________

安装

基本安装

# Clone the repository
git clone https://github.com/reddynalamari/staged-rag-mcp.git
cd staged-rag-mcp

# Create virtual environment
python -m venv .venv

# Activate virtual environment
# Windows:
.venv\Scripts\activate
# macOS/Linux:
source .venv/bin/activate

# Install the package in editable mode
pip install -e .

使用可选提供程序进行安装

# Install with OpenAI support
pip install -e ".[openai]"

# Install with Ollama support
pip install -e ".[ollama]"

# Install with HuggingFace support
pip install -e ".[huggingface]"

# Install with Together AI support
pip install -e ".[together]"

# Install with FAISS support (faster vector search)
pip install -e ".[faiss]"

# Install ALL optional providers
pip install -e ".[all-providers]"

# Install with development tools
pip install -e ".[dev]"

开发安装

# Install everything (all providers + dev tools)
pip install -e ".[all-providers,dev]"

# Verify installation
python -c "from staged_rag import __version__; print(f'Staged RAG MCP v{__version__}')"

______________________________________________________________________

配置

配置文件

系统使用分层的YAML配置:

  1. 内置默认值 --硬编码 config.py
  2. config.yaml --基础项目配置(版本控制)
  3. config.local.yaml --本地覆盖(gitignored,具有最高优先级)

设置按顺序合并:默认值→ config.yamlconfig.local.yaml。以后文件中的任何键都会覆盖以前文件中的相同键。

服务器配置

server:
  name: staged-rag              # Server name (shown in MCP clients)
  transport: streamable-http    # Transport protocol: "streamable-http" or "stdio"
  host: 127.0.0.1              # Bind address for HTTP transport
  port: 8090                   # Port for HTTP transport

运输选项:

  • streamable-http --基于HTTP的传输;服务器在host:port上作为web服务运行
  • stdio --标准I/O传输;当MCP客户端生成服务器进程时使用

嵌入配置

embedding:
  provider: gemini              # Provider name (see Embedding Providers section)
  model: gemini-embedding-001   # Model name (provider-specific)
  dimensions: 3072              # Embedding vector dimensions
  batch_size: 32                # Max texts per embedding batch
  provider_config: {}           # Additional provider-specific config

发电配置

generation:
  model: gemini-2.5-flash-lite  # Model for summary generation
  summary_max_sentences: 4      # Max sentences in generated summaries

分块配置

chunking:
  chunk_size: 200               # Target tokens per chunk
  chunk_overlap: 20             # Overlap tokens between adjacent chunks
  min_chunk_size: 50            # Minimum tokens for a chunk to be kept

分块是如何工作的:

  • 文本在句末标点处被拆分为句子(., !, ?)
  • 句子被累积,直到块达到 chunk_size 代币
  • 当达到块边界时,最后一个 chunk_overlap 代币转移到下一个区块
  • 小于的块 min_chunk_size 令牌将被丢弃(除非它们是唯一的内容)

检索配置

retrieval:
  default_top_k: 5             # Default number of results per search
  max_top_k: 50                # Maximum allowed top_k (safety cap)
  default_collection: default  # Default collection name
  hybrid_semantic_weight: 0.7  # Semantic score weight in hybrid search
  hybrid_keyword_weight: 0.3   # Keyword score weight in hybrid search
  min_similarity_score: 0.0    # Minimum score threshold for results

存储配置

storage:
  data_dir: ./data              # Root data directory
  store_dir: ./data/store       # Document JSON store directory
  index_dir: ./data/index       # Vector index (NPZ) directory
  log_dir: ./data/logs          # Audit log directory

创建的存储文件:

  • data/store/.json --每个集合一个包含所有文档的JSON文件
  • data/index/.npz --每个集合一个NumPy压缩文件,包含所有向量
  • data/logs/audit.jsonl --仅附加审核日志

摄入配置

ingestion:
  max_document_tokens: 50000    # Maximum tokens per document (rejects larger)
  max_batch_size: 50            # Maximum documents per batch ingest
  auto_summary: true            # Auto-generate summaries on ingestion

日志记录配置

logging:
  audit_file: ./data/logs/audit.jsonl  # Audit log file path
  max_log_entries: 10000               # Auto-truncate after this many entries
  log_level: INFO                      # Python logging level

知识库配置

knowledge_base:
  enabled: true                       # Enable/disable the folder watcher
  kb_dir: ./knowledge_base            # Directory to watch for documents
  manifest_file: ./data/kb_manifest.json  # Manifest tracking file
  collection: default                 # Target collection for KB documents
  poll_interval: 5.0                  # Seconds between file system scans
  max_file_size: 10485760             # Maximum file size in bytes (10 MB)

环境变量

创建一个 .env 项目根目录中的文件:

# Required for Gemini (default provider)
GEMINI_API_KEY=your_gemini_api_key_here

# Alternative: Google API Key
GOOGLE_API_KEY=your_google_api_key_here

# For OpenAI provider
OPENAI_API_KEY=your_openai_api_key_here

# For Azure OpenAI provider
EMBEDDING_AZURE_OPENAI_API_KEY=your_azure_api_key
EMBEDDING_AZURE_DEPLOYMENT=your_deployment_name
EMBEDDING_AZURE_ENDPOINT=https://your-resource.openai.azure.com/
EMBEDDING_AZURE_API_VERSION=2024-02-01

# For Together AI provider
TOGETHER_API_KEY=your_together_api_key

# For HuggingFace Inference API
HUGGINGFACE_API_KEY=your_hf_api_key

完整配置参考

Click to expand — Complete config.yaml with all options and defaults

# ============================================================
# Staged RAG MCP Server — Full Configuration Reference
# ============================================================

server:
  name: staged-rag                   # Server display name
  transport: streamable-http         # "streamable-http" or "stdio"
  host: 127.0.0.1                   # HTTP bind address
  port: 8090                        # HTTP port

embedding:
  provider: gemini                   # gemini | openai | ollama | huggingface
                                     # | azure_openai | together | lmstudio
  model: gemini-embedding-001       # Model name (varies by provider)
  dimensions: 3072                   # Output vector dimensions
  batch_size: 32                     # Batch size for embedding calls
  provider_config: {}                # Provider-specific overrides:
    # ollama_base_url: http://localhost:11434
    # openai_base_url: https://api.openai.com/v1
    # huggingface_base_url: https://api-inference.huggingface.co/...
    # azure_kwargs:
    #   azure_deployment: my-deployment
    #   azure_endpoint: https://my-resource.openai.azure.com/
    #   api_version: 2024-02-01

generation:
  model: gemini-2.5-flash-lite      # Summary generation model
  summary_max_sentences: 4           # Max sentences in summaries

chunking:
  chunk_size: 200                    # Target tokens per chunk
  chunk_overlap: 20                  # Overlap between chunks
  min_chunk_size: 50                 # Minimum tokens per chunk

retrieval:
  default_top_k: 5                  # Default results per search
  max_top_k: 50                     # Maximum allowed top_k
  default_collection: default       # Default collection name
  hybrid_semantic_weight: 0.7       # Semantic weight in hybrid search
  hybrid_keyword_weight: 0.3        # Keyword weight in hybrid search
  min_similarity_score: 0.0         # Score threshold

storage:
  data_dir: ./data
  store_dir: ./data/store
  index_dir: ./data/index
  log_dir: ./data/logs

ingestion:
  max_document_tokens: 50000        # Max tokens per document
  max_batch_size: 50                # Max documents per batch
  auto_summary: true                # Auto-generate summaries

logging:
  audit_file: ./data/logs/audit.jsonl
  max_log_entries: 10000
  log_level: INFO                   # DEBUG | INFO | WARNING | ERROR

knowledge_base:
  enabled: true                     # true = active, false = disabled
  kb_dir: ./knowledge_base
  manifest_file: ./data/kb_manifest.json
  collection: default
  poll_interval: 5.0                # Seconds between scans
  max_file_size: 10485760           # 10 MB

______________________________________________________________________

快速开始

5分钟后起床跑步:

# 1. Clone and install
git clone https://github.com/reddynalamari/staged-rag-mcp.git
cd staged-rag-mcp
python -m venv .venv
.venv\Scripts\activate          # Windows
pip install -e .

# 2. Set your API key
echo GEMINI_API_KEY=your_key_here > .env

# 3. Seed sample data (optional)
python scripts/seed_mock_data.py

# 4. Start the server
python -m staged_rag.server

服务器启动于 http://127.0.0.1:8090.连接任何MCP客户端以开始查询。

______________________________________________________________________

如何使用指南

有关包含真实世界示例、每个功能的详细演练和广泛故障排除的全面、分步使用指南,请参阅 HOWTOUSE.md.

本指南包括:

第节你将学到什么
入门指南安装、API密钥设置、服务器启动、验证
配置所有配置选项,包括调优指南和完整示例
连接MCP客户端VS Code(HTTP/STDIO)、克劳德桌面、自定义客户端
文件摄入单次、批量、标记和基于收集的摄入
两级检索分阶段搜索的完整演练→ 扩展→ 块工作流
高级搜索混合搜索、多查询融合、相似文档、标签过滤
文档管理更新、删除、元数据检查
知识库自动同步文件夹设置、PDF、子文件夹、重新同步、自动标记
集合创建、组织和监视隔离的文档命名空间
可观测性解释检索评分、审核日志、系统健康监控
嵌入提供者所有7个提供商的详细设置及其示例
提示工程LLM集成的系统、评估和分析提示
真实世界用例团队知识库、研究论文、代码库文档、支持、个人笔记、多租户
性能调优搜索质量,API成本降低,大量收集处理
故障排除40+个问题,提供分步解决方案和错误消息参考
常见问题解答最常见问题的答案
新加入舞台RAG?HOWTOUSE.md 指南——它旨在让你在几分钟内从零到高效。

______________________________________________________________________

Python快速测试

from staged_rag.tools import search_summaries, get_documents

# Level 1: Search summaries
results = search_summaries("machine learning", top_k=3)
for r in results["results"]:
    print(f"  [{r['similarity_score']:.2f}] {r['title']}: {r['summary'][:80]}...")

# Level 2: Expand top result
if results["results"]:
    top_doc_id = results["results"][0]["doc_id"]
    full = get_documents([top_doc_id], include_chunks=True)
    print(f"\nFull text ({full['total_tokens']} tokens):")
    print(full["documents"][0]["full_text"][:200])

______________________________________________________________________

运行服务器

标准模式(流式HTTP)

python -m staged_rag.server

输出:

2026-02-09 10:00:00 [staged_rag.server] INFO: Starting Staged RAG MCP Server...
2026-02-09 10:00:01 [staged_rag.server] INFO: Server listening on http://127.0.0.1:8090

STDIO模式

对于生成服务器进程的MCP客户端(例如,Claude Desktop):

# In config.local.yaml
server:
  transport: stdio

然后,客户端使用以下命令启动服务器:

python -m staged_rag.server

使用知识库监视器

# In config.yaml or config.local.yaml
knowledge_base:
  enabled: true

输出包括:

2026-02-09 10:00:02 [staged_rag.server] INFO: Knowledge-base watcher active – monitoring ./knowledge_base
2026-02-09 10:00:02 [staged_rag.core.kb_manager] INFO: Running initial KB sync...
2026-02-09 10:00:03 [staged_rag.core.kb_manager] INFO: Initial KB sync complete: {'created': 3, 'modified': 0, 'deleted': 0, 'errors': 0}

______________________________________________________________________

嵌入提供者

Staged RAG通过工厂模式和延迟导入支持7个嵌入提供者。您只需要实际使用的提供程序的依赖关系。

谷歌双子座(默认)

embedding:
  provider: gemini
  model: gemini-embedding-001
  dimensions: 3072
# Required environment variable
GEMINI_API_KEY=your_key

# No additional pip install needed (google-genai is a core dependency)
型号尺寸备注
gemini-embedding-001768–3072可配置的输出维度

开放人工智能

embedding:
  provider: openai
  model: text-embedding-3-small
  dimensions: 1536
OPENAI_API_KEY=your_key
pip install -e ".[openai]"
型号尺寸备注
text-embedding-3-small1536快速、经济高效
text-embedding-3-large3072质量更高
text-embedding-ada-0021536旧型号

Ollama(当地)

embedding:
  provider: ollama
  model: nomic-embed-text
  dimensions: 768
  provider_config:
    ollama_base_url: http://localhost:11434
# No API key needed — runs locally
pip install -e ".[ollama]"
ollama pull nomic-embed-text
型号尺寸备注
nomic-embed-text768通用性良好
all-minilm384轻量化
mxbai-embed-large1024更高质量

拥抱脸

本地模式(句子转换):

embedding:
  provider: huggingface
  model: all-MiniLM-L6-v2
  dimensions: 384
pip install -e ".[huggingface]"

API模式(HuggingFace推理):

embedding:
  provider: huggingface
  model: sentence-transformers/all-MiniLM-L6-v2
  dimensions: 384
  provider_config:
    huggingface_base_url: https://api-inference.huggingface.co/pipeline/feature-extraction/sentence-transformers/all-MiniLM-L6-v2
HUGGINGFACE_API_KEY=your_key
pip install -e ".[openai]"   # Uses OpenAI-compatible client

Azure OpenAI

embedding:
  provider: azure_openai
  model: text-embedding-3-small
  dimensions: 1536
  provider_config:
    azure_kwargs:
      azure_deployment: my-embedding-deployment
      azure_endpoint: https://my-resource.openai.azure.com/
      api_version: 2024-02-01
EMBEDDING_AZURE_OPENAI_API_KEY=your_key
pip install -e ".[openai]"

一起AI

embedding:
  provider: together
  model: togethercomputer/m2-bert-80M-8k-retrieval
  dimensions: 768
TOGETHER_API_KEY=your_key
pip install -e ".[together]"

LM工作室(本地)

embedding:
  provider: lmstudio
  model: text-embedding-nomic-embed-text-v1.5
  dimensions: 768
  provider_config:
    openai_base_url: http://localhost:1234/v1
# No API key needed — runs locally via LM Studio
pip install -e ".[openai]"   # Uses OpenAI-compatible client

切换提供商

要切换提供商,请更新 config.local.yaml:

embedding:
  provider: ollama
  model: nomic-embed-text
  dimensions: 768

然后重新启动服务器。现有文件保留其嵌入内容;新文档使用新提供程序。

重要:如果更改嵌入提供程序或模型,现有的向量索引将变得不兼容。删除 data/index/*.npz 重新摄取文档或使用 kb_resync() 用于知识库文档。

确定性回退

如果嵌入API不可用(没有API密钥、速率受限、网络错误),则引擎返回到确定性向量生成器:

  1. 输入文本的SHA-256哈希→ seed
  2. 具有该种子的NumPy随机正态分布→ 向量
  3. L2标准化→ 单位向量

这确保了服务器永远不会因嵌入失败而崩溃。确定性向量产生一致的(但质量较低的)相似性得分。

______________________________________________________________________

MCP工具参考

所有工具都通过模型上下文协议公开,可以从任何MCP客户端调用。每个工具都被包裹在一个错误捕获装饰器中(@_safe_tool)--如果工具抛出异常,则返回 {"error": "ExceptionType: message"} 而不是使服务器崩溃。

检索工具

搜索_总结

一级检索 --每次搜索的入口点。返回具有相似性得分的紧凑摘要。

search_summaries(
    query: str,
    top_k: int = 5,
    collection: str = "default",
    min_score: float = 0.0,
    tags_filter: list[str] | None = None
) → dict

参数:

参数类型默认值说明
querystr*必需的*自然语言搜索查询
top_kint5结果数量(上限为 max_top_k)
collectionstr"default"要搜索的收藏
min_scorefloat0.0最小相似性得分阈值(0.0–1.0)
tags_filterlist[str]None仅返回至少有一个匹配标签的文档

退货:

{
  "query": "machine learning algorithms",
  "results": [
    {
      "doc_id": "a1b2c3d4-...",
      "title": "Introduction to ML",
      "summary": "This document covers fundamental machine learning concepts...",
      "similarity_score": 0.92,
      "token_count": 1500,
      "tags": ["ml", "tutorial"],
      "collection": "default"
    }
  ],
  "total_candidates": 25,
  "search_time_ms": 145.3
}

______________________________________________________________________

get_文档

二级检索 --获取所选文档ID的完整文档文本。

get_documents(
    doc_ids: list[str],
    include_chunks: bool = False,
    collection: str = "default"
) → dict

参数:

参数类型默认值说明
doc_idslist[str]*必需的*要检索的文档ID
include_chunksboolFalse包括单个块数据
collectionstr"default"要搜索的收藏

退货:

{
  "documents": [
    {
      "doc_id": "a1b2c3d4-...",
      "title": "Introduction to ML",
      "full_text": "Complete document text...",
      "source": "manual",
      "token_count": 1500,
      "tags": ["ml", "tutorial"],
      "metadata": {"author": "John"},
      "chunks": [
        {
          "chunk_index": 0,
          "text": "First chunk text...",
          "token_count": 195,
          "start_char": 0,
          "end_char": 1024
        }
      ]
    }
  ],
  "total_tokens": 1500
}

______________________________________________________________________

get_document_chunk

2.5级检索 --通过索引或语义查询检索单个块。

get_document_chunk(
    doc_id: str,
    chunk_index: int | None = None,
    chunk_query: str | None = None,
    collection: str = "default"
) → dict

参数:

参数类型默认值说明
doc_idstr*必需的*文档ID
chunk_indexintNone特定块索引(从0开始)
chunk_querystrNone语义查询以找到最相关的块
collectionstr"default"收藏名称
提供其中之一 chunk_indexchunk_query不是两者都有。

返回值(按索引):

{
  "doc_id": "a1b2c3d4-...",
  "chunk_index": 2,
  "total_chunks": 8,
  "text": "The chunk text content...",
  "token_count": 195,
  "has_previous": true,
  "has_next": true
}

返回(通过查询,包括相关性得分):

{
  "doc_id": "a1b2c3d4-...",
  "chunk_index": 5,
  "total_chunks": 8,
  "text": "Most relevant chunk...",
  "token_count": 180,
  "has_previous": true,
  "has_next": true,
  "relevance_score": 0.87
}

______________________________________________________________________

高级搜索工具

混合搜索

将语义(向量)搜索与BM25关键字匹配相结合,以提高召回率。

hybrid_search(
    query: str,
    top_k: int = 5,
    collection: str = "default",
    semantic_weight: float = 0.7,
    keyword_weight: float = 0.3
) → dict

参数:

参数类型默认值说明
querystr*必需的*搜索查询
top_kint5结果数量
collectionstr"default"收藏名称
semantic_weightfloat0.7向量相似度权重(0.0–1.0)
keyword_weightfloat0.3BM25关键字匹配权重(0.0–1.0)

它是如何工作的:

  1. 运行语义搜索→ 获取余弦相似性得分(已经为0-1)
  2. 运行BM25关键字搜索→ 将分数归一化为0-1(除以最大值)
  3. 计算加权组合: score = (semantic_weight × sem_score) + (keyword_weight × kw_score)
  4. 权重会自动归一化为1.0
  5. 返回按综合得分排名的top_k结果

最适合: 关键字精确匹配的查询与语义含义一起重要。

______________________________________________________________________

多查询搜索

运行多个查询并使用排名融合合并结果。

multi_query_search(
    queries: list[str],
    top_k: int = 5,
    collection: str = "default",
    fusion_method: str = "rrf"
) → dict

参数:

参数类型默认值说明
querieslist[str]*必需的*两个或多个搜索查询
top_kint5最终结果数量
collectionstr"default"收藏名称
fusion_methodstr"rrf"融合方法: "rrf" (互惠排名融合)或 "max" (最高分)

融合方法:

  • rrf (互惠排名融合): score = Σ 1/(60 + rank + 1) 对于文档出现的每个查询。出现在多个查询结果中的文档得到增强。
  • max:获取每个文档的所有查询的最大相似性得分。

最适合: 捕捉一个主题的多个方面。例如,同时搜索“神经网络”、“深度学习”、“反向传播”。

______________________________________________________________________

find_类似物

查找与参考文档类似的文档。

find_similar(
    doc_id: str,
    top_k: int = 5,
    exclude_same_source: bool = False,
    collection: str = "default"
) → dict

参数:

参数类型默认值说明
doc_idstr*必需的*参考文档ID
top_kint5类似文件的数量
exclude_same_sourceboolFalse从同一来源排除文档
collectionstr"default"收藏名称

它是如何工作的:

  1. 检索参考文档的摘要(或标题)
  2. 嵌入摘要文本
  3. 在向量索引中搜索最近邻
  4. 从结果中排除参考文档本身

______________________________________________________________________

文档管理工具

ingest_文档

将单个文档添加到系统中。

ingest_document(
    title: str,
    text: str,
    source: str = "manual",
    collection: str = "default",
    tags: list[str] | None = None,
    metadata: dict | None = None,
    summary: str | None = None
) → dict

参数:

参数类型默认值说明
titlestr*必需的*文档标题(不得为空)
textstr*必需的*文档全文(不得为空)
sourcestr"manual"源标识符(URL、路径、标签)
collectionstr"default"目标集合
tagslist[str]None可搜索标签
metadatadictNone任意键值元数据
summarystrNone预先计算的摘要(如果提供,则跳过自动生成)

加工管道:

  1. 验证标题和文本是否为非空
  2. 对照检查令牌计数 max_document_tokens
  3. 生成摘要(Gemini API→ 本地提取回退)
  4. 将文本分割成重叠的片段
  5. 创建 Document 具有UUID的模型
  6. 保存到JSON存储
  7. 嵌入摘要(或标题)→ 向矢量索引追加销售
  8. 重建BM25索引
  9. 写入审核日志条目

退货:

{
  "doc_id": "a1b2c3d4-e5f6-...",
  "title": "My Document",
  "collection": "default",
  "chunk_count": 8,
  "token_count": 1500,
  "summary": "Generated or provided summary...",
  "status": "indexed"
}

______________________________________________________________________

ingest_batch

在一次操作中批量摄取多个文档。

ingest_batch(
    documents: list[dict],
    collection: str = "default"
) → dict

参数:

参数类型默认值说明
documentslist[dict]*必需的*文档字典列表(每个字典都必须有 titletext)
collectionstr"default"目标集合

每个文档字典都支持与 ingest_document: title, text, source, tags, metadata, summary.

退货:

{
  "total": 10,
  "succeeded": 9,
  "failed": 1,
  "results": [
    {"doc_id": "...", "title": "Doc 1", "status": "indexed"},
    {"title": "Doc 2", "status": "error", "error": "Text must not be empty"}
  ],
  "total_tokens_indexed": 12500
}

______________________________________________________________________

update_document

更新现有文档的元数据、文本或摘要。

update_document(
    doc_id: str,
    text: str | None = None,
    title: str | None = None,
    tags: list[str] | None = None,
    metadata: dict | None = None,
    summary: str | None = None,
    collection: str = "default"
) → dict

除以下参数外的所有参数 doc_id 是可选的——只有提供的字段才会更新。

行为:

  • title, tags:直接更换
  • metadata:与现有元数据进行浅层合并
  • text:触发完整的重新分块、重新摘要和重新嵌入
  • summary (无 text):更新摘要并重新嵌入

______________________________________________________________________

删除文档

删除文档和所有相关数据。

delete_document(
    doc_id: str,
    collection: str = "default"
) → dict

清理的内容:

  1. 从JSON存储中删除文档
  2. 从NumPy索引中删除向量
  3. 在没有文档的情况下重建BM25索引
  4. 已记录审核日志条目

______________________________________________________________________

元数据工具

get_document_metadata

在不加载全文的情况下检索文档元数据(轻量级)。

get_document_metadata(
    doc_id: str,
    collection: str = "default"
) → dict

退货:

{
  "doc_id": "a1b2c3d4-...",
  "title": "Document Title",
  "source": "manual",
  "collection": "default",
  "tags": ["tag1", "tag2"],
  "token_count": 1500,
  "chunk_count": 8,
  "created_at": "2026-02-08T10:30:00+00:00",
  "updated_at": "2026-02-09T14:20:00+00:00",
  "metadata": {"author": "Jane Doe"}
}

______________________________________________________________________

观察性工具

collection_stats

获取集合的全面统计数据。

collection_stats(
    collection: str = "default"
) → dict

退货:

{
  "collection": "default",
  "document_count": 25,
  "total_tokens": 37500,
  "avg_tokens_per_doc": 1500.0,
  "total_chunks": 200,
  "tag_distribution": {"ml": 10, "tutorial": 5, "source:knowledge_base": 8},
  "source_distribution": {"manual": 15, "knowledge_base:notes.md": 5, "batch": 5},
  "oldest_document": "2026-01-15T08:00:00+00:00",
  "newest_document": "2026-02-09T12:00:00+00:00",
  "index_size_bytes": 245760
}

______________________________________________________________________

list_collections

枚举所有具有摘要统计信息的集合。

list_collections() → dict

退货:

{
  "collections": [
    {"name": "default", "document_count": 25, "total_tokens": 37500, "description": ""},
    {"name": "research", "document_count": 10, "total_tokens": 18000, "description": ""}
  ]
}

______________________________________________________________________

解释检索

了解文档在给定查询中排名的原因。

explain_retrieval(
    query: str,
    doc_ids: list[str],
    collection: str = "default"
) → dict

退货:

{
  "query": "neural networks",
  "explanations": [
    {
      "doc_id": "a1b2c3d4-...",
      "title": "Deep Learning Basics",
      "cosine_similarity": 0.92,
      "bm25_score": 15.7,
      "top_matching_terms": ["neural", "networks"],
      "query_doc_term_overlap": 0.8,
      "explanation_text": "Combined semantic and keyword scores to rank this document."
    }
  ]
}

______________________________________________________________________

检索日志

查询审核日志中最近的检索事件。

retrieval_log(
    last_n: int = 10,
    tool_filter: str | None = None,
    session_id: str | None = None
) → dict

参数:

参数类型默认值说明
last_nint10最近要返回的条目数
tool_filterstrNone按工具名称过滤(例如。, "search_summaries")
session_idstrNone按会话ID筛选

______________________________________________________________________

知识库工具

kb_status

检查知识库监视器的当前状态。

kb_status() → dict

退货:

{
  "kb_dir": "/path/to/knowledge_base",
  "collection": "default",
  "watcher_running": true,
  "manifest": {
    "total_files": 12,
    "total_indexed": 11,
    "total_errors": 1,
    "last_scan": "2026-02-09T12:00:00+00:00"
  }
}

______________________________________________________________________

惊讶

强制知识库文件夹完全重新同步。

kb_resync() → dict

发生了什么:

  1. 所有来自KB的文档都将从矢量存储中删除
  2. 清单已完全清除
  3. 执行新的初始同步(完整文件夹扫描+摄取)

退货:

{
  "created": 12,
  "modified": 0,
  "deleted": 0,
  "errors": 0
}

______________________________________________________________________

知识库系统

概述

知识库(KB)系统提供基于文件夹的自动文档摄取。而不是手动呼叫 ingest_document 对于每个文件,您只需将文件放入 knowledge_base/ 目录,服务器自动处理一切。

运作原理

                   knowledge_base/
                   ├── notes.md          ← File appears
                   ├── report.pdf
                   └── data/
                       └── analysis.txt
                            │
                            ▼
                   ┌─────────────────┐
                   │  File Watcher   │    Polls every N seconds
                   │  (Polling)      │    Computes SHA-256 hashes
                   └────────┬────────┘
                            │
                   ┌────────┴────────┐
                   │  Diff Engine    │    Compares with known state
                   │  Created?       │    Created → ingest
                   │  Modified?      │    Modified → re-ingest
                   │  Deleted?       │    Deleted → remove
                   └────────┬────────┘
                            │
                   ┌────────┴────────┐
                   │  KB Manager     │    Reads file, cleans text
                   │  _ingest_file() │    Derives title and tags
                   │                 │    Calls RAGService.ingest
                   └────────┬────────┘
                            │
                   ┌────────┴────────┐
                   │  KB Manifest    │    Records file → doc_id
                   │  (JSON)         │    Persists across restarts
                   └─────────────────┘

支持的文件类型

类别扩展
文本.txt, .md, .markdown, .rst
数据.json, .yaml, .yml, .csv, .tsv
代码.py, .js, .ts, .java, .c, .cpp, .h, .go, .rs
网络.html, .htm, .xml
配置.log, .cfg, .ini, .toml
文件.pdf (通过pypdf提取文本)

自动生成的标签

从知识库中获取的每个文件都会收到自动标签:

  • source:knowledge_base --识别KB来源的文档
  • filetype: --文件扩展名(例如。, filetype:md, filetype:py)
  • folder: --子文件夹名称(例如。, folder:research, folder:docs)

PDF支持

PDF文件会自动处理:

  1. 文本提取 通过 pypdf (逐页)
  2. 标题提取 来自PDF /Title 元数据字段
  3. 文本清理 --删除页码,修复CamelCase连接,规范空白
  4. 回退标题 --第一行实质性文本,或已清理的文件名

限制:

  • 仅图像/扫描的PDF不产生文本(在清单中记录为“错误”)
  • 跳过无法用空密码解密的加密PDF
  • 非常大的PDF可能会影响 max_file_size 限制(默认值为10 MB)

清单跟踪

kb_manifest.json file持久化文件到文档的映射:

{
  "version": 1,
  "kb_dir": "/absolute/path/to/knowledge_base",
  "files": {
    "notes.md": {
      "relative_path": "notes.md",
      "doc_id": "a1b2c3d4-e5f6-7890-...",
      "content_hash": "sha256_hex_string",
      "file_size": 2048,
      "indexed_at": "2026-02-09T10:00:00+00:00",
      "updated_at": "2026-02-09T10:00:00+00:00",
      "status": "indexed"
    },
    "broken.pdf": {
      "relative_path": "broken.pdf",
      "doc_id": "",
      "content_hash": "sha256_hex_string",
      "file_size": 5242880,
      "indexed_at": "2026-02-09T10:00:00+00:00",
      "updated_at": "2026-02-09T10:00:00+00:00",
      "status": "error",
      "error": "No extractable text found in PDF"
    }
  },
  "stats": {
    "total_files": 2,
    "total_indexed": 1,
    "total_errors": 1,
    "last_scan": "2026-02-09T10:00:00+00:00"
  }
}

状态值:

  • indexed --成功摄入并可搜索
  • skipped --文件可读但为空
  • error --无法处理文件(原因在 error 现场)

文件夹组织

使用子文件夹按主题组织文档。子文件夹名称变为可搜索标签:

knowledge_base/
├── engineering/
│   ├── architecture.md        → tags: [filetype:md, source:knowledge_base, folder:engineering]
│   ├── testing-guide.md       → tags: [filetype:md, source:knowledge_base, folder:engineering]
│   └── apis/
│       └── rest-design.md     → tags: [filetype:md, source:knowledge_base, folder:engineering, folder:apis]
├── product/
│   ├── roadmap.md             → tags: [filetype:md, source:knowledge_base, folder:product]
│   └── specs/
│       └── feature-x.pdf      → tags: [filetype:pdf, source:knowledge_base, folder:product, folder:specs]
└── meeting-notes.txt          → tags: [filetype:txt, source:knowledge_base]

使用标签过滤器搜索:

# Find only engineering documents
results = search_summaries("API design", tags_filter=["folder:engineering"])

# Find only PDF documents
results = search_summaries("specification", tags_filter=["filetype:pdf"])

初始同步与后台监视器

阶段时间发生了什么
初始同步服务器启动完整文件夹扫描;比较清单与文件系统;摄入新内容、重新摄入已修改内容、删除已删除内容
后台监视器每一个 poll_interval增量扫描;检测并处理自上次扫描以来的更改

后台监视器在守护进程线程中运行,并在服务器关闭时自动停止。

______________________________________________________________________

文档生命周期

数据摄取管道

Input Text
    │
    ├─→ Token Count Check (max_document_tokens)
    │       │ fail → return error
    │       │ pass ↓
    ├─→ Summary Generation
    │       ├─→ Gemini API (if available + auto_summary=true)
    │       │       │ fail → local fallback
    │       └─→ Local Extractive Fallback
    │               ├─→ Clean text (PDF noise, CamelCase, whitespace)
    │               ├─→ Split sentences
    │               ├─→ Filter noise (short, numeric, header-like)
    │               └─→ Select top N substantive sentences
    │
    ├─→ Chunking (sentence-based)
    │       ├─→ Split into sentences
    │       ├─→ Accumulate until chunk_size tokens
    │       ├─→ Carry over chunk_overlap tokens
    │       └─→ Filter chunks .json)
    │       ├─→ Vector Index (data/index/.npz)
    │       └─→ BM25 Index (in-memory rebuild)
    │
    └─→ Audit Log (data/logs/audit.jsonl)

文档模型

每个文档都存储为Pydantic Document 型号:

class Document(BaseModel):
    doc_id: str          # UUID4 — stable unique identifier
    title: str           # Human-readable title
    source: str          # Origin: path, URL, or label
    full_text: str       # Complete document text
    summary: str         # 2–4 sentence summary for Level 1 retrieval
    chunks: list[DocumentChunk]  # Overlapping text segments
    tags: list[str]      # Searchable tags (e.g., ["ml", "tutorial"])
    collection: str      # Collection name (default: "default")
    token_count: int     # Token count of full_text
    created_at: datetime # UTC creation timestamp
    updated_at: datetime # UTC last-update timestamp
    metadata: dict       # Arbitrary key-value metadata

每个区块:

class DocumentChunk(BaseModel):
    chunk_index: int     # 0-based position in document
    text: str            # Chunk text content
    token_count: int     # Token count of this chunk
    start_char: int      # Start character offset in full_text
    end_char: int        # End character offset in full_text

分块策略

系统使用 基于句子的重叠组块:

  1. 句子分割 --文本在句末标点处被拆分(., !, ?),单个换行符连接到段落中
  2. 积累 --句子累积成一大块,直到 chunk_size 已达到令牌
  3. 重叠 --当达到块边界时,最后一个 chunk_overlap 令牌会传递到下一个块,提供上下文连续性
  4. 最小尺寸 --小于的块 min_chunk_size 令牌将被丢弃(除非它们是唯一的内容)

摘要生成

摘要对于一级检索效率至关重要。系统提供两条路径:

路径1:Gemini API(默认)

  • 发送带有结构化提示的完整文档文本
  • 生成2-4个句子的摘要
  • 关注关键事实和文件意图

路径2:局部提取回退

  • 在以下情况下自动激活:

- 未配置API密钥 - API调用失败(速率限制、网络错误等)

  • 管道:

1. 干净的文本(PDF工件、CamelCase连接、空白) 1. 拆分成句子 1. 过滤噪音(太短,主要是数字、全大写标题、样板) 1. 从开头选择前N个实质性句子(主题陈述位置)

嵌入和索引

嵌入 --使用配置的嵌入提供程序将文档的摘要(或标题,如果摘要为空)编码为固定维度的浮点向量。

向量索引 --矢量存储在NumPy压缩文件中(.npz).搜索使用归一化余弦相似度:

similarity(q, d) = (q · d) / (|q| × |d|)

向量在存储前进行L2归一化,因此相似性降低为点积。

BM25指数 --内存中的Okapi BM25索引是由文档标题、摘要和全文构建的。每次摄取、更新或删除时都会重建此索引,以确保一致性。

______________________________________________________________________

搜索和检索

语义搜索

主搜索模式。嵌入查询,然后使用余弦相似度找到最近的文档向量。

优势: 理解意思,处理同义词,跨语言工作 缺点: 可能会错过精确的术语匹配,取决于嵌入质量

BM25关键字搜索

使用Okapi BM25算法的经典词频逆文档频率评分。

优势: 精确的术语匹配,快速,无需API调用 缺点: 没有语义理解,对词汇不匹配敏感

混合搜索详细信息

将语义和BM25分数与可配置的权重相结合:

final_score = (semantic_weight × cosine_sim) + (keyword_weight × normalized_bm25)

哪里:

  • cosine_sim ∈\[0,1\]——向量搜索中的余弦相似度
  • normalized_bm25 = bm25_score / max(bm25_scores) --标准化为\[0,1\]
  • 权重会自动归一化:如果 semantic_weight=0.7keyword_weight=0.3,它们除以它们的总和

多查询融合

运行多个独立查询并合并结果:

互惠秩融合(RRF):

score(d) = Σ_{q ∈ queries} 1 / (60 + rank_q(d) + 1)

出现在多个查询结果中的文档累积了更高的RRF分数。常数60减弱了等级差异的影响。

最高分数:

score(d) = max_{q ∈ queries} similarity_q(d)

只需在所有查询中获得最高的相似性得分。

相似性搜索

find_similar 使用参考文档的摘要作为查询:

  1. 检索参考文档
  2. 嵌入其摘要(或标题)
  3. 搜索最近邻的向量索引
  4. 从结果中排除参考文档
  5. 可选择排除具有相同内容的文档 source

及排名

所有分数在返回给客户端之前都被限制在\[0.0,1.0\]。这确保了无论采用何种评分方法,都能得到一致的解释。

______________________________________________________________________

集合

什么是收藏

集合是独立的文档命名空间。每个系列都有自己的:

  • JSON文档存储(data/store/.json)
  • 矢量索引(data/index/.npz)
  • BM25索引(内存中)

不同收藏中的文档在搜索过程中不会相互作用。

创建收藏

集合是隐式创建的——只需摄入一个具有新集合名称的文档:

ingest_document(
    title="My Doc",
    text="Content...",
    collection="research"  # Creates "research" collection automatically
)

多重收集策略

推荐模式:

模式何时使用
单身 default 集合小项目、原型设计
基于主题(research, docs, code)具有不同文档类别的中型项目
基于租户(user_123, org_456)多租户应用程序
时间(2026_q1, 2026_q2)时间序列文档档案

收款统计

监控集合 collection_stats:

stats = collection_stats("research")
# Check document count, token usage, tag distribution, etc.

______________________________________________________________________

存储后端

文档存储(JSON)

  • 地点: data/store/.json
  • 格式: JSON对象映射 doc_id → 完整文档记录
  • 螺纹安全: threading.Lock 用于并发访问
  • 缓存: 每个集合的内存缓存(延迟加载)

矢量索引(NumPy)

  • 地点: data/index/.npz
  • 格式: NumPy压缩存档 doc_ids 阵列和 vectors 矩阵
  • 操作: upsert, delete, search (余弦相似度)
  • 螺纹安全: threading.Lock 对于所有操作
  • 坚持不懈: 每次突变后自动保存到磁盘

BM25索引(内存中)

  • 图书馆: rank-bm25 (霍加皮BM25)
  • 重建触发器: 每次文档摄取、更新或删除
  • 语料库: 每份文档的标题+摘要+全文
  • 没有毅力 --在服务初始化时从文档存储中重建

审核日志(jsonl)

  • 地点: data/logs/audit.jsonl
  • 格式: 每行一个JSON对象(仅可追加)
  • 自动截断: 超过时删除最旧的条目 max_log_entries
  • 螺纹安全: threading.Lock 为写作

KB清单(JSON)

  • 地点: data/kb_manifest.json
  • 目的: 跟踪已摄入的文件、它们的文档ID和内容哈希
  • 坚持不懈: 更新每个文件事件(创建、修改、删除)

______________________________________________________________________

可观察性和审计

审计日志

每次工具调用都会记录以下内容:

{
  "timestamp": "2026-02-09T12:34:56.789+00:00",
  "tool": "search_summaries",
  "params": {
    "query": "machine learning",
    "top_k": 5,
    "collection": "default"
  },
  "result_count": 3,
  "doc_ids": ["a1b2c3d4-...", "e5f6g7h8-...", "i9j0k1l2-..."],
  "latency_ms": 145.3
}

检索说明

对于任何查询文档对, explain_retrieval 提供:

  • 余弦相似度 --原始语义相似度得分
  • BM25得分 --原始关键字匹配分数
  • 术语重叠率 --文档中找到的查询词的比例
  • 最匹配的术语 --哪些查询词匹配

收集监控

跟踪系统健康状况 collection_stats:

  • 文档数量和随时间的增长
  • 代币预算消耗
  • 标签和来源分布分析
  • 索引文件大小

______________________________________________________________________

与MCP客户端集成

VS代码/GitHub副本

添加到您的VS代码MCP设置(.vscode/mcp.json 或用户设置):

{
  "mcpServers": {
    "staged-rag": {
      "command": "python",
      "args": ["-m", "staged_rag.server"],
      "cwd": "/path/to/staged-rag-mcp",
      "env": {
        "GEMINI_API_KEY": "your_key_here"
      }
    }
  }
}

对于HTTP传输:

{
  "mcpServers": {
    "staged-rag": {
      "url": "http://127.0.0.1:8090/mcp"
    }
  }
}

克劳德桌面版

添加到Claude Desktop的MCP配置(claude_desktop_config.json):

{
  "mcpServers": {
    "staged-rag": {
      "command": "python",
      "args": ["-m", "staged_rag.server"],
      "cwd": "/path/to/staged-rag-mcp",
      "env": {
        "GEMINI_API_KEY": "your_key_here"
      }
    }
  }
}

自定义MCP客户端

任何兼容MCP的客户端都可以连接。服务器公开了17个工具:

类别工具
检索search_summaries, get_documents, get_document_chunk
高级搜索hybrid_search, multi_query_search, find_similar
管理层ingest_document, ingest_batch, update_document, delete_document
元数据get_document_metadata
可观察性collection_stats, list_collections, explain_retrieval, retrieval_log
知识库kb_status, kb_resync

______________________________________________________________________

分阶段RAG的快速工程设计

prompts.py 该模块为在LLM应用程序中实现分阶段检索工作流提供了结构化提示。

系统提示

from staged_rag.prompts import staged_rag_system_prompt

prompt = staged_rag_system_prompt("What are the benefits of microservices?")

生成:

You are a knowledge assistant with access to a staged RAG system.

RETRIEVAL PROTOCOL:
1) SEARCH: call search_summaries with the user's question.
2) EVALUATE: read summaries and scores.
3) EXPAND: call get_documents for relevant docs only.
4) SYNTHESIZE: answer using retrieved content.
5) CITE: reference doc_ids for claims.

USER QUESTION: What are the benefits of microservices?

评估摘要提示

from staged_rag.prompts import evaluate_summaries_prompt

prompt = evaluate_summaries_prompt(json.dumps(summaries, indent=2))

指示法学硕士审查搜索结果,并决定是展开还是跳过。

深度分析提示

from staged_rag.prompts import deep_analysis_prompt

prompt = deep_analysis_prompt(
    question="What are the benefits?",
    context=retrieved_text
)

指示法学硕士根据检索到的上下文和引用综合答案。

______________________________________________________________________

测试

运行测试

# Run all tests
pytest tests/ -v

# Run with coverage
pytest tests/ --cov=staged_rag --cov-report=term-missing

# Run specific test file
pytest tests/test_document_store.py -v

# Run specific test
pytest tests/test_vector_index.py::test_upsert_and_search -v

测试结构

测试文件它测试什么
test_document_store.pyJSON文档存储上的CRUD操作
test_vector_index.py矢量更新、删除、搜索、持久化
test_embeddings.py嵌入提供程序初始化和编码
test_tools.pyMCP工具功能签名和响应
test_agent_flow.py端到端检索工作流

编写新测试

import pytest
from staged_rag.core.document_store import DocumentStore

def test_save_and_retrieve(tmp_path):
    store = DocumentStore(tmp_path)
    doc = {"doc_id": "test-1", "title": "Test", "full_text": "Content"}
    store.save("default", doc)

    result = store.get("default", "test-1")
    assert result is not None
    assert result["title"] == "Test"

def test_delete_nonexistent(tmp_path):
    store = DocumentStore(tmp_path)
    result = store.delete("default", "nonexistent")
    assert result is None

______________________________________________________________________

性能考量

速率限制

嵌入引擎包括内置的速率起搏:

  • 默认限制: 每分钟80个请求(RPM)
  • 窗口: 60秒滑动窗
  • 行为: 接近极限时自动休眠
  • 目的: 保持在自由层API配额范围内

代币预算管理

  • 在接收时跟踪每个文档的令牌计数
  • collection_stats 报告每个集合的总令牌数和平均令牌数
  • max_document_tokens 拒绝超出预算的文件
  • 1级(摘要)回报 token_count 因此,LLM可以做出明智的扩张决策

嵌入缓存

  • 嵌入在NumPy中持久化 .npz 文件——从不为现有文档重新计算
  • 只有新的或更新的文档触发嵌入API调用
  • BM25索引在内存中重建(快速,无API调用)

指标表现

  • 矢量搜索: O(n)线性扫描,带NumPy矩阵乘法——适用于高达~100K文档的集合
  • BM25搜索: O(n×m),其中n=文档,m=查询词
  • 文档查找: 从内存缓存中查找O(1)哈希映射

对于较大的集合(100000多个文档),请考虑FAISS可选依赖关系:

pip install -e ".[faiss]"

______________________________________________________________________

安全

API密钥管理

  • 将API密钥存储在 .env 文件(gitignored)
  • 密钥通过以下方式加载 python-dotenv 启动时
  • 切勿在配置文件中硬编码密钥
  • 在CI/CD管道中使用环境变量

数据隐私

  • 所有数据都存储在本地(没有外部数据库)
  • 以明文JSON存储的文档内容——如果需要,在静止时加密
  • 审计日志可能包含查询文本——通过配置保留 max_log_entries
  • KB清单包含文件路径和哈希值(无内容)

访问控制

  • 默认情况下,MCP服务器不实现身份验证
  • 使用HTTP传输时,通过以下方式限制访问:

- 绑定到 127.0.0.1 (仅限本地主机,默认) - 使用带有身份验证的反向代理 - 部署在VPN或防火墙后面

______________________________________________________________________

故障排除

安装问题

问题解决方案
pip install -e . 失败确保Python 3.11+: python --version
ModuleNotFoundError: google.genai快跑 pip install google-genai
ModuleNotFoundError: fastmcp快跑 pip install fastmcp>=0.5.0
ModuleNotFoundError: openai快跑 pip install -e ".[openai]" 适用于OpenAI/Azure/LMStudio

运行时问题

问题解决方案
服务器无法启动检查 .env 具有有效的API密钥;检查端口未使用
“文档超过最大令牌数”增加 ingestion.max_document_tokens 在配置中
嵌入API速率限制等待重试;减少 batch_size;使用本地提供商
确定性回退活动设置有效的API密钥或使用Ollama进行本地嵌入
空搜索结果检查集合名称;尝试 min_score=0.0;验证索引文件
KB文件未被索引确保 knowledge_base.enabled: true;检查文件扩展名支持
PDF提取失败安装 pypdf: pip install pypdf>=4.0.0

搜索质量问题

问题解决方案
无关结果使用 hybrid_search 关键词助推;改进文档摘要
缺少明显匹配项尝试 multi_query_search 具有查询变化
低相似性得分检查配置和提供者之间的嵌入维度是否匹配
提供者更改后得分不一致删除 data/index/*.npz 并重新摄取所有文档

数据问题

问题解决方案
索引不同步删除 data/index/.npz 并重新摄入
KB清单已过时运行 kb_resync() 强制全面重建
审核日志太大减少 logging.max_log_entries 或删除 audit.jsonl
损坏的JSON存储从备份还原;文档存储是 data/store/.json

______________________________________________________________________

贡献

欢迎投稿!请遵循以下指南:

  1. 分叉 存储库
  2. 创建 特征分支: git checkout -b feature/my-feature
  3. 制造 您的更改具有清晰、描述性的提交
  4. 测试 您的更改: pytest tests/ -v
  5. 提交 带有明确描述的拉取请求

开发设置

git clone https://github.com/reddynalamari/staged-rag-mcp.git
cd staged-rag-mcp
python -m venv .venv
.venv\Scripts\activate
pip install -e ".[all-providers,dev]"
pytest tests/ -v

代码风格

  • 遵循PEP 8惯例
  • 对所有函数签名使用类型提示
  • 为公共函数和类添加文档字符串
  • 保持功能集中和小型化
  • 使用有意义的变量和函数名

出资协议

提交贡献即表示您同意 许可证 文件。您的贡献是根据相同的许可条款提供的,您授予原作者使用它们的永久权利。

______________________________________________________________________

路线图

计划的功能

  • \[\]用于大规模集合的FAISS矢量索引后端
  • \[\]超大型文档的流式摄取
  • \[\]多模态嵌入(图像+文本)
  • \[\]KB文件事件的Webhook通知
  • \[\]非MCP客户端的REST API和MCP
  • \[\]文档版本控制和历史记录
  • \[\]进出口收款
  • \[\]用于收款管理的Web UI仪表板
  • \[\]可插拔摘要生成器(OpenAI、Anthropic、本地LLM)
  • \[\]扫描PDF的OCR支持
  • \[\]增量向量索引更新(避免完全重建)
  • \[\]收藏级访问控制
  • \[\]分布式存储后端(S3、GCS)

______________________________________________________________________

作者

沙希达·雷迪·纳拉马里

本项目由Shashidhar Reddy Nalamari设计、架构和开发。两级分阶段检索架构、多提供者嵌入系统、知识库自动同步引擎和完整的MCP服务器实现是作者的原创作品。

______________________________________________________________________

许可证

该项目发布于 自定义许可证 允许出于任何目的(个人、商业、教育)免费使用,但有两个关键条件:

  1. 需要归因 --你必须赞扬原作者(Shashidhar Reddy Nalamari)
  2. 无虚假所有权声明 --您不能声称此项目是您自己的原创作品

许可证 文件以获取完整条款。

快速摘要

允许不允许
用于任何目的(免费)声明为您自己的创作
修改和分发删除作者归因
商业用途(免费)在软件上注册IP
创作衍生作品在投资组合中以原创形式呈现,不含信用
学习和教学提交自己的学分

______________________________________________________________________

致谢

本项目基于并感谢以下开源项目:

嵌入提供者架构模式的灵感来自 mem0ai/mem0 项目的嵌入器抽象。

______________________________________________________________________

Staged RAG MCP Server

Search smart. Retrieve less. Answer better.

Copyright © 2026-present Shashidhar Reddy Nalamari. All Rights Reserved.

Released under a custom license — see LICENSE for details.

目录标签

目录标签

检索增强生成搜索PythonClaude文档检索本地部署知识管理语义搜索AI辅助

支持客户端

Claude DesktopClaudeVS Code

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

api-key

运行时(runtime,运行环境)

Python

工具数量(toolCount,工具数)

17

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdioapi-key部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP