POML 与 MCP(Model Context Protocol)集成

POML 与 MCP(Model Context Protocol)集成

本文基于官方页面(microsoft.github.io/poml/stable... MCP 的工作原理、安装方式、基于 POML 模板的动态工具集成方案、完整示例、与直接使用 MCP 的对比,以及未来原生支持计划。

导语/背景介绍

  • MCP 是一种开放协议,为 LLM 应用与外部数据源和工具之间提供标准化的上下文访问与工具调用能力。
  • 警告:当前 POML 尚未内置支持 MCP。官方建议通过"工具调用 + 模板"的方式模拟 MCP 行为;未来版本计划提供原生支持。
  • 说明:部分提供方支持远程调用 MCP 服务器(如 OpenAI Response API),这类行为不在本文档范围内,因为开发者无需直接处理 MCP 调用细节。

安装与使用方法(Installation)

bash 复制代码
pip install mcp

工作原理(How MCP Works)

  • 客户端---服务端架构:
    1. 工具发现:MCP 服务器公开可调用的工具/函数
    2. 工具调用:客户端(LLM 应用)按参数调用工具
    3. 响应处理:服务器执行并返回结果给客户端
  • 典型流程:
    • 初始化:建立与 MCP 服务器的连接
    • 列出工具:查询可用工具及其 schema
    • 工具执行:当 LLM 需要调用时向 MCP 服务器发送请求
    • 结果集成:将工具结果整合回对话

动态工具(Dynamic Tools with MCP)

  • 通过 POML 的模板能力,可在运行时动态加载 MCP 服务器提供的工具定义,并在上下文中跟踪交互。
  • 该方案适用于 MCP 的原因(官方表述):
    • MCP 服务器在运行时动态提供工具
    • 不同 MCP 服务器的工具 schema 各不相同
    • 同一个 POML 模板可适配任意 MCP 服务器
    • 需要跨轮次跟踪工具交互

动态工具模板(POML Template for Dynamic Tools)

xml 复制代码
<poml> <system-msg>{{ system }}</system-msg> <human-msg>{{ input }}</human-msg> <!-- Dynamic Tool Loading: Iterates through tools discovered from the MCP server --> <div for="tool in tools"> <!-- Each tool's name, description, and JSON schema are inserted dynamically --> <tool-definition name="{{ tool.name }}" description="{{ tool.description }}"> {{ tool.schema }} </tool-definition> </div> <!-- Interaction History: Maintains conversation history with tool calls and responses --> <div for="i in interactions"> <!-- All dynamic content is provided through the context parameter --> <tool-request for="res in i" id="{{ res.id }}" name="{{ res.name }}" parameters="{{ res.input }}" /> <tool-response for="res in i" id="{{ res.id }}" name="{{ res.name }}"> <!-- Embeds the tool output directly via POML's Object componenet. --> <object data="{{ res.output }}"/> </tool-response> </div> <runtime model="gpt-4.1"/> </poml>

完整示例(Complete Example with MCP Server)

官方示例基于一个"掷骰子"的公共 MCP 演示服务器,演示工具发现、工具调用处理与主对话循环。

1) 工具发现与转换(Tool Discovery and Conversion)

python 复制代码
async def discover_mcp_tools(mcp_session): """Discover available tools from MCP server and convert to POML format""" mcp_tools = (await mcp_session.list_tools()).tools print(f"Available MCP tools: {mcp_tools}") # Convert MCP tools to POML context format. # The format must be compatible with the POML template above. poml_tools = [] for tool in mcp_tools: poml_tools.append({ "name": tool.name, "description": tool.description, "schema": tool.inputSchema }) return poml_tools

2) 处理工具调用(Process Tool Calls)

python 复制代码
async def process_tool_calls(mcp_session, tool_calls): """Execute MCP tool calls and format responses""" responses = [] for tool_call in tool_calls: function = tool_call.function args = json.loads(function.arguments or "{}") # Call MCP server tool result = await mcp_session.call_tool(function.name, args) print(f"Tool {function.name} result: {result}") # Format for POML context. # This format must be compatible with the POML template above. responses.append({ "id": tool_call.id, "name": function.name, "input": args, "output": result.model_dump() }) return responses

3) 主对话循环(Main Conversation Loop)

python 复制代码
async def run_mcp_conversation(mcp_session, context): """Run the conversation loop with MCP tools""" # Discover and add tools to context context["tools"] = await discover_mcp_tools(mcp_session) client = OpenAI() # Conversation loop while True: # Generate OpenAI parameters from POML params = poml.poml("dynamic_tools.poml", context=context, format="openai_chat") response = client.chat.completions.create(**params) message = response.choices[0].message if message.tool_calls: # Process and add tool responses to context responses = await process_tool_calls(mcp_session, message.tool_calls) context["interactions"].append(responses) else: # Final response - conversation complete print(f"Assistant: {message.content}") return message.content

4) 完整集成(Complete Integration)

python 复制代码
import json import asyncio from openai import OpenAI import poml from mcp import ClientSession from mcp.client.sse import sse_client async def main(): # Initialize context for POML context = { "system": "You are a helpful DM assistant. Use the dice-rolling tool when needed.", "input": "Roll 2d4+1", "tools": [], "interactions": [] } # Connect to MCP server (using public demo server) server_url = "https://dmcp-server.deno.dev/sse" async with sse_client(server_url) as (read, write): async with ClientSession(read, write) as mcp_session: await mcp_session.initialize() result = await run_mcp_conversation(mcp_session, context) print(f"Conversation completed: {result}") if __name__ == "__main__": asyncio.run(main())

与直接使用 MCP 的对比(Comparison with Direct MCP Usage)

  • 主要差异(官方表述):
    • 消息管理:直接方式需要手动区分 "role": "assistant""role": "tool";POML 通过请求/响应成对管理,自动处理
    • 内容渲染:直接方式需手动字符串转换与格式化;POML 使用 <object> 组件统一处理各类内容
    • 工具格式:直接方式需手动按 OpenAI 等提供方要求格式化;POML 使用声明式模板完成转换

不使用 POML(Direct Approach)

python 复制代码
# Manually manage message roles and format
messages.append({"role": "assistant", "content": msg.content or "", "tool_calls": msg.tool_calls})
messages.append({"role": "tool", "tool_call_id": tc.id, "name": fn.name, "content": text_result})
# Manually format tool results from MCP
if result.structuredContent is not None:
    text_result = json.dumps(result.structuredContent)
else:
    text_result = "\n".join([c.text for c in result.content if isinstance(c, types.TextContent)])
# Convert MCP tools to OpenAI format
oa_tools.append({
    "type": "function",
    "function": {"name": t.name, "description": t.description, "parameters": t.inputSchema}
})

使用 POML(Structured Approach)

python 复制代码
# Simply track tool request/response pairs
context["interactions"].append([
    {"id": tc.id, "name": fn.name, "input": args, "output": result.model_dump()}
])

未来原生支持(Future Native Support)

  • POML 计划提供 MCP 的原生支持,届时会为 MCP 操作提供简化语法。
  • 在此之前,可采用本文基于模板的方式作为过渡性解决方案。

使用场景

  • 官方页面未提供具体使用场景示例。

总结/展望

  • 文中基于官方页面介绍了 MCP 的工作原理、安装方法、POML 模板的动态工具集成方案、完整示例,以及与直接使用 MCP 的对比与未来计划。
  • 获取完整细节与最新进展,请参考官方文档:
相关推荐
月小水长3 天前
Agent 接入云上 MCP Server,驱动产品评论反馈智能化总结,并自动推送公司微信群
llm·mcp
花酒锄作田3 天前
MCP07-logging和progress等功能说明
后端·llm·mcp
r0ad3 天前
如何用RAG增强的动态能力与大模型结合打造企业AI产品?
后端·llm
花酒锄作田3 天前
[MCP][07]logging和progress等功能说明
llm·mcp
聚客AI4 天前
⭐超越CNN与RNN:为什么Transformer是AI发展的必然选择?
人工智能·llm·掘金·日新计划
智泊AI4 天前
多模态大语言模型(MLLM)是什么?MLLM的基本架构是什么?
llm
花酒锄作田5 天前
用FastAPI和Streamlit实现一个ChatBot
llm·fastapi·streamlit
r0ad5 天前
有没有可能不微调也能让大模型准确完成指定任务?(少样本学习)
llm
虫无涯5 天前
LangSmith:大模型应用开发的得力助手
人工智能·langchain·llm
聚客AI5 天前
🎉7.6倍训练加速与24倍吞吐提升:两项核心技术背后的大模型推理优化全景图
人工智能·llm·掘金·日新计划