最近在折腾把公司的RAG知识库接入MCP,想统一管理内部工具和数据源。本来以为能提升检索效率,结果发现召回结果质量明显变差了。具体现象是:query经过MCP的tool调用后,返回的chunk相关性不如之前直接走向量检索准,尤其是涉及多轮对话上下文时,MCP的tool输入好像把原始意图“稀释”了。我试着调整了embedding阈值和topk,但效果不稳定。想问问各位:你们在MCP里接RAG时,是怎么处理查询改写或上下文拼接的?有没有踩过类似的坑?或者是不是我工具描述(tool schema)写得不够清晰导致模型选错了检索参数?求指点,感谢!
RAG系统接入MCP后检索质量反而下降了,大家有遇到吗?
全部回复
共 103 条这问题我太有同感了,之前我们团队试过把RAG挂到MCP上,结果也是召回率掉得莫名其妙。后来排查发现,MCP那层tool调用确实会改变query的原始语义,尤其是多轮对话里,模型在生成tool输入时容易把历史信息过度压缩,甚至把关键实体给吞掉,导致后续检索的向量空间对不上。我现在的做法是,在MCP的tool描述里明确要求“保留原query中的名词和数字”,同时把多轮上下文单独做一个拼接字段传进去,而不是让模型自由发挥。另外topk和阈值真不能瞎调,我们最后是拿一小组bad case反向标注,去校准tool的返回格式,比如强制让MCP返回一个结构化的“检索意图+关键词列表”,再喂给向量库。你提到的tool schema,我觉得确实可能是主因——如果描述里没写清楚“不要改写原问题,只补充上下文”,模型就会自作主张去压缩,结果就是现在的样子。还有就是,建议你对比一下不走MCP、直接走原始query的召回结果,如果差距特别大,那问题基本就锁定在查询改写环节了。
我们团队也踩过这个坑,后来发现问题多半出在tool schema对查询意图的约束上。MCP的tool调用本质是让模型做一次“决策”,如果描述里没明确说清楚什么时候该用向量检索、什么时候该用关键词,它就容易自己发挥,把原始query改得面目全非。我们现在是强制把原始用户query原样传给检索tool,同时在schema里加了一条“禁止改写”的指令,效果立马稳了不少。另外多轮上下文拼接这块,建议别一股脑全塞进去,只提取最近两轮的核心实体和意图,不然embedding真的会被稀释。
我遇到过类似情况,感觉不是MCP本身的问题,而是它把“检索”变成了一个中间步骤,模型在生成tool输入时会不自觉做“预压缩”,把关键信息丢了。你可以试试在tool描述里直接给出“返回结果必须基于原始query逐字匹配”这种强约束,另外把topk调高到20再让rerank去兜底,比单纯调embedding阈值靠谱。多轮对话的话,我们是用单独的上下文压缩模块先提炼出当前轮的核心问题,再喂给MCP,别让它自己拼接历史。
这问题我太熟了,MCP把RAG包了一层之后,query改写和工具描述其实会互相干扰。你试试把tool description里加上“保持用户原始query语义不变”这种提示,另外多轮上下文别一股脑全塞进tool参数,做个精简历史摘要再传,效果能稳不少。
我这边之前也是召回率掉得离谱,后来干脆在MCP外面先做一层查询意图判断,简单场景直接走向量检索,复杂场景才调工具,反而好了。你topk调不稳定是不是因为MCP返回的结构里带了额外字段,影响了重排?检查下返回的metadata有没有被污染。
有没有试过对比一下MCP调用前后query的embedding余弦相似度?如果偏差太大,大概率是tool schema强制要求了某些必填参数,导致模型为了填参数把原问题改写了。这种时候宁可把参数全设成可选,也别让模型自作主张加条件。