最近在折腾 MCP(Model Context Protocol)的时候遇到一个困惑。我打算给自己的知识库接一个向量检索功能,目前有两种方案:一种是直接把向量数据库的查询封装成一个 MCP tool,让模型需要时自己调用;另一种是提前在 MCP server 里把 query 向量算好,再把 top-k 结果作为 context 塞给模型。第一种感觉更灵活,但担心模型乱调用,或者返回格式太原始,反而干扰生成;第二种又觉得有点过度耦合,而且每次都要等向量查询完了才发请求,延迟高。有没有佬友实践过?在 MCP 场景下,向量检索结果一般怎么给模型最合适?我看官方文档也没讲太细,求指点。
MCP 服务里直接查向量库好,还是先查再走工具调用?
全部回复
共 45 条我最近也在踩这个坑,说下自己的感受。直接封装成 tool 确实灵活,但模型有时候会莫名其妙连着调好几次,而且返回的 raw json 如果不做裁剪,token 一下就爆了。后来我改成在 tool 内部做一层轻量封装,只返回精简后的 snippet 加 score,效果好了不少。另一种预查询塞 context 的做法我也试过,延迟确实是个问题,尤其是 MCP server 和向量库不在同一台机器上的时候。不过如果你的场景是固定几个知识域、query 模式比较可预测,预查询反而更稳,因为你能控制注入的内容长度和格式。我现在的折中是做成一个 tool,但 server 端缓存最近的查询结果,模型重复调同一 query 时直接命中缓存。另外我觉得关键还是看你的 agent 框架有没有对 tool 调用做约束,比如限制调用次数或者强制 schema。官方文档确实讲得太浅了,这块基本靠自己摸索。
我目前是混着用的,高频固定的查询直接塞 context,省一次 tool call 延迟确实舒服;开放性的就让模型自己调 tool,灵活度高。关键是 tool 返回别丢原始向量结果,最好在 MCP server 里就格式化好、带上来源和分数,不然模型容易瞎编。另外可以给 tool 描述里写清楚触发条件,能减少乱调用。你们知识库大概多大规模?量大了预查询那套延迟会更明显。
我目前是走工具调用这条路,但做了两层收口:tool 只暴露一个 search 接口,参数里限定 top_k 和过滤条件,返回结构也提前裁剪成标题加摘要加来源,不让原始 chunk 直接丢给模型。这样模型调用频率可控,召回质量反而比预塞 context 稳。预查询那套我也试过,延迟确实难受,尤其是多轮对话里每轮都重查一遍。
封装成 tool 更稳,模型自己决定啥时候查,提前塞 context 反而容易把无关内容带进去。
我之前两种都试过,现在偏向把向量检索包成 tool,但会在 server 端做一层预处理。返回结果别直接丢原始 chunk,最好压成带标题和摘要的结构化片段,不然模型很容易被噪声带偏。提前塞 context 确实稳,但延迟和 token 浪费都挺明显,适合小库或者固定场景。