文档向量化搜索工具

Signal Stash是一个将Markdown文档处理成可搜索向量数据库的工具,支持REST和MCP API,适用于文档管理和语义搜索场景。

  • by HamStudy
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 hamstudy/signalstash

使用说明

信号停滞

使用REST和MCP API将Markdown文档处理到可搜索的矢量数据库中。

特性

  • 🗂️ Markdown摄入:流程 .md 支持frontmatter的文件
  • 🔍 语义搜索:使用OpenAI嵌入的基于矢量的搜索
  • 🌐 REST API:通过HTTP端点查询文档
  • 🔌 HTTP MCP API:基于HTTP的JSON-RPC 2.0模型上下文协议
  • 📊 Qdrant集成:具有自动复制功能的高效矢量存储和检索
  • 🎯 多源支持:以智能相关性处理多个文档来源
  • ⚡ 重要性评分:在搜索结果中优先考虑关键信息

快速开始

  1. 安装依赖项

    npm install
    
  2. 设置环境

    cp .env.example .env
    # Edit .env with your API keys
    
  3. 启动Qdrant (使用Docker)

    docker run -p 6333:6333 qdrant/qdrant
    
  4. 摄入文件

    # Basic ingestion (to default collection)
    npm run ingest -- /path/to/markdown/files
    
    # Ingest to specific collection
    npm run ingest -- /path/to/emails --collection=emails
    npm run ingest -- /path/to/documentation --collection=docs
    
    # With source context (improves search relevance)
    npm run ingest -- /path/to/vendure-docs --source="vendure" --context="e-commerce backend"
    npm run ingest -- /path/to/react-docs --source="react" --context="frontend framework"
    
    # With importance scoring (higher = more important, default: 10)
    npm run ingest -- /path/to/critical-docs --importance=20
    npm run ingest -- /path/to/archive-docs --importance=5
    
    # Combine all options
    npm run ingest -- /path/to/emails --collection=emails --source="gmail" --context="personal emails" --importance=15
    
  5. 启动服务器

    npm run dev
    

配置

环境变量(参见 .env.example):

  • OPENAI_API_KEY -用于嵌入的OpenAI API密钥
  • QDRANT_HOST -Qdrant服务器URL(默认值: http://localhost:6333)
  • QDRANT_API_KEY -Qdrant API密钥(可选)
  • QDRANT_COLLECTION -集合名称(默认值: docs)
  • PORT -服务器端口(默认值: 3000)
  • HOST -要绑定的服务器主机/接口(默认值: 0.0.0.0)
  • LOG_LEVEL -日志记录级别(默认值: info)
  • EMBEDDING_MODEL -要使用的模型(openai 或 huggingface,默认值: openai)

API终点

REST API

搜索端点:

  • GET /search/:collection?q=<query> -语义搜索(JSON格式)
  • GET /search/:collection?q=<query>&format=markdown -语义搜索(Markdown格式)
  • GET /search/:collection?q=<query>&source=<source> -在特定文档源中搜索

搜索参数:

  • q -搜索查询(必填)
  • format -响应格式: json (默认)或 markdown
  • limit -最大结果(默认值:5)
  • source -按文档来源筛选
  • scoreThreshold -最低相关性得分0-1(默认值:0.7,仅降价)
  • expandSections -用多个匹配项展开整个部分(默认值:true,仅markdown)
  • maxResponseChars -最大响应大小(默认值:50000,仅降价)

其他终点:

  • GET /sources/:collection -列出所有摄入的文件来源
  • GET /section/:collection/:hash -通过标题哈希获取部分
  • GET /document/:collection/:filename -按文件名获取文档
  • GET /health -健康检查

注: 这 :collection 参数在所有路由中都是可选的。如果省略,则默认集合(default)使用。为了向后兼容性。, /search?q=...)继续工作。

MCP API(基于HTTP)

MCP API可作为HTTP端点在 /mcp/:collection 使用JSON-RPC 2.0协议:

可用方法:

  • searchDocs -搜索具有语义相似性的文档
  • getSection -获取特定标题下的所有段落
  • getFile -从特定文件中获取所有段落
  • listCollections -列出所有可用收藏

收款处理:

  • URL中的集合(例如。, /mcp/emails)作为所有工具的默认集合
  • 每个工具都接受一个可选 collection 用于覆盖URL默认值的参数
  • 使用 listCollections 查找可用收藏

请求示例:

# Search in default collection
curl -X POST http://localhost:3000/mcp/default \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "searchDocs",
    "params": {
      "query": "authentication",
      "limit": 5
    },
    "id": 1
  }'

# Search in emails collection
curl -X POST http://localhost:3000/mcp/emails \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "searchDocs",
    "params": {
      "query": "invoice",
      "limit": 5
    },
    "id": 1
  }'

# List all collections
curl -X POST http://localhost:3000/mcp/default \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "listCollections",
    "params": {},
    "id": 1
  }'

# Search with collection override (search "notes" collection while using emails endpoint)
curl -X POST http://localhost:3000/mcp/emails \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "searchDocs",
    "params": {
      "query": "todo",
      "collection": "notes"
    },
    "id": 1
  }'

示例响应:

{
  "jsonrpc": "2.0",
  "result": [
    {
      "match": {
        "text": "The login mutation allows...",
        "score": 0.89,
        "document": {
          "path": "guides/auth/index.md",
          "source": "vendure",
          "context": "e-commerce backend",
          "title": "Authentication Guide"
        },
        "location": {
          "paragraphIndex": 12,
          "headingHierarchy": ["API Reference", "Authentication", "Login"]
        }
      },
      "context": {
        "before": ["Previous paragraph..."],
        "after": ["Next paragraph..."]
      },
      "section": {
        "headingHash": "a1b2c3d4",
        "chunks": ["Other paragraphs in the same section..."]
      }
    }
  ],
  "id": 1
}

示例:Markdown搜索结果

# Search with markdown format (default collection)
curl "http://localhost:3000/search/default?q=authentication&format=markdown"

# Search in specific collection
curl "http://localhost:3000/search/emails?q=invoice&format=markdown"

返回一个格式良好的markdown文档:

# Search Results

**Query:** "authentication"

---

## Authentication Guide
**Source:** vendure | **Context:** e-commerce backend | **Path:** `guides/auth/index.md`

### Authentication > Login

The login mutation allows users to authenticate with the system...

### Authentication > JWT Tokens

JWT tokens are used for maintaining session state...

*[Section expanded - 3 relevant matches, scores: 0.92, 0.89, 0.87]*

---

*Found 5 relevant results*

发展

npm run dev       # Start dev server with hot reload
npm run build     # Build TypeScript
npm run test      # Run tests
npm run lint      # Lint code
npm run format    # Format code

高级功能

多个集合(命名空间)

Signal Stash支持多个集合来组织不同类型的内容:

  • 集合命名:所有集合都使用该模式 docs-<collection> 内部地
  • 默认集合:如果没有指定收集, default 被使用
  • 隔离:每个收藏都与其他收藏完全隔离
  • 用例:
    • 将文档与电子邮件分开
    • 隔离不同的项目或域
    • 创建测试与生产集合
# Ingest different content types to separate collections
npm run ingest -- /docs/api --collection=api-docs
npm run ingest -- /emails/archive --collection=emails
npm run ingest -- /notes/personal --collection=notes

# Search within specific collections
curl "http://localhost:3000/search/api-docs?q=authentication"
curl "http://localhost:3000/search/emails?q=invoice"
curl "http://localhost:3000/search/notes?q=todo"

多源文档支持

Signal Stash智能地处理多个文档源:

  1. 上下文感知嵌入:在摄取过程中指定源和上下文时,此信息将包含在嵌入文本中。例如,Vendure文档中关于“用户身份验证”的区块将嵌入上下文,如“Vendure(电子商务后端)>API参考>身份验证>登录::登录突变…”

  2. 自动关联:在搜索时,嵌入自然倾向于来自相关文档集的结果,而不需要显式过滤器。搜索“用户身份验证”将根据完整上下文自动将Vendure auth-docs的排名高于React auth-docs。

  3. 可选过滤:如果需要,您可以使用 source 搜索查询中的参数。

重要性评分

控制哪些信息在搜索结果中具有优先级:

  • 在摄入过程中设置重要性 --importance=<number> (默认值:10)
  • 数字越大,表示内容越重要
  • 有助于确定优先级:
    • API关键文件(重要性:20)
    • 标准文件(重要性:10)
    • 存档或遗留内容(重要性:5)

自动Qdrant复制

Signal Stash会自动检测您的Qdrant群集配置,并设置适当的复制因子以实现高可用性。

建筑

  • TypeScript 用于类型安全
  • 快速 对于HTTP服务器
  • 统一/备注 用于Markdown AST解析
  • OpenAI 用于嵌入
  • Qdrant 用于矢量存储
  • 皮诺 用于结构化日志记录

许可证

麻省理工学院