news 2026/9/27 15:34:06

【AgentScope Java新手村系列】(12)计划模式:用 enablePlanMode 给 HarnessAgent 装上任务拆解大脑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【AgentScope Java新手村系列】(12)计划模式:用 enablePlanMode 给 HarnessAgent 装上任务拆解大脑

1. 为什么 HarnessAgent 需要计划模式

如果你用过 AgentScope Java 的 HarnessAgent 跑多步任务,大概率遇到过这种场景:你让它"帮我搭一个用户认证模块",它上来就开始写代码,写到一半发现数据库表结构没设计,回头改,改完发现接口定义又对不上,来回折腾四五轮。更糟的是,有些操作是破坏性的——文件已经覆盖了,命令已经执行了,你想喊停都来不及。

这就是 ReAct 循环的天然缺陷:思考、调工具、看结果、再思考,每一步都是临场判断,没有全局视角。任务越复杂,跑偏的概率越高。

计划模式(Plan Mode)要解决的就是这个问题。开启enablePlanMode(true)之后,HarnessAgent 会把一次复杂任务拆成两个阶段:先进入只读的 PLAN 阶段,agent 只能看文件、调研现状,然后把计划写进workspace/plans/PLAN.md;你审完这份计划说"行",它才进入 BUILD 阶段真正动手。这就像装修队先出图纸给你审,审过了再砸墙布线,而不是一进门就开始砸。

这篇面向 AgentScope Java 新手,从零讲清楚enablePlanMode开启后 HarnessAgent 怎么把复杂指令拆成可执行步骤,给出可复制的配置骨架,并用一次多步任务让你直观看到计划模式前后的行为差异。适合正在用 HarnessAgent 做多步工作流、又不想让 agent 跑偏的开发者。

2. 前置准备:模型接入与依赖

在写代码之前,先把模型接入这块理清楚。AgentScope Java 的 HarnessAgent 需要一个 ChatModel 实例,你可以用 DashScope、OpenAI 兼容接口,或者通过 TaoToken 这类聚合网关来统一管理模型调用。

TaoToken 的定位是模型 API 聚合平台,把不同厂商的模型接口统一成一套 OpenAI 兼容协议,你换模型时不用改代码,只换 modelName 就行。对于新手来说,好处是不用同时维护好几套 SDK 和 Key。

注册和拿 Key 的流程不复杂:进官网注册账号,在控制台创建一个 API Key,然后把它配到环境变量里。接入文档里有各语言的调用示例,Java 这边直接用 OpenAI 兼容的 base_url 即可。

# 把 Key 配到环境变量,避免硬编码进代码 export TAOTOKEN_API_KEY="sk-你的key"

如果你用的是 DashScope 原生接口,那就配DASHSCOPE_API_KEY,两者选其一即可。下面示例里我用 TaoToken 的兼容端点,方便你换模型。

依赖方面,AgentScope Java 的核心包和 harness 包都要引进来。Maven 里大致是这样:

<dependency> <groupId>io.agentscope</groupId> <artifactId>agentscope-core</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>io.agentscope</groupId> <artifactId>agentscope-harness</artifactId> <version>2.0.0</version> </dependency>

版本号以你实际拉到的为准,2.0 之后enablePlanMode才下沉到 HarnessAgent,1.x 时代用的是 PlanNotebook,这个后面会讲迁移。

3. 可复制的 HarnessAgent 配置骨架

先看一个最小的计划模式配置。核心就一行.enablePlanMode(true),但周边几个参数决定了 agent 的行为边界。

import io.agentscope.core.agent.RuntimeContext; import io.agentscope.core.message.UserMessage; import io.agentscope.core.model.OpenAIChatModel; import io.agentscope.harness.HarnessAgent; import java.nio.file.Path; import java.util.List; public class PlanModeDemo { public static void main(String[] args) { OpenAIChatModel model = OpenAIChatModel.builder() .apiKey(System.getenv("TAOTOKEN_API_KEY")) .baseUrl("https://taotoken.net/api") .modelName("qwen-plus") .build(); HarnessAgent agent = HarnessAgent.builder() .name("project_planner") .sysPrompt("你是一个项目经理,遇到多步任务先用 plan mode 写计划。") .model(model) .workspace(Path.of("./workspace")) .enablePlanMode(true) // 关键:开启计划模式 .build(); agent.call( List.of(new UserMessage("user", """ 我下周要办一场 200 人技术大会,请帮我做一份执行计划: - 场地 - 议程 - 嘉宾 - 报名 - 现场 """)), RuntimeContext.empty()) .block(); } }

几个参数值得单独说:

workspace是 agent 的工作目录,计划文件会落在workspace/plans/PLAN.md,todo 状态会持久化到workspace/state/session-*.json。这个目录建议纳入 git 管理,计划变更就有版本记录。

sysPrompt里最好明确告诉 agent"多步任务先写计划",虽然 plan mode 本身有强制门控,但系统提示词能减少它误判单步任务的情况。

enablePlanMode(true)是开关。关掉它,agent 就是普通 ReAct 循环;打开它,agent 在 PLAN 阶段会被拦截所有非只读工具调用。

跑完这段代码,你去workspace/plans/PLAN.md看,大致会是这样:

# 技术大会执行计划 ## Step 1 — 锁定场地 - 目标:确定可容纳 200 人的宴会厅 - 负责:行政 - 完成标准:拿到合同 + 付款凭证 ## Step 2 — 公布议程 - 目标:议程在官网公开 - 依赖:Step 1 ## Step 3 — 确认嘉宾 ...

注意,这时候 agent 还没真正去订场地、发议程,它只是把计划写下来了。这就是 PLAN 阶段和 BUILD 阶段的分界。

4. 四个内置工具到底做什么

开启计划模式后,HarnessAgent 会注入四个内置工具,理解它们的分工是用好这个功能的前提。

工具何时被调用副作用
plan_enteragent 判断这是多步任务写入 PLAN.md 头部,进入只读计划模式
plan_write写或修订计划步骤修改 workspace/plans/PLAN.md
plan_exit所有计划步骤完成收尾 PLAN.md,状态置为 DONE
todo_write任何时候记录子任务写入 AgentState 的 todo 列表

plan_enter是进入计划模式的入口。LLM 调了它,PlanModeMiddleware 就开始拦截所有非只读工具,返回 DENIED。这时候 agent 只能读文件、查资料,不能写文件、不能调部署接口。

plan_write负责写和改计划。你中途想调整方向,比如"把第三步的嘉宾改成都用远程连线",agent 会读当前 PLAN.md,调plan_write改对应步骤,然后输出确认。

plan_exit是退出信号。所有步骤做完,agent 调它,PLAN.md 收尾,执行能力恢复。

todo_write严格说不是计划工具,而是待办工具。plan 管长期大计划,todo 管短期可勾掉的清单。两者在计划模式下是配对的:agent 一边按 PLAN.md 推进,一边用 todo 跟踪每个子任务的完成状态。

这里有个容易踩的坑:plan_enter和plan_exit是成对的,如果 agent 调了plan_enter但任务中途失败没调plan_exit,下次会话可能还停在只读模式。排查时先看 PLAN.md 的状态字段。

5. 验证一次多步任务的行为差异

光看配置不够直观,我们跑一个对比实验。任务用"调研三个城市的咖啡店数量",这是典型的多步任务,每步都要调搜索工具。

先跑不开计划模式的版本:

HarnessAgent agent = HarnessAgent.builder() .name("researcher") .model(model) .workspace(Path.of("./workspace")) // .enablePlanMode(true) // 注释掉 .build();

你会看到 agent 直接开始搜第一个城市,搜完搜第二个,中间没有任何计划输出。如果它搜到一半理解偏了,比如把"咖啡店数量"理解成"咖啡品牌数量",你只能等它全跑完才发现。

再跑开启计划模式的版本,这次加上 subagent 协作:

import io.agentscope.harness.SubagentDeclaration; 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 列表

PLAN.md 里会列出三个调研步骤,session 文件里能看到 todo 的勾选状态。行为差异很明显:不开计划模式,agent 边想边做;开了计划模式,agent 先把三步写清楚,你审完再放行。

提示:计划模式下 subagent 调度不受影响,agent_spawn、agent_send、agent_list照常可用。主 agent 可以一边写计划一边 spawn 子 agent,这是 2.0 推荐的中型工作流模式。

6. 本篇常见错排查

新手用计划模式,报错和困惑集中在几个地方,我按出现频率排一下。

问题一:agent 不进入计划模式,直接开始执行。先确认enablePlanMode(true)真的加上了,再看 sysPrompt 有没有引导它识别多步任务。有些模型对"多步"的判断偏保守,你可以在提示词里明确"超过两步的任务必须先 plan_enter"。

问题二:PLAN.md 没生成。检查 workspace 目录是否有写权限,以及路径是不是相对路径导致的定位问题。建议用绝对路径或确认工作目录。

问题三:agent 卡在只读模式出不来。大概率是plan_enter调了但plan_exit没调。打开 PLAN.md 看状态字段,如果是 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();

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

问题五:从 1.x 迁移过来找不到 PlanNotebook。2.0 移除了io.agentscope.core.plan.PlanNotebook,对应关系是:PlanNotebook.createPlan(...)换成enablePlanMode(true)加 LLM 自己调plan_enter;notebook.addStep(...)换成plan_write;notebook.finishStep(idx)换成plan_write改对应步骤状态;notebook.getCurrentPlan()换成直接读workspace/plans/PLAN.md。

注意:PLAN.md 是普通 Markdown,你可以直接编辑它,下一轮 agent 推理时会读到人编辑后的版本。这个特性让"人改计划"和"agent 改计划"能无缝衔接。

7. 继续深入的方向

计划模式跑通之后,下一步可以往两个方向走。一是把 Permission 规则配细,让不同工具走不同审批策略,比如plan_enter走 ASK、只读工具走 ALLOW、写文件走 ASK。二是把计划模式和 subagent 编排结合,主 agent 负责写计划和汇总,子 agent 负责并行执行,适合调研、批量重构这类可以拆分的任务。

如果你还没配好模型接入,可以先去 TaoToken 控制台创建一个 API Key,接入文档里有 Java 的完整示例。想先直观感受计划模式的行为差异,用模型对话跑一轮多步任务,看它会不会先写计划再动手,比读文档快得多。长期做编码类 Agent 的话,Coding Plan 那边有更完整的工程化配置可以参考。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/27 15:34:00

网站做多语言对比评测:3种方案费用全拆解

网站做多语言对比评测:3种方案费用全拆解 网站做好了没人访问,除了内容不行,多半是门槛太高。很多老板花几万块建了个纯中文站,想拓展海外或港澳台业务,结果发现外国人看不懂,国内用户也不买账。这时候才想起来问:“网站做多语言到底要多少钱?”…

作者头像 李华
网站建设 2026/9/27 15:33:44

3个真实案例对比评测wordpress一键ssl避坑指南

3个真实案例对比评测wordpress一键ssl避坑指南 网站做好了没人访问,这不仅仅是流量焦虑,更是信任危机的直接体现。当用户点击浏览器地址栏,看到“不安全”的红字警告时,跳出率瞬间飙升,任何SEO努力都变得毫无意义。在2024年的建站环境里,HTTPS已经是底线而非加分项,而很多站长在配置SSL…

作者头像 李华
网站建设 2026/9/27 15:33:36

3个核心技能拆解做网站的后台开发需要会些什么与对比评测

3个核心技能拆解做网站的后台开发需要会些什么与对比评测 模板网站太丑不够用,这是无数创业者和技术新人的第一道坎。你花了几千块买的套模板,配色土气,功能僵化,客户一眼就看穿了廉价感。想改吧,代码看不懂;想定制吧,外包报价吓死人。这时候,懂点技术就成了刚需。很多前端初学者或者想转型全栈的开发者,都会问:…

作者头像 李华
网站建设 2026/9/27 15:33:12

肇庆网站建设方案咨询避坑指南:看清3个关键点,建站报价不踩雷

肇庆网站建设方案咨询避坑指南:看清3个关键点,建站报价不踩雷 找肇庆本地建站公司,最怕啥?不是网站丑,是怕被坑高价。很多老板拿着几百块的预算去咨询,结果对方张口就是大几千,还要加各种“隐性消费”。 建站报价 这块水太深,不懂行真的容易多花冤枉钱。…

作者头像 李华
网站建设 2026/9/27 15:32:58

深圳论坛网站建设适合什么场景

深圳论坛网站建设:从零搭建选对技术栈,流量才不白搭 深圳论坛网站建设:从零搭建选对技术栈,流量才不白搭 网站做好了没人访问,是不是你现在的真实写照?很多深圳的站长和运营负责人,花了大几万定制开发,上线三天后打开后台,访客数还是个位数。这时候再去改代码、换服务器,钱已经打水漂了。问题往往出在起步阶段的…

作者头像 李华
网站建设 2026/9/27 15:32:55

动易网站只能进首页怎么修?别被坑,这方案才300块

动易网站只能进首页怎么修?别被坑,这方案才300块 找建站公司最怕什么?怕你刚把域名交过去,对方张口就要几千块,还说这是“标准配置”。更坑的是,钱付了,网站上线没两天,后台正常,前台却死活只能进首页,点任何栏目全是404或者跳转回主页。这时候你问客服,对方回你:“这是动易系统的特性,得重写代码,加钱…

作者头像 李华