思考:MCP与Agentic RAG的融
RAG是一种借助外部知识来给LLM提供上下文的AI应用范式。从这个角度来说,RAG与MCP有着相似的意义:给大模型补充上下文,以增强其能力。只是MCP以提供外部工具为主,而RAG则是以注入参考知识为主。这就像一个考试的学生,MCP给你提供计算器,而RAG则是给你一本书。
当然,两者的重点并不一样,MCP强调的是提供工具的方式(集成标准);而RAG则是需要你实现的完整应用。所以两者并不冲突,完全可以用MCP的方法来集成一个RAG应用。
特别是在Agentic RAG系统(如下图)中,由于通常涉及到多个RAG查询管道与Agent的融合,这就与MCP的思想非常契合:
一个针对大量不同文档的问答Agent,这些问答有事实性问题也有摘要性问题,更有跨越多个文档的融合问题,甚至需要搜索引擎来补充信息。
MCP标准下的Agentic RAG架构
Agent 智能体在MCP架构下,无论是SSE还是stdio模式,都是Client/Server模式。你必须在开始之前清晰的设计好MCP Server与Client应用的分工及交互。比如:
【总体思想】
我们基于如下的总体架构来实现:
MCP Server:RAG管道的核心
【工具(Tools)】
需要说明,在这里的设计中,不同的RAG管道查询的工具是一样的,但参数(索引名,依赖于Agent推理)不同。一个是推理工具,一个推理参数,效果一致。
【缓存机制】
服务端要对文档解析(含分割)与索引创建的信息进行缓存(持久化存储),以防止可能的重复解析与索引创建,提高性能。
文档缓存的唯一名称是文档内容hash值+解析参数的联合。比如:
“questions.csv_f4056ac836fc06bb5f96ed233d9e2b63_500_50”
索引缓存的唯一名称是每个文档关联的唯一索引名称。比如:
“questions_for_customerservice”
以下情况下会导致索引被重建:
这样的缓存管理方式,可以增加处理的灵活性与健壮性。如:
【工具实现:create_vector_index】
这是服务端两个重要工具之一,核心代码如下,请参考注释理解:
【工具实现:query_document】
这是客户端调用的主要工具。其输入是索引名与查询问题。借助索引缓存,可以快速加载并执行RAG查询。这里不再展示完整处理过程:
按类似方法,再创建一个用于回答总结性问题的工具(利用LlamaIndex的SummaryIndex类型索引),此处不在赘述。
MCP客户端:实现Agent(基于LangGraph)
客户端的工作流程如下:
客户端的几个设计重点简单说明如下:
【配置文件】
客户端有两个重要的配置信息,分别用于MCP Server与知识文档的配置。
doc_config.json:
【主程序】
客户端主程序流程非常简单,基于一个封装的MCP客户端与AgenticRAG类型:
篇幅原因,一些细节部分不在这做详细展示。如果有疑问,欢迎后台交流。
端到端效果演示
现在让我们来测试下这个的“MCP化”的Agentic RAG应用的运行效果。按照如下步骤来进行:
1. 启动MCP RAG-Server。这里用更复杂的SSE模式(暂时未支持文档上传,所以只能本机启动):
启动时会自动提取并展示服务端的工具清单。
2. 准备客户端知识文档与配置文件。将需要索引和查询的文档放在应用的data/目录,配置好mcp_config与doc_config。不做任何其他处理。直接启动客户端应用:
* 观察首次运行的跟踪信息(如下图),这里的过程是:
* 现在退出程序,再次启动客户端,观察输出(如下图),可以看到由于索引已经创建,所以会显示“无需创建”。
3. 交互式测试
进入交互式测试环节(图中的服务端信息是通过MCP接口推送到客户端的远程日志,方便观察服务端的工作状态):
1. 关联两个文档信息的查询
由于提供的文档有北京和上海的城市信息介绍,所以看到这个问题调用了北京和上海的RAG管道查询,还自作主张的调用了搜索引擎做补充,然后输出答案:
2. 查询知识库答案,并要求和网络搜索结果核对。
日志显示,Agent先用本地向量索引查询,然后通过搜索引擎对比,非常准确。
3. 总结性问题测试。
日志显示,这里未加载向量索引,而是由工具加载这个文档的节点,并生成文档摘要后返回(SummaryIndex的效率不太高,有待优化)
4. 最后一个很有意思的测试。
由于我们把创建索引的过程“工具”化了,所以甚至可以用自然语言来管理索引。比如这里我要求把csv文档的索引重建,智能体准确的推理出工具及参数,并重建了csv文档索引(实际应用要考虑安全性):
以上展示了一个基于MCP架构的Agentic RAG系统的实现。总结这种架构下的一些明显的变化:
end
福利时间
为了帮助LLM开发人员更系统性与更深
RAG是一种借助外部知识来给LLM提供上下文的AI应用范式。从这个角度来说,RAG与MCP有着相似的意义:给大模型补充上下文,以增强其能力。只是MCP以提供外部工具为主,而RAG则是以注入参考知识为主。这就像一个考试的学生,MCP给你提供计算器,而RAG则是给你一本书。
当然,两者的重点并不一样,MCP强调的是提供工具的方式(集成标准);而RAG则是需要你实现的完整应用。所以两者并不冲突,完全可以用MCP的方法来集成一个RAG应用。
特别是在Agentic RAG系统(如下图)中,由于通常涉及到多个RAG查询管道与Agent的融合,这就与MCP的思想非常契合:
一个针对大量不同文档的问答Agent,这些问答有事实性问题也有摘要性问题,更有跨越多个文档的融合问题,甚至需要搜索引擎来补充信息。
MCP标准下的Agentic RAG架构
在MCP架构下,无论是SSE还是stdio模式,都是Client/Server模式。你必须在开始之前清晰的设计好MCP Server与Client应用的分工及交互。比如:
【总体思想】
我们基于如下的总体架构来实现:
MCP Server:RAG管道的核心
【工具(Tools)】
需要说明,在这里的设计中,不同的RAG管道查询的工具是一样的,但参数(索引名,依赖于Agent推理)不同。一个是推理工具,一个推理参数,效果一致。
【缓存机制】
服务端要对文档解析(含分割)与索引创建的信息进行缓存(持久化存储),以防止可能的重复解析与索引创建,提高性能。
文档缓存的唯一名称是文档内容hash值+解析参数的联合。比如:
“questions.csv_f4056ac836fc06bb5f96ed233d9e2b63_500_50”
索引缓存的唯一名称是每个文档关联的唯一索引名称。比如:
“questions_for_customerservice”
以下情况下会导致索引被重建:
这样的缓存管理方式,可以增加处理的灵活性与健壮性。如:
【工具实现:create_vector_index】
这是服务端两个重要工具之一,核心代码如下,请参考注释理解:
【工具实现:query_document】
这是客户端调用的主要工具。其输入是索引名与查询问题。借助索引缓存,可以快速加载并执行RAG查询。这里不再展示完整处理过程:
按类似方法,再创建一个用于回答总结性问题的工具(利用LlamaIndex的SummaryIndex类型索引),此处不在赘述。
MCP客户端:实现Agent(基于LangGraph)
客户端的工作流程如下:
客户端的几个设计重点简单说明如下:
【配置文件】
客户端有两个重要的配置信息,分别用于MCP Server与知识文档的配置。
doc_config.json:
【主程序】
客户端主程序流程非常简单,基于一个封装的MCP客户端与AgenticRAG类型:
篇幅原因,一些细节部分不在这做详细展示。如果有疑问,欢迎后台交流。
端到端效果演示
现在让我们来测试下这个的“MCP化”的Agentic RAG应用的运行效果。按照如下步骤来进行:
1. 启动MCP RAG-Server。这里用更复杂的SSE模式(暂时未支持文档上传,所以只能本机启动):
启动时会自动提取并展示服务端的工具清单。
2. 准备客户端知识文档与配置文件。将需要索引和查询的文档放在应用的data/目录,配置好mcp_config与doc_config。不做任何其他处理。直接启动客户端应用:
* 观察首次运行的跟踪信息(如下图),这里的过程是:
* 现在退出程序,再次启动客户端,观察输出(如下图),可以看到由于索引已经创建,所以会显示“无需创建”。
3. 交互式测试
进入交互式测试环节(图中的服务端信息是通过MCP接口推送到客户端的远程日志,方便观察服务端的工作状态):
1. 关联两个文档信息的查询
由于提供的文档有北京和上海的城市信息介绍,所以看到这个问题调用了北京和上海的RAG管道查询,还自作主张的调用了搜索引擎做补充,然后输出答案:
2. 查询知识库答案,并要求和网络搜索结果核对。
日志显示,Agent先用本地向量索引查询,然后通过搜索引擎对比,非常准确。
3. 总结性问题测试。
日志显示,这里未加载向量索引,而是由工具加载这个文档的节点,并生成文档摘要后返回(SummaryIndex的效率不太高,有待优化)
4. 最后一个很有意思的测试。
由于我们把创建索引的过程“工具”化了,所以甚至可以用自然语言来管理索引。比如这里我要求把csv文档的索引重建,智能体准确的推理出工具及参数,并重建了csv文档索引(实际应用要考虑安全性):
以上展示了一个基于MCP架构的Agentic RAG系统的实现。总结这种架构下的一些明显的变化:
end
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/235806.html原文链接:https://javaforall.net
