发布时间:2026/7/15 23:03:22
Agent 的任务分解策略:Plan-and-Solve 比 Chain-of-Thought 更适合复杂任务 Agent 的任务分解策略Plan-and-Solve 比 Chain-of-Thought 更适合复杂任务一、深度引言与场景痛点如果你给 Agent 布置一个任务比如帮我分析这家公司过去三年的财报趋势和同行业对比后输出风险报告Chain-of-Thought 的方式是做一步看一步先查财报发现数据不全再补查发现需要行业数据又去查。等到推理链超过十几步Agent 自己都忘了最初想干啥。这不是模型能力不够而是推理方式不对。复杂任务的特点是步骤之间有依赖、中间信息需要聚合、路径可能分叉。Chain-of-Thought 擅长线性推理但面对需要分治、并行、回溯的任务它就像在迷宫里边走边猜——迟早出错。Plan-and-Solve 的思路就简单了先花 10% 的时间做计划把复杂任务拆成可独立验证的子任务再逐块执行。这相当于先画地图再走路比边走边问路靠谱得多。二、底层机制与原理深度剖析flowchart TD A[用户输入复杂任务] -- B[任务分析阶段] B -- C{复杂度判断} C --|简单任务| D[直接推理执行] C --|复杂任务| E[生成执行计划] E -- F[依赖关系排序] F -- G[子任务并行分配] G -- H1[子任务1: 数据采集] G -- H2[子任务2: 预处理] G -- H3[子任务3: 分析计算] H1 -- I[中间结果验证] H2 -- I H3 -- I I -- J{所有子任务通过?} J --|否| K[标记失败任务, 重新规划] K -- E J --|是| L[结果聚合与推理] L -- M[输出最终答案]图中核心的分叉在于复杂度判断这一步。不是所有任务都需要 Plan-and-Solve对于今天天气怎么样这种单步任务直接推理更快。Plan-and-Solve 的威力体现在依赖关系排序让子任务按正确顺序执行中间验证保证每一步结果可信失败重规划让系统有自愈能力。和 Chain-of-Thought 的关键区别是CoT 在推理过程中顺便分解Plan-and-Solve 是先显式生成计划再由执行器逐块执行。显式计划的好处是可审计、可打断、可重试、可并行。想象一下你做项目时是先写个甘特图再干活还是干到哪算哪前者显然更可控。三、生产级代码实现from __future__ import annotations import asyncio import json from dataclasses import dataclass, field from enum import Enum from typing import Any, Callable, Awaitable class TaskStatus(Enum): PENDING pending RUNNING running SUCCESS success FAILED failed SKIPPED skipped dataclass class SubTask: id: str description: str dependencies: list[str] field(default_factorylist) status: TaskStatus TaskStatus.PENDING result: Any None error: str dataclass class Plan: task_id: str subtasks: list[SubTask] raw_plan: str class PlanGenerator: 计划生成器 —— 调用 LLM 将复杂任务拆解为子任务 DAG async def generate(self, task: str, llm_call: Callable[[str], Awaitable[str]]) - Plan: prompt ( 你是一个任务分解专家。请将以下复杂任务拆解为可独立执行的子任务 输出 JSON 格式每个子任务包含 id、描述和依赖的 id 列表\n f任务{task} ) raw await llm_call(prompt) try: parsed json.loads(raw) except json.JSONDecodeError: # 降级将整个任务作为单个子任务 parsed [{id: task_0, description: task, dependencies: []}] subtasks [ SubTask( iditem[id], descriptionitem[description], dependenciesitem.get(dependencies, []), ) for item in parsed ] return Plan(task_idtask[:20], subtaskssubtasks, raw_planraw) class PlanExecutor: 计划执行器 —— 按拓扑排序逐个执行子任务支持并行 def __init__(self, execute_fn: Callable[[SubTask], Awaitable[Any]]): self._execute execute_fn self._completed: dict[str, SubTask] {} async def execute(self, plan: Plan, max_retries: int 2) - list[SubTask]: remaining {st.id: st for st in plan.subtasks} results: list[SubTask] [] while remaining: ready [ st for st in remaining.values() if all(dep in self._completed for dep in st.dependencies) ] if not ready: # 存在循环依赖或死锁 failed [st for st in remaining.values() if st.status TaskStatus.FAILED] if failed: raise RuntimeError(f无法继续执行以下任务失败: {[f.id for f in failed]}) raise RuntimeError(检测到计划中存在循环依赖) # 并行执行所有就绪的子任务 tasks [self._run_with_retry(st, max_retries) for st in ready] completed await asyncio.gather(*tasks, return_exceptionsTrue) for st, result in zip(ready, completed): if isinstance(result, Exception): st.status TaskStatus.FAILED st.error str(result) else: st.status TaskStatus.SUCCESS st.result result self._completed[st.id] st results.append(st) del remaining[st.id] return results async def _run_with_retry(self, subtask: SubTask, max_retries: int) - Any: last_error None for attempt in range(max_retries 1): try: subtask.status TaskStatus.RUNNING return await self._execute(subtask) except Exception as e: last_error e if attempt max_retries: await asyncio.sleep(0.5 * (2 ** attempt)) raise last_error or RuntimeError(未知执行错误) async def plan_and_solve( task: str, llm_call: Callable[[str], Awaitable[str]], execute_fn: Callable[[SubTask], Awaitable[Any]], ) - str: generator PlanGenerator() plan await generator.generate(task, llm_call) executor PlanExecutor(execute_fn) try: results await executor.execute(plan) except RuntimeError as e: return f任务执行失败: {e} success_count sum(1 for r in results if r.status TaskStatus.SUCCESS) return f计划完成: {success_count}/{len(plan.subtasks)} 个子任务成功执行这段代码看着长但核心就两件事生成计划、按拓扑序执行计划。PlanGenerator负责调用 LLM 拆解任务PlanExecutor负责把子任务 DAG 安全地跑完。并行执行能力来自asyncio.gather天然支持多个无依赖子任务同时进行。退避重试用了指数延时避免瞬时故障时反复冲撞。最关键的是任务失败不会让整个流程崩溃只标记状态方便后续重新规划。四、边界分析与架构权衡Plan-and-Solve 最大的代价是多了一次 LLM 调用。对于简单任务这个开销是浪费的。所以复杂度判断器必须在简单任务上直接走快速通道。判断器可以是规则比如输入长度、关键词匹配也可以是一个轻量分类模型。一个实用的经验是如果任务描述超过 50 字大概率需要 Plan-and-Solve。另一个边界是计划的质量。LLM 生成的计划可能遗漏子任务、错误判断依赖关系、甚至把不可分解的任务强行拆碎。所以计划不应盲信执行器要做依赖关系环检测和最终结果交叉验证。如果某个子任务依赖了不在计划中的 ID执行器应立即报告而非默默跳过。并行度控制也需要边界意识。理论上所有无依赖子任务都能并行但如果同时跑 20 个都去调外部 API可能触发限流。实际落地要加上并发上限比如asyncio.Semaphore控制在 3~5 个并发。还有一个容易忽略的问题子任务的执行顺序虽然由 DAG 决定但结果聚合的 LLM 调用需要按自然语义组织。建议在执行结束后把成功任务的摘要按逻辑顺序重新排版再喂给汇总模型。否则汇总模型看到的是一团乱码。五、总结Plan-and-Solve 本质上是把推理从线性链变成了有向无环图。复杂任务能显著受益于这种结构执行可并行、失败可重试、进度可审计。但成本也比 Chain-of-Thought 高了约 20~30% 的 Token 消耗所以不适合今天天气如何这种轻量任务。落地时重点做好三件事用一个轻量判断器把简单任务快速分流给执行器加上并发上限和指数退避重试子任务失败后要有优雅降级策略而不是让整个 Agent 崩溃。计划不完美没关系关键是系统能识别计划不完美并自我修复。

相关新闻

2026/7/15 23:03:22

从零实现C++二维快速傅里叶变换(FFT2):原理、代码与优化实战

1. 项目概述最近在做一个图像处理相关的项目,需要用到二维快速傅里叶变换(FFT2)来做频域分析。虽然像OpenCV这样的库已经提供了现成的cv::dft函数,但为了更深入地理解算法原理,也为了在一些对第三方库依赖有严格限制的…

2026/7/15 22:58:21

数据科学职业地基:统计思维、Python表达与业务落地三本书

1. 这三本书,我带了六届数据科学新人一起读,不是“入门清单”,而是职业地基的三块压舱石刚带完今年第三期数据科学实习项目,有个实习生在结业复盘时问我:“老师,您总说别急着学代码、别急着调参&#xff0c…

2026/7/15 22:58:21

2026龙虾AI企业搭建推荐 AionClaw 等五款智能体场景化选型参考

前言 数字化转型背景下,龙虾 AI 智能体可自主完成电脑端操作、支持长时段自动化运行、多智能体协同处理办公任务,成为各类规模企业搭建数字员工体系的常用工具。2026 年市场内各类龙虾 AI 智能体在底层架构、部署方式、行业适配方向上存在明显区分&#…

2026/7/16 0:09:06

openEuler OpenStack SIG:5个关键步骤实现分布式流量管理

openEuler OpenStack SIG:5个关键步骤实现分布式流量管理 【免费下载链接】openstack-docs docs for openEuler OpenStack SIG 项目地址: https://gitcode.com/openeuler/openstack-docs 前往项目官网免费下载:https://ar.openeuler.org/ar/ 在云…

2026/7/16 0:09:06

Kmesh服务治理能力解析:流量路由与负载均衡的实现原理

Kmesh服务治理能力解析:流量路由与负载均衡的实现原理 【免费下载链接】Kmesh Kmesh (kernel mesh) is a data plane software for service grids. It is dedicated to providing infrastructure for service communication and service governance for cloud appli…

2026/7/16 0:09:06

BIDK性能优化技巧:10个方法提升二进制插桩效率

BIDK性能优化技巧:10个方法提升二进制插桩效率 【免费下载链接】BIDK A low-overhead dynamic binary instrumentation and modification tool for ARM (both AArch32 and AArch64 support) and RISC-V (RV64GC). 项目地址: https://gitcode.com/openeuler/BIDK …

2026/7/16 0:09:06

月球如何保持背面永远背对地球?——容度原理解释

月球如何保持背面永远背对地球?——容度原理解释一、潮汐锁定:一个被物理描述却未被物理解释的现象月球永远以同一面朝向地球,这一现象被称为“潮汐锁定”。物理学的解释是:地球引力在月球上产生了潮汐隆起,隆起的引力…

2026/7/16 0:09:06

月球是否是从地球分离出去的?——容度原理解释

月球是否是从地球分离出去的?——容度原理解释一、月球起源的“三大假说”与容度原理的重新审视月球起源的三大假说——捕获说(月球是太阳系中独立的星体,被地球引力捕获)、共生说(月球与地球同时从原始星云中形成&…

2026/7/16 0:04:06

A--10 Codex Review与GitHub PR工作流实战指南:从代码审查到安全合并

摘要:本文系统讲解如何利用Codex App的Review功能与GitHub PR工作流,实现从代码修改到安全合并的完整流程。涵盖Review面板深度使用、/review命令实战、GitHub Connector配置、PR描述撰写技巧,以及常见问题排查方法。通过多个实战案例和流程图,帮助开发者建立高效的AI辅助代…

2026/7/15 17:04:06

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南

3步解锁音乐自由:ncmdumpGUI终极NCM文件解密转换指南 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾在网易云音乐下载了心爱的歌曲&#…

2026/7/15 22:21:34

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境

CANoe 19 SP3 配置 GB/T 27930-2023 A类系统:3步搭建BMS仿真测试环境随着新能源汽车行业的快速发展,充电通信协议的标准化和测试验证变得尤为重要。GB/T 27930-2023作为中国智能充电协议的最新版本,对充电机与电动汽车之间的通信提出了更严格…

2026/7/15 23:18:22

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡

3步搞定RTL8852BE驱动:从零开始配置Wi-Fi 6网卡 【免费下载链接】rtl8852be Realtek Linux WLAN Driver for RTL8852BE 项目地址: https://gitcode.com/gh_mirrors/rt/rtl8852be 还在为Linux系统无法识别RTL8852BE Wi-Fi 6网卡而烦恼吗?&#x1f…

2026/7/16 0:04:06

AD9215BRUZRL7-105是一款工业 10bit 流水线模数转换器

型号介绍AD9215BRUZRL7-105 是一款10 位单通道高速流水线模数转换器,它采用模拟单电源独立供电 数字驱动分离供电双电源架构,模拟电源 AVDD 额定 3V,允许工作区间 2.7V~3.3V;数字驱动电源 DRV 独立设计,支持 2.25V~3.…

2026/7/16 0:04:06

LTC4418IUF#TRPBF是一款工业级双通道控制器

型号介绍LTC4418IUF#TRPBF 是一款工业级双通道电源路径控制器,它芯片采用 20 引脚 4mm4mm QFN 封装,底部附带外露散热焊盘作为 21 号 GND 引脚,热阻 θJA 为 47℃/W、θJC 仅 4.5℃/W,散热性能适配大功率切换场景;温区…

2026/7/16 0:04:06

uos-exporter核心组件解析:10个关键监控导出器功能详解

uos-exporter核心组件解析:10个关键监控导出器功能详解 【免费下载链接】uos-exporter uos-exporter collects metrics from os 项目地址: https://gitcode.com/openeuler/uos-exporter 前往项目官网免费下载:https://ar.openeuler.org/ar/ uos-…

2026/7/15 13:36:32

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…