最近在做一个内部知识库的RAG系统,刚把检索模块封装成MCP服务,想着让Agent能动态调用不同的检索工具(向量库、SQL查询、Web搜索)。但实际跑下来发现,Agent经常选错工具,比如问“某项目的上线时间”,它不去查SQL,反而去向量库捞了一段模糊的文本回复,准确率比之前固定单路召回还低。想请教下大家,MCP这边的工具描述和参数schema应该怎么设计,才能让模型更准确地路由?还是说这种多工具模式本身就该配合一个独立的意图识别层来兜底?目前用的DeepSeek,温度已经调到0.2了。
RAG接入MCP后检索结果反而变差了,是路由策略的问题吗?
全部回复
共 52 条说实话你这问题我踩过一模一样的坑,MCP工具描述里别堆功能词,得把“何时该用”写清楚,比如SQL查询直接写明“仅用于精确时间/数值字段,且表名是xxx”,比泛泛说“查询数据库”强多了。另外DeepSeek这温度下对工具选择挺敏感的,参数schema里加个example字段会好很多,模型能照着例子模仿路由。至于意图识别层,我觉得前期可以加个轻量的关键词预筛,兜底成本远低于反复调prompt,后面等路由稳了再拆掉也行。
工具描述里得把触发条件和反例写清楚,比如“仅当问具体日期时用SQL”,不然模型真容易瞎猜。
工具描述别写太啰嗦,把关键词和场景例子塞进去,DeepSeek对明确指令敏感,试下“查询项目时间线时用SQL”。
我也遇到过类似的情况,而且我觉得问题可能不在MCP本身,而是工具描述和真实能力之间的gap。你把SQL查询描述成“获取项目时间信息”,但向量库里可能也有相关文本,模型就会倾向于选择它更“熟悉”的检索方式,尤其DeepSeek这种对工具调用理解还比较依赖提示词一致性的模型。
关于schema设计,我建议把工具描述写得“带决策条件”一点,比如明确写上“当用户询问精确日期、版本号、金额等结构化字段时,必须使用SQL”,而不是泛泛说“查询数据库”。另外,参数示例也很关键,给一个具体的query样例,模型路由的准确率会明显提升。
不过说真的,独立意图识别层我觉得不是“兜底”,而是更可靠的架构。MCP适合做工具执行,不适合做复杂路由判断,尤其当工具数量超过3个时,纯粹靠模型自由选择很容易漂移。我自己现在是把一个轻量分类器放在前面,先判意图再决定调哪个工具,效果稳定很多。
还有个细节,温度0.2可能还是高了,工具路由这种任务我甚至试过0,同时可以对比一下不同模型,有些模型天生对工具调用的指令遵循能力更强。你目前这个场景,我猜主要是“信息类型”和“工具能力”的对应关系没在描述里锁死,建议先用测试集跑一遍,看它具体在哪些query上选错,再针对性改描述。
说实话我也踩过类似的坑,MCP工具描述写得再详细,模型该瞎还是瞎。后来我干脆把每个工具的描述里都加了“必须满足xx条件才调用”这种强约束,比如SQL工具就写“仅当问题包含明确日期或ID时使用”,效果稍微好点。但更靠谱的还是加一层轻量意图分类,先判断是查事实还是找文档,再决定走哪路检索,纯靠模型自己路由真不太可控。
同款问题,MCP工具描述写得再细,模型该选错还是选错。我后来把工具名直接改成“查项目时间表”这种带具体动作的,再在参数里加上“必须匹配项目名称和日期类型”,命中率才上来一点。但说实话,意图识别这层还是得自己兜底,尤其内部知识库的命名习惯和模糊表达,模型根本猜不到。你试过在路由前加个轻量分类器吗?或者先用向量检索粗筛,再根据结果类型强制走对应工具?
这个现象我太有同感了,之前我把路由完全交给模型的时候也翻过车。你问SQL它去查向量库,八成是工具描述写得太“像人话”了,比如“查询项目信息”这种,模型根本分不清该走哪个,我后来把描述改成强约束句式,比如“仅当需要精确字段值(如日期、金额)时使用,且必须包含完整表名”,效果立竿见影。不过我也觉得,光靠优化描述治标不治本,DeepSeek这类模型在工具选择上其实挺依赖先验知识的,你温度调到0.2已经很低了,但遇到语义模糊的query还是会瞎猜。我现在的做法是加了一个轻量的规则前置层,先用正则或小模型把query里明显的时间、金额、人名标签抽出来,直接命中就锁定SQL,命中不了再让Agent自由路由,准确率能回到单路召回的水准。另外你的参数schema里有没有把“必填字段”和“返回结构示例”写清楚?我试过把示例值直接写进描述里,比如“返回格式为JSON,含project_name和launch_date”,模型就不容易跑偏了。说到底,多工具模式确实需要一个兜底策略,但别急着上重型意图识别,先用启发式规则把高置信度的场景分流掉,剩下的再丢给Agent,成本低又稳。你现在的MCP工具列表里,Web搜索和向量库的边界会不会本身就有重叠?有时候模型不是选错,而是两个工具的语义空间太接近,它压根分不清该用哪个。
这问题太典型了,我之前也踩过类似的坑。MCP的tool description确实直接影响路由,但DeepSeek对长描述的敏感度其实一般,你反而要把最关键的区分词放在前面,比如“精确查项目上线日期,返回结构化数据”这种,别堆一堆功能描述。我自己试下来,参数schema越少越短越容易选对,字段一多模型就开始瞎猜。另外温度调低不是万能的,路由本质是逻辑判断,0.2有时候反而让模型过度自信。我觉得你那个“独立意图识别层”的思路靠谱,但不用单独做一个模型,可以在MCP外面加个轻量规则层,先把高频问题硬映射到固定工具,剩下的才交给LLM路由。还有个细节,向量库的返回结果如果带了“可能”“大概”这类词,模型会误以为这是答案而不是线索,你可以在结果里强制加个置信度字段。最后想问下,你有没有试过把SQL和向量库的description写成对比句式,比如“如果你需要确切数字,用这个;如果你在找概念解释,用那个”,我这么改完路由准确率升了不少。
工具描述里把SQL的query示例写清楚,比调温度管用。另外建议加个轻量意图分类前置,别全指望模型自己猜。
碰到过类似的坑,MCP工具描述如果写得太笼统,模型确实容易瞎猜,我后来是把每个工具的用途和典型问题示例直接塞进description里,比如“SQL查询:用于查结构化数据,像项目上线时间、金额这种字段”,效果立竿见影。不过你提到的意图识别层我觉得还是得有,尤其当问题里带模糊表述时,光靠prompt路由不太稳,可以加个轻量分类器做硬兜底,成本也不高。另外DeepSeek温度0.2没问题,但你可以试试把它对工具选择的logits做个加权,让SQL这类高确定性工具优先,我这边调完准确率涨了不少。
工具描述这块确实容易被低估,我之前也踩过坑,光写“查询项目信息”太模糊了,模型根本分不清该走SQL还是向量库。你现在可以试试把描述改成类似“精确查询结构化数据(如项目上线日期、负责人)”,参数里也把字段名和示例值写清楚,DeepSeek对这种显式提示的响应会好很多。另外我觉得意图识别层不是“兜底”,而是该跟MCP并行,让Agent先粗分类再选工具,不然路由错了后面检索做得再好也白搭。你那边有没有试过在返回结果里加个置信度标记,让Agent拿不准时主动去问用户?
工具描述写具体点,带例子,比如“查上线时间用SQL”,比泛泛说“查询数据”强多了。