Skip to main content
委派任务给 Agent

Outcome 验收判定

通过 user.define_outcome 为 Session 设置验收标准,并读取评估结果。

Outcome 为 Session 设置一个可评估的验收目标:description 描述任务,rubric 描述验收标准。Agent 完成工作后,由独立的评估线程按 rubric 评估产出,并给出 satisfied、failed 等结论。 端到端的推荐用法见 Outcome 最佳实践。

工作方式

定义 Outcome 会启动一个 Agent turn,description 是该 turn 的输入。turn 结束后评估线程开始评估;未通过时,评估结论作为反馈交给 Agent 修订,直到通过或达到最大轮次。
1

定义 Outcome

发送 user.define_outcome,携带 description 和 rubric。outcome_id 由服务端生成。
2

Agent 工作

Agent 按 description 完成产出。turn 正常结束后直接进入评估,Session 保持 running。
3

评估

评估线程按 rubric 评估产出,事件流发送 span.outcome_evaluation_start 和 span.outcome_evaluation_ongoing。
4

修订

span.outcome_evaluation_end.result 为 needs_revision 时,Agent 根据评估结论开始修订 turn,客户端不需要发送事件。
5

终态

Outcome 进入 satisfied、failed、max_iterations_reached 或 interrupted,并写入 completed_at。评估线程给出结论后,Agent 再执行一个收尾 turn 输出最终回复,随后 Session 回到 idle。
同一个 Session 同一时刻只能有一个活跃 Outcome。Outcome 进入终态后,可以在同一个 Session 上定义下一个,Session 保留之前的评估记录。

编写 rubric

rubric 是一份 Markdown 文档,逐条列出验收标准。评估线程逐条评估,标准越具体,结论越稳定。
# 性能报告 rubric

## 产出物
- 存在 /data/report.html
- 报告包含吞吐与延迟两组数据,各至少 1 个图表

## 结论质量
- 明确列出 Top 3 瓶颈
- 每个瓶颈附代码位置或 profiling 数据作为证据

## 排除项
- 不含占位内容、TODO 或示例数据
评估线程只能读取 rubric、沙箱内容和 Agent 的回复,无法读取 description。标准依赖的期望值或源数据需要写进 rubric。
  • 每条标准可核验。写「CSV 中存在数值型的 price 列」,而不是「数据质量良好」。
  • 要求具体证据。例如抓取到的页面、可追溯的计算过程、file:line 引用。
  • 描述目标而非步骤。rubric 指定的命令不可用时,评估无法进行。
  • 写明不接受的做法。例如「不接受转载、镜像或搜索摘要作为依据」。
  • 规定反馈格式。要求逐条给出是否通过以及差距。
  • 写明忽略项。例如忽略排版,忽略与标准无关的附加产物。
  • 没有现成 rubric 时,可以让模型分析一份合格的产出物,再把分析结果整理成 rubric。
标准含糊时,评估线程倾向于给出 satisfied;标准过严则增加评估轮次。建议先用 max_iterations: 1 调整 rubric,确认一轮评估即可得出正确结论。
需要跨 Session 复用同一份 rubric 时,先上传文件,再通过 {"type":"file","file_id":"file_..."} 引用。

定义 Outcome

POST /api/v1/cloud/sessions/{session_id}/events
{
  "events": [
    {
      "type": "user.define_outcome",
      "description": "交付一份可运行的性能分析报告,并指出 Top 3 瓶颈",
      "rubric": {
        "type": "text",
        "content": "必须产出 /data/report.html;包含吞吐与延迟两组数据;明确列出 Top 3 瓶颈及其证据"
      },
      "max_iterations": 1
    }
  ]
}
字段类型必填说明
descriptionstring是任务描述,作为 Agent turn 的输入
rubricobject是验收标准,仅供评估线程使用。取 {"type":"text","content":"..."} 或 {"type":"file","file_id":"file_..."};不允许多余字段
max_iterationsinteger否最大评估轮次,1–20 之间的整数,默认 3
  • user.define_outcome 会立即启动一个计费的 Agent turn。任务内容写在 description 中,rubric 只写验收标准。
  • rubric(文本或文件内容)上限为 64 KiB,超出返回 400。rubric.type 为 file 时,引用的文件必须可读。
  • 每轮评估都会消耗 credits。max_iterations 越大,最坏情况下的评估次数越多。
  • outcome_id(outc_ 前缀)由服务端生成,请求中不能携带。

评估状态

每个 Outcome 在 Session 对象的 outcome_evaluations 数组中对应一条记录,可通过获取 Session、列出 Session 和搜索 Session 读取。
字段类型说明
typestring固定为 outcome_evaluation
outcome_idstringOutcome ID,outc_ 前缀
descriptionstring定义时传入的 description
iterationinteger当前评估轮次,从 0 开始
resultstring当前状态,取值见下表
explanationstring | null最近一轮评估的说明;首次评估完成前为 null
completed_atstring | null进入终态的时间;未进入终态时为 null
result 取值:
取值说明
pending已定义,Agent 尚未开始工作
runningAgent 正在工作或修订
evaluating评估线程正在评估
satisfied终态。所有标准均已满足
max_iterations_reached终态。达到最大轮次后仍未通过
failed终态。评估线程判定任务无法满足 rubric(例如 description 与 rubric 矛盾),或评估线程未给出结论
interrupted终态。Outcome 被取消、中断,或被服务端回收

评估事件

每轮评估的记录通过事件流(列出事件或流式订阅事件)提供:
事件字段说明
span.outcome_evaluation_startoutcome_id, iteration一轮评估开始
span.outcome_evaluation_ongoingoutcome_id, iteration评估进行中。发送间隔不固定,不要据此设置超时
span.outcome_evaluation_endoutcome_id, iteration, result, explanation, outcome_evaluation_start_id, usage一轮评估结束
  • span.outcome_evaluation_end.result 除终态取值外,还可能为 needs_revision,表示本轮未通过且仍有剩余轮次。最后一轮未通过时,取值为 max_iterations_reached。
  • usage.credits 是本轮评估消耗的 credits。本轮没有计量记录时,不返回 usage。
  • Outcome 在评估开始前被中断时,事件流只有 span.outcome_evaluation_end(result 为 interrupted),没有对应的 span.outcome_evaluation_start,outcome_evaluation_start_id 为空字符串。

运行期间的 Session 状态

Agent turn、评估和修订之间的切换由服务端完成,不产生 session.status_idle 或 session.status_running 事件。从定义 Outcome 到收尾 turn 结束,Session 持续处于 running,期间发送 user.message 或 user.define_outcome 返回 409。 completed_at 在评估线程给出终态结论时写入,早于收尾 turn 结束:
目的判断条件
读取评估结论outcome_evaluations[].completed_at 不为 null
读取 Agent 的最终回复,或发送下一个事件Session status 回到 idle
一个 Outcome 会产生多条 agent.message:Agent turn、每个修订 turn 和收尾 turn 各一条。最终回复是终态 span.outcome_evaluation_end 之后的一条。interrupted,以及评估线程未给出结论导致的 failed,没有收尾 turn。 运行期间事件流仍可能出现以下状态事件,它们不表示 Outcome 结束:
事件原因处理方式
session.status_idle,stop_reason.type 为 requires_action工具调用等待确认见工具确认
session.status_rescheduled,随后 session.status_running模型请求自动重试无需处理,见模型请求自动重试

工具确认

评估线程继承 Agent 的工具权限,用于在沙箱中核验产出。配置为 always_ask 的工具由 Agent 或评估线程调用时,都会暂停并等待确认,流程与 Pending Action 流程一致:
  1. 事件流发送 agent.tool_use(evaluated_permission 为 ask)和 session.status_idle(stop_reason.type 为 requires_action)。
  2. 客户端使用 stop_reason.event_ids 中的事件 ID 发送 user.tool_confirmation。
  3. 确认后评估继续。
等待确认期间,Session 的 status 仍为 running,outcome_evaluations[].result 为 running 或 evaluating。Pending action 不会自动超时,未确认时评估不会继续。 评估线程发起的 agent.tool_use 携带内部线程的 session_thread_id,该线程不出现在线程列表中;调用确认后,这条事件不保留在事件历史中。 需要评估无人值守完成时,将评估所需的只读工具(如 Read、Bash、Glob、Grep)配置为 always_allow。

Agent turn 出错

只有正常结束的 Agent turn 才会进入评估。Agent turn 或修订 turn 在自动重试耗尽后以错误结束时:
  • 事件流发送 session.error(error.retry_status.type 为 exhausted),不发送 session.status_idle。Session 的 status 回到 idle。
  • Outcome 保持活跃:result 为 pending 或 running,completed_at 为 null。
  • 此时定义新的 Outcome 返回 409。发送 user.message 会启动新的 turn,该 turn 结束后仍按当前 Outcome 的 rubric 评估。
  • 一段时间内没有新的 turn 时,服务端回收该 Outcome:result 变为 interrupted,事件流发送 span.outcome_evaluation_end。
需要立即结束时,取消 Session。

请求约束

约束结果
user.define_outcome 与 user.message、user.tool_result 或 user.custom_tool_result 在同一请求中发送整个请求返回 400,所有事件都不生效
同一请求包含多个 user.define_outcome事件依次处理:第一个生效,后续事件返回 409,第一个不回滚
Session 正在处理 turn(running 或 rescheduling)返回 409
Session 已有活跃 Outcome(result 为 pending、running 或 evaluating)返回 409
Session 为 idle 时仍可能存在活跃 Outcome(见 Agent turn 出错)。发送 user.define_outcome 前,同时确认 Session 为 idle 且没有活跃 Outcome:
curl -s "https://api.qoder.com.cn/api/v1/cloud/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  | jq '{status, active_outcomes: [.outcome_evaluations[] | select(.completed_at == null)] | length}'
Outcome 只能通过 user.define_outcome 事件定义,不是创建 Session 的字段。Deployment 可以在 initial_events 中携带该事件。

取回产物

Agent 通过 DeliverArtifacts 交付的文件归属于当前 Session,交付成功时事件流发送 agent.artifact_delivered。
# 列出 Session 的文件
curl -s "https://api.qoder.com.cn/api/v1/cloud/files?scope_id=$SESSION_ID" \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN"

# 获取下载 URL 并下载
curl -s "https://api.qoder.com.cn/api/v1/cloud/files/$FILE_ID/content" \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" | jq -r '.url' | xargs curl -s -o report.html
  • 修订 turn 重新交付时会生成新的 File。使用最后一条 agent.artifact_delivered 的 file_id 获取最终版本。
  • 文件可能在交付数秒后才出现在列表中。
  • Agent 也可能直接在 agent.message 中给出结果,客户端应同时处理这两种情况。
接口说明见 Session 产出物的交付与取回。

取消与中断

以下操作都会使活跃 Outcome 进入 interrupted:
  • 取消 Session:POST /api/v1/cloud/sessions/{session_id}/cancel。
  • 发送不带 session_thread_id 的 user.interrupt,效果与取消 Session 相同。
Outcome 运行期间需要调整任务时,先取消,再定义新的 Outcome。

完整示例

# 1. 定义 Outcome
curl -s -X POST "https://api.qoder.com.cn/api/v1/cloud/sessions/$SESSION_ID/events" \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "type": "user.define_outcome",
        "description": "分析这个仓库的性能问题,并把结论写成 /data/report.html",
        "rubric": {"type": "text", "content": "存在 /data/report.html;包含 Top 3 瓶颈与证据;不含占位内容"},
        "max_iterations": 1
      }
    ]
  }'

# 2. 等待 Outcome 进入终态
until [ "$(curl -s "https://api.qoder.com.cn/api/v1/cloud/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  | jq -r '.outcome_evaluations[-1].completed_at // empty')" != "" ]; do sleep 5; done

# 3. 读取评估结论
curl -s "https://api.qoder.com.cn/api/v1/cloud/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" \
  | jq '.outcome_evaluations[-1] | {result, iteration, explanation}'

# 4. 等待收尾 turn 结束
until [ "$(curl -s "https://api.qoder.com.cn/api/v1/cloud/sessions/$SESSION_ID" \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" | jq -r '.status')" = "idle" ]; do sleep 2; done

# 5. 列出产物
curl -s "https://api.qoder.com.cn/api/v1/cloud/files?scope_id=$SESSION_ID" \
  -H "Authorization: Bearer $QODER_ACCESS_TOKEN" | jq '.data[] | {id, filename}'

使用建议

场景建议
只需要通过或不通过的结论max_iterations: 1,在 rubric 中写明通过条件和失败条件
需要 Agent 根据评估结论修订max_iterations 大于 1,评估成本随轮次增加
任务已完成,只需要核验产物定义 Outcome 仍会启动 Agent turn,在 description 中要求核验并修正已有产物
只需要确认是否交付无需使用 Outcome,通过 agent.artifact_delivered 和 Session 状态判断

错误

HTTP 状态码场景
400rubric 结构不合法;max_iterations 不在 1–20 之间;rubric 超过 64 KiB;携带 outcome_id 等不允许的字段;与 user.message 或工具结果事件在同一请求中发送
404Session 不存在;rubric.file_id 引用的文件不存在
409Session 正在处理 turn;Session 已有活跃 Outcome