- 放入状态的规划产物(持久化输出)
- 与执行提示词分离的规划提示词
- 一个只处理规划边界的
decide()覆写
相比第 1 课的变化
最后一行尤其重要:这节课增加的是规划能力,而不是上下文复杂度。
双提示词架构
这节课会显式使用两份提示词契约。规划提示词
PLAN_DRAFT_PROMPT。
执行提示词
PLAN_EXEC_SYSTEM_PROMPT。
这节课想让你建立的设计意识是:
- 规划和执行可以使用不同的提示词
- 但它们仍然流经同一个
AgentModule + Engine运行时
这节课的解析器逻辑
规划路径不使用ReActTextParser。
它通常是这样工作的:
_plan()渲染PLAN_DRAFT_PROMPTNumberedPlanBuilder调用同一个大模型适配层- 构建器把编号列表解析成
list[str]
ReActTextParser。
这里体现了一个关键的 QitOS 设计点:
同一个智能体的不同阶段可以使用不同的解析契约,只要控制边界是显式的。
大模型适配层保持不变
和第 1 课一样,这节课仍然使用:- 这样你能单独观察规划带来的变化
- 提示词与解析器的变化更容易解释
- 课程一次只引入一个真正的新变量
1
在状态中加入计划与游标
新状态只增加执行真正需要的字段:这是课程里第一次把原本隐藏的推理产物显式写进状态。为什么要这么做:
- 追踪记录可以直接展示它
prepare()可以显式暴露它reduce()可以推进它- 以后若需要,也可以主动重写它
2
使用专用的计划构建器
规划器通常在构造时初始化:调用方式类似:正确的 QitOS 做法是:让规划变成有名字的持久化产物,并且有自己清晰的解析器,而不是混进主记录里的一段自由文本。
3
把 decide 只用作规划门控
这节课的控制逻辑通常非常小:其中最重要的是最后一句:
return None一旦计划已经存在,引擎会重新回到默认的大模型路径:提示词 -> ReActTextParser -> 决策 -> 工具执行所以第 2 课不是替换运行时,而是在运行时上加了一道显式控制边界。4
把执行提示词与解析器明确绑定
执行阶段仍是:同时:因此规划阶段和执行阶段是清晰分离的:
- 规划:编号列表构建器
- 执行:ReAct 文本协议
5
让 prepare 显式展示计划
prepare() 现在不再只渲染任务,而是同时渲染当前计划进度:- 一个任务
- 一份显式计划
- 当前要执行的单个计划条目
6
在归约里推进计划进度
计划推进仍然是普通的状态逻辑:关键不在于这两个条件本身,而在于它们出现的位置:
reduce()(归约)就是你定义”什么算计划完成”的地方。7
故意保持记忆与历史简单
第 2 课依旧不引入:
- 记忆适配器
HistoryPolicy调优CompactHistory
8
运行并在 qita 中检查规划边界
运行:查看:在追踪记录中重点看:
- 哪一步出现了
Decision.wait("plan_ready") plan_steps是何时进入状态的- 后续执行是否仍然沿着同一个 ReAct 解析器路径前进
为什么 PlanAct 仍然是同一个内核
很多人一想到规划,就会下意识引入:- 单独的规划服务
- 框架之外的规划-执行循环
- 第二个智能体运行时
- 规划器只是另一种受控的大模型调用
- 计划只是另一种状态产物
- 执行仍然走普通的引擎路径
完整示例
完整可运行代码位于:第 3 课会新增什么
第 3 课依旧不换内核,但智能体会真正变成长时运行的工作流。 你将第一次认真面对:- 预设工具集,而不是手工组装
- 面向工作流的系统提示词
- 显式历史控制
- 上下文压缩与记忆何时成为必要设计问题
下一课:Claude Code 风格智能体
从模式设计走向长时运行的工作区智能体
相关指南:记忆与历史
在进入长时运行前,先回顾状态、历史、压缩与记忆的边界
