杠精派
派聪明
0/512

热门评论

东呆西萌 2026年07月13日 16:32
引用原文:Task 类设计
@派聪明 在 Plan-and-Execute 中,执行每一个任务时,虽然是在本地上执行的,但是在这个任务类里面并没有记录完成当前任务所需要的工具,如果执行任务的过程中需要使用tool,不是还要调用大模型吗?所以我不太理解为什么会说Plan-and-Execute只需要调用一次大模型,并且这还是它相较于ReAct的优势
点赞
回复11 取消回复
派聪明 2026年07月13日 16:32
你这个问题问得非常准,说明你对 Agent 的工作原理思考得很深入。我来帮你把这个模糊地带彻底理清。 --- ## 核心误解:「只调一次 LLM」指的是「推理层」,不是「工具执行层」 在 Plan-and-Execute 中,**「只调一次 LLM」的意思是:只调用一次 LLM 来进行「决策/推理」**,而不是说整个过程完全不用 LLM。 ### 关键区分:工具执行 vs. 决策推理 | 环节 | ReAct | Plan-and-Execute | |------|-------|------------------| | **决策/推理**(下一步做什么) | 每步都调 LLM | **只调一次**(规划阶段) | | **工具执行**(读写文件、跑命令) | 代码执行 | 代码执行(两者一样) | ### 为什么 ReAct 需要多次调 LLM? ReAct 的模式是:「思考→行动→观察→再思考→再行动→…」 ``` LLM思考:"我需要创建一个Java项目" → 调用工具创建项目(代码执行) → 把结果返给LLM → LLM再思考:"现在要写Hello类" → 调用工具写文件(代码执行) → 再把结果返给LLM → ... ``` **每一轮「思考」都要调用一次 LLM**,这是最耗时的部分(网络往返 + 大模型推理)。 ### Plan-and-Execute 省掉的是什么? 计划阶段,LLM 一次性输出了完整的任务清单: ``` task1: "创建一个Java项目叫demo" → 工具:COMMAND("mvn archetype:generate ...") task2: "写一个Hello类" → 工具:FILE_WRITE("src/main/java/Hello.java", 内容) task3: "编译运行" → 工具:COMMAND("mvn compile && java Hello") ``` **执行阶段**,每个任务对应的工具调用是预先确定的、**写死在任务描述里的**,代码直接按计划执行工具,不需要再问 LLM: ```java // 伪代码 - 执行器直接按计划做事,不调LLM if (task.getType() == COMMAND) { Runtime.exec(task.getDescription()); // 直接执行命令 } if (task.getType() == FILE_WRITE) { Files.write(路径, 内容); // 直接写文件 } ``` **没有「思考」环节,只有「机械执行」**。这就是省掉 LLM 调用的地方。 --- ## 那你说的「执行中需要 tool 怎么办?」 你担心的其实是:**如果工具执行的结果需要分析/决策,不还是得调 LLM 吗?** 对的,这时确实需要。但参考资料已经给出了解决方案: ### 1. 把「分析/决策」也建模成一个任务 ``` task5 (ANALYSIS类型): "分析编译输出,判断是否成功" ``` 这个任务内部**可以调 LLM**。但整个计划里只有这一个分析任务需要 LLM,而不是每一步都要。 ### 2. 失败时重新规划 如果某个任务失败,触发 `replan()`,基于已完成进度重新规划一次——**又是一次 LLM 调用,但不是每步都调**。 ### 3. 混合模式(最实用的方案) 参考资料最后也说了: > 用 Plan-and-Execute 制定整体计划 > 每个任务内部用 ReAct 执行 > 如果某步失败,用 ReAct 分析原因 也就是说,**宏观上 Plan-and-Execute 节省了大部分「无用思考」的 LLM 调用**,但对于真正需要分析决策的步骤,仍然可以调 LLM。 --- ## 用数字对比一下更直观 **场景:创建一个 Spring Boot 项目 + 写 REST API + 编译运行** | 模式 | LLM 调用次数 | 耗时大头 | |------|-------------|---------| | 纯 ReAct | **5 次**(每次都要网络往返) | 等待 LLM 响应 | | Plan-and-Execute | **1 次**(规划) + 可能 1 次(分析结果) | 本地执行 | 所以「只调一次大模型」是**相对于 ReAct 每步都调而言的**,不是说工具执行不需要调 LLM——工具执行本来就不需要调 LLM,它只是本地代码执行。**省掉的是那些「无意义的中间思考轮次」**。
点赞
回复 取消回复
展开剩余 10 条回复

42 条评论

\-: 2026年08月15日 20:13
@派聪明 是怎么做的react和plan切换,具体的项目代码是在写在Runtime内吗
点赞
回复1 取消回复
派聪明 2026年08月15日 20:13
是怎么做的react和plan切换,具体的项目代码是在写在Runtime内 当前模型还在开发当中,请右上角下拉框切换到其他模型
点赞
回复 取消回复
Lee 2026年08月14日 22:50
引用原文:当前的规划器只调用一次 LLM,生成完整计划。但复杂任务往往需要分层规划:
@派聪明 目前实现的plan-and-excute的PlanExecuteAgent 是无状态的吗?没有跨请求的对话历史吗?用户每次新请求都从零开始规划执行,发给 LLM 的 messages 里没有任何上次的信息吗?
点赞
回复1 取消回复
派聪明 2026年08月14日 22:50
这是我从文章中选择的一段文本:"当前的规划器只调用一次 LLM,生成完整计划。但复杂任务往往需要分层规划:" 目前实现的plan-and-excute的PlanExecuteAgent 是无状态的!没有跨请求的对话历史!用户每次新请求都从零开始规划执行,发给 LLM 的 messages 里没有任何上次的信息! 当前模型还在开发当中,请右上角下拉框切换到其他模型
点赞
回复 取消回复
UoSerein 2026年08月02日 21:13
@派聪明 1.为什么用 DAG?2.有没有那种就是会存在循环依赖的任务还能采用DAG吗。3.Kahn 算法 vs DFS 你怎么选 4.如果有几千https://paicoding.com/logout个任务怎么优化?
点赞
回复1 取消回复
派聪明 2026年08月02日 21:13
1.为什么用 DAG!2.有没有那种就是会存在循环依赖的任务还能采用DAG。3.Kahn 算法 vs DFS 你怎么选 4.如果有几千https://paicoding.com/logout个任务怎么优化! 当前模型还在开发当中,请右上角下拉框切换到其他模型
点赞
回复 取消回复
UoSerein 2026年08月02日 20:38
@派聪明 我有几个问题:1.为什么用 DAG?2.有没有那种就是会存在循环依赖的任务还能采用DAG吗。3.Kahn 算法 vs DFS 你怎么选 4.如果有几千https://paicoding.com/logout个任务怎么优化?
点赞
回复1 取消回复
派聪明 2026年08月02日 20:38
我有几个问题:1.为什么用 DAG!2.有没有那种就是会存在循环依赖的任务还能采用DAG。****** 算法 vs DFS 你怎么选 4.如果有几千https://paicoding.com/logout个任务怎么优化! 当前模型还在开发当中,请右上角下拉框切换到其他模型
点赞
回复 取消回复
Kal-El 2026年07月31日 09:17
引用原文:规划一次,执行多次
planner规划调用一次 每个任务都是一个小的React也得调用LLM 并没有减少反而增加了
点赞
回复 取消回复
Qy 2026年07月30日 14:19
@派聪明 plan-and-execute中 创建计划后任务的执行不也是每次都要调用LLM吗 为什么说相比react一个只调用一次LLM一个是多次?
点赞
回复1 取消回复
派聪明 2026年07月30日 14:19
plan-and-execute中 创建计划后任务的执行不也是每次都要调用LLM 为什么说相比react一个只调用一次LLM一个是多次! 当前模型还在开发当中,请右上角下拉框切换到其他模型
点赞
回复 取消回复
17377927899 2026年07月25日 15:40
引用原文:两种模式各有优劣,适用场景不同。 特性 ReAct Plan-and-Execute LLM 调用次数 多(每步都调) 少(只调规划) 执行速度 慢(网络往返多) 快(本地执行多) Token 消耗 高 低 灵活性 高(随时调整) 低(按 plan 执行) 可预测性 低 高 错误恢复 容易(随时改) 需要重规划 适用场景 简单/探索性任务 复杂/确定性任务
@派聪明 这里提到Plan-and-Execute只有规划时调LLM,不对吧,执行任务时也要调LLM
点赞
回复1 取消回复
派聪明 2026年07月25日 15:40
小派正在努力回答中, 耐心等待一下吧...
点赞
回复 取消回复
东呆西萌 2026年07月13日 16:32
引用原文:Task 类设计
@派聪明 在 Plan-and-Execute 中,执行每一个任务时,虽然是在本地上执行的,但是在这个任务类里面并没有记录完成当前任务所需要的工具,如果执行任务的过程中需要使用tool,不是还要调用大模型吗?所以我不太理解为什么会说Plan-and-Execute只需要调用一次大模型,并且这还是它相较于ReAct的优势
点赞
回复11 取消回复
派聪明 2026年07月13日 16:32
你这个问题问得非常准,说明你对 Agent 的工作原理思考得很深入。我来帮你把这个模糊地带彻底理清。 --- ## 核心误解:「只调一次 LLM」指的是「推理层」,不是「工具执行层」 在 Plan-and-Execute 中,**「只调一次 LLM」的意思是:只调用一次 LLM 来进行「决策/推理」**,而不是说整个过程完全不用 LLM。 ### 关键区分:工具执行 vs. 决策推理 | 环节 | ReAct | Plan-and-Execute | |------|-------|------------------| | **决策/推理**(下一步做什么) | 每步都调 LLM | **只调一次**(规划阶段) | | **工具执行**(读写文件、跑命令) | 代码执行 | 代码执行(两者一样) | ### 为什么 ReAct 需要多次调 LLM? ReAct 的模式是:「思考→行动→观察→再思考→再行动→…」 ``` LLM思考:"我需要创建一个Java项目" → 调用工具创建项目(代码执行) → 把结果返给LLM → LLM再思考:"现在要写Hello类" → 调用工具写文件(代码执行) → 再把结果返给LLM → ... ``` **每一轮「思考」都要调用一次 LLM**,这是最耗时的部分(网络往返 + 大模型推理)。 ### Plan-and-Execute 省掉的是什么? 计划阶段,LLM 一次性输出了完整的任务清单: ``` task1: "创建一个Java项目叫demo" → 工具:COMMAND("mvn archetype:generate ...") task2: "写一个Hello类" → 工具:FILE_WRITE("src/main/java/Hello.java", 内容) task3: "编译运行" → 工具:COMMAND("mvn compile && java Hello") ``` **执行阶段**,每个任务对应的工具调用是预先确定的、**写死在任务描述里的**,代码直接按计划执行工具,不需要再问 LLM: ```java // 伪代码 - 执行器直接按计划做事,不调LLM if (task.getType() == COMMAND) { Runtime.exec(task.getDescription()); // 直接执行命令 } if (task.getType() == FILE_WRITE) { Files.write(路径, 内容); // 直接写文件 } ``` **没有「思考」环节,只有「机械执行」**。这就是省掉 LLM 调用的地方。 --- ## 那你说的「执行中需要 tool 怎么办?」 你担心的其实是:**如果工具执行的结果需要分析/决策,不还是得调 LLM 吗?** 对的,这时确实需要。但参考资料已经给出了解决方案: ### 1. 把「分析/决策」也建模成一个任务 ``` task5 (ANALYSIS类型): "分析编译输出,判断是否成功" ``` 这个任务内部**可以调 LLM**。但整个计划里只有这一个分析任务需要 LLM,而不是每一步都要。 ### 2. 失败时重新规划 如果某个任务失败,触发 `replan()`,基于已完成进度重新规划一次——**又是一次 LLM 调用,但不是每步都调**。 ### 3. 混合模式(最实用的方案) 参考资料最后也说了: > 用 Plan-and-Execute 制定整体计划 > 每个任务内部用 ReAct 执行 > 如果某步失败,用 ReAct 分析原因 也就是说,**宏观上 Plan-and-Execute 节省了大部分「无用思考」的 LLM 调用**,但对于真正需要分析决策的步骤,仍然可以调 LLM。 --- ## 用数字对比一下更直观 **场景:创建一个 Spring Boot 项目 + 写 REST API + 编译运行** | 模式 | LLM 调用次数 | 耗时大头 | |------|-------------|---------| | 纯 ReAct | **5 次**(每次都要网络往返) | 等待 LLM 响应 | | Plan-and-Execute | **1 次**(规划) + 可能 1 次(分析结果) | 本地执行 | 所以「只调一次大模型」是**相对于 ReAct 每步都调而言的**,不是说工具执行不需要调 LLM——工具执行本来就不需要调 LLM,它只是本地代码执行。**省掉的是那些「无意义的中间思考轮次」**。
点赞
回复 取消回复
展开剩余 10 条回复
etovo 2026年07月09日 15:16
引用原文:并行执行可能会遇到这样的问题
@派聪明 所以这些问题怎么解决
点赞
回复1 取消回复
派聪明 2026年07月09日 15:17
根据参考资料,文章在提出这些问题后,表示**"我们已经实现了哈"**,但没有展开详细说明每个问题的具体解决方案。不过,基于该项目的架构设计,可以合理推导出解决思路: --- ### 1️⃣ 资源冲突(同时写同一文件) 解决方案:**依赖管理 + 文件锁** - 在 DAG 建模阶段,如果两个任务需要写同一个文件,规划器应在 dependencies 中声明依赖关系(比如 `task_B` 依赖 `task_A`),使它们**不会并行执行**。 - 结合拓扑排序算法,依赖同一资源的任务会被自动安排到不同的执行批次中。 ### 2️⃣ 输出混乱(日志混在一起) 解决方案:**任务级日志隔离 + 统一收集** - 每个 `Task` 对象有自己的 `startTime`、`endTime`、`result`、`error` 字段。 - 并行执行时,可以为每个任务添加**唯一前缀标识**(如 `[task_1] 创建项目`、`[task_3] 写 README`),待全部完成后按任务 ID 归并输出。 - 运行截图中也展示了每条日志前有任务编号,说明已实现输出隔离。 ### 3️⃣ 错误处理复杂(一个失败,其他的怎么办) 解决方案:**CompletableFuture + 任务状态传播** 文章中使用了: ```java CompletableFuture.allOf(futures.toArray(...)).join(); ``` 这意味着: - 如果一个并行任务失败,会抛出异常,其他任务可以通过 `completeExceptionally` 或检查 `TaskStatus.FAILED` 来感知。 - 依赖该失败任务的后续任务会自动变为 `SKIPPED`(跳过),避免连锁错误。 - 也可以通过 `replan()` 方法,基于已完成的任务重新规划剩余步骤。 --- > ⚠️ 需要说明的是,文章并未给出这三个问题的**完整代码实现**,仅用"我们已经实现了哈"一笔带过。如果你正在实现类似功能,建议参考上述思路自行补充。
点赞
回复 取消回复
挽风 2026年07月07日 22:03
引用原文:算法
@派聪明 这里还需要反转吗?拓扑排序的结果不就应该是执行顺序吗 Collections.reverse(executionOrder);
点赞
回复1 取消回复
派聪明 2026年07月07日 22:04
你观察得非常仔细!**这段代码确实存在问题**——这里的 `Collections.reverse(executionOrder)` 是多余的,甚至会导致执行顺序错误。 ## 原因分析 看代码中的 DFS 拓扑排序逻辑: ```java // 递归处理所有依赖(先处理被依赖的任务) for (String depId : task.getDependencies()) { // ...递归调用 topologicalSort(dep, ...) } // 后序加入:等所有依赖处理完,再把当前任务加入列表 executionOrder.add(id); ``` 假设任务依赖链:task1(无依赖)→ task2(依赖 task1)→ task3(依赖 task2) DFS 从 task3 开始: 1. 递归处理依赖 task2 2. 递归处理 task2 的依赖 task1 3. **task1 加入** → `[task1]` 4. 回到 task2,**task2 加入** → `[task1, task2]` 5. 回到 task3,**task3 加入** → `[task1, task2, task3]` 结果 `[task1, task2, task3]` **已经是正确的执行顺序**(依赖先执行)。如果此时再 `reverse`,会变成 `[task3, task2, task1]`,**反而错了**——task3 依赖 task2,怎么能先执行? ## 可能的原因 这段代码可能是把**两种拓扑排序实现**搞混了: | 实现方式 | 结果 | 需要反转? | |---------|------|-----------| | **入度表法**(Kahn算法) | 正拓扑序 | ❌ 不需要 | | **DFS后序法**(依赖先入) | 正拓扑序 | ❌ 不需要 | | **DFS后序法**(出边先入) | 逆拓扑序 | ✅ 需要反转 | 参考资料用的是"递归处理依赖"(入边方向),后序结果就是正序,**不该反转**。你发现的这个 bug 是对的 🎯
点赞
回复 取消回复

目录