想让模型用上自己的资料,又不想每种客户端各写一套检索代码,就会碰到「RAG MCP 服务」这个词。它本质是把检索能力包成一个标准工具接口,让任何支持该协议的客户端都能直接调。这篇不讲协议细节,只讲模块怎么切、超时并发怎么设、日志该怎么记,以及什么情况下不该这么做。
想让模型用上自己的资料,又不想每种客户端各写一套检索代码,就会碰到「RAG MCP 服务」这个词。它本质是把检索能力包成一个标准工具接口,让任何支持该协议的客户端都能直接调。你写的检索逻辑只维护一份,谁接进来都能用。
这篇不讲协议细节,只讲工程落地:模块怎么切、超时并发怎么设、日志该怎么记,以及什么情况下不该这么做。想先确认某个中转站或工具值不值得用,可以到 /sites 与 /tools/speed-test 核对当时的数字,再决定要不要接进自己的链路。
它到底是什么:把检索包成一个能被调用的工具
拆开看:RAG 负责「资料怎么找」,MCP 服务负责「让外部客户端按统一方式调用它」。两者叠在一起,就是把检索做成一个可被多次复用的接口层。调用方只知道工具名和参数结构,不关心底层用哪个向量库、哪家嵌入模型。换底层实现时,改的是服务侧,客户端一行不用动。
| 对比项 | 直接写检索函数 | 包成 RAG MCP 服务 |
|---|---|---|
| 调用方 | 只有当前项目能用 | 任何支持该协议的客户端 |
| 换向量库 | 改代码各处调用点 | 只改索引层实现 |
| 多客户端 | 每个都重写一遍 | 注册一次,复用 |
| 维护成本 | 单场景更低 | 多一层服务和部署 |
模块怎么切:四块职责拆开才好换
模块化不是把代码分文件,而是让每块能独立替换而不牵动其他块。推荐按下面四层切,接口定好后各层可以并行迭代,谁也不用等谁。
- 进料层:文档解析、清洗、切片,负责把原始文件变成干净文本,换解析器不影响下游
- 索引层:嵌入模型加向量库,负责写入与召回,这是最常换的一块,接口要留抽象
- 检索层:召回、重排、拼装上下文,决定返回给模型的内容形态
- 服务层:工具定义、参数校验、鉴权与返回格式,是唯一和外部客户端打交道的一层
切分是否合格,用一条标准检验:改任何一层时,是否需要动到其他层的代码。如果换个嵌入模型要顺带改服务层的返回结构,说明抽象没做够。落地顺序建议从服务层倒着来,先把工具签名和参数结构定死,再往里填实现。
跑起来要调的几个参数
- 先量延迟基线在 /tools/speed-test 量出自己这条链路的真实耗时分布,再按基线往上加余量,别抄别人的超时值,环境和资料量都不一样。
- 定并发上限检索服务通常比生成服务先被打满,要在服务层做排队,而不是无限放大并发,否则向量库先撑不住,表现是全链路一起变慢。
- 挂降级路径召回为空或重排超时时,退化为纯关键词检索,或者直接回一句没找到,别让整次对话卡死在那里。
- 加短周期缓存同一份资料被反复问到是常态,把查询结果做短周期缓存能省掉大量重复召回。
日志和评测:怎么知道它到底有没有用
检索出问题时最难的不是修,是判断到底哪一步坏了。日志字段缺失基本等于没法复盘,所以每次调用至少要覆盖下面这几项。
- 工具名
- 区分是哪个检索工具被调的
- 查询原文
- 保留用户原始问法,别只存清洗后的
- 召回条数
- 为 0 或异常多都是信号
- 耗时
- 分段记,进料、索引、重排各自多少
- 命中片段标识
- 方便反查是哪份资料的哪一段
准备一组固定问题当回归用例,改切片或换嵌入模型后重跑一遍,看召回命中率有没有掉。线上盯两个指标:检索命中率指召回里有没有答案,空召回率指多少次什么都没找到。后者升高通常说明切片或索引出问题了,比整体延迟更早暴露故障。
什么情况下别上这套
- 资料量很小、更新很频繁、只有单客户端:直接塞进上下文或写个简单函数更快
- 团队没人维护索引:检索效果会随资料增长持续下滑,最后不如不用
- 对延迟极度敏感:多一层服务调用和检索往返,首字延迟一定比纯生成高
- 预算和排期都很紧的首版验证:先用最小可用的检索函数跑通效果,再考虑包成服务
换个角度说,这套方案适合的是「检索逻辑会被多个客户端复用、底层组件预计要换」的场景。如果这两个条件一个都不成立,包成服务只是给自己加运维负担。
下一步先看看同类工具和各家接入方案的实际表现,再决定自己的模块边界怎么定,页面上有当时的对比数据可核对。→常见问题
RAG MCP 服务和普通 RAG 接口有什么不一样?
普通 RAG 接口一般是你自己定义 HTTP 路径,客户端要照你的文档接。MCP 服务是把检索能力按统一工具描述暴露出去,支持该协议的客户端不需要为你的服务写定制代码,换个客户端也能直接用。代价是你要多维护一份工具定义和参数校验。
模块化之后,换向量库需要改哪些地方?
理想情况只改索引层。前提是检索层只通过抽象接口拿结果,不直接依赖某个向量库的返回结构。实践中常见问题是重排和过滤条件写死在索引层里,换库时跟着一起改。建议一开始就把「召回」和「过滤」分成两个入参。
检索服务要不要单独部署?
看调用方数量。只有一个客户端时,和业务服务放一起更省事。多个客户端或多人共用时,独立部署才好单独扩缩容和限流,也方便在不影响业务的情况下换嵌入模型、重建索引。独立部署后一定要在服务层加鉴权,别裸奔。