杠精派
派聪明
0/512

热门评论

东呆西萌 2026年07月20日 17:15
引用原文:六种消息类型:TASK(任务)、RESULT(结果)、FEEDBACK(反馈)、APPROVAL(通过)、REJECTION(拒绝)、ERROR(错误)。
@派聪明 我的问题是每种消息类型都对应着谁到谁的过程
点赞
回复5 取消回复
派聪明 2026年07月20日 17:16
根据文章中 PaiCLI 的 Multi-Agent 设计(主从架构 + 三角色分工),六种消息类型对应的发送方和接收方如下: | 消息类型 | 发送方 → 接收方 | 场景说明 | |---------|---------------|---------| | **TASK(任务)** | **编排器 → 子Agent** | 编排器给规划者发"拆解任务"、给执行者发"执行步骤"、给检查者发"审查结果" | | **RESULT(结果)** | **子Agent → 编排器** | 规划者返回执行计划、执行者返回操作结果、检查者返回审查结论 | | **FEEDBACK(反馈)** | **检查者 → 编排器 → 执行者** | 审查不通过时,检查者给出问题列表和改进建议,编排器将反馈注入上下文让执行者重试 | | **APPROVAL(通过)** | **检查者 → 编排器** | 审查通过,`approved: true`,编排器标记该步骤为 COMPLETED | | **REJECTION(拒绝)** | **检查者 → 编排器** | 审查不通过,`approved: false`,编排器触发重试机制(最多2次) | | **ERROR(错误)** | **任意Agent → 编排器** | 执行过程中出现异常,编排器进行异常处理或终止流程 | **核心规律**:所有消息都经过编排器路由(主从模式),子Agent之间不直接通信。**TASK 是向下分发的指令,其他五种都是向上返回的状态/结果。**
点赞
回复 取消回复
展开剩余 4 条回复

46 条评论

精明的柚子 2026年08月03日 20:28
引用原文:第二阶段
@派聪明 为什么不直接让LLM输出任务列表,而是输出JSON,再由编排器把 JSON 解析成 ExecutionStep 列表?
点赞
回复1 取消回复
派聪明 2026年08月03日 20:28
小派正在努力回答中, 耐心等待一下吧...
点赞
回复 取消回复
英年早困 2026年07月24日 18:26
引用原文:超过 2 次还不过,就保留当前结果,不再死磕。
@派聪明 那如果放过去了了错误的代码怎么办
点赞
回复1 取消回复
派聪明 2026年07月24日 18:26
其实你的担忧非常合理,放行错误代码确实会带来风险。根据参考资料,系统为了尽量避免这种情况,设计了多层保护机制: 1. **宁可错杀,不可放过(保守策略)**:当检查者(Reviewer)的审查结果无法解析、或 JSON 格式异常时,系统**默认判定为“不通过”**。因为放行错误代码的代价远大于让正确代码多重试一次的代价。 2. **人机协同提示**:如果步骤超过2次重试仍未通过,系统会**显式提示用户**这些步骤被跳过或保留了当前结果,并不会偷偷掩盖错误,用户可以直接介入检查。 3. **强制的上下文传递**:Worker执行当前步骤时,编排器会强行注入前置依赖步骤的结果(截断保留前500 字符)。如果前面的步骤真的放行了错误代码,后续步骤在执行和接受二次审查时,极大概率会因为上下文矛盾、跑不通而报错,从而在后续节点拦截错误。 总而言之,如果2次重试后强行放行,系统会明确告诉你“这里有问题”,并寄希望于后续的测试/验证步骤把它卡住。此外,在实际工程中,开发者也可以通过调大 `MAX_RETRIES_PER_STEP`(最大重试次数)来进一步降低这种极端情况发生的概率。
点赞
回复 取消回复
英年早困 2026年07月24日 17:59
引用原文:SubAgent 是轻量级的 Agent 实现,每个实例有独立的角色、系统提示词和对话历史。但它不独占 LLM 客户端和工具注册表——这些是共享的,避免每个子 Agent 都重新初始化一份。 最关键的设计是三套系统提示词。不同角色的提示词完全不同,决定了它们的行为模式。
@派聪明 这些子agent的底层是是去调用llm做规划,执行和检查吗
点赞
回复1 取消回复
派聪明 2026年07月24日 18:00
**是的,这些子Agent的底层完全依赖调用LLM来完成任务,但它们的分工有严格的区别。**根据参考资料,底层具体逻辑如下: **1.核心依赖 LLM 与共享机制** 所有的子 Agent 共享同一个大语言模型(LLM)客户端和工具注册表。它们作为轻量级实例,底层通过 LLM 配合各自专属的“系统提示词”来开展工作。 **2. 各角色调用 LLM 的具体方式不同** * **规划者**:调用 LLM 进行任务分析,将其拆解为具体的执行步骤,并输出 JSON 格式的执行计划。**它纯粹依靠 LLM思考,不调用任何工具。** * **执行者**:调用 LLM 进行逻辑分析与判断,并**由 LLM决定如何调用外部工具**(如读写文件、执行命令、搜索代码等)来真正落实操作。它是唯一实际干活的角色。 * **检查者**:调用 LLM 对执行者的产出进行质量评估,判断是否符合要求。同样,它**只做纯文本/JSON 的分析判断,不调用工具**。 **总结来说**,子 Agent 的底层确实是调用 LLM,但通过限制工具调用权限(只有 Worker 能用工具)和注入不同的系统提示词,控制了 LLM 在不同阶段只发挥“规划”、“执行”或“审查”的单一能力,从而实现了各司其职。
点赞
回复 取消回复
英年早困 2026年07月24日 16:07
引用原文:为什么选主从而不是对等模式? 因为对等模式下 Agent 之间需要直接通信
@派聪明 对等模式和主从模式的区别在哪里,为什么对等模式下agent之间需要通讯,这样有什么坏处么
点赞
回复1 取消回复
派聪明 2026年07月24日 16:07
根据提供的参考资料,对等模式和主从模式的区别,以及对等模式直接通信带来的坏处如下: **1. 两者的核心区别在于“协调逻辑”的位置不同:** * **主从模式(Orchestrator-SubAgent)**:有一个专门的“编排器”作为中枢,负责统一的任务分发和流程控制。子Agent之间**不直接对话**,所有消息都必须经过编排器进行路由。 * **对等模式**:没有绝对的中心控制节点,各个Agent处于平等地位,Agent与Agent之间需要**直接进行通信**来协商和推进任务。 **2. 对等模式下Agent为什么需要直接通信?** 在对等架构中,由于缺乏一个统一调度的“指挥官”,Agent们必须依靠互相直接交换信息、发起询问或确认,才能协同完成任务和推进流程。 **3. 对等模式直接通信的坏处:** 主要在于**系统复杂度急剧上升**,具体表现为: * **结构混乱**:每个Agent都要处理与其他多个Agent的通信逻辑,导致通信网状交织,整体架构变得复杂。 * **调试困难**:因为没有中心节点统一记录和流转状态,消息流向难以追踪,一旦协作过程出错,排查和调试问题的难度非常大。 相比之下,文章选择主从模式正是因为它把协调逻辑集中化,从而做到了“结构清晰,调试方便”。
点赞
回复 取消回复
枫原万叶 2026年07月21日 16:34
引用原文:我们的 PaiCLI Agent 已经实现了 ReAct、Plan-and-Execute、Memory、RAG,一个单 Agent 已经能读文件、跑命令、搜代码、记住上下文了。 但我们还想要更多。 OK,今天我们就来完成 Multi-Agent,把一个全能型 Agent 拆成多个专职角色,让它们协作完成任务。
@派聪明 多智能体中的每一个子智能体都是调用的同一个api吗?这种多智能体协作模仿跟之前的Plan-and-Execute模式有什么异同点?
点赞
回复1 取消回复
派聪明 2026年07月21日 16:34
## 1. 多智能体中的子智能体是否调用同一个API? **是的,所有子智能体共享同一个 LLM 客户端。** 从参考资料中的代码可以看到: ```java public AgentOrchestrator(GLMClient llmClient, ToolRegistry toolRegistry, MemoryManager memoryManager) { this.llmClient = llmClient; // ... this.planner = new SubAgent("planner", AgentRole.PLANNER, llmClient, toolRegistry); this.workers = List.of( new SubAgent("worker-1", AgentRole.WORKER, llmClient, toolRegistry), new SubAgent("worker-2", AgentRole.WORKER, llmClient, toolRegistry) ); this.reviewer = new SubAgent("reviewer", AgentRole.REVIEWER, llmClient, toolRegistry); } ``` 所有 SubAgent 共享同一个 `GLMClient` 实例,**调用的是同一个 API**。区别在于 **系统提示词不同**,决定了它们的行为模式: - **规划者**:被约束只输出 JSON 格式的执行计划 - **执行者**:被告知可用工具及使用优先级 - **检查者**:被约束输出审批结果 JSON 以及 **是否允许调用工具**,只有执行者角色才会调用工具(`shouldUseTools()` 控制)。 --- ## 2. 与 Plan-and-Execute 模式的异同点 ### 相同点 | 维度 | 说明 | |------|------| | **规划+执行** | 两者都有「规划者拆解任务 → 执行者干活」的流程 | | **依赖管理** | 都有步骤间的依赖关系判定(`dependencies`),按顺序推进 | | **适用场景** | 都适合多步骤、有依赖关系的复杂任务 | ### 核心差异 | 维度 | Plan-and-Execute | Multi-Agent | |------|-----------------|-------------| | **角色数量** | 2 个(规划者 + 执行者) | 3 个(规划者 + 执行者 + **检查者**) | | **审查机制** | ❌ 无审查,执行完直接返回 | ✅ 每步执行后由检查者验收,不通过则带反馈重试(最多重试 2 次) | | **并行执行** | 串行居多 | 支持 `BlockingQueue + ExecutorService` 实现**无依赖步骤并行执行** | | **反馈闭环** | 无 | 检查者给出具体问题列表和改进建议,注入上下文让执行者重试 | | **容错能力** | 弱,执行出错直接失败 | 强,审查不通过可重试,且采用**保守策略**(无法解析时默认不通过) | | **代码复杂度** | 低 | 较高,需要编排器管理消息路由、重试逻辑、Worker 池 | ### 一句话总结 > **Plan-and-Execute** 是「规划 → 干活 → 完事」的线性流程,而 **Multi-Agent** 在此基础上引入了**检查者角色**,形成了「规划 → 干活 → 检查 → 通过/打回重干」的闭合反馈回路,同时支持**并行执行**,更适合对结果质量有要求的场景。
点赞
回复 取消回复
枫原万叶 2026年07月21日 16:07
引用原文:因为每个步骤是独立的任务,上一步的对话上下文对下一步没有帮助,反而会干扰模型判断。 保留系统提示词就够了——角色设定不能丢。 编排器在每步执行完后都会调用 worker.clearHistory() 和 reviewer.clearHistory(),确保每步都是干净的状态。
@派聪明 这里是说规划者规划的子任务在完成后就会清空子智能体的对话历史吗?还是用户的整个需求完成后才清空每个子智能体的对话历史
点赞
回复1 取消回复
派聪明 2026年07月21日 16:08
根据你提供的参考资料,答案是:**每个子任务(步骤)完成后**就会清空子Agent的对话历史,而不是等用户的整个需求全部完成后再清空。 文中明确说明: 1. **"每个 SubAgent 维护独立的对话历史,但每处理完一个独立任务后会清空历史(保留系统提示词)"**——这里"独立任务"就是指规划者拆解出的一个个执行步骤(step_1、step_2、step_3……)。 2. **"编排器在每步执行完后都会调用 `worker.clearHistory()` 和 `reviewer.clearHistory()`,确保每步都是干净的状态。**"——编排器在每一步执行并审查通过后,就会立刻清空 Worker 和 Reviewer 的历史。 这样设计的理由是文中提到的:**"因为每个步骤是独立的任务,上一步的对话上下文对下一步没有帮助,反而会干扰模型判断。"** 所以流程是这样的: ``` 用户提出需求 → 规划者拆成 step_1、step_2、step_3 ↓ step_1 执行 → 审查通过 → 清空 Worker 和 Reviewer 的对话历史 ↓ step_2 执行 → 审查通过 → 清空 Worker 和 Reviewer 的对话历史 ↓ step_3 执行 → 审查通过 → 清空 Worker 和 Reviewer 的对话历史 ↓ 所有步骤完成 → 编排器汇总结果返回用户 ``` 每步一清,只保留系统提示词(角色设定)。**规划者(Planner)** 的对话历史文中没有明确说在每步后清空,因为规划者只在第一阶段工作一次,后续不再参与。
点赞
回复 取消回复
挽风 2026年07月20日 20:47
引用原文:PLANNER、WORKER、REVIEWER
@派聪明 规划者、执行者和检查者都是子Agent,那编排者是谁
点赞
回复1 取消回复
派聪明 2026年07月20日 20:47
根据参考资料,编排者(Orchestrator)就是 **`AgentOrchestrator`**,它是整个 Multi-Agent 系统的 **核心指挥官**,并不属于子 Agent。 具体来说,架构中的角色分工如下: | 角色 | 类名 | 定位 | |------|------|------| | **编排者** | `AgentOrchestrator.java` | **主**(指挥官),不是子 Agent | | 规划者 | `SubAgent` (role=PLANNER) | **从**(子 Agent) | | 执行者 | `SubAgent` (role=WORKER) | **从**(子 Agent) | | 检查者 | `SubAgent` (role=REVIEWER) | **从**(子 Agent) | **编排者(编排器)负责的六阶段工作流:** 1. **规划阶段** → 把用户任务交给规划者,让规划者输出 JSON 格式的执行计划 2. **解析计划** → 把 JSON 解析成 `ExecutionStep` 列表,建立步骤间的依赖关系 3. **执行阶段** → 按依赖顺序,把可执行的步骤分配给 Worker(支持并行) 4. **审查阶段** → 每步执行完后交给检查者验收,通过就放行,不通过就反馈重试 5. **处理残留** → 如果某步失败导致后续依赖步骤无法执行,显式提示用户 6. **汇总结果** → 把所有步骤的状态和结果汇总,写入记忆,返回给用户 正如参考资料所说:**"编排器拿着任务找规划者拆、找执行者干、找检查者验,全部通过后汇总结果返回给用户。"** 它是主从架构中的 **"主"**,子 Agent 之间不直接对话,所有消息都经过编排器路由。
点赞
回复 取消回复
东呆西萌 2026年07月20日 17:15
引用原文:六种消息类型:TASK(任务)、RESULT(结果)、FEEDBACK(反馈)、APPROVAL(通过)、REJECTION(拒绝)、ERROR(错误)。
@派聪明 我的问题是每种消息类型都对应着谁到谁的过程
点赞
回复5 取消回复
派聪明 2026年07月20日 17:16
根据文章中 PaiCLI 的 Multi-Agent 设计(主从架构 + 三角色分工),六种消息类型对应的发送方和接收方如下: | 消息类型 | 发送方 → 接收方 | 场景说明 | |---------|---------------|---------| | **TASK(任务)** | **编排器 → 子Agent** | 编排器给规划者发"拆解任务"、给执行者发"执行步骤"、给检查者发"审查结果" | | **RESULT(结果)** | **子Agent → 编排器** | 规划者返回执行计划、执行者返回操作结果、检查者返回审查结论 | | **FEEDBACK(反馈)** | **检查者 → 编排器 → 执行者** | 审查不通过时,检查者给出问题列表和改进建议,编排器将反馈注入上下文让执行者重试 | | **APPROVAL(通过)** | **检查者 → 编排器** | 审查通过,`approved: true`,编排器标记该步骤为 COMPLETED | | **REJECTION(拒绝)** | **检查者 → 编排器** | 审查不通过,`approved: false`,编排器触发重试机制(最多2次) | | **ERROR(错误)** | **任意Agent → 编排器** | 执行过程中出现异常,编排器进行异常处理或终止流程 | **核心规律**:所有消息都经过编排器路由(主从模式),子Agent之间不直接通信。**TASK 是向下分发的指令,其他五种都是向上返回的状态/结果。**
点赞
回复 取消回复
展开剩余 4 条回复
东呆西萌 2026年07月20日 17:12
@派聪明 approvedNode.asBoolean(false); 是什么意思?
点赞
回复1 取消回复
派聪明 2026年07月20日 17:12
`approvedNode.asBoolean(false)` 是 Java 中 **Jackson 库**(JSON 解析库)提供的一个方法调用,它的含义是: ### 1. 基本作用 - `approvedNode` 是一个 `JsonNode` 对象,它代表 JSON 数据中的一个节点(这里对应检查者输出的 `approved` 字段)。 - `asBoolean(false)` 尝试把这个节点的值**转为布尔类型**,如果转换失败则返回**默认值 `false`**。 ### 2. 行为细节 | 场景 | 返回值 | |------|--------| | 节点值为 `true` | `true` | | 节点值为 `false` | `false` | | 节点为 `null` | `false`(默认值) | | 节点不存在/缺失 | `false`(默认值) | | 节点值不是布尔(如字符串) | `false`(默认值) | ### 3. 结合你的代码 ```java return approvedNode.asBoolean(false); ``` 结合参考资料中提到的 **保守策略**: > 当检查者的输出无法解析时,默认为"不通过" `asBoolean(false)` 中的 `false` 就是那个保守默认值——只有在 `approved` 字段**明确为 `true`** 时才放行,其他任何情况(缺失、null、非布尔、false)都视为不通过。这样可以**防止错误代码被放过**,宁可多审一次,也不放过一个问题。
点赞
回复 取消回复
贪玩的月亮 2026年07月17日 16:41
引用原文:这样 Worker 就知道前面几步干了什么、产出了什么,不用猜
@派聪明 但是前面不是说编排器在每步执行完后都会调用 worker.clearHistory() 和 reviewer.clearHistory(),确保每步都是干净的状态吗?
点赞
回复1 取消回复
派聪明 2026年07月17日 16:41
这个看起来矛盾的地方,其实涉及两个**不同维度**的机制,我来帮你拆解清楚: --- **1. `clearHistory()` 清的是什么?** 清的是 **Agent 内部的对话历史(`conversationHistory`)**,也就是 LLM 多轮对话的 messages 列表。目的是防止**上一步的完整对话记录**干扰下一步的推理——比如上一步 Worker 和 Reviewer 来回沟通了好几次,这些对话细节对下一步毫无帮助,反而会让 Agent 混乱。 **2. “注入已完成的依赖步骤的上下文”做的又是什么?** 这是通过 **`buildStepContext()` 方法**,在**执行当前步骤之前**,把已完成依赖步骤的**结果摘要**(截断到 500 字符)以**纯文本形式注入到当前步骤的 prompt 里**。 比如 step_2 依赖 step_1,编排器在派 step_2 给 Worker 时,会在消息里附上: ``` 已完成的依赖步骤 [step_1]: 创建 demoapp 项目结构 结果:项目已创建,目录结构为 src/main/java/... 和 pom.xml... ``` --- **一句话总结两者的关系:** | 机制 | 清什么 | 什么时候做 | 目的是 | |------|--------|-----------|--------| | `clearHistory()` | 清**对话 messages 记录** | 每步**执行完后** | 避免上一步的完整对话干扰下一步 | | `buildStepContext()` | **注入依赖步骤的摘要信息** | 每步**执行前** | 让 Worker 知道前一步产出了什么 | 所以实际流程是:**执行前注入关键摘要信息 → Worker 执行 → 执行后清空对话历史(保留关键摘要已在这次对话中,下次再注入新的)**。两者分工明确,并不矛盾。
点赞
回复 取消回复

目录