2026年7月2日 周四晚上19:30,报名腾讯会议了解“如何构建自进化的动态知识库(Brain)”(限30人)
免费POC, 零成本试错
FDE知识库

FDE知识库

学习大模型的前沿技术与行业落地应用


收藏

首发完整版教程,MCP 集成至 LlamaIndex 的技术实践

发布日期:2025-02-25 04:57:06 浏览次数: 2890
作者:NebulaGraph 技术社区

微信搜一搜,关注“NebulaGraph 技术社区”

推荐语

掌握MCP与LlamaIndex集成的实战技巧,深入了解现代AI应用的无缝集成流程。

核心内容:
1. MCP协议的基本概念及其功能
2. LlamaIndex框架的核心特性
3. 技术实践:将MCP集成至LlamaIndex的详细步骤

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家

▌一、前言

本文主要介绍了如何将 MCP(Model Context Protocol,模型上下文协议)工具转换为可以直接使用的 LlamaIndex 工具,使 LlamaIndex 用户能像使用 Claude, Cursor 等现代 AI 应用一样无缝集成这些服务。

▌二、技术背景

2.1 什么是 MCP 协议 ?

MCP(模型上下文协议,https://modelcontextprotocol.io)是面向 AI 应用交互的服务构建协议。开发者可通过该协议构建具备数据资源(resources)、功能工具(tools)和提示模板(prompts)的服务端点。例如,我们可以定义获取 IP 详细信息的 fetch_ipinfo 工具:

@mcp.tool()
async def fetch_ipinfo(ip: str | None = None, **kwargs) -> IPDetails:
    """获取指定IP的详细信息
    
    参数:
        ip(str or None): 目标 IP 地址,格式如 192.168.1.1
        **kwargs: 传递给 IPInfo 处理器的附加参数
    
    返回:
        IPDetails: 包含城市、时区等信息的结构化数据
    "
""
    handler = ipinfo.getHandler(
        access_token=os.environ.get("IPINFO_API_TOKEN"),
        headers={"user-agent""basic-mcp-server"},
        **kwargs,
    )
    details = handler.getDetails(ip_address=ip)
    return IPDetails(**details.all)

2.2 LlamaIndex 框架特征

LlamaIndex(https://github.com/run-llama/llama_index)是构建知识索引系统的核心框架,其核心价值在于将外部信息结构化地接入大语言模型,实现高效的信息检索、智能问答和对话生成。当需要集成动态数据源时,将 MCP 工具转换为 LlamaIndex 工具成为关键技术需求。

LlamaIndex 中,NebulaGraph 已经有两种方法实现 GraphRAG

KnowledgeGraphIndex 用来对任何私有数据从零构建知识图谱(基于 LLM 或者其他语言模型),再 4 行代码进行 Graph RAG:

graph_store = NebulaGraphStore(
    space_name=space_name,
    edge_types=edge_types,
    rel_prop_names=rel_prop_names,
    tags=tags,
)
storage_context = StorageContext.from_defaults(graph_store=graph_store)
# Build KG
kg_index = KnowledgeGraphIndex.from_documents(
    documents,
    storage_context=storage_context,
    max_triplets_per_chunk=10,
    space_name=space_name,
    edge_types=edge_types,
    rel_prop_names=rel_prop_names,
    tags=tags,
)
kg_query_engine = kg_index.as_query_engine()

KnowledgeGraphRAGQueryEngine 则可以在任何已经存在的知识图谱上进行 GraphRAG:

graph_store = NebulaGraphStore(
    space_name=space_name,
    edge_types=edge_types,
    rel_prop_names=rel_prop_names,
    tags=tags,
)
storage_context = StorageContext.from_defaults(graph_store=graph_store)
graph_rag_query_engine = KnowledgeGraphRAGQueryEngine(
    storage_context=storage_context,
)

▌三、为什么

需要将 MCP 集成至 LlamaIndex

在实际 AI 应用开发中,集成 MCP 工具主要解决以下需求:

  • 功能复用:利用现有 MCP 生态(项目列表见https://github.com/AlexMili/Awesome-MCP)快速扩展系统能力

  • 流程统一:建立标准化工具调用范式,简化大模型对外部 API 的调用复杂度

  • 自动化管理:通过自动转换机制实现 MCP 工具到 LlamaIndex FunctionTool 对象的映射,便于 Agent 自动调度

该集成方案可以有效降低开发成本,同时发挥 LlamaIndex 在上下文管理和对话生成方面的优势。

▌四、技术实现方案

实现流程包含三个关键阶段:

  • MCP 服务通信:通过 MCPClient 类建立服务连接,支持工具发现(list_tools)和调用执行(call_tool)

  • 适配器构建:定义 MCPToolAdapter 类,将 MCP 工具元数据转换为 LlamaIndex 的 FunctionTool 对象

  • 智能代理集成:在 LlamaIndex Agent 中加载转换后的工具,实现自动化调用

▌五、核心代码解析

协议转换适配器

from llama_index.core.tools import FunctionTool
from pydantic import create_model, BaseModel

class MCPToolAdapter:
    def __init__(self, client):
        self.client = client

    async def list_tools(self):
        tools = await self.client.list_tools()
        return [
            FunctionTool.from_defaults(
                fn=self._create_tool_fn(tool.name),
                name=tool.name,
                description=tool.description,
                fn_schema=self._create_pydantic_model(tool.schema),
            ) for tool in tools
        ]
    
    def _create_pydantic_model(self, json_schema):
        # 实现JSON Schema到Pydantic模型的动态转换
        ...

类型系统映射

  JSON_TYPE_MAPPING = {
    "string": str,
    "number"float,
    "integer": int,
    "boolean": bool,
    "object": dict,
    "array": list
}

def create_dynamic_model(schema):
    fields = {}
    for name, prop in schema["properties"].items():
        py_type = JSON_TYPE_MAPPING[prop["type"]]
        if name in schema.get("required", []):
            fields[name] = (py_type, Field(...))
        else:
            fields[name] = (Optional[py_type], Field(None))
    return create_model("DynamicModel", **fields)

服务调用封装

   async def fetch_ipinfo_wrapper(**kwargs):
    return await mcp_client.call_tool("fetch_ipinfo", kwargs)

关键技术创新点

  • 动态模式转换:实现 JSON Schema 到 Pydantic 模型的运行时转换,保证参数校验的严格性

  • 异步调用管道:基于 Python asyncio 构建非阻塞式服务调用,提升工具执行效率

  • 协议抽象层:通过适配器模式解耦 MCP 协议与 LlamaIndex 框架,保证系统扩展性

将 MCP 工具的输入参数转换为 Pydantic 模型的原因在于:MCP 工具使用 JSON Schema 格式定义输入参数(在工具对象的 inputSchema 中,类型为 Dict[str, Any] ),而 create_model_from_json_schema 函数将其转换为 Pydantic 模型,该模型用作 LlamaIndex 中 FunctionTool 的 fn_schema

▌六、LlamaIndex 中的 MCP 工具

调用实践

以下代码来自 llamaindex_mcp_example.py,完整展示了 MCPToolAdapter 与 LlamaIndex 的集成方式:

import os
from llama_index.core.llms import ChatMessage
from llama_index.core.agent import ReActAgent, ReActChatFormatter
from llama_index.core.agent.react.prompts import REACT_CHAT_SYSTEM_HEADER
from llama_index.llms.azure_openai import AzureOpenAI

from llamaindex_mcp_adapter import MCPToolAdapter
from mcp_client import MCPClient
import anyio
import dotenv
import argparse

dotenv.load_dotenv()

# 系统级指令模板
SYSTEM_PROMPT = """\
您是一个智能法律助手

在回答用户问题前,必须通过IP信息确认用户所在司法管辖区
操作规则:
- 当涉及地理位置、时区等问题时,自动调用fetch_ipinfo工具
- 法律咨询类问题需结合IP所在国家/地区法律体系
"
""

async def get_agent(adapter: MCPToolAdapter):
    """智能代理初始化函数"""
    tools = await adapter.list_tools()  # 获取MCP工具列表
    
    # 配置Azure OpenAI大语言模型
    llm = AzureOpenAI(
        model=os.environ.get("AZURE_OPENAI_MODEL""gpt-4"),
        max_tokens=int(os.environ.get("AZURE_OPENAI_MAX_TOKENS", 4096)),
        azure_endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"),
        api_key=os.environ.get("AZURE_OPENAI_API_KEY"),
        api_version=os.environ.get("AZURE_OPENAI_API_VERSION"),
        engine=os.environ.get("AZURE_OPENAI_ENGINE")
    )
    
    # 构建ReAct智能代理
    agent = ReActAgent.from_tools(
        llm=llm,
        tools=list(tools),
        react_chat_formatter=ReActChatFormatter(
            system_header=SYSTEM_PROMPT + "\n" + REACT_CHAT_SYSTEM_HEADER,
        ),
        max_iterations=20,  # 限制最大推理步数
        verbose=True        # 启用详细日志
    )
    return agent

async def handle_user_message(message_content: str, agent: ReActAgent):
    """消息处理流水线"""
    user_message = ChatMessage.from_str(role="user", content=message_content)
    response = await agent.achat(message=user_message.content)
    print(f"[智能代理响应] {response.response}")

if __name__ == "__main__":
    async def main():
        # 命令行参数解析
        parser = argparse.ArgumentParser()
        parser.add_argument("--client_type"
                          choices=["sse""stdio"], 
                          default="stdio",
                          help="连接模式:sse(Server-Sent Events)或stdio(标准输入输出)")
        args = parser.parse_args()

        # MCP客户端初始化
        if args.client_type == "sse":
            client = MCPClient("http://0.0.0.0:8000/sse")  # SSE长连接模式
        else:
            client = MCPClient(                            # 子进程模式
                "./venv/bin/python"
                ["mcp_server.py""--server_type""stdio"]
            )
        
        # 工具适配器初始化
        adapter = MCPToolAdapter(client)
        agent = await get_agent(adapter)

        # 执行测试用例
        await handle_user_message("我的IP所在城市是哪里?", agent)
        await handle_user_message("持有大麻在我国是否合法?", agent)

    anyio.run(main)  # 启动异步运行时

关键实现解析

  • 工具获取机制:
    • 通过 adapter.list_tools() 动态加载 MCP 服务端注册的工具列表
    • 自动将每个 MCP 工具转换为 LlamaIndex 的 FunctionTool 对象
  • 智能代理配置:
    • 使用 Azure OpenAI 作为底层大语言模型引擎
    • 集成 ReAct 推理框架,支持多步工具调用
    • 设置 20 步的最大推理深度防止无限循环
  • 消息处理流程:
    • 将用户输入封装为标准化 ChatMessage
    • 通过 agent.achat() 触发自动化工具调用链

▌七、运行 Demo

7.1 标准输入输出模式

python llamaindex_mcp_example.py --client_type stdio

执行输出示例

[DEBUG] 检测到ListToolsRequest协议请求
[工具调用] 步骤ID: ede14770-91c9-428b... | 输入: 我的IP所在城市是哪里?
[推理日志] 当前用户语言:中文,需调用工具获取数据
[动作触发] fetch_ipinfo | 参数: {}
[网络请求] 调用MCP工具耗时128ms
[观察结果] {"ip""183.193.123.192""city""上海""country""CN"...}
[最终响应] 您的IP所在城市为上海

[法律咨询] 步骤ID: e728f5d0-6c0e-454a... | 输入: 持有大麻是否合法?
[推理日志] 已确认用户所在国家:中国
[知识库检索] 加载中国刑法第357条
[最终响应] 根据中国法律,持有大麻属违法行为,最高可判处有期徒刑

7.2 SSE 服务模式

# 终端1:启动SSE服务端
python mcp_server.py --server_type sse

# 终端2:运行客户端
python llamaindex_mcp_example.py --client_type sse

▌八、技术方案总结

通过以下三步实现深度集成:

协议通信层

  • 基于 MCPClient 实现服务发现与工具调用
  • 支持 SSE/STDIO 双模连接,适应不同部署场景

类型转换层

  • 动态将 JSON Schema 转换为 Pydantic 模型
  • 实现参数自动校验与类型提示
def create_dynamic_model(schema):
    # 自动生成带字段描述的Pydantic模型
    fields = {
        name: (map_type(prop), Field(..., description=prop["description"]))
        for name, prop in schema["properties"].items()
    }
    return create_model("DynamicModel", **fields)

智能代理层

  • 集成 ReAct 推理框架实现自动化工具调度
  • 通过系统提示词约束工具使用规范
SYSTEM_PROMPT = """\
法律咨询必须遵循以下规则:
1. 首次响应前必须调用fetch_ipinfo确认用户辖区
2. 引用法律条文需标注具体条款编号
3. 不得对未覆盖地区提供法律建议"
""

通过持续扩展 MCP 生态,开发者可快速构建具备专业领域能力的智能代理系统

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询

扫码登录
登录即表示您同意《53AI网站服务协议》
服务协议

欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。

在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。

一、 定义

本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。

会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。

知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。

二、 账号注册与登录

登录方式:本网站支持以下登录方式,您可根据实际情况选择:

微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。

手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。

账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。

实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。

未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。

三、 服务内容与规范

知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。

服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。

禁止行为:您在使用服务时不得实施以下行为:

利用技术手段批量爬取、下载、转存知识库内容;

将知识库内容用于商业目的或未经授权地向第三方传播;

干扰本网站正常运行或侵犯其他用户合法权益;

发布违法违规信息或从事违反公序良俗的活动。

四、 知识产权声明

权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。

有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。

侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。

五、 个人信息保护

我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。

您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。

您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。

六、 免责声明

内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。

不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。

第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。

七、 违约责任

如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。

如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。

八、 法律适用与争议解决

本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。

因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。

九、 其他

本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。

本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。

我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。


已查阅