多Agent协作入门:移交编排模式

多Agent协作入门:移交编排模式

在单Agent系统中,一个模型(如GPT-4)负责处理全部任务,这往往导致上下文过长、职责混乱、单点故障。而多Agent(Multi-Agent)系统通过拆分角色、移交任务(Handoff)来提升鲁棒性和可维护性。移交编排模式(Handoff Orchestration Pattern) 是最基础也最实用的协作范式:一个主控Agent(Supervisor)根据任务类型,将控制权移交给对应的专业Agent,完成后回收控制权。本文从实战出发,用两个可运行的Python代码示例,带你从零实现移交编排。---### 1. 核心概念:什么是移交编排?想象一个客服中心:- 主控 :接听电话,判断需求(退换货/技术咨询/投诉)。- 退换货Agent :处理订单流程。- 技术Agent :提供产品支持。主控不处理具体业务,只做"路由"(Routing)和"移交"(Handoff)。每个子Agent有独立的上下文窗口和工具集,完成后将结果返回主控。关键设计点 :- 显式状态机 :主控维护当前活跃的Agent指针。- 消息协议 :定义 HandoffRequestHandoffResult 数据结构。- 失败回退 :子Agent异常时,主控需接管或降级。---### 2. 实战示例一:基于字典路由的简单移交(无外部依赖)下面的代码用纯Python实现,不依赖LangChain等框架,方便理解底层逻辑。python# simple_handoff.pyfrom typing import Dict, Any, Optionalimport re# ---------- 数据结构 ----------class Task: def __init__(self, text: str): self.text = text self.category = self._classify() def _classify(self) -> str: # 简单规则分类:包含"订单"则归为售后,包含"API"则归为技术 if "订单" in self.text: return "aftersales" elif "API" in self.text or "代码" in self.text: return "tech" else: return "general"# ---------- 各Agent实现 ----------class AftersalesAgent: def handle(self, task: Task) -> str: # 模拟处理退换货 return f"[售后] 已处理订单问题: {task.text}"class TechAgent: def handle(self, task: Task) -> str: # 模拟技术支持 return f"[技术] 已提供API调试建议: {task.text}"class GeneralAgent: def handle(self, task: Task) -> str: return f"[通用] 已记录咨询: {task.text}"# ---------- 主控Agent(Supervisor) ----------class SupervisorAgent: def __init__(self): # 注册所有可移交的Agent self.agents = { "aftersales": AftersalesAgent(), "tech": TechAgent(), "general": GeneralAgent() } self.current_agent: Optional[str] = None def route(self, task: Task) -> str: # 核心逻辑:根据任务分类,决定移交目标 if task.category == "aftersales": self.current_agent = "aftersales" elif task.category == "tech": self.current_agent = "tech" else: self.current_agent = "general" # 移交执行 agent = self.agents[self.current_agent] result = agent.handle(task) # 移交完成,回收控制权 self.current_agent = None return result# ---------- 测试 ----------if __name__ == "__main__": boss = SupervisorAgent() tasks = [ "我的订单#1234需要退货", "如何使用你的API发送请求?", "你们公司几点下班?" ] for t in tasks: task = Task(t) print(boss.route(task))输出[售后] 已处理订单问题: 我的订单#1234需要退货[技术] 已提供API调试建议: 如何使用你的API发送请求?[通用] 已记录咨询: 你们公司几点下班?点评 :这个例子展示了最基础的"路由-移交-回收"流程。但实际生产环境中,子Agent可能需要多轮对话,且主控需要动态决定是否追加移交。---### 3. 实战示例二:带状态记忆的移交编排(使用LangChain)当子Agent需要多轮交互时,我们需要为每个Agent维护独立的对话历史。下面使用LangChain的 AgentExecutor 和自定义工具,实现更真实的场景。python# langchain_handoff.pyfrom langchain.agents import AgentExecutor, create_react_agentfrom langchain.tools import Toolfrom langchain_openai import ChatOpenAIfrom langchain.prompts import PromptTemplatefrom langchain.memory import ConversationBufferMemory# ---------- 子Agent工厂 ----------def create_sub_agent(system_prompt: str, tools: list): """创建一个带独立记忆的子Agent""" llm = ChatOpenAI(model="gpt-4o-mini", temperature=0) prompt = PromptTemplate.from_template( "你是一个专业助手。你的职责:{system_prompt}\n\n" "可用工具:{tools}\n" "历史对话:{chat_history}\n" "用户输入:{input}\n" "请用中文回答。" ) agent = create_react_agent(llm, tools, prompt) memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) return AgentExecutor(agent=agent, tools=tools, memory=memory, verbose=False)# ---------- 定义子任务工具 ----------def payment_refund(order_id: str) -> str: """查询订单退款状态""" return f"订单{order_id}已退款,金额200元。"def check_stock(product: str) -> str: """检查库存""" return f"{product}有货,剩余5件。"# ---------- 移交编排器 ----------class HandoffOrchestrator: def __init__(self): # 创建两个子Agent:售后和技术支持 self.aftersales_agent = create_sub_agent( "你负责处理退款、退货、发票问题。", [Tool(name="payment_refund", func=payment_refund, description="退款")] ) self.tech_agent = create_sub_agent( "你负责API集成、代码调试。", [Tool(name="check_stock", func=check_stock, description="查库存")] ) # 主控逻辑:根据关键词路由 self.keyword_map = { "退款": "aftersales", "退货": "aftersales", "API": "tech", "代码": "tech", } def run(self, user_input: str) -> str: # 1. 路由决策 target = "aftersales" if any(k in user_input for k in ["退款", "退货"]) else \ "tech" if any(k in user_input for k in ["API", "代码"]) else "general" # 2. 移交并执行 if target == "aftersales": response = self.aftersales_agent.invoke({"input": user_input}) elif target == "tech": response = self.tech_agent.invoke({"input": user_input}) else: response = {"output": f"通用问题,暂不处理:{user_input}"} # 3. 返回结果(此处可添加后处理) return response["output"]# ---------- 测试多轮移交 ----------if __name__ == "__main__": orchestrator = HandoffOrchestrator() # 第一轮:售后问题 print(orchestrator.run("我想退款订单#5678")) # 第二轮:技术问题(注意:此时内存中已有售后对话,但主控会切到技术Agent) print(orchestrator.run("为什么我的API总是报401错误?")) # 第三轮:再次售后(验证记忆隔离) print(orchestrator.run("那退款什么时候到账?"))运行说明 :需要安装 langchainlangchain-openai,并设置 OPENAI_API_KEY。输出为每个Agent独立记忆的对话结果。---### 4. 移交编排的高级策略实战中,移交不仅仅是"路由",还需要考虑:- 上下文压缩 :当子Agent任务完成后,主控将关键结果(如订单号、决策)压缩成摘要,传给下一个Agent,避免上下文爆炸。- 超时与重试 :子Agent执行超时(如30秒),主控应自动降级或重试。- 审计日志 :记录每次移交的"源Agent、目标Agent、时间、原因",便于追踪。以下是一个带审计日志的移交装饰器实现(伪代码):pythonimport loggingfrom functools import wrapsdef handoff_logger(func): @wraps(func) def wrapper(supervisor, task): logging.info(f"移交前: 当前Agent={supervisor.current_agent}, 任务类型={task.category}") result = func(supervisor, task) logging.info(f"移交后: 目标Agent={supervisor.current_agent}") return result return wrapper---### 5. 总结移交编排模式(Handoff Orchestration)是多Agent系统的基石,其核心价值在于:1. 职责隔离 :每个Agent只处理自己领域,减少幻觉。2. 资源优化 :无需将所有上下文塞入一个模型。3. 可扩展性 :新增Agent只需注册到主控,不影响其他模块。实践建议 :- 从简单的字典路由开始,逐步引入记忆和工具。- 务必设计"未知类别"的兜底Agent(如 general)。- 在生产环境,建议使用LangGraph或AutoGen等框架,它们内置了状态图和移交机制。记住:移交不是"代码跳转",而是有状态的对话上下文转移。掌握这个模式,你就迈入了多Agent协作的大门。

相关推荐
笨鸟先飞,勤能补拙7 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
XR1234567888 小时前
企业全光网络架构选型技术白皮书:从物理层到运维层的全链路分析
运维·网络·架构
似的8358 小时前
一步一步学习使用FireMonkey动画() 使用TAnimator类创建动画
linux·学习·nginx
长和信泰光伏储能8 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂9 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
萧瑟余晖9 小时前
Java深入解析篇九之NIO详解
java·网络·nio
Gu Gu Study9 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
我不管我就要叫小猪9 小时前
嵌入式Linux----网络通信
linux·运维·服务器
泡沫冰@10 小时前
ECS 的介绍和使用
linux·服务器·网络
笨鸟先飞,勤能补拙10 小时前
AI 赋能网络安全领域深度剖析
网络·人工智能·windows·安全·web安全·网络安全·github