大数跨境

Coding Agent Goal 机制详解

Coding Agent Goal 机制详解 独立开发
2026-09-15
5
导读:Claude Code, Codex, dsh, Kimi Code 的 Goal 实现原理

Coding Agent Goal 机制详解

前两篇整理了 Claude Code 与 Codex 的 Memory上下文压缩

Claude Code 与 Codex Memory 机制详解

Claude Code 与 Codex 压缩机制详解

本次聚焦 Goal 机制。

对比 Kimi Code、Codex、DeepSeek Harness (dsh) 和 Claude Code 的实现与文档,它们核心解决同一问题:如何让 Agent 持续执行任务直至目标达成?

解析 Goal 需关注三点:

• 目标如何保存
• 如何判断目标达成或终止
• 下一轮如何自动启动

Kimi Code、Codex、DeepSeek Harness 和 Claude CodeGoal 机制上大同小异。本文将其流程串联为主线,并在关键处剖析异同,供读者把握核心思路。

Goal 的整体流程

首先定义"turn"(回合):Agent 围绕一次输入持续工作的过程,期间可能多次调用模型和工具

用户输入
  → 模型决定调用工具
  → 程序执行工具,返回结果
  → 模型继续思考和调用工具
  → 模型输出最终回复,本轮结束

例如让 Agent 进行数据库迁移。它修改完数据访问层并运行部分测试后,回复:“基础改造已完成,接下来需适配接口层。”此时单轮对话结束,但整体任务未完。

Goal 机制在此之上增加了一层控制:

设置并保存目标
  → Agent 执行一轮
  → 检查目标状态、完成情况和执行限制
      ├─ 可以继续 → 提交后续输入,继续当前会话
      └─ 应当停止 → 完成、暂停或记录阻塞

上述四种 Coding Agent 均遵循此主线,差异主要体现在:状态存储方式、下一轮触发源头、任务完成判定者

Kimi Code、Codex 和 dsh 提供了模型可调用的 Goal 工具;Claude Code 则将完成检查交由独立的评估模型处理(后文详述)。

目标如何创建和保存

#目标 Goal 状态

用户命令入口与模型工具入口可分离。

以 Kimi Code 为例,执行 /goal 完成数据库迁移 后,CLI 直接调用 session.createGoal() 保存目标,并将目标文本作为输入交给 Agent,无需模型先调用 CreateGoal

模型侧仍保留对应工具,供其他场景使用:

项目 模型侧的 Goal 工具 值得注意的区别
Kimi Code CreateGoalGetGoalSetGoalBudgetUpdateGoal 预算有独立设置工具
Codex create_goalget_goalupdate_goal 创建时可传 token 预算;模型更新仅允许 complete 或 blocked
dsh create_goalget_goalupdate_goal 创建时可传自动续轮上限;更新需带目标 ID 与 revision

这些工具操作的是程序状态,可概括为:

目标:完成数据库迁移
状态:active
限制:允许消耗 tokens 数、执行轮数或运行时长
消耗:当前已用资源

“任务进度”与“资源消耗”需区分:进度由模型判断,消耗由程序计量。

dsh 的 revision 机制颇为实用:模型读取 Goal 后携带版本号更新;若期间目标被修改,旧版本更新将无法覆盖新状态,避免冲突。

#状态放在哪里

上述状态追踪了目标进度与消耗,需同时存在于内存与持久化存储中,以便从旧 session 恢复。

Kimi Code 将 Goal 变更写入主 Agent 的持久化事件日志。

主要包含三个事件:

goal.create:创建目标
goal.update:更新状态、预算或累计消耗
goal.clear:清除目标

这些事件存入该 Session 下主 Agent 的 wire.jsonl

goal.update 可仅携带部分字段(如仅更新 tokensUsed 或 status)。恢复时需按顺序重放事件,不可仅取最后一条 update 作为完整 Goal。

dsh 也采用 Session 事件,但组织形式不同。

goal/change 保存目标生命周期状态;自动续轮消息正式进入 Session 后,对应的 user/message 会推进轮数。

若 Coding Agent 中途退出,可通过 session 文件中的事件推导 goal 的真实状态。

Codex 直接将当前 Goal 保存在 SQLite。

Codex 独树一帜,将 Goal 状态追踪存储于本地 Sqlite 数据库(goals_1.sqlite)。thread_goals 表通过 thread_id 关联会话,保存目标、状态、token 预算与累计消耗等字段。读取时直接查询当前记录,不依赖重放聊天历史中的工具调用。

Claude Code 的 Goal 存储字段与写入路径因无对应新源码,暂不作推断。

Agent 停下来后,如何继续

假设数据库迁移完成第一部分,Agent 正常结束本轮 turn,但 Goal 仍未完成。

#轮次结束与空闲回调

Kimi Code 调用链直接,当前 turn 结束后:

handleTurnEnded()
  → 检查结束原因、当前目标与预算
  → launchContinuationTurn()
  → IAgentLoopService.submit({ message })

提交的消息简化如下:

{
  role'user',
  content: [{ type'text'text'继续推进当前目标……' }],
  origin: { kind'system_trigger'name'goal_continuation' }
}

消息角色为 user,但来源标记为程序触发。即以 user 口吻自动发送:"**当前任务进度 xxx,请继续**"。

Codex 将续轮置于线程空闲阶段:

on_turn_stop:结算本轮消耗
  → on_thread_idle
  → continue_if_idle()
  → start_turn_if_idle(...)

它从数据库读取 active Goal,检查是否允许自动继续,将 Goal 提示词包装成内部上下文输入并启动下一轮,触发来源标记为 goal

dsh 由独立的 goal-round-driver 插件负责:

agent/status 变为 idle
  → requestDrive()
  → drive()
  → agent.followup(message)

其要求目标为 active、自动执行已激活、无竞争待处理输入且未达轮数上限。续轮消息 source 中包含 goalId、revision 和 round。

这些检查至关重要:自动续轮排队后,用户可能已修改目标或发送新问题。dsh 会在消息执行前再次核对,避免旧的续轮请求生效。

#Claude Code 的 Stop hook

Claude Code 官方将 /goal 描述为 Session 级的 prompt-based Stop hook:在模型准备结束时进行评估,决定是否允许停止。

通用 Stop hook 可返回阻止停止的理由,由程序反馈给模型以继续执行。

泄露源码显示基础机制:stopHooks.ts 将阻塞理由包装成消息;query.ts 在允许继续时将其追加到上下文,并 continue 查询循环。

下一轮模型会看到什么

程序保存 Goal 并不意味模型自动知晓状态。每次调用模型,仍需将必要信息放入请求。

#目标与预算重新进入上下文

Kimi 的续轮消息负责推动执行,内容概括如下(中文示意):

当前有一个 active Goal。
目标:完成数据库迁移。
已执行轮数、消耗 tokens、经过时间。
预算与剩余额度:……

本轮完成部分有效工作。
若有剩余工作则保持 active,正常结束并由程序继续下一轮。
全部要求完成并验证后,再调用 UpdateGoal。

它还要求模型检查用户是否明确提出预算。若用户说明“最多 10 轮”而状态未记录,需先调用 SetGoalBudget

关键点:用户在自然语言中提出的预算限制,会通过工具调用真正写入系统内存/session。

Codex 直接在续轮提示词中放入 objective、tokens_used、token_budget 和 remaining_tokens。dsh 的 renderGoalRoundPrompt() 则将目标和 Round: 当前轮数/上限 一起写入续轮消息。

Claude Code 的反馈还包含评估器给出的未完成理由,作为后续工作指引。

#继续工作,也要防止目标缩水

Kimi Code 和 Codex 的提示词均强调:不可因预算快用完或完成小阶段,就将整个目标标为 complete。

Codex 还要求区分实际进展、经验证的等待和无进展。例如等待后台任务时需确认任务仍在运行,不能仅凭聊天记录反复声称“还在等待”。

dsh 的提示词较短,同样要求根据当前工作区、工具结果和持久化状态判断,完成前需读取当前 Goal。

这些 Prompt 价值在于防止持续执行中的常见问题:模型为结束当前工作,将“完成全部迁移”悄悄缩小为“完成基础改造”。

Goal 的原始目标与完成要求需不断保持在上下文中。

谁来判断目标完成了

#执行模型通过工具声明完成

Kimi Code、Codex 和 dsh 路径中,主 Agent 模型根据执行结果调用 Goal 更新工具。

以 Codex 为例:

{
  "status": "complete"
}

程序验证参数、当前状态和预算后保存变更。

这主要靠提示词要求模型自查:原始目标有哪些条件,哪些已验证,还缺哪些证据。Kimi 和 Codex 均明确禁止将计划、总结或部分结果视为完成。

#Claude Code 额外评估一次

Claude Code 使用独立的小模型评估目标,返回未满足、已满足或不可能满足的判断;后两种结果会清除目标并记录。评估器仅查看对话证据,不读取文件或运行测试。

此设计将执行判断分离,初现 multi-agent 雏形,契合其博客中宣传的 executor 与 evaluator 分离理念。

预算

除执行流程外,Goal 还需约束,即预算。为防止无休止执行,需人为设定 token、轮次或时间预算。各 Coding Agent 可设置的预算如下:

项目 本文检查到的 Goal 限制
Kimi Code tokens、turns、运行时间
Codex token 预算,另有耗时统计
dsh 自动 Goal 续轮次数,默认上限 256

同为 token 预算,Kimi 与 Codex 计算方式不同。

Kimi 的 Goal usage 读取主 Agent 的输出 token 数。Codex 公式为:

Goal token 消耗 = 输入 tokens − 缓存输入 tokens + 输出 tokens

Codex 还会将相关 sub-Agent 的 usage 计入 Agent 计账状态,不同 Agent 计算口径不一。

Claude Code 文档建议将时间或轮数要求写进完成条件,由评估器判断。

写在最后

Goal 是 Coding Agent 向长程任务的试探。虽在开发中个人更倾向于手动输入“继续”,但对比四套机制后可见,Goal 的核心逻辑清晰:保存目标,在合适节点检查状态,自动提交后续输入直至完成。这比单纯输入“继续”更具目标一致性。

Goal 实现大同小异,真正影响效果的是细节:预算计量方式、用户插话后旧请求的处理、会话恢复是否自动运行,以及模型声明完成的证据标准。

【声明】内容源于网络
0
0
独立开发
技术变现,实现被动收入,SEO优化技巧,流量获取与变现,独立开发指南,网站搭建,niche站点,独立站,affiliate,广告,订阅
内容 92
粉丝 1
独立开发 技术变现,实现被动收入,SEO优化技巧,流量获取与变现,独立开发指南,网站搭建,niche站点,独立站,affiliate,广告,订阅
总阅读14.3k
粉丝1
内容92