基于 AutoGen 实现多智能体协同的电商客服系统
前言
单个 LLM 再强大,也难以胜任复杂业务流程中的多角色协同。电商客服场景就是一个典型案例:客户咨询一个订单问题,可能涉及订单查询、物流跟踪、库存管理等多个专业领域,单一模型很难同时精通所有领域。
解决思路是角色分工 :将不同职能拆解为独立的智能体(Agent),每个 Agent 专注自己的领域,通过群组对话实现协同。本文基于 AutoGen 框架,实现一个多智能体电商客服系统,展示如何通过角色定义、工具绑定和群组编排来完成复杂任务协同。
1. 整体架构
1.1 系统全景

1.2 智能体角色
| 角色 | 职责 | 绑定工具 |
|---|---|---|
| 客服接待 | 问题分类、路由分发 | 无 |
| 订单查询 | 查询订单详情 | get_order_info |
| 物流跟踪 | 查询物流状态 | get_logistics_info |
| 库存管理 | 查询库存、补货预估 | get_inventory_info |
| 用户代理 | 模拟用户确认结束 | 无 |
1.3 技术栈
- AutoGen:微软开源的多智能体对话框架
- DashScope(通义千问):LLM 接口
- SelectorGroupChat:自动选择下一个发言者的群组聊天模式
2. 环境准备
2.1 依赖安装
bash
pip install autogen-agentchat autogen-ext openai python-dotenv
2.2 环境变量
env
DASHCOPE_KEY=sk-your-api-key
BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
2.3 数据文件
将模拟数据存储在 data/ 目录下的 JSON 文件中:
data/
├── orders.json # 订单数据
├── inventory.json # 库存数据
└── logistics.json # 物流数据
2.4 初始化 LLM 客户端
python
from autogen_ext.models.openai import OpenAIChatCompletionClient
model_client = OpenAIChatCompletionClient(
model="qwen-plus",
api_key=api_key,
base_url=base_url,
model_info={
"vision": False,
"function_calling": True,
"json_output": True,
}
)
AutoGen 通过 OpenAIChatCompletionClient 兼容所有 OpenAI 协议的 LLM 服务。
3. 数据服务层:模拟企业数据库
3.1 设计思路
真实场景中,Agent 需要调用企业内部的 API 获取数据。这里用 EnterpriseDataService 类模拟这一层,从外部 JSON 文件加载数据:
python
class EnterpriseDataService:
"""企业数据服务模拟类,从外部 JSON 文件加载数据"""
def __init__(self):
with open(DATA_DIR / "orders.json", "r", encoding="utf-8") as f:
self.orders = json.load(f)
with open(DATA_DIR / "inventory.json", "r", encoding="utf-8") as f:
self.inventory = json.load(f)
with open(DATA_DIR / "logistics.json", "r", encoding="utf-8") as f:
self.logistics = json.load(f)
def get_order_info(self, order_id: str) -> Dict:
return self.orders.get(order_id, {})
def get_inventory_info(self, product: str) -> Dict:
return self.inventory.get(product, {})
def get_logistics_info(self, tracking_number: str) -> Dict:
return self.logistics.get(tracking_number, {})
3.2 工具函数封装
Agent 通过工具函数访问数据服务。工具函数必须是 async 的:
python
data_service = EnterpriseDataService()
async def get_order_info(order_id: str) -> str:
"""获取订单信息的工具函数"""
order_info = data_service.get_order_info(order_id)
if order_info:
return f"订单信息查询成功:\n{json.dumps(order_info, ensure_ascii=False, indent=2)}"
return f"未找到订单号 {order_id} 的信息"
async def get_inventory_info(product: str) -> str:
"""获取库存信息的工具函数"""
...
async def get_logistics_info(tracking_number: str) -> str:
"""获取物流信息的工具函数"""
...
4. 智能体定义
4.1 AssistantAgent:专业角色
每个 AssistantAgent 代表一个专业角色,通过 system_message 定义职责,通过 tools 绑定可调用的工具:
python
from autogen_agentchat.agents import AssistantAgent
# 客服接待 - 负责问题分类和路由
customer_service_agent = AssistantAgent(
name="customer_service_agent",
model_client=model_client,
system_message="""你是一名专业的电商客服接待员。你的职责是:
1. 友好接待客户,了解客户问题
2. 对问题进行初步分类
3. 将问题转交给相应的专业团队处理""",
reflect_on_tool_use=True,
model_client_stream=True,
)
# 订单查询 - 绑定订单查询工具
order_query_agent = AssistantAgent(
name="order_query_agent",
model_client=model_client,
tools=[get_order_info], # 绑定工具
system_message="""你是订单查询专员,负责处理所有订单相关的查询。
当客户提供订单号时,请立即使用 get_order_info 函数查询订单信息。""",
reflect_on_tool_use=True,
model_client_stream=True,
)
关键参数:
| 参数 | 含义 |
|---|---|
system_message |
角色定义和职责说明 |
tools |
可调用的工具函数列表 |
reflect_on_tool_use |
工具调用后是否反思结果 |
model_client_stream |
是否启用流式输出 |
4.2 UserProxyAgent:模拟用户
UserProxyAgent 模拟真实用户行为,用于自然结束对话:
python
from autogen_agentchat.agents import UserProxyAgent
def auto_reply_input(input_prompt: str = "") -> str:
return "谢谢您的帮助,问题已解决!"
user_agent = UserProxyAgent(
name="user_agent",
description="模拟用户行为,用于自然结束对话",
input_func=auto_reply_input
)
当智能体完成服务后,user_agent 自动回复"谢谢",触发对话终止。
5. 群组编排:SelectorGroupChat
5.1 核心概念
AutoGen 提供多种群组聊天模式,本例使用 SelectorGroupChat:
- LLM 根据对话上下文自动选择下一个发言者
- 类似真实群聊中"谁该接话"的自然流转
5.2 终止条件
python
from autogen_agentchat.conditions import TextMentionTermination, MaxMessageTermination
# 文本终止:消息包含特定文本时结束
text_termination = (
TextMentionTermination("谢谢您的帮助") |
TextMentionTermination("问题已解决")
)
# 最大消息数终止:防止无限轮询
max_msg_termination = MaxMessageTermination(max_messages=12)
# 组合终止条件
termination_condition = text_termination | max_msg_termination
5.3 创建群组
python
from autogen_agentchat.teams import SelectorGroupChat
def create_group_chat():
return SelectorGroupChat(
[customer_service_agent, order_query_agent,
logistics_agent, inventory_agent, user_agent],
model_client=model_client,
termination_condition=termination_condition,
selector_prompt="""
你是一个客服调度协调员。当前可用的专员角色如下:
{roles}
请根据以下对话记录,判断当前客户的问题最需要哪个专员来处理,然后从{participants}中选择下一个发言的专员。只需返回专员名称。
选择原则:
- 订单相关问题 → 优先分配给订单查询专员
- 物流/配送问题 → 优先分配给物流跟踪专员
- 库存/缺货问题 → 优先分配给库存管理专员
- 问题已解决 → 分配给用户代理确认结束
{history}
请根据上述对话记录,选择下一个最合适的发言专员。只需返回专员名称。
"""
)
selector_prompt 是群组调度的核心,定义了 LLM 如何选择下一个发言者。生产环境中应遵循以下原则:
| 原则 | 说明 |
|---|---|
| 任务导向 | 定位为"调度协调员",而非娱乐化的"角色扮演" |
| 明确路由规则 | 按问题类型指定对应专员,减少 LLM 随机性 |
| 终止条件清晰 | 明确"问题已解决→用户代理确认结束" |
| 输出约束 | "只需返回专员名称",避免 LLM 输出多余内容 |
6. 运行流程
6.1 执行对话
python
async def run_scenario(scenario_name: str, customer_message: str):
group_chat = create_group_chat()
await Console(group_chat.run_stream(task=customer_message))
Console 将对话流式输出到控制台,run_stream 以流模式运行。
6.2 场景示例
场景1:订单状态查询

场景2:缺货问题处理(跨部门协作)

6.3 智能体协作拓扑

7. 运行效果
7.1 订单查询场景输出

7.2 跨部门协作场景
缺货处理场景展示了多智能体的协同能力:
- 订单查询 Agent 发现问题 → 通知库存 Agent
- 库存 Agent 查询到缺货 → 提供补货预估
- 客服 Agent 总结 → 提供替代方案
- 用户 Agent 确认 → 结束
8. 总结与扩展
核心设计要点
- 角色分工:每个 Agent 专注一个领域,通过 system_message 定义职责边界
- 工具绑定:Agent 通过 tools 参数访问外部数据,实现"能力扩展"
- 群组编排:SelectorGroupChat 让 LLM 自动选择下一个发言者,模拟真实协作
- 终止控制:组合多种终止条件,确保对话可控结束
AutoGen 的核心优势
| 特性 | 说明 |
|---|---|
| 多角色协同 | 天然支持多 Agent 对话,无需手动编排流程 |
| 工具调用 | Agent 可绑定任意 Python 函数作为工具 |
| 灵活编排 | 支持 SelectorGroupChat、RoundRobinGroupChat 等多种模式 |
| 流式输出 | 支持实时流式展示对话过程 |
可扩展方向
- 真实 API 对接 :将
EnterpriseDataService替换为真实的企业 API - 记忆持久化:使用 AutoGen 的 memory 模块保存对话历史
- 人工介入 :将
UserProxyAgent改为真实用户输入,实现人机协同 - 评估与优化:添加对话质量评估 Agent,自动优化回复质量