Skip to content

3.7 会话内目标 Goal

本章概览:Goal 域为一个 agent 会话保留一个持久化的完成目标:目标状态写在会话日志里(事件溯源),而"允许继续"则是进程本地激活。本章覆盖 compare-and-set 围栏、goal/change 事件、激活不持久化、轮次驱动与单一 blocked 阶段。

概述 / 定位

dsh-goal 通过 ctx.goals 持有一个"当前同会话目标"。目标状态是所属会话日志的一部分;消费方(模型工具、续跑驱动器、人类命令)依赖 dsh-goal,从不依赖具体 agent loop 实现。族内包:goal(状态与生命周期)、goal-round-driver(同会话续跑)、tool-goal(模型侧工具)、command-goal(人类 /goal 命令)。

出处:packages/goal/README.mddeepseek-harness-src/packages/goal/README.md

一个当前目标与 compare-and-set

同一时刻至多一个当前目标GoalRef { id, revision } 是比较交换(compare-and-set)围栏:每次被接受的持久变更递增 revision,陈旧 ref 被拒绝。get() 返回 detached GoalView;变更动词为 create / edit / pause / resume / complete / block / clear。disarm() 是生命周期例外——移除进程本地续跑权威而不写 revision、不发变更事件。创建物化部署默认 defaultMaxGoalRounds(默认 256);已完成目标可被全局新 id 替换,其他阶段的当前目标必须先 clear 或 resume。

每次变更追加一条版本化的 goal/change 会话事件,载荷是完整的后变更快照(clear 用 revisioned tombstone)。会话日志是唯一持久权威:目标状态不依赖 inbox 放置、认领、接纳或丢弃。严格重放只从 goal/change 派生生命周期状态,拒绝畸形形状、不连续 revision、非法生命周期迁移、非单调时间戳与非顺序轮次;损坏记录令目标访问停在该记录处(完整性检测,非插件隔离)。

出处:packages/goal/goal/README.mddeepseek-harness-src/packages/goal/goal/README.md)、docs/subsystems/goal.mddeepseek-harness-src/docs/subsystems/goal.md

激活:进程本地且不持久化

激活(activation)回答"续跑消费者现在能否再开一轮",是 armed/disarmed 的进程本地状态,从不持久化。创建与显式 resume 武装;pause、complete、block、clear 解除。任何 agent/session-start 边界都解除武装——即使重放发现持久 phase 是 active。因此会话恢复(resume)、fork 与驱动器替换都保留目标、阶段、revision 与已接纳轮次数,但绝不自行开工;之后的人类提示由模型解释,并可经 update_goal action resume 显式重新武装。续跑驱动器在卸载前或持久性不确定后也会调用 disarm()

轮次驱动

roundsStarted 只从目标源 user/message 事件推进:携带 GoalMessageSourcekind: 'goal' + goalId + revision + 正数 round)的被接纳轮次才递增。普通人类轮次不计入——一个会话中的人类澄清、检查与无关工作不消耗自动工作预算。goal-round-driver 在精确活 agent 空闲、目标 active/armed 且容量有余时:先 checkpoint 待决目标变更,为当前 { goalId, revision } 保留 roundsStarted + 1,以 GoalMessageSource 排队 <goal_round> 提示;agent/pre-step 监听器在前后都验证认领记录与当前目标,只有进入的 user/message 才递增。maxGoalRounds 是已接纳轮次上限;被拒为陈旧的保留不消耗轮次数。驱动器本身无可调配置——上限属于目标定义,阻塞阈值属于 tool-goal,避免策略发散。

出处:packages/goal/goal-round-driver/README.mddeepseek-harness-src/packages/goal/goal-round-driver/README.md

blocked:单一持久停止阶段

blocked 是唯一的"被问题停止"持久阶段,配 policy-owned 的小写 kebab-case code + 人类/模型可读的 message。provider 上限、配置预算、执行错误、等待人类输入都映射到这一个阶段,不增殖生命周期状态。模型侧 update_goal action blocked 必须携带 blocked_reason(稳定 code model-reported),且受 blockedAfterConsecutiveRounds(默认 3)硬下界约束:连续轮次数不足时机械拒绝,模型自行判断同一阻塞条件是否真实持续并说明之;直接人类权威可立即停止目标。resume 接受 stopped 阶段或 disarmed active 目标(容量有余时),并清除旧的 blocker reason。

与长任务 / 自动续跑的关系

Goal 域是状态,不是调度:它不决定武装目标何时续跑、不重试异常失败、不取消活跃轮次——这些策略属于 agent-seam 消费者(goal-round-driver)。与 Ralph 的边界:Ralph 每轮开一个全新子代理做独立尝试、以工作报告定完成;goal 在同一会话内连续轮次、共享历史、由记录 complete/blocked 的调用方权威决定结果,无独立评估者。轮次上限只计自动续跑;token、货币、墙钟与 provider 配额由策略消费者映射为 blocked 原因。

模型侧工具与权威

tool-goal 注册 get_goal / create_goal / update_goalcreate_goal 仅接受直接顶层人类轮次——模型可推断长跑意图,非人类轮次与子代理被拒;edit/pause/resume 要求当前轮次含 { kind: 'user' } 消息(宿主证明——插件、调度器必须自带 source,不得继承人类权威)。complete/blocked 额外接受当前目标轮次:goal 源 user/message 的 id/revision/round 与折叠当前目标一致。所有调用独占执行,模型有序批次能看到此前变更及其新 revision;结果中 activation 是活观察,永不成重放权威。

出处:packages/goal/tool-goal/README.mddeepseek-harness-src/packages/goal/tool-goal/README.md

关键设计决策

  • 状态在会话日志而非独立库/头部:排序、持久化、fork 前缀与可重建性一次到位;"模型可见即已记录"延伸为目标变更必写 goal/change
  • 持久生命周期与续跑许可分离:恢复/打开会话绝不静默自动开工。
  • 全量快照事件:简化检查、严格重放与 last-wins 投影,不给模型历史加变更-only 消息。
  • 单 blocked 阶段 + code/message:多种停止原因共用一个生命周期状态且不丢原因。
  • 目标轮次独立于人类轮次:预算只计自动续跑,人类澄清不消耗额度。

扩展点

  • 策略插件:调用服务动词并响应 scoped goal/changed 事件(每次持久变更提交后发出)。
  • 续跑消费者:以 GoalMessageSource 接纳轮次——goal-round-driver 是范本。
  • 新入口command-goal/goal 是独立消费者(无模型轮次);服务动词已带 @Remote 远程边界可接 UI/远程端。
  • 评估者:独立完成认证/阻塞判定是延后策略层,可在此接入。

参考资料

本文档为学习用途的原创讲解,基于 MIT 许可的开源项目 deepseek-ai/deepseek-harness 编写;所有引用均注明出处。