Correct final-only trigger analysis in C8 review
Why: independent review found the budget reserve also triggered final-only. Evidence: provider-records outputCap 4000; material_final_reserve.go:21-30 Impact: docs and task card only. Refs: feature/fast-slow-o2-c8-review Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -93,9 +93,9 @@
|
||||
|
||||
## 结果与验证(完成后填写)
|
||||
|
||||
- 结果:C8 成因为 `publish_work_checkpoint` 在 final-only 请求中未声明(SavedCheckpoints>=2 触发),与任务指令 reading→crosscheck 冲突;「schema 不符交给工具层」不适用且不建议实施。P2:3 次付费请求、17955 tokens、NOT_PASS(C8),证据合规达成(2 检查点 0 拒绝),路由文件已删除;本次复核零付费。
|
||||
- 结果:C8 成因为 `publish_work_checkpoint` 在 final-only 请求中未声明(已存 2 个检查点与预算预留两条件同时触发 final-only),A01 预算只够两轮检查点加一次最终答复,与任务指令 reading→crosscheck 冲突;「schema 不符交给工具层」不适用且不建议实施。P2:3 次付费请求、17955 tokens、NOT_PASS(C8),证据合规达成(2 检查点 0 拒绝),路由文件已删除;本次复核零付费。
|
||||
- 验证:只读复核,依据见复核文档;模型复验 NOT_RUN(未授权)
|
||||
- 影响与剩余项:推荐 F1(达阈值时工具结果与任务指令告知上限),需单独授权实施及一次付费复验
|
||||
- 影响与剩余项:推荐 F1(宿主判定下一次为 final-only 时由工具结果告知,并使任务指令与预算一致),需单独授权实施及一次付费复验
|
||||
|
||||
## 规划进展与下一步
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
- 首选下一任务:F1 final-only 上限告知(Backend)
|
||||
- 推荐依据:不动契约、零付费单测可验证宿主侧行为
|
||||
- 前置条件/待确认:用户授权实施 F1 与之后的付费复验
|
||||
- 预期产物/验收条件:final-only 前一次检查点结果含上限提示;付费复验无 C8
|
||||
- 预期产物/验收条件:final-only 前一次检查点结果含提示;付费复验无 C8
|
||||
- 重复任务核对:无在途同题任务
|
||||
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## 结论
|
||||
|
||||
P2 第 3 次请求的 C8 是**工具名未声明**,不是参数 schema 不符。原因是宿主的 final-only 阈值与任务指令冲突:第 2 个检查点保存后,宿主把第 3 次请求切到 final-only,从工具声明里移除了 `publish_work_checkpoint`;任务指令却要求模型按 reading → crosscheck 推进,模型仍去调用 `publish_work_checkpoint`。
|
||||
P2 第 3 次请求的 C8 是**工具名未声明**,不是参数 schema 不符。第 3 次请求被宿主切到 final-only,从工具声明里移除了 `publish_work_checkpoint`;模型按任务指令(reading → crosscheck)仍去调用它。final-only 由两个条件同时触发:已保存 2 个检查点;30000 预算在 4000 输出上限下只够再留一次最终答复。即使只存了 1 个检查点,第 3 次也会是 final-only。根因是:A01 的预算只够两轮检查点请求加一次最终答复,任务指令却期望至少两个阶段再加最终答复;同时模型无视了 final-only 系统提醒。
|
||||
|
||||
所以「schema 不符时不丢弃整轮、交给工具层返回可修正错误」这一改法**不适用于本次失败**,即使实施也不会让 P2 通过。
|
||||
|
||||
@@ -12,11 +12,11 @@ P2 第 3 次请求的 C8 是**工具名未声明**,不是参数 schema 不符
|
||||
|
||||
| # | 事实 | 来源 |
|
||||
|---|---|---|
|
||||
| E1 | 物料子 Agent 在 `SavedCheckpoints >= 2` 时无条件进入 final-only(预算充足同样触发) | Backend `internal/runtime/material_final_reserve.go:30` |
|
||||
| E1 | 物料子 Agent 在 `SavedCheckpoints >= 2` 或 `remaining <= 2*(LastPrompt+OutputCap+margin)` 时进入 final-only | Backend `internal/runtime/material_final_reserve.go:21-30` |
|
||||
| E2 | final-only 请求从 `requestDecls` 中删除 `publish_work_checkpoint`,并插入系统提醒「不再发布检查点」 | Backend `internal/runtime/sub_loop.go:125-148` |
|
||||
| E3 | P2 在第 3 次请求前已保存 2 个检查点(均 ok、0 拒绝),且 `phaseId` 只出现过 `reading` | P2 数据库 events |
|
||||
| E4 | 第 3 次请求的预算核算:已用 12317、上次 prompt 5926、limit 30000,剩余 17683 > 5926+1481,不触发 stop;E1 触发 final-only | provider-records 第 1、2 次 usage,按 E1 公式计算 |
|
||||
| E5 | 第 3 次 prompt_tokens 为 5160,比第 2 次的 5926 少;cache_read 从 5503 跌到 128。历史变长、prompt 反而变短且前缀缓存失效,与「删去大段检查点工具声明」一致 | provider-records 第 2、3 次 |
|
||||
| E4 | 第 3 次请求的预算核算:已用 12317、上次 prompt 5926、outputCap 4000、limit 30000。剩余 17683 > 5926+1481,不触发 stop;17683 <= 2×(5926+4000+1481)=22814,且已存 2 个检查点,两个条件都触发 final-only | provider-records 第 1、2 次 usage 与 outputCap,按 E1 公式计算 |
|
||||
| E5 | 第 3 次 prompt_tokens 为 5160,比第 2 次的 5926 少。历史变长、prompt 反而变短,与「删去大段检查点工具声明」一致。cache_read 从 5503 跌到 128,由删声明与在首条 system 后插入提醒共同造成 | provider-records 第 2、3 次;`sub_loop.go:137-148` |
|
||||
| E6 | 第 3 次思考末句为「Now crosscheck phase.」,随后发出一个 1000 字节、可解析的工具调用;任务指令要求 crosscheck 阶段调用 `publish_work_checkpoint` | P2 数据库;Backend `internal/runmgr/material.go:306` |
|
||||
| E7 | C8 = `callsDeclared` 失败,即工具名不在本次请求声明中,或顶层 `argschema.Validate` 失败 | agent-native `runtime/llm/route_contract.go` `check`/`callsDeclared` |
|
||||
|
||||
@@ -25,7 +25,7 @@ E1、E2、E4 是确定性代码路径,可以确定第 3 次请求未声明 `pu
|
||||
## 对「schema 不符交给工具层」的只读评估
|
||||
|
||||
- **不解决本次问题**:本次是名称未声明,不经过 schema 分支。
|
||||
- **schema 分支本身风险有限,但收益也有限**:`argschema.Validate` 只校验顶层,即必填项非空、顶层原始类型、未声明的顶层键,不递归 `findings`。证据结构等深层错误本来就由工具层返回可修正结果。
|
||||
- **schema 分支本身风险有限,但收益也有限**:`argschema.Validate` 只校验顶层,即必填项非空、顶层原始类型,以及在声明了 `properties` 时拒绝未声明的顶层键;不递归 `findings`。证据结构等深层错误本来就由工具层返回可修正结果。
|
||||
- **改契约语义需要设计评审**:C8 是 O2 已批准契约的一项。放宽后,一次顶层违规会从「终态失败」变成「多一轮请求」,影响付费上限的估算。
|
||||
- **即使没有契约也是终态**:final-only 阶段调用检查点时,`runTool` 返回可修正错误,但同时置位 `finalOnlyRejected`;下一次请求直接以 `checkpoint requested after final-only transition` 结束(`sub_loop.go:109-110`、`380-388`)。所以单改契约不能把它变成可恢复路径。
|
||||
|
||||
@@ -35,8 +35,8 @@ E1、E2、E4 是确定性代码路径,可以确定第 3 次请求未声明 `pu
|
||||
|
||||
| 选项 | 做法 | 影响 | 建议 |
|
||||
|---|---|---|---|
|
||||
| F1 | 让模型知道上限:达到阈值的那次检查点,工具结果明确写「检查点已满,下一步直接写最终结论」;任务指令把「先 reading 再 crosscheck」改为与 2 次上限一致(例如第 2 次即 crosscheck) | 只改 Backend 物料提示与工具结果文字,不动契约;零付费单测可以验证请求声明和结果文本 | **推荐** |
|
||||
| F2 | final-only 阶段保留检查点声明,由工具层拒绝,并去掉 `finalOnlyRejected` 终止 | 前缀缓存稳定(本次缓存从 5503 跌到 128),但每次违规多一轮付费请求 | 备选 |
|
||||
| F1 | 让模型提前知道下一次是 final-only:宿主按 E1 的两个条件,判定下一次请求将是 final-only 时,在当次检查点工具结果里写明「下一步直接写最终结论,不再发布检查点」;任务指令把阶段要求改为与预算一致(例如第 2 次检查点即 crosscheck,或预算紧时允许跳过)。本次的 final-only 系统提醒已被无视,所以工具结果提示是否有效必须付费复验 | 只改 Backend 物料提示与工具结果文字,不动契约;零付费单测可以验证宿主侧行为 | **推荐** |
|
||||
| F2 | final-only 阶段保留检查点声明,由工具层拒绝,并去掉 `finalOnlyRejected` 终止 | 避免 C8,但每次违规多一轮付费请求,可能击穿最终答复预留;缓存还受插入提醒影响,不会因此稳定 | 备选 |
|
||||
| F3 | C8 对未声明名称改为可修正 | 削弱路由契约,与 O2 设计相悖 | 不建议 |
|
||||
|
||||
F1、F2 是否真能让模型遵守,只能靠付费复验判定;零付费单测只能证明宿主侧行为。
|
||||
|
||||
Reference in New Issue
Block a user