【AgentScope Java新手村系列】(12)计划模式

简介: 计划模式 — enablePlanMode() 让 LLM 强制先写计划再执行,内置 plan_enter/write/exit 与 todo_write 工具。

第十二章 计划模式:enablePlanMode() 让 LLM 先写计划再执行,支持中途改计划

"用户让 agent 调研 5 件事。1.x 时代我们用 PlanNotebook 让 agent 自己写计划;2.0 把这个能力下沉到 HarnessAgent.enablePlanMode(),多了 plan_enter / plan_write / plan_exit / todo_write 一套内置工具——LLM 在 plan 模式下会强制先写计划再执行。"

本章你将学到:如何开启 plan mode、4 个内置工具各自做什么、怎么让用户中途改计划、以及 plan 与 subagent 的协作。

12.1 Plan 模式解决了什么问题?

没有 plan 模式时,agent 收到一个复杂任务(比如"给我从零搭一个用户认证系统")后,ReAct 循环是:

思考 → 调工具 → 看结果 → 思考 → 调工具 → 看结果 → ...

每一步都是临场判断。这会导致三个问题:

风险 例子
跳过关键步骤 先写代码再想数据库表结构,改四五轮
做多余的事 用户只要登录,agent 把 OAuth2.0、SAML、FIDO 全实现了
人无法中途介入 agent 一口气跑到底,发现方向错了已经晚了——之前的所有操作都是破坏性的

Plan 模式把一次复杂任务拆成两个阶段

PLAN 阶段(只读)                  BUILD 阶段(执行)
───────────────────              ─────────────────
agent 看文件、调研项目现状          agent 按 plans/PLAN.md 一步步做
agent 把计划写入 plans/PLAN.md       每条做完勾掉 todo
⚠ 此时所有非只读工具被阻止          限制解除,可以写文件、调 API、部署
                                                  │
    人看完 PLAN.md 说"行" ──────→ 放行              │
    人看完 PLAN.md 说"不行,改" → agent 用 plan_write 修订
    人看完 PLAN.md 说"别做了" ──→ 止损,零破坏

核心思想:让人在 agent 动手之前有"一票否决权"。 这就像装修队先出图纸给你审,审过了再砸墙布线——而不是一进门就开始砸。

对于"今天天气怎么样"这种单步任务,plan 模式毫无意义。对于"从零搭建一个项目"、"同时调研 5 件事"、"批量重构代码"这类多步任务,plan 模式是防止 agent 跑偏的最后一道防线。

12.2 1.x PlanNotebook → 2.0 plan mode

1.x 的 PlanNotebook 是一个"让 agent 写计划的笔记本"对象,业务方需要:

  • 手动 notebook.createPlan(...)
  • 写自己的 ReActAgent 适配层让 agent 知道有 PlanNotebook
  • 计划改起来需要主动调用

2.0 把"写计划"做成 agent 运行模式之一:

  • enablePlanMode(true) 一行开启
  • 内置 4 个工具:plan_enter / plan_write / plan_exit / todo_write
  • PlanModeMiddleware 在 PLAN 阶段拦截所有非只读工具调用,返回 DENIED
  • LLM 调了 plan_enter 才进入只读阶段,调了 plan_exit 才恢复执行能力
  • 计划文件落在 workspace/plans/PLAN.md,可读、可改、可被 git 管理

⚠️ 2.0 重大变更

1.x 的 io.agentscope.core.plan.PlanNotebook 在 2.0 中被移除。本章 12.8 给出从 PlanNotebook 到 plan mode 的最小迁移。

12.3 第一个 plan mode 例子

import io.agentscope.core.agent.RuntimeContext;
import io.agentscope.core.message.UserMessage;
import io.agentscope.core.model.DashScopeChatModel;
import io.agentscope.harness.HarnessAgent;

import java.nio.file.Path;
import java.util.List;

public class Chapter12_PlanMode {
   

    public static void main(String[] args) {
   
        HarnessAgent agent = HarnessAgent.builder()
                .name("project_planner")
                .sysPrompt("你是一个项目经理,会用 plan mode 写计划。")
                .model(DashScopeChatModel.builder()
                        .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                        .modelName("qwen-plus")
                        .build())
                .workspace(Path.of("./workspace"))
                .enablePlanMode(true)        // 开启 plan mode
                .build();

        agent.call(
                List.of(new UserMessage("user", """
                        我下周要办一场 200 人技术大会,请帮我做一份执行计划:
                        - 场地
                        - 议程
                        - 嘉宾
                        - 报名
                        - 现场
                        """)),
                RuntimeContext.empty())
                .block();

        // 跑完看 workspace/plans/PLAN.md —— agent 把计划写在这里
    }
}

跑完 workspace/plans/PLAN.md 大致是:

# 大会执行计划(2026-06-15)

## Step 1 — 锁定场地
- 目标:杭州某酒店宴会厅
- 负责:行政
- 完成标准:拿到合同 + 付款凭证

## Step 2 — 公布议程
- 目标:议程在官网公开
- 依赖:Step 1

... (后续 4 步)

12.4 四个内置 plan 工具

工具 何时被调用 副作用
plan_enter agent 决定"这是个多步任务" 写入 workspace/plans/PLAN.md 头部,进入 plan 模式
plan_write 写或修订 PLAN.md 里的步骤 修改 workspace/plans/PLAN.md
plan_exit agent 完成所有计划步骤 PLAN.md 收尾,更新状态为 DONE
todo_write 任何时候记录子任务 写入 AgentState 的 todo 列表,配合 Session 持久化

todo_write 严格说不是"plan 工具",而是"todo 工具"——但 plan mode 下两者是配对的:plan 管"长期大计划",todo 管"短期可勾掉的清单"。

12.5 用户中途改计划

workspace/plans/PLAN.md 是普通 Markdown,agent 在每轮推理时都会读一遍当前 PLAN.md。这意味着:

用户:把 step 3 的'嘉宾'改成都用远程连线的形式。

agent:
  1. 读当前 PLAN.md
  2. 调用 plan_write 改 step 3
  3. 输出确认

人也可以直接编辑 PLAN.md——下一轮 agent 看到的是人编辑后的版本。

12.6 plan + subagent 协作

enablePlanMode() 不影响 subagent 调度——agent_spawn / agent_send / agent_list 仍然可用。一个常见模式:

主 agent 拿到任务:
1. plan_enter,写下 5 步
2. 第 1 步:spawn subagent A(同步)
3. 第 2 步:spawn subagent B(同步)
4. 第 3、4 步:async spawn C、D
5. todo_write 跟踪
6. 等 C、D 回来,todo 勾掉
7. plan_exit

HarnessAgent.builder().enablePlanMode(true) + 多个 subagent 一起用,是 2.0 推荐的中型工作流模式。

12.7 plan 模式的"自动门控"

Plan mode 下,prompt 里强制设定了“agent 在写完 plan 之前不会调用任何业务工具”的规则。这是 2.0 优于 1.x 的安全设计:

  • 1.x:LLM 可能跳过 PlanNotebook 直接动手做事。
  • 2.0:plan mode 下必须先 plan_enter,用户可以在 plan 阶段介入。

如果你想"先看 plan 再放行"——给 plan_enter 配一个 Permission 规则 ASK

import io.agentscope.core.permission.*;

PermissionContextState perms = PermissionContextState.builder()
        .mode(PermissionMode.ACCEPT_EDITS)
        .addAskRule("plan_enter",
                new PermissionRule("plan_enter", null, PermissionBehavior.ASK, "userSettings"))
        .build();

这样每次 plan_enter 时前端会弹出"agent 写了如下 plan,是否放行?",体现了HITL 模式(Human In The Loop)。

12.8 最小迁移清单(1.x PlanNotebook → 2.0 plan mode)

1.x 用法 2.0 等价
PlanNotebook.createPlan(...) enablePlanMode(true) + LLM 自己调 plan_enter
notebook.addStep(...) plan_write
notebook.finishStep(idx) plan_write 改对应 step 状态
notebook.getCurrentPlan() workspace/plans/PLAN.md
业务方主动调 notebook.xxx LLM 在 plan mode 下自动调

12.9 完整可运行示例

public class Chapter12_PlanWithSubagent {
   

    public static void main(String[] args) {
   
        DashScopeChatModel model = DashScopeChatModel.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .modelName("qwen-plus")
                .build();

        SubagentDeclaration research = SubagentDeclaration.builder()
                .name("research")
                .description("做单点调研;输入主题,输出 200 字摘要")
                .inlineAgentsBody("你是一个研究员,每主题输出 200 字摘要。")
                .build();

        HarnessAgent agent = HarnessAgent.builder()
                .name("research_lead")
                .sysPrompt("""
                        你是一个研究主管。接到多主题调研任务时:
                        1. 先 plan_enter 写出计划
                        2. 对每个主题 async spawn research subagent
                        3. 用 todo_write 跟踪每个 subagent 的状态
                        4. 等所有 subagent 回来后 plan_exit
                        """)
                .model(model)
                .workspace(Path.of("./workspace"))
                .subagent(research)
                .enablePlanMode(true)
                .build();

        agent.call(
                List.of(new UserMessage("user", """
                        请调研以下 3 个主题:
                        1. 杭州咖啡店数量
                        2. 上海咖啡店数量
                        3. 成都咖啡店数量
                        """)),
                RuntimeContext.empty())
                .block();
    }
}

跑完你会看到:

workspace/
├── plans/
│   └── PLAN.md          # 3 步计划
└── state/
    └── session-*.json   # 包含 todo 列表

12.10 本章小结

  • HarnessAgent.enablePlanMode(true) 开启 plan mode,强制 agent 先 plan 再 act。
  • 4 个内置工具:plan_enter / plan_write / plan_exit / todo_write
  • workspace/plans/PLAN.md 是普通 Markdown,可以被人编辑、git 管理。
  • plan mode 不影响 subagent:可以一边写计划一边 spawn。
  • Permission 规则可以让用户在 plan_enter 时介入。
目录
相关文章
|
前端开发 NoSQL Java
【AgentScope Java新手村系列】(2)第一个Agent-基础对话
第一个Agent-基础对话 — 演示 HarnessAgent 的 Builder 模式创建、ReAct 推理循环、流式事件与思考模式三个核心能力。
478 2
|
前端开发 Java 中间件
【AgentScope Java新手村系列】(3)工具系统
工具系统 — @Tool/@ToolParam 注解将 Java 方法注册为 Agent 能力,自主决定调用时机,支持同步/异步返回。
307 0
|
19天前
|
中间件 Java API
【AgentScope Java新手村系列】(17)长期记忆系统
长期记忆 — 废弃 LongTermMemory,改用 MEMORY.md + Compaction 压缩 + MemoryFlush 冲刷 + @Tool 主动写。三层机制互补,框架自动维护,业务方按需定制。
225 0
|
25天前
|
前端开发 安全 中间件
【AgentScope Java新手村系列】(14)人机交互
人机交互 — Permission 系统五种模式配合 ALLOW/DENY/ASK 规则,运行时 HITL 自动拦截与决策收集。
288 6
【AgentScope Java新手村系列】(14)人机交互
|
1月前
|
Java
【AgentScope Java新手村系列】(8)多Agent协作
多Agent协作 — orchestrator + workers 模式替代 MsgHub,一个 HarnessAgent 搭载多个 SubagentDeclaration,LLM 主持群聊与辩论。
389 0
|
1月前
|
Java 中间件 API
【AgentScope Java新手村系列】(10)实战-多Agent天气助手
实战-多Agent天气助手 — 文件驱动 subagent 实战,主 agent 自主编排天气查询、航班搜索、景点推荐三个子任务并行调研。
374 1
|
NoSQL Java 关系型数据库
【AgentScope Java新手村系列】(5)记忆与会话管理
记忆与会话管理 — AgentState 管理上下文窗口,AgentStateStore 持久化,RuntimeContext.sessionId 隔离多用户会话。
382 0
|
1月前
|
存储 安全 Java
AgentScope Java 2.0:打造分布式、企业级智能体底座
AgentScope 2.0 面向分布式部署、稳定运行、权限安全等企业级需求全面升级,打造支持多租户隔离与长期稳定运行的企业级智能体底座。
1130 24
|
1月前
|
自然语言处理 Java API
【AgentScope Java新手村系列】(7)子Agent编排
子Agent编排 — SubagentDeclaration 描述子 agent,主 agent 通过 agent_spawn 工具同步/异步委派子任务。
403 0
|
23天前
|
SQL JSON Java
【AgentScope Java新手村系列】(15)MCP协议工具
MCP协议工具 — tools.json 一行声明一个 MCP server,支持 stdio/sse/ws 协议,McpMeta 传递调用元数据。
272 1

热门文章

最新文章