尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

从单Agent问答到多Agent协同:任务分解与动态路由策略

从单Agent问答到多Agent协同:任务分解与动态路由策略
📅 发布时间:2026/7/17 11:13:27

从单Agent问答到多Agent协同:任务分解与动态路由策略

当一个问题需要多种能力协同解决时,单Agent的“全能”幻想往往败给现实。本文从实践出发,拆解多Agent协同的核心命题——任务分解与动态路由,并附可运行的代码示例。

一、单Agent的边界

过去两年,基于大语言模型的单Agent问答系统发展迅速。给定一个用户问题,检索相关上下文,让LLM生成答案——这套RAG流程已经成为标配。

但随着业务场景变复杂,单Agent的局限开始暴露:

  • 知识冲突:一个模型很难同时精通法律、医疗、编程等多个垂直领域
  • 上下文过载:把多个子任务塞进一次推理,既浪费token,也降低准确率
  • 工具调用混乱:当Agent同时拥有计算器、数据库查询、外部API等多种工具时,模型经常选错或漏调

举个例子,用户问:“对比A公司和B公司过去三年的营收增长率,并结合行业平均值给出投资建议。”

这个问题天然包含多个子任务:

  1. 查询A公司财报数据
  2. 查询B公司财报数据
  3. 查询行业平均增长率
  4. 计算复合增长率
  5. 综合对比并生成投资建议

单Agent的做法是一次性把所有信息塞给LLM。但财报数据可能来自不同的内部数据库,行业数据需要外部API,计算增长率又需要精确的数值运算。把这些全部交给一个模型决策,出错概率极高。

二、多Agent协同的核心命题

多Agent系统不是简单地“多开几个模型实例”。它的设计围绕两个核心命题展开:

命题一:任务分解(Task Decomposition)

如何将复杂问题拆解为可独立执行的子任务?

好的分解需要满足:

  • 独立性:子任务之间耦合度低,可并行或顺序执行
  • 可分配性:每个子任务能匹配到擅长该领域的Agent
  • 可组合性:子任务的结果能合并为最终答案

命题二:动态路由(Dynamic Routing)

如何将每个子任务调度到最合适的Agent?

路由策略需要考虑:

  • Agent能力画像:每个Agent擅长什么领域、支持什么工具
  • 任务特征匹配:当前子任务属于什么类型(问答、计算、检索、生成等)
  • 负载与成本:避免某些Agent过载,控制API调用成本

这两个命题相互依赖——好的分解能降低路由难度,好的路由能弥补分解的不足。

三、系统架构设计

我们设计一个轻量级的多Agent协同框架,核心组件如下:

┌─────────────────────────────────────────────────────────┐ │ 用户输入 │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ Planner(规划器) │ │ - 任务分解(LLM + Few-shot) │ │ - 生成DAG格式的执行计划 │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ Router(路由器) │ │ - 基于向量相似度 + 规则匹配 选择Agent │ │ - 支持fallback机制 │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ Agent Pool(Agent池) │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 问答Agent│ │ 数据Agent│ │ 计算Agent│ │ 报告Agent│ │ │ │ (RAG) │ │ (SQL) │ │ (Python) │ │ (生成) │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ Aggregator(聚合器) │ │ - 合并子任务结果 │ │ - 冲突解决与最终生成 │ └─────────────────────────────────────────────────────────┘

四、关键实现:任务分解

任务分解模块是整个系统的入口。我们使用LLM配合结构化输出来生成执行计划。

fromtypingimportList,Dict,AnyfrompydanticimportBaseModelimportjsonclassSubTask(BaseModel):task_id:strdescription:strtask_type:str# "qa", "data_query", "calculation", "generation"dependencies:List[str]# 依赖的前置任务IDrequired_tools:List[str]expected_output:strclassExecutionPlan(BaseModel):tasks:List[SubTask]execution_order:List[str]# 拓扑排序后的执行顺序classTaskDecomposer:def__init__(self,llm_client):self.llm=llm_clientdefdecompose(self,user_query:str,context:str="")->ExecutionPlan:prompt=f""" 你是一个任务分解专家。请将以下用户问题拆解为可执行的子任务列表。 用户问题:{user_query}上下文:{context}要求: 1. 每个子任务必须独立、可分配 2. 明确标注任务类型: qa(问答), data_query(数据查询), calculation(计算), generation(生成) 3. 标注依赖关系 4. 输出为JSON格式 输出格式: {{ "tasks": [ {{ "task_id": "task_1", "description": "查询A公司2023-2025年营收", "task_type": "data_query", "dependencies": [], "required_tools": ["sql_db"], "expected_output": "营收数据列表" }} ], "execution_order": ["task_1", "task_2"] }} """response=self.llm.chat(prompt)plan_dict=json.loads(response)returnExecutionPlan(**plan_dict)

五、关键实现:动态路由

路由器根据子任务的特征和Agent的能力进行匹配。我们采用混合路由策略:向量检索做初筛,规则引擎做精排。

fromsentence_transformersimportSentenceTransformerimportnumpyasnpfromtypingimportOptionalclassAgentProfile:def__init__(self,name:str,description:str,task_types:List[str],tools:List[str],embedding:np.ndarray):self.name=name self.description=description self.task_types=task_types self.tools=tools self.embedding=embeddingclassDynamicRouter:def__init__(self,agents:List[AgentProfile]):self.agents=agents self.encoder=SentenceTransformer('all-MiniLM-L6-v2')# 预计算Agent的embeddingforagentinself.agents:ifagent.embeddingisNone:agent.embedding=self.encoder.encode(agent.description)defroute(self,subtask:SubTask)->AgentProfile:# 1. 规则匹配(精确过滤)candidates=self._rule_filter(subtask)ifnotcandidates:# fallback: 放宽规则candidates=self._rule_filter(subtask,strict=False)# 2. 向量相似度排序task_emb=self.encoder.encode(subtask.description)scores=[]foragentincandidates:sim=np.dot(task_emb,agent.embedding)/(np.linalg.norm(task_emb)*np.linalg.norm(agent.embedding))scores.append((agent,sim))# 按相似度降序排列scores.sort(key=lambdax:x[1],reverse=True)# 如果最高分低于阈值,触发fallback到通用Agentifscores[0][1]<0.5:returnself._get_fallback_agent()returnscores[0][0]def_rule_filter(self,subtask:SubTask,strict:bool=True)->List[AgentProfile]:candidates=[]foragentinself.agents:# 任务类型必须匹配ifsubtask.task_typenotinagent.task_types:continue# 工具必须包含(严格模式)ifstrictandnotall(tinagent.toolsfortinsubtask.required_tools):continuecandidates.append(agent)returncandidatesdef_get_fallback_agent(self)->AgentProfile:# 返回一个通用的LLM问答Agentreturnself.agents[0]

六、完整执行流程

将上述模块组合成一个完整的协同系统:

classMultiAgentSystem:def__init__(self,decomposer:TaskDecomposer,router:DynamicRouter,agent_executors:Dict[str,callable],aggregator):self.decomposer=decomposer self.router=router self.executors=agent_executors# agent_name -> executor functionself.aggregator=aggregatordefrun(self,query:str)->str:# Step 1: 任务分解plan=self.decomposer.decompose(query)# Step 2: 按执行顺序执行results={}fortask_idinplan.execution_order:# 找到对应的子任务task=next(tfortinplan.tasksift.task_id==task_id)# 路由到合适的Agentagent=self.router.route(task)# 执行(注入前置任务结果)context={dep:results[dep]fordepintask.dependencies}result=self.executors[agent.name](task,context)results[task_id]=result# Step 3: 聚合结果final_answer=self.aggregator.aggregate(query,plan,results)returnfinal_answer# ---------- 使用示例 ----------if__name__=="__main__":# 模拟初始化fromunittest.mockimportMock mock_llm=Mock()mock_llm.chat=lambdax:'{"tasks": [{"task_id": "t1", "description": "查询数据", "task_type": "data_query", "dependencies": [], "required_tools": ["sql"], "expected_output": "data"}], "execution_order": ["t1"]}'# 创建Agent画像agents=[AgentProfile("data_agent","擅长SQL数据查询",["data_query"],["sql"],None),AgentProfile("qa_agent","擅长通用问答和文本理解",["qa","generation"],["llm"],None),]decomposer=TaskDecomposer(mock_llm)router=DynamicRouter(agents)# 模拟执行器executors={"data_agent":lambdatask,ctx:"模拟数据结果","qa_agent":lambdatask,ctx:"模拟问答结果",}aggregator=lambdaquery,plan,results:f"最终答案基于:{results}"system=MultiAgentSystem(decomposer,router,executors,aggregator)answer=system.run("对比A公司和B公司的营收")print(answer)

七、进阶策略:自适应路由与反馈闭环

在实际生产中,静态路由往往不够。我们加入两个增强机制:

7.1 路由置信度自适应

classAdaptiveRouter(DynamicRouter):def__init__(self,agents,confidence_threshold=0.6):super().__init__(agents)self.threshold=confidence_threshold self.feedback_history={}# agent_name -> [success_rate]defroute(self,subtask:SubTask)->AgentProfile:# 获取基础路由结果agent=super().route(subtask)# 根据历史成功率调整ifagent.nameinself.feedback_history:success_rate=np.mean(self.feedback_history[agent.name])ifsuccess_rate<0.5:# 如果该Agent历史表现差,尝试第二选择second_best=self._get_second_choice(subtask)ifsecond_best:returnsecond_bestreturnagentdefrecord_feedback(self,agent_name:str,success:bool):ifagent_namenotinself.feedback_history:self.feedback_history[agent_name]=[]self.feedback_history[agent_name].append(1.0ifsuccesselse0.0)# 只保留最近100次iflen(self.feedback_history[agent_name])>100:self.feedback_history[agent_name].pop(0)

7.2 并行执行优化

对于无依赖关系的子任务,可以并行执行以降低延迟:

importasynciofromconcurrent.futuresimportThreadPoolExecutorclassParallelMultiAgentSystem(MultiAgentSystem):def__init__(self,*args,max_workers=4,**kwargs):super().__init__(*args,**kwargs)self.executor=ThreadPoolExecutor(max_workers=max_workers)defrun(self,query:str)->str:plan=self.decomposer.decompose(query)# 构建依赖图task_map={t.task_id:tfortinplan.tasks}completed=set()results={}whilelen(completed)<len(plan.tasks):# 找出所有依赖已满足的任务ready=[tfortinplan.tasksift.task_idnotincompletedandall(dincompletedfordint.dependencies)]# 并行执行withThreadPoolExecutor(max_workers=len(ready))asexecutor:futures={}fortaskinready:agent=self.router.route(task)ctx={dep:results[dep]fordepintask.dependencies}futures[executor.submit(self.executors[agent.name],task,ctx)]=task.task_idforfutureinasyncio.as_completed(futures):task_id=futures[future]results[task_id]=future.result()completed.add(task_id)returnself.aggregator.aggregate(query,plan,results)

八、总结与最佳实践

多Agent协同系统不是银弹,但在复杂任务场景下,它提供了比单Agent更可控、更可扩展的架构。以下是我们从实践中总结的几点经验:

  1. 分解粒度要适中:子任务太小会导致路由开销过大,太大会失去多Agent的优势。一般以“一个子任务调用1-2个工具”为参考。

  2. 路由需要可观测:在生产环境中记录每次路由决策和结果,便于排查问题和优化策略。

  3. Agent能力要正交:避免多个Agent能力重叠,否则路由会变得混乱。每个Agent应该有明确的职责边界。

  4. 始终保留fallback:无论路由策略多完善,都要有一个兜底的通用Agent,确保系统不会完全失效。

  5. 成本与性能的权衡:多Agent意味着多次LLM调用。对于简单问题,可以直接走单Agent快速通道,避免过度设计。

多Agent协同的终极目标不是“用更多Agent解决问题”,而是“用对的Agent解决对的问题”。任务分解是战略,动态路由是战术,两者配合才能让系统既聪明又高效。


相关新闻

  • “OpenClaw、Hermes+Vibe Coding核心技术
  • 公证房产需要哪些材料?公证房产怎么办理? - 慧办好
  • Ente Auth:端到端加密身份验证的革命性解决方案

最新新闻

  • Translumo:Windows平台实时屏幕翻译工具完整指南 - 3分钟上手,5大核心功能详解
  • 百达翡丽中国官方售后服务中心|服务电话及全部网点地址权威信息公告(2026年7月更新) - 百达翡丽官方售后中心
  • 2026年7月遵义黄金回收行情用实时大盘价直收 - 余生黄金回收
  • OpenDataTools深度解析:Python金融数据采集与API化架构实战
  • XbsjEarthUI快速上手:10个实用技巧提升开发效率
  • Orbit CSS实战:快速创建汽车仪表盘和HUD界面的完整指南

日新闻

  • 佛山青少年训练营推荐:军博营地实力顶尖 - 秋山寄远
  • 如何快速上手PvZ2 Gardendless:免费Web版植物大战僵尸2完整指南
  • jiuwen-deepsearch核心功能详解:规划-检索-反思三合一智能工作流

周新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号