LangChain DeepAgents子智能体架构:构建模块化AI系统的核心原理与实践
1. 项目概述为什么需要子智能体如果你已经跟着这个系列一路走来从基础的智能体搭建到复杂的工具调用再到多轮对话和记忆管理你应该已经能感受到LangChain DeepAgents框架的强大之处。它能帮你把一个想法快速变成一个能理解、能思考、能行动的AI应用。但当我们面对的任务越来越复杂比如要同时处理客户咨询、查询订单、生成报告或者一个任务需要拆解成多个高度专业化的子步骤时把所有逻辑都塞进一个“超级智能体”里代码会变得臃肿不堪逻辑也会像一团乱麻。这时候子智能体SubAgent机制的价值就凸显出来了。你可以把它想象成一个公司的组织架构。一个CEO主智能体不可能精通所有部门的事务他需要CTO负责技术、CFO负责财务、COO负责运营。CEO只负责接收最高层的任务比如“提升公司年利润”然后将其分解指派给相应的部门负责人子智能体去执行。每个部门负责人都有自己专业的技能工具集、工作流程内部逻辑和汇报方式输出格式。他们完成任务后将结果汇总给CEO由CEO整合并给出最终决策。在DeepAgents中SubAgent机制正是为了实现这种“分而治之”的架构。它允许你创建多个独立的、功能聚焦的智能体并由一个主智能体或称为协调者、路由智能体来动态地调用它们。这不仅仅是代码模块化更是智能体能力在逻辑层面的解耦和复用。主智能体像一个总调度中心它根据用户输入的内容判断应该由哪个“专家”子智能体来处理然后将任务分发出去等待专家返回结果最后再组织成对用户的回复。这种架构带来了几个核心优势首先是可维护性每个子智能体职责单一代码清晰修改一个不会影响其他其次是可扩展性需要新功能时只需新增一个子智能体并注册到主智能体即可无需重构整个系统最后是专业性你可以为特定领域如数据分析、代码生成、客服问答训练或配置高度优化的子智能体让它们在各自领域达到最佳表现。2. DeepAgents子智能体机制的核心设计思想理解了“为什么”之后我们来看看DeepAgents是如何实现这套机制的。它的设计并非简单地“调用另一个函数”而是构建了一套完整的、基于消息传递和状态管理的协作体系。2.1 基于角色的任务路由DeepAgents子智能体机制的核心思想是基于角色的路由Role-Based Routing。主智能体我们称之为RouterAgent的核心职责是做一个“分类器”。它不直接处理任务的具体内容而是分析用户请求的意图判断这个请求属于哪个“角色”或“领域”的职责范围。例如用户说“帮我分析一下上个月的销售数据并生成一个总结报告。” 主智能体需要识别出这里包含两个潜在的子任务1.数据分析属于“数据分析师”角色2.报告撰写属于“内容生成”角色。它内部维护着一个映射表角色 - 对应的子智能体。识别出角色后它就把对应的任务描述转发给注册好的DataAnalysisSubAgent和ReportGenerationSubAgent。这个路由决策的过程通常由主智能体内部的一个LLM大语言模型来完成。我们会给这个LLM一个清晰的系统提示词System Prompt定义好所有可用的角色及其职责并让它根据用户输入选择最合适的一个或多个角色。这本质上是一个文本分类任务。2.2 独立的执行环境与状态隔离每个子智能体都是一个完全独立的DeepAgent实例。这意味着它们拥有自己独立的系统提示词System Prompt定义了该子智能体的身份、能力和行为规范。自己专属的工具集Tools例如数据库查询子智能体可能绑定了SQL执行工具而邮件发送子智能体绑定了SMTP工具。自己独立的对话记忆Memory子智能体与用户的交互历史是独立管理的。这非常重要它保证了会话上下文的纯净。数据分析子智能体不需要知道用户之前和客服子智能体聊过什么它只需要关注与当前数据分析任务相关的对话历史。自己的输出解析逻辑子智能体可以按照自己领域最合适的格式输出结果比如JSON、Markdown表格或纯文本。这种隔离性确保了系统的健壮性。一个子智能体的崩溃或异常理论上不应该直接影响其他子智能体或主智能体。主智能体需要具备一定的错误处理能力例如当某个子智能体调用失败时可以尝试其他备用方案或给用户一个友好的错误提示。2.3 协同工作流与信息流子智能体之间并非完全孤立的。在主智能体的协调下它们可以形成复杂的工作流。最常见的是顺序工作流和并行工作流。顺序工作流任务A的输出是任务B的输入。例如“翻译这篇中文文章并总结其大意”。主智能体会先调用“翻译子智能体”将其输出的英文文本作为输入再传递给“总结子智能体”。并行工作流多个子任务可以同时执行。例如“查询北京和上海明天的天气”。主智能体可以同时调用“天气查询子智能体”但需要执行两次参数不同然后汇总两个结果。信息如何在智能体间传递DeepAgents通常依靠共享的上下文Context或工作空间Workspace。主智能体在分发任务时可以将必要的背景信息如用户ID、会话ID、前期结果作为“上下文”附加到子任务中。子智能体完成任务后将其输出写入这个共享上下文。主智能体最后从上下文中收集所有子结果进行整合。在实现上这可以通过一个全局的字典变量、一个共享的消息总线或者更工程化的方案如Redis等外部存储来实现。关键在于设计好数据的结构和传递协议避免信息丢失或混乱。3. 构建你的第一个多智能体系统从零到一理论说再多不如动手做一遍。我们来构建一个简单的“智能助理”系统它包含一个主路由智能体和两个子智能体一个“计算器”和一个“闲聊助手”。3.1 定义子智能体首先我们定义两个功能纯粹的子智能体。1. 计算器子智能体 (CalculatorAgent)这个智能体只做一件事执行数学计算。我们给它一个专门的计算工具这里用Python的eval简单模拟生产环境请使用更安全的库如numexpr。from langchain.agents import DeepAgent from langchain.tools import Tool from langchain.memory import ConversationBufferMemory import re def safe_calculate(expression: str) - str: 安全地计算数学表达式。仅支持数字和基本运算符。 # 简单的安全过滤移除所有非数字和运算符的字符 safe_pattern r^[\d\s\\-\*\/\(\)\.]$ if not re.match(safe_pattern, expression): return 错误输入包含不安全的字符仅支持数字和 - * / ( ) 运算符。 try: # 警告生产环境应使用 ast.literal_eval 或 numexpr 等更安全的计算方式 result eval(expression) return f计算结果{expression} {result} except Exception as e: return f计算错误{e} # 创建计算器工具 calc_tool Tool( nameCalculator, funcsafe_calculate, description用于计算数学表达式。输入一个包含数字和 - * / ( ) 的字符串例如 3 5 * (2 - 1)。 ) # 创建计算器子智能体 calculator_agent DeepAgent( nameCalculatorAgent, system_prompt你是一个专业的计算器助手。你的唯一职责是响应用户的数学计算请求。当用户输入一个数学表达式时使用Calculator工具进行计算并返回结果。不要回答任何与计算无关的问题。如果输入不是数学表达式请直接回答我仅能处理数学计算问题。, tools[calc_tool], memoryConversationBufferMemory(memory_keychat_history, return_messagesTrue), llm... # 传入你的LLM实例例如ChatOpenAI )2. 闲聊子智能体 (ChatAgent)这个智能体负责处理所有非计算类的、开放域的对话。from langchain.agents import DeepAgent from langchain.memory import ConversationBufferMemory chat_agent DeepAgent( nameChatAgent, system_prompt你是一个友好、热情的闲聊助手。你可以和用户谈论天气、心情、电影、音乐、书籍等任何轻松的话题。你的目标是提供有趣、积极和富有同理心的回应。如果用户询问需要专业处理的问题如计算、查资料请礼貌地建议他们使用相应的功能。, tools[], # 闲聊不需要特殊工具 memoryConversationBufferMemory(memory_keychat_history, return_messagesTrue), llm... # 传入相同的LLM实例 )注意这里为了清晰给两个子智能体都配置了独立的ConversationBufferMemory。在实际的多轮交互中主智能体需要管理子智能体记忆的调用和存储通常不会让子智能体自动保存所有历史而是由主智能体在每次调用时传入相关的历史上下文。3.2 构建主路由智能体主智能体是大脑它没有自己的专业工具但有一个最重要的能力决策调用哪个子智能体。我们通过一个自定义的“路由工具”来实现。from langchain.agents import DeepAgent from langchain.tools import Tool from langchain.memory import ConversationBufferMemory from typing import Dict, Any class RouterAgent: def __init__(self, sub_agents: Dict[str, DeepAgent]): 初始化路由智能体。 Args: sub_agents: 字典键为角色名值为对应的DeepAgent实例。 self.sub_agents sub_agents self.memory ConversationBufferMemory(memory_keychat_history, return_messagesTrue) def route_and_execute(self, user_input: str) - str: 核心路由逻辑判断用户意图调用对应的子智能体。 这里使用一个简单的规则匹配实际应用中应使用LLM进行意图分类。 # 简单的关键词路由规则生产环境应用LLM进行意图识别 user_input_lower user_input.lower() if any(word in user_input_lower for word in [计算, 算一下, , -, *, /, 等于, 几加几]): role calculator else: role chat # 获取对应的子智能体 target_agent self.sub_agents.get(role) if not target_agent: return f抱歉暂时无法处理【{role}】类型的请求。 # 调用子智能体 # 注意这里简化了调用实际应将当前对话的上下文也传递给子智能体 try: response target_agent.run(user_input) # 可选将本次交互存入主智能体记忆 self.memory.save_context({input: user_input}, {output: response}) return response except Exception as e: return f调用 {role} 智能体时出错{e} # 创建路由智能体实例 sub_agents_dict { calculator: calculator_agent, chat: chat_agent } router_agent RouterAgent(sub_agents_dict) # 将路由逻辑包装成一个Tool以便集成到更复杂的Agent流程中如果需要 router_tool Tool( nameMaster_Router, funcrouter_agent.route_and_execute, description总路由工具。分析用户输入自动分配给计算器或闲聊助手处理。 ) # 也可以将RouterAgent本身升级为一个完整的DeepAgent master_agent DeepAgent( nameMasterAssistant, system_prompt你是智能助理的总调度员。用户的所有请求都会先发给你。你需要判断请求的意图如果是数学计算就交给计算器处理如果是其他聊天就交给闲聊助手处理。你只负责路由不直接回答问题。, tools[router_tool], # 将自己路由逻辑作为工具 memoryrouter_agent.memory, llm... # 主智能体也可以有自己的LLM来做更复杂的路由决策 )3.3 运行与测试现在我们可以通过主智能体来统一响应用户了。# 测试场景 test_queries [ 3加5等于几, 今天天气真好你感觉怎么样, (12 8) * 2 / 4 等于多少, 推荐一部好看的电影吧。 ] for query in test_queries: print(f用户: {query}) # 使用路由智能体的方法 response router_agent.route_and_execute(query) # 或者使用封装好的Master Agent # response master_agent.run(query) print(f助理: {response}\n)预期输出会显示计算问题被路由到CalculatorAgent并返回计算结果而闲聊问题则被路由到ChatAgent并返回友好对话。这个例子虽然简单但完整展示了子智能体机制的核心流程注册 - 路由 - 执行 - 返回。你已经搭建了一个可工作的多智能体系统雏形。4. 进阶实战基于LLM的智能路由与复杂工作流上面的例子使用硬编码规则关键词匹配进行路由这显然不够灵活。在实际项目中我们需要主智能体能够理解更复杂的用户意图。这就需要引入LLM本身来做路由决策。4.1 实现一个真正的LLM路由控制器我们创建一个LLMRouterController类它利用LLM来分析用户输入并选择最合适的子智能体。from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate from langchain.schema import AIMessage, HumanMessage import json class LLMRouterController: def __init__(self, sub_agents: Dict[str, DeepAgent], llm): self.sub_agents sub_agents self.llm llm # 定义路由提示词模板 self.router_prompt ChatPromptTemplate.from_messages([ SystemMessagePromptTemplate.from_template( 你是一个智能路由分发器。你的任务是根据用户的问题将其分配给最专业的下属智能体处理。 你拥有以下下属智能体 {agent_descriptions} 请严格按以下JSON格式输出你的路由决策 {{ reasoning: 简要说明为什么选择该智能体, selected_agent: 智能体名称, confidence: 0.9 // 置信度0-1之间 }} 只输出JSON不要有其他任何内容。 ), HumanMessagePromptTemplate.from_template(用户问题{user_input}) ]) # 构建智能体描述字符串 self.agent_descriptions_str \n.join([f- {name}: {agent.system_prompt[:100]}... for name, agent in sub_agents.items()]) def route(self, user_input: str) - Dict[str, Any]: 使用LLM进行路由决策返回解析后的JSON结果。 # 填充提示词 messages self.router_prompt.format_messages( agent_descriptionsself.agent_descriptions_str, user_inputuser_input ) # 调用LLM response self.llm.invoke(messages) # 解析JSON输出 try: decision json.loads(response.content) return decision except json.JSONDecodeError: # 如果LLM输出不规范返回一个默认决策或抛出错误 print(fLLM路由输出解析失败: {response.content}) return {selected_agent: chat, reasoning: Fallback due to parse error, confidence: 0.5} def execute(self, user_input: str) - str: 路由并执行先路由再调用选中的子智能体。 decision self.route(user_input) selected_name decision.get(selected_agent) if selected_name not in self.sub_agents: return f路由错误找不到名为 {selected_name} 的智能体。决策详情{decision} target_agent self.sub_agents[selected_name] print(f[路由日志] 问题{user_input} - 路由至{selected_name}理由{decision.get(reasoning)}) try: return target_agent.run(user_input) except Exception as e: return f执行子智能体 {selected_name} 时发生错误{e} # 使用示例 from langchain_openai import ChatOpenAI # 假设已有之前定义的 calculator_agent 和 chat_agent sub_agents { CalculatorExpert: calculator_agent, FriendlyChatter: chat_agent } llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 路由需要低随机性 router LLMRouterController(sub_agents, llm) # 测试复杂查询 complex_query “我想知道我的房贷如果贷款100万利率4.5%30年还清每月要还多少另外今天心情有点低落有什么建议吗” result router.execute(complex_query) print(result)在这个例子中LLM需要理解用户问题包含“房贷计算”属于数学计算和“心情建议”属于闲聊两部分。一个设计良好的路由提示词可以指导LLM做出“选择CalculatorExpert”的决策或者更高级地识别出这是一个复合问题。对于复合问题我们下一节讨论。4.2 处理复合任务与顺序工作流用户的问题常常是复合的比如“翻译这句话‘Hello, world!’成中文然后告诉我它的长度。” 这需要先调用翻译子智能体再调用计算子智能体。我们需要升级主控制器使其具备任务分解和顺序执行的能力。这里我们可以引入LangChain的另一个强大组件LangGraph。但为了保持DeepAgents的纯粹性我们先实现一个简化版。class SequentialWorkflowController: def __init__(self, router_controller: LLMRouterController): self.router router_controller # 定义一个任务分解提示词 self.decomposition_prompt ChatPromptTemplate.from_messages([ SystemMessagePromptTemplate.from_template( 你是一个任务分解专家。用户可能提出一个包含多个步骤的复合请求。 请将请求分解成一系列独立的、可顺序执行的子任务。 每个子任务应该足够简单可以被一个专业的智能体处理。 输出格式必须是严格的JSON列表 [ {{task: 第一个子任务描述, expected_agent: 建议处理的智能体名称}}, {{task: 第二个子任务描述, expected_agent: 建议处理的智能体名称}} ] 智能体名称必须是CalculatorExpert, FriendlyChatter 中的一个。 如果无法分解或只有一个任务也输出一个单元素的列表。 ), HumanMessagePromptTemplate.from_template(用户请求{user_input}) ]) def run_workflow(self, user_input: str) - str: 执行复合任务工作流分解 - 顺序执行 - 汇总。 # 1. 任务分解 messages self.decomposition_prompt.format_messages(user_inputuser_input) decomposition_response self.router.llm.invoke(messages) try: subtasks json.loads(decomposition_response.content) if not isinstance(subtasks, list): subtasks [{task: user_input, expected_agent: None}] except: # 分解失败当作单一任务处理 subtasks [{task: user_input, expected_agent: None}] print(f[工作流] 分解出 {len(subtasks)} 个子任务{subtasks}) # 2. 顺序执行子任务 results [] context {} # 用于在子任务间传递信息的上下文 for i, subtask in enumerate(subtasks): task_description subtask[task] suggested_agent subtask.get(expected_agent) # 可以根据建议或重新路由来决定使用哪个智能体 # 这里简单处理如果有建议且存在则用建议的否则重新路由 if suggested_agent and suggested_agent in self.router.sub_agents: target_agent self.router.sub_agents[suggested_agent] result target_agent.run(task_description) else: # 将子任务描述作为新的用户输入进行路由 result self.router.execute(task_description) results.append(f步骤{i1} ({task_description}): {result}) # 可以将上一步的结果作为上下文的一部分传递给下一步这里简化了 context[fstep_{i}_result] result # 3. 汇总结果 final_output 任务执行完成\n \n.join(results) return final_output # 使用示例 workflow_controller SequentialWorkflowController(router) compound_query “先计算 25 * 4 等于多少然后基于这个结果和我聊聊天。” final_result workflow_controller.run_workflow(compound_query) print(final_result)这个SequentialWorkflowController展示了如何处理需要多个步骤的任务。它首先尝试将复合问题分解然后逐个执行子任务并收集结果。在实际应用中你还需要考虑错误处理与重试某个子任务失败怎么办上下文传递如何将步骤一的结果如“100”作为输入的一部分传递给步骤二闲聊智能体并行执行优化如何识别可以并行执行的子任务以提升效率这些正是LangGraph等框架擅长的领域。DeepAgents提供了构建智能体的基础而LangGraph则提供了编排智能体工作流的强大引擎。两者结合可以构建出极其复杂的多智能体应用。5. 核心配置、调试与性能优化心法构建多智能体系统时配置和调试的复杂度呈指数级上升。以下是我在实际项目中总结的一些关键心法。5.1 子智能体的配置隔离与共享配置隔离是黄金法则。每个子智能体应该被当作一个独立的微服务来配置。独立的LLM配置虽然可以共享同一个LLM实例但为不同的子智能体配置不同的temperature、max_tokens等参数往往效果更好。例如路由智能体需要低temperature如0以保证决策稳定性而创意写作子智能体可能需要更高的temperature如0.7来激发多样性。独立的内存配置ConversationBufferWindowMemory只保留最近N轮对话对于处理实时数据流的智能体很合适而ConversationSummaryMemory总结历史对于需要长期背景知识的智能体更好。根据子智能体的职责选择。工具的精简与专属切忌给子智能体赋予它用不到的工具。这不仅会增加不必要的Token消耗工具描述会被放入提示词还可能干扰LLM的决策。一个只负责数据查询的子智能体就不需要邮件发送工具。可以共享的配置LLM客户端连接多个智能体可以共享同一个LLM API客户端如OpenAI客户端实例以管理连接池和认证。向量数据库连接如果多个智能体都需要检索知识可以共享同一个向量数据库客户端实例。日志与监控服务统一的日志记录和性能监控入口便于追踪整个系统的行为。5.2 调试多智能体系统的“火眼金睛”当系统行为不符合预期时如何定位是哪个环节出了问题启用详细日志为每个智能体的run方法添加详细的日志记录打印出输入、输出、中间步骤如工具调用、LLM请求/响应。import logging logging.basicConfig(levellogging.INFO) # 在智能体调用关键方法时使用 logging.info(f“[AgentName] Input: {input}”)可视化工作流对于复杂的工作流考虑将执行步骤路由决策、子智能体调用序列、数据流输出为结构化的数据如JSON甚至可以用简单的图表工具生成流程图。这能帮你一眼看清执行路径是否正确。隔离测试这是最重要的方法。单独测试每个子智能体确保其输入输出符合预期。然后再测试路由逻辑给定输入X路由决策是否正确最后再测试整个工作流。检查提示词工程多智能体系统对提示词极其敏感。路由提示词的一个微小改动可能导致完全不同的分发结果。务必仔细检查每个智能体的system_prompt和router_prompt确保指令清晰、无歧义。一个技巧是将LLM在路由或决策时的“思考过程”如果模型支持打印出来看看它到底是如何理解你的指令和用户输入的。5.3 性能优化与成本控制多智能体系统意味着多次LLM调用成本和延迟会显著增加。缓存策略对于频繁出现的、结果确定的查询如“公司的产品介绍是什么”可以在主智能体或子智能体层面引入缓存如langchain.cache配合SQLiteCache或RedisCache。避免相同问题重复调用LLM。短路逻辑在主智能体的路由逻辑中可以先进行一层快速的规则匹配正则表达式或关键词。例如如果用户输入是“ping”可以直接返回“pong”而无需经过LLM路由。这能节省大量简单请求的开销。批量处理如果系统需要处理大量相似请求可以考虑设计成批处理模式将多个问题打包发送给LLM如果API支持而不是逐个请求。超时与熔断为每个子智能体的调用设置超时。如果一个子智能体响应过慢主智能体应能跳过它或返回降级结果如“该服务暂时不可用”防止整个系统被拖垮。Token消耗分析定期审计日志分析每个请求的Token使用情况。你会发现大部分Token消耗在system_prompt和tool descriptions上。精简这些描述删除冗余信息是降低成本最有效的手段之一。例如工具描述应简洁准确避免长篇大论。6. 避坑指南从理论到实践的血泪教训在真实项目中踩过坑才能深刻理解这些设计决策的重要性。以下是我总结的几个关键陷阱及应对策略。陷阱一子智能体间的“信息孤岛”与“上下文污染”问题子智能体A处理了用户关于“项目A”的对话留下了记忆。当用户稍后问一个模糊问题“它的进度怎么样了”主智能体可能错误地将其路由给子智能体B。子智能体B因为没有“项目A”的上下文要么胡言乱语要么错误地引用自己记忆里的其他内容。解决方案主智能体管理全局上下文所有与当前会话相关的关键信息如当前讨论的项目名、用户ID、上一轮的结果应由主智能体维护在一个“会话上下文”对象中。精准传递上下文当主智能体调用子智能体时除了用户当前问题还应将必要的上下文信息作为“背景”或“历史”附加到提示词中。例如“背景用户正在讨论‘项目A’。问题它的进度怎么样了”谨慎使用子智能体的长期记忆对于大多数场景子智能体最好使用无状态的ConversationBufferMemory并且每次调用都由主智能体传入完整的上下文。避免子智能体自动保存全局历史防止交叉污染。陷阱二路由决策的“摇摆”与“死循环”问题用户问题边界模糊导致LLM路由器在不同子智能体间摇摆。更糟糕的是子智能体A处理完后可能生成一个输出该输出又被主智能体路由给子智能体BB又触发A形成死循环。解决方案设置明确的路由优先级和回退策略在路由提示词中明确“如果问题同时涉及A和B优先选择A”。并设置一个默认的“兜底”智能体如通用聊天助手。在路由决策中引入历史将本次会话之前的路由决策历史也作为输入给路由LLM帮助它保持一致性。“刚才用户问了计算问题你派给了计算器现在他接着问‘结果对吗’这很可能还是对计算器的追问。”防止循环调用在主智能体状态中记录当前或最近被调用的子智能体。如果连续多次路由到同一个智能体或出现了A-B-A的 pattern可以强制中断并提示用户澄清问题。陷阱三错误处理的“黑洞”问题子智能体在执行时可能因为各种原因失败工具API异常、LLM调用超时、输出解析错误。如果主智能体只是简单地捕获异常并返回一个通用错误信息用户和开发者都难以定位问题。解决方案结构化错误返回要求每个子智能体不仅返回成功结果也定义清晰的错误格式。例如返回一个字典{status: success/error, data: ..., error_detail: ...}。主智能体的优雅降级当某个子智能体失败时主智能体应尝试备用方案。例如专业翻译失败可以降级到调用通用LLM的翻译能力或者直接告知用户“某项功能暂时不可用您可以尝试...”。完善的日志与告警所有错误包括被优雅处理的都必须以足够的上下文用户输入、智能体名称、错误堆栈记录到日志系统并设置告警以便及时修复。陷阱四无限扩展导致的“管理灾难”问题随着业务增长子智能体数量膨胀到几十上百个。手动维护路由映射表、更新提示词、部署新智能体变得极其困难。解决方案服务发现与注册中心借鉴微服务架构建立一个智能体注册中心。新的子智能体启动时自动向中心注册自己的名称、描述、端点地址。主路由智能体动态地从注册中心拉取可用的智能体列表。标准化接口与描述强制所有子智能体实现统一的接口如run(input, context)并提供机器可读的元数据描述能力、输入输出格式、示例等便于路由LLM自动理解和使用。分层路由不要用一个主智能体路由所有请求。可以建立层级路由。第一层按大领域分如“技术问题”、“生活问题”第二层再细分“技术问题”下分“编程”、“运维”。这能降低单个路由器的决策复杂度。构建一个健壮、高效的多智能体系统是一个持续迭代和优化的过程。从最简单的两个智能体开始逐步增加复杂度并在每一步都做好测试、监控和复盘是通往成功最稳妥的路径。DeepAgents的SubAgent机制为你提供了强大的积木但如何搭建出稳固而精巧的建筑则依赖于你对业务逻辑的深刻理解和对这些“心法”的灵活运用。