首页 › AI Agent › Agent100道面试题 › 规划与推理-planning-and-reasoning › 任务分解(Task Decomposition)的基本方法

任务分解(Task Decomposition)的基本方法

难度:基础 分类:Planning & Reasoning​

简短回答​

任务分解是将复杂目标拆分为更小、可执行的子任务的过程,是 Agent 规划能力的基础。主要方法包括:LLM 驱动分解(用 Prompt 让 LLM 自行拆分任务,最灵活但可能不稳定)、程序化分解(用代码预定义拆分规则,最可靠但不灵活)、层级分解(HTN)(递归拆分直到每个子任务可直接执行)、自适应分解(ADaPT)(只在 LLM 无法直接执行时才拆分,按需递归)。ADaPT 在多个基准上比固定分解提升 27-33%。关键权衡:拆分粒度——太粗则 LLM 处理不了,太细则协调开销过大。​

详细解析​

为什么需要任务分解?​

​

代码块​

Plain Text

LLM 擅长:聚焦、范围明确的任务​

LLM 不擅长:模糊、多步骤、长依赖链的复杂任务​

​

复杂任务:"帮我做一份竞品分析报告"​

↓ 分解​

子任务 1: 确定要分析的竞品列表​

子任务 2: 收集每个竞品的产品特性​

子任务 3: 收集市场数据和定价信息​

子任务 4: 对比分析优劣势​

子任务 5: 生成报告和可视化图表​

​

方法 1:LLM 驱动分解​

​

代码块​

Bash

async def llm_decompose(task: str) -> list[dict]:​

prompt = f"""​

将以下任务分解为可独立执行的子任务列表。​

​

任务:{task}​

​

要求:​

1. 每个子任务应该足够小,可以用一次 LLM 调用或一次工具调用完成​

2. 明确标注子任务间的依赖关系​

3. 标注每个子任务需要的工具​

​

输出 JSON 格式:​

[​

{{"id": 1, "task": "...", "depends_on": [], "tools": ["search"]}},​

{{"id": 2, "task": "...", "depends_on": [1], "tools": ["analyze"]}}​

]​

"""​

return await llm.invoke(prompt, response_format="json")​

​

# 示例输出​

subtasks = [​

{"id": 1, "task": "搜索竞品列表", "depends_on": [], "tools": ["web_search"]},​

{"id": 2, "task": "收集竞品A的数据", "depends_on": [1], "tools": ["web_search"]},​

{"id": 3, "task": "收集竞品B的数据", "depends_on": [1], "tools": ["web_search"]},​

{"id": 4, "task": "对比分析", "depends_on": [2, 3], "tools": []},​

​

方法 2:程序化分解​

​

代码块​

Python

# 预定义的分解模板——确定性、可靠​

class ReportGenerationPipeline:​

"""程序化分解:代码定义固定步骤"""​

​

steps = [​

{"name": "data_collection", "agent": "researcher", "parallel": True},​

{"name": "data_analysis", "agent": "analyst", "parallel": False},​

{"name": "draft_writing", "agent": "writer", "parallel": False},​

{"name": "review", "agent": "reviewer", "parallel": False},​

]​

​

async def execute(self, task):​

​

方法 3:层级分解(HTN)​

​

代码块​

Python

class HierarchicalDecomposition:​

"""递归分解:直到每个子任务可直接执行"""​

​

async def decompose(self, task, depth=0, max_depth=3):​

if depth >= max_depth:​

return [task] # 达到最大深度,不再分解​

​

# 判断任务是否足够简单可以直接执行​

if await self.is_primitive(task):​

return [task]​

​

​

方法 4:自适应分解(ADaPT)​

​

代码块​

Python

class ADaPT:​

"""As-Needed Decomposition and Planning with LLMs"""​

​

async def solve(self, task):​

# 先尝试直接执行​

result = await self.attempt(task)​

​

if result.success:​

return result​

else:​

# 执行失败 → 分解后重试​

subtasks = await self.decompose(task)​

results = []​

for subtask in subtasks:​

# 递归:每个子任务也先尝试直接执行​

sub_result = await self.solve(subtask)​

results.append(sub_result)​

return self.aggregate(results)​

​

​

​

ADaPT 按需分解:先尝试直接执行,失败才分解,子任务递归走同一流程。​

ADaPT 的优势: 只在必要时分解,避免过度分解。在 ALFWorld 上提升 28.3%,WebShop 提升 27%,TextCraft 提升 33%。​

子任务表示方式​

​

代码块​

Python

​

分解粒度的权衡​

​

代码块​

Plain Text

太粗(少步骤):​

"做一份完整的竞品分析报告"​

→ LLM 无法一次完成,输出质量差​

​

太细(多步骤):​

"搜索关键词'竞品A产品特性'"​

"提取搜索结果第一条的标题"​

"提取搜索结果第一条的内容"​

→ 100 个微步骤,协调开销巨大​

​

​

方法选择指南​

​

​

常见误区 / 面试追问​

误区:"LLM 分解总是最好的" — LLM 分解灵活但不稳定,可能产生逻辑错误或遗漏关键步骤。对于成熟的业务流程,程序化分解更可靠。最佳实践是混合:程序化定义主流程,LLM 处理需要判断力的子步骤。​

误区:"分解越细越好" — 过度分解增加 LLM 调用次数和协调复杂度。研究指出,小模型+精细分解可能损失大模型整体推理产生的创造性洞见。找到合适的粒度是关键。​

追问:"如何验证分解结果的质量?" — 检查三个方面:(1) 完整性——子任务是否覆盖了原始目标的所有方面;(2) 独立性——子任务间是否有不必要的耦合;(3) 可执行性——每个子任务是否足够具体可以执行。​

追问:"任务分解和 Agent 编排的关系?" — 分解产生子任务图(DAG),编排决定执行策略(顺序/并行/条件)。分解是"做什么",编排是"怎么做"。LangGraph 等框架将两者统一:分解结果直接映射为图的节点和边。​