使用说明
mcp松果抹布
基于Go的 MCP服务器 它通过查询提供RAG(检索增强生成)功能 松果 使用Google Vertex AI嵌入的矢量数据库。
两种运输方式:
- 标准 (默认)--由本地MCP主机作为子进程启动,例如。 mcp走
- 可流式传输HTTP (
--transport http)--在港口供应 远程MCP主机 (Claude Code、Antigravity、GitHub Copilot、任何通过HTTP说MCP的东西)都可以跨网络连接——请参阅 连接MCP主机
为什么谷歌嵌入不能简单地换掉: 该索引由谷歌顶点RAG引擎填充
text-embedding-005矢量。嵌入模型定义了自己的向量空间——查询向量必须来自 相同模型 构建索引或余弦相似性是没有意义的(测量:在开源嵌入器中交换约0.5%recall@1即随机)。因此,消除对谷歌的依赖需要用开源模型重新嵌入语料库(块文本存储在Pinecone元数据中,因此这在没有原始文档的情况下是可能的——将其嵌入到一个单独的名称空间中,使当前向量保持不变)。除非这样做,否则Vertex AI仍然只需要用于查询嵌入;其他一切(搜索、关键字增强、重新登录、MCP层)都是谷歌免费的。
它的作用
显示单个MCP工具-- rag_query --LLM可以使用 三层检索管道:
User question
→ rag_query tool called by LLM
→ text-embedding-005 (Vertex AI) embeds the query → 768-dim vector
→ Pinecone vector search → top-20 candidate chunks
→ Keyword boost — exact matches for module names, error codes, filenames promoted
→ (Optional) Cross-encoder reranker → final top-K results reordered
→ chunks rendered as compact readable text and returned to LLM
→ LLM synthesizes a grounded answer
→ trajectory entry written to log file (if configured)
回收管道
三层协同工作以获得更高的精度:
| 图层 | 功能 | 强度 |
|---|---|---|
| 语义嵌入 | 通过余弦相似度查找概念上相似的文档 | 处理释义、同义词 |
| 关键字提升 | 从查询中提升包含精确域标记的文档 | 捕获模块名称(SFILE.C),错误代码(CEE9901),缩略语(CAS, JCL) |
| 交叉编码器重定器 | 根据完整的上下文相关性对候选人进行重新排序 | 最终权威——最精确 |
关键字提取规则
与这些模式中的任何一个匹配的令牌都被视为域关键字:
| 模式 | 示例 |
|---|---|
| 包含一个点 | SFILE.C, DENV.PL1 |
| 所有大写字母(≥2个字符,非常见英语单词) | CAS, JCL, COBOL |
| 包含数字 | CEE9901, COBRT162 |
关键字boost被标准化为 [0, 1] 加权为 0.2,所以语义相似性总是占主导地位——当两个结果接近时,关键字只是打破了平衡。
FetchK vs TopK
矢量搜索检索 20名候选人 (FetchK=20),然后对其进行评分和排名,然后将其调整为所需值 top_k (默认值5)。获取更多的候选词可以提高关键字的效率,并使重新排名的人有更多的工作机会。
先决条件
| 要求 | 注意事项 |
|---|---|
| 转到1.21+ | 构建二进制文件 |
| 松果账户 | 具有填充的矢量索引 |
| 谷歌云项目 | 启用Vertex AI API |
| 服务帐户JSON密钥 | 带 顶点AI平台Express用户 (或 顶点AI用户)角色 |
松果指数要求
索引必须已填充由生成的嵌入 text-embedding-005 (768个维度)。每个向量应有的元数据字段:
| 字段 | 内容 |
|---|---|
chunk_data |
块的文本内容 |
file_original_uri |
源文档路径(例如。 gs://bucket/file.pdf) |
快速开始
1.克隆和构建
git clone https://github.com/aravindanugonda/mcp-pinecone-rag.git
cd mcp-pinecone-rag
go build -o mcp-pinecone-rag .
2a。作为网络服务运行(远程MCP主机)
scripts/mcp-ctl.sh start # builds, starts MCP server on 0.0.0.0:7778 (reranker OFF by default)
scripts/mcp-ctl.sh start --with-reranker # also starts the local cross-encoder reranker
scripts/mcp-ctl.sh status
scripts/mcp-ctl.sh stop
MCP端点为 http://<vm-ip>:7778/mcp (健康检查: /health).配置来自 ./.env.用以下内容覆盖绑定地址 MCP_ADDR=host:port.
Reranker可选择加入。 默认情况下,服务器以普通模式运行(嵌入+松果矢量搜索+仅关键字增强),通常在不到一秒钟的时间内响应。重新登录会为每个查询增加约20-25s的CPU限制延迟(请参阅 本地排名)--在普通硬件上,这可能会超过MCP主机自己的工具调用超时,导致客户端取消请求并退回到未接地的答案。通过 --with-reranker 到 start/restart (或设置 WITH_RERANKER=1)选择更慢、更高精度的模式。即使 RERANKER_URL 开始 .env,默认(无标志)调用会忽略它,并在没有重新链接器的情况下运行。
安全: 服务器没有身份验证。绑定到localhost,或将防火墙/云安全组级别的端口限制为需要它的特定客户端IP地址——永远不要打开它 0.0.0.0/0.
2b。配置mcp以使用此服务器(本地stdio)
在你的 mcp-go config.yaml,添加:
mcp_servers:
- name: "pinecone-rag"
type: "stdio"
command: "/path/to/mcp-pinecone-rag/mcp-pinecone-rag"
args: []
env:
PINECONE_API_KEY: "your-pinecone-api-key"
GOOGLE_CLOUD_PROJECT: "your-gcp-project-id"
GOOGLE_APPLICATION_CREDENTIALS: "/path/to/service-account.json"
VERTEX_AI_LOCATION: "us-central1"
PINECONE_INDEX_HOST: "your-index-host.svc.aped-xxxx.pinecone.io"
PINECONE_NAMESPACE: ""
RAG_TOP_K: "5"
RERANKER_URL: "http://localhost:8090" # optional — see Local Reranker below
TRAJECTORY_LOG_FILE: "/tmp/trajectory.jsonl" # optional — see Trajectory Logging below
环境变量
| 变量 | 必填 | 描述 |
|---|---|---|
PINECONE_API_KEY |
是 | Pinecone API密钥 |
GOOGLE_CLOUD_PROJECT |
是 | 启用Vertex AI的GCP项目ID |
PINECONE_INDEX_HOST |
是 | 松果索引主机URL(有或没有 https://) |
GOOGLE_APPLICATION_CREDENTIALS |
是* | 服务帐户JSON密钥的路径 |
VERTEX_AI_LOCATION |
无 | GCP区域(默认值: us-central1) |
PINECONE_NAMESPACE |
否 | Pinecone命名空间(默认值: "") |
RAG_TOP_K |
否 | 最终结果返回给LLM(默认值: 5,最大值: 20) |
RERANKER_URL |
否 | 本地重新登录服务的基本URL(默认:禁用)。仅在直接二进制调用或以下情况下生效 scripts/mcp-ctl.sh 与一起运行 --with-reranker/WITH_RERANKER=1 --脚本的默认值 start/restart 忽略此变量并在不重新登录的情况下运行。 |
TRAJECTORY_LOG_FILE |
否 | JSON行轨迹日志的路径(默认:禁用) |
MCP_TRANSPORT |
没有 | stdio (默认)或 http --也可通过以下方式设置 --transport 旗帜 |
MCP_ADDR |
否 | HTTP传输的绑定地址(默认值: :7778)--也 --addr 旗帜 |
*或使用 gcloud auth application-default login 如果gcloud CLI可用。
本地排名
重新登录是一个 可选,选择加入 Python服务(reranker.py)使用 快速嵌入 (ONNX运行时——不需要PyTorch)在本地运行交叉编码器模型。它是 默认情况下关闭 — scripts/mcp-ctl.sh start 在没有它的情况下运行普通管道(嵌入+Pinecone+关键字boost)。通过 scripts/mcp-ctl.sh start --with-reranker 也可以将其与MCP服务器一起启动。
为什么选择加入:重新登录增加了真正的精度,但付出了真正的延迟代价——请参阅 重新排序延迟 在......下面在适度的硬件上(例如2个vCPU),一次重新排序调用可能需要大约20-25秒,这可能会超过MCP主机自己的工具调用超时,并导致客户端在接地应答到达之前取消请求。只有在确认主机的超时预算足以覆盖延迟后,才能启用它。
重要提示:启动时间
开 首次运行,fastembed下载模型权重(约280 MB bge-reranker-base).这需要30-60秒。在此窗口期间发送的查询将优雅地回退到关键字增强的结果(reranked: false 在轨迹日志中)。在后续启动时,模型将在几秒钟内从缓存中加载。
手动启动
pip install fastembed flask
python3 reranker.py
环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
RERANKER_MODEL |
BAAI/bge-reranker-base |
拥抱脸部模型ID |
RERANKER_PORT |
8090 |
要收听的端口 |
支持的型号
| 型号 | 尺寸 | 质量 |
|---|---|---|
BAAI/bge-reranker-base |
约280 MB | 良好——英语 |
BAAI/bge-reranker-v2-m3 |
约570 MB | 最佳--多语言 |
模型文件在首次启动时自动下载并缓存到 ~/.cache/fastembed/.
健康检查
GET http://localhost:8090/health
→ {"model": "BAAI/bge-reranker-base", "status": "ok"}
如果 /health 挂起时,重新登录器仍在处理请求(服务器是多线程的,但CPU推理每批可能需要10-20秒)。请稍候,然后重试。
重新排序延迟
BAAI/bge-reranker-base 在CPU上运行,并独立地对每个(查询、块)对进行评分。对于20名候选人和典型的区块大小,重新排名需要 10-25秒 在现代CPU上(在低核数VM上更长)。HTTP客户端超时设置为 60秒 为了适应这一点。如果您需要更低的延迟,请减少 RAG_TOP_K 或者切换到较小的型号。
并发请求被序列化。 重新登录器是一个单CPU绑定进程(fastembed/ONX运行时),因此在vCPU较少的主机上,两个同时运行 rag_query 调用不是并行运行的——它们争夺同一个CPU,而且速度都变慢了。早期版本同时发出重新登录调用,这可能会导致 两者 请求超过HTTP超时,并自动退回到未重新登录(关键字增强)的结果。Go客户端(internal/reranker/local.go)现在,使用size-1信号量对重新排序的调用进行排队,这样每个请求都能让CPU自己处理,并在自己的超时窗口内完成,但代价是排队第二秒的任何调用都会增加延迟。
轨迹记录
当 TRAJECTORY_LOG_FILE 已设置,每 rag_query 调用会附加一个JSON行,记录完整的检索管道执行情况。这是理解和提高检索质量的主要工具。
日志格式(JSON行——每个查询一个对象)
{
"timestamp": "2026-04-04T03:42:21Z",
"query": "AMODE 31 64 cross mode calling P64 directive",
"fetch_k": 20,
"top_k": 10,
"retrieved": [
{"id": "...", "source": "gs://bucket/file.pdf", "score": 0.936},
...
],
"final": [
{"id": "...", "source": "gs://bucket/file.pdf", "score": 5.27},
...
],
"reranked": true,
"latency_ms": 14823
}
retrieved --所有20个松果候选词在关键字增强后,按分数排序。
final --前K个结果返回给LLM(当以下情况发生时,重新分级分数将替换余弦分数 reranked: true).
有用的jq查询
# Pretty-print all entries
jq . /tmp/trajectory.jsonl
# Last query summary
tail -1 /tmp/trajectory.jsonl | jq '{query, reranked, latency_ms}'
# Check if reranking is working
jq '{query, reranked}' /tmp/trajectory.jsonl
# See how reranker reordered results (compare retrieved vs final source order)
tail -1 /tmp/trajectory.jsonl | jq '{retrieved: [.retrieved[].source], final: [.final[].source]}'
# Watch live
tail -f /tmp/trajectory.jsonl | jq .
块渲染
松果指数中存储的块为 JSON数组 (例如,来自结构化提取管道)在返回LLM之前会自动转换为紧凑、可读的项目符号线:
• EXEC (JCL Keywords) [Enterprise Developer for Eclipse (UNIX)]: Executes a program, a JCL procedure or a REXX procedure.
• DLBL (JCL Keywords) [Enterprise Developer for Eclipse (UNIX)]: Associates a DD name with a dataset.
纯文本块将原封不动地返回。此转换发生在 internal/server/server.go 并且显著减少了发送到LLM的令牌计数,同时保留了所有相关信息。
MCP工具: rag_query
说明: 搜索知识库。查询矢量数据库以查找相关文档段落。
输入架构:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
query |
string | 是 | 自然语言搜索查询 |
top_k |
integer | 否 | 结果数(默认值:5,最大值:20) |
项目结构
.
├── main.go # Entry point: env config, transport selection, stdio loop
├── reranker.py # Local cross-encoder reranker (fastembed + Flask, threaded)
├── scripts/
│ └── mcp-ctl.sh # start/stop/status for reranker + HTTP MCP server
├── internal/
│ ├── embedding/
│ │ └── google.go # Vertex AI text-embedding-005 client (via ADC)
│ ├── protocol/
│ │ └── types.go # MCP JSON-RPC 2.0 protocol types
│ ├── reranker/
│ │ └── local.go # HTTP client for local reranker (30s timeout)
│ ├── retriever/
│ │ ├── retriever.go # 3-layer pipeline: embed → hybrid → rerank
│ │ └── logger.go # Trajectory logger (JSON lines)
│ ├── server/
│ │ ├── server.go # MCP server + chunk JSON→text rendering
│ │ └── http.go # Streamable HTTP transport (POST /mcp, /health)
│ └── vectordb/
│ └── pinecone.go # Pinecone query client
├── go.mod
└── go.sum
身份验证的工作原理
此服务器使用 应用程序默认凭据(ADC).何时 GOOGLE_APPLICATION_CREDENTIALS 指向服务帐户JSON密钥时,Vertex AI客户端库会自动拾取它。
服务帐户需要以下之一:
roles/aiplatform.expressUser--顶点AI平台快速用户(测试版)roles/aiplatform.user--顶点AI用户
连接MCP主机
服务器必须在VM上以HTTP模式运行(scripts/mcp-ctl.sh start),并且VM的防火墙/安全组必须允许端口7778上的入站TCP 仅来自连接主机的IP (端点上没有身份验证)。
Claude 代码
claude mcp add --transport http pinecone-rag http://<vm-ip>:7778/mcp
或在 .mcp.json / ~/.claude.json:
{
"mcpServers": {
"pinecone-rag": {
"type": "http",
"url": "http://<vm-ip>:7778/mcp"
}
}
}
反重力
进入 ~/.gemini/antigravity/mcp_config.json (注意字段名称为 serverUrl,不 url):
{
"mcpServers": {
"pinecone-rag": {
"serverUrl": "http://<vm-ip>:7778/mcp"
}
}
}
仅启动本地stdio服务器的主机
过桥 mcp-remote (需要节点/npx 在客户端机器上):
{
"mcpServers": {
"pinecone-rag": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://<vm-ip>:7778/mcp"]
}
}
}
本地stdio(同一台机器)
直接运行二进制文件,不带任何标志(stdio是默认传输)——请参阅上面的mcp-go示例。
MCP协议
实施MCP协议版本 2024-11-05 / 2025-03-26 / 2025-06-18 (客户端请求的版本在支持时会被回显)通过两种传输方式:
- 标准 --stdin上每个请求一行JSON-RPC,stdout上一行响应
- 可流式传输HTTP —
POST /mcp具有JSON-RPC主体→application/json回应;通知→202 Accepted;无状态(无会话ID);GET /mcp→405(无服务器启动的流)
| 方法 | 行为 |
|---|---|
initialize |
返回服务器信息和 tools 能力 |
initialized |
通知--已确认,未发送响应 |
tools/list |
返回 rag_query 工具定义 |
tools/call |
执行 rag_query:嵌入→ 混合搜索→ 重新排序→ 渲染块 |
ping |
退货 {} |
许可证
麻省理工学院