AutoGen与MCP:构建强大的多智能体系统
引言
在人工智能快速发展的今天,大型语言模型(LLM)的应用已经从简单的对话系统演变为复杂的智能体系统。Microsoft的AutoGen框架作为一个强大的多智能体构建工具,正在引领这一领域的创新。本文将深入探讨AutoGen框架中的一个关键组件——Model Context Protocol (MCP),以及如何利用它构建功能强大的多智能体系统。
AutoGen简介
AutoGen是Microsoft开发的一个开源框架,旨在简化基于大型语言模型的多智能体系统的构建过程。它提供了一套灵活的工具和API,使开发者能够创建可以相互协作的智能体网络,每个智能体都可以执行特定的任务或扮演特定的角色。
AutoGen的核心优势在于:
- 多智能体协作:支持多个智能体之间的复杂交互和协作
- 工具使用能力:智能体可以使用各种工具来扩展其能力
- 灵活的对话流程:支持自定义对话流程和控制逻辑
- 可扩展性:易于集成新的模型和工具
什么是MCP (Model Context Protocol)?
Model Context Protocol (MCP) 是一个开放标准,旨在统一AI模型与外部工具和服务的交互方式。在AutoGen框架中,MCP扮演着连接智能体与外部工具的桥梁角色。
MCP的核心理念是提供一个标准化的协议,使AI模型(如大型语言模型)能够以一致的方式与各种外部服务和工具进行交互。这些工具可以是本地的命令行工具、远程的API服务,甚至是其他AI系统。
MCP的关键特性
- 标准化接口:提供统一的工具调用和响应格式
- 多种通信方式:支持标准输入/输出(STDIO)和服务器发送事件(SSE)等通信方式
- 工具发现机制:允许动态发现和使用可用工具
- 会话管理:支持维护工具调用的会话状态
AutoGen中的MCP实现
在AutoGen框架中,MCP通过autogen_ext.tools.mcp
模块提供支持。该模块提供了多种组件,使开发者能够轻松地将MCP兼容的工具集成到AutoGen智能体中。
核心组件
- McpWorkbench:包装MCP服务器并提供接口来列出和调用服务器提供的工具
- StdioMcpToolAdapter:允许通过标准输入/输出与MCP工具进行交互
- SseMcpToolAdapter:允许通过HTTP与支持服务器发送事件(SSE)的MCP工具进行交互
- McpSessionActor:管理与MCP服务器的会话
配置参数
MCP工具适配器需要特定的服务器参数来建立连接:
StdioServerParams:用于通过标准输入/输出连接到MCP服务器的参数
command
:要执行的命令args
:命令参数env
:环境变量read_timeout_seconds
:读取超时时间
SseServerParams:用于通过HTTP/SSE连接到MCP服务器的参数
url
:服务器URLheaders
:HTTP头信息timeout
:连接超时时间sse_read_timeout
:SSE读取超时时间
实际案例:构建多源信息检索系统
下面我们将通过一个实际案例,展示如何使用AutoGen和MCP构建一个能够从多个信息源(GitHub、Jira和Confluence)检索信息的系统。
系统架构
该系统由三个主要组件组成:
- 搜索智能体(Search Agent):负责从多个信息源检索相关信息
- 总结智能体(Summary Agent):负责处理和总结检索到的信息
- 用户代理(User Proxy):代表用户与其他智能体交互
系统使用MCP工具连接到GitHub和Atlassian(Jira和Confluence)服务,使智能体能够访问这些平台上的信息。
代码实现
from typing import Sequence
import os
import asyncio
from autogen_ext.tools.mcp import StdioServerParams, mcp_server_tools
from autogen_ext.models.openai import AzureOpenAIChatCompletionClient
from autogen_agentchat.messages import BaseAgentEvent, BaseChatMessage
from autogen_agentchat.agents import AssistantAgent, UserProxyAgent
from autogen_agentchat.teams import SelectorGroupChat
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.ui import Console
def get_model_client() -> AzureOpenAIChatCompletionClient:
return AzureOpenAIChatCompletionClient(
azure_deployment=os.getenv("AZURE_OPENAI_MODEL_DEPLOYMENT"),
api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
model="gpt-4o"
)
search_agent_prompt = """
Please search for as much related information as possible from Jira, Confluence and Github using the tools provided to you,
based on the user's question. Return the information you have found without any processing or comments.
If no information is found, reply with "Sorry, I couldn't find any relevant information on this issue.
"""
summary_agent_prompt = """
You are an AI assistant. Please help answer the user's question accoding to Search_Agent's response.
"""
async def main() -> None:
github_server_params = StdioServerParams(
command="docker",
args=[
"run",
"-i",
"--rm",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"-e",
"GH_HOST",
"ghcr.io/github/github-mcp-server"
],
env={
"GITHUB_PERSONAL_ACCESS_TOKEN": os.getenv("GITHUB_PERSONAL_ACCESS_TOKEN"),
"GH_HOST": os.getenv("GH_HOST")
}
)
github_tools = await mcp_server_tools(github_server_params)
atl_server_params = StdioServerParams(
command="uv",
args=[
'run',
'mcp-atlassian',
'-v',
'--jira-url',
os.getenv("JIRA_HOST"),
'--jira-personal-token',
os.getenv("JIRA_PERSONAL_TOKEN"),
'--confluence-url',
os.getenv("CONFLUENCE_HOST"),
'--confluence-personal-token',
os.getenv("CONFLUENCE_PERSONAL_TOKEN"),
],
)
atl_tools = await mcp_server_tools(atl_server_params)
# Create an agent that can use the translation tool
search_agent = AssistantAgent(
name="search_agent",
model_client=get_model_client(),
tools=github_tools + atl_tools,
system_message=search_agent_prompt,
)
summary_agent = AssistantAgent(
name="summary_agent",
model_client=get_model_client(),
system_message=summary_agent_prompt,
)
user_proxy = UserProxyAgent("user", input_func=input)
# Create the termination condition which will end the conversation when the user says "Exit".
termination = TextMentionTermination("Exit")
def selector_func(messages: Sequence[BaseAgentEvent | BaseChatMessage]) -> str | None:
if messages[-1].source == "user":
return search_agent.name
elif messages[-1].source == search_agent.name:
return summary_agent.name
elif messages[-1].source == summary_agent.name:
return user_proxy.name
return user_proxy.name
team = SelectorGroupChat(
[search_agent, summary_agent, user_proxy],
model_client=get_model_client(),
termination_condition=termination,
selector_func=selector_func,
allow_repeated_speaker=False, # Allow an agent to speak multiple turns in a row.
)
task = "what is Marvin?"
await Console(team.run_stream(task=task))
if __name__ == "__main__":
asyncio.run(main())
代码解析
MCP服务器配置:
- 使用
StdioServerParams
配置GitHub和Atlassian MCP服务器 - 通过环境变量传递认证信息和服务器地址
- 使用
工具获取:
- 使用
mcp_server_tools
函数从MCP服务器获取可用工具 - 将GitHub和Atlassian工具合并为一个工具列表
- 使用
智能体创建:
- 创建搜索智能体,并为其分配所有MCP工具
- 创建总结智能体,负责处理搜索结果
- 创建用户代理,处理用户输入
对话流程控制:
- 使用
selector_func
定义智能体之间的交互顺序 - 实现了一个简单的工作流:用户提问 -> 搜索智能体检索 -> 总结智能体总结 -> 返回给用户
- 使用
终止条件:
- 使用
TextMentionTermination
定义对话终止条件
- 使用
MCP的高级应用场景
除了上述示例外,MCP还可以应用于多种高级场景:
1. 文件系统操作
使用文件系统MCP服务器,智能体可以执行文件创建、读取、写入等操作:
# 设置文件系统MCP服务器参数
desktop = str(Path.home() / "Desktop")
server_params = StdioServerParams(
command="npx.cmd",
args=["-y", "@modelcontextprotocol/server-filesystem", desktop]
)
# 获取所有可用工具
tools = await mcp_server_tools(server_params)
# 创建能够使用这些工具的智能体
agent = AssistantAgent(
name="file_manager",
model_client=OpenAIChatCompletionClient(model="gpt-4"),
tools=tools,
)
2. Web内容获取
使用fetch MCP服务器,智能体可以获取和处理Web内容:
# 获取fetch工具
fetch_mcp_server = StdioServerParams(command="uvx", args=["mcp-server-fetch"])
tools = await mcp_server_tools(fetch_mcp_server)
# 创建能够使用fetch工具的智能体
agent = AssistantAgent(
name="fetcher",
model_client=OpenAIChatCompletionClient(model="gpt-4o"),
tools=tools,
reflect_on_tool_use=True
)
3. Web浏览器自动化
使用Playwright MCP服务器,智能体可以控制Web浏览器执行复杂的交互:
params = StdioServerParams(
command="npx",
args=["@playwright/mcp@latest"],
read_timeout_seconds=60,
)
async with create_mcp_server_session(params) as session:
await session.initialize()
tools = await mcp_server_tools(server_params=params, session=session)
agent = AssistantAgent(
name="Assistant",
model_client=model_client,
tools=tools,
)
MCP的优势与局限性
优势
- 标准化接口:提供统一的工具调用方式,简化集成过程
- 多样化工具支持:支持各种类型的工具,从本地命令行工具到远程API服务
- 会话管理:支持维护工具调用的会话状态,适用于需要状态的工具(如浏览器)
- 可扩展性:易于添加新的工具和服务
局限性
- 依赖外部服务:需要外部MCP服务器的支持
- 配置复杂性:某些工具的配置可能较为复杂
- 性能开销:通过进程间通信或网络通信可能引入额外延迟
- 安全考虑:需要谨慎处理工具的权限和认证信息
结论
AutoGen的MCP模块为构建功能强大的多智能体系统提供了关键支持。通过标准化的工具接口,开发者可以轻松地将各种外部工具和服务集成到智能体系统中,大大扩展了智能体的能力范围。
从简单的文件操作到复杂的Web浏览器自动化,MCP使智能体能够与现实世界进行更加丰富的交互。这种能力对于构建真正有用的AI应用至关重要,因为它使AI系统能够不仅理解用户的意图,还能采取具体行动来实现这些意图。
随着AutoGen和MCP的不断发展,我们可以期待看到更多创新的多智能体应用出现,这些应用将在各个领域为用户提供更加智能和高效的服务。