docs(gen): 蒸馏便宜档生成死圈失败模式 + 修复计划(不阻塞内测)
根因实证(amgen-dify-9da8f701):小红线违规(rng/nowMs 裸 Math.random/Date.now) →check FAIL→agent 正确想修但六工具面无增量 edit→改3行变重写22KB→MiniMax 反复 漏 path 参数→连撞4次 stuck 熔断强杀→九门没跑→ok=False。品类跑偏真但非因(对照 dify-1783477578 同动作类 brief 成功改出 Shmup);读多写少是常态非杀手。 蒸馏 cheap-model-game-generation.md §11(失败模式+非根因清单+可追溯缺口)。 计划 2026-07-08-便宜档生成死圈修复(上级=便宜档M3 cutover):fix①增量修改工具+ 畸形参数纠偏(最高杠杆)/fix②模板 rng/nowMs 默认合规+check 报错指行/fix③ brief 落盘。阻塞判断:不阻塞已交付 A 段、非内测 beta 硬阻塞(死圈少数模式+飞轮迭代), 归便宜档质量线排期 fix① 优先。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b9d73ae3c7
commit
47f0f404e1
@ -59,7 +59,7 @@
|
||||
| `staging-ops.md` | staging 运维配方:机器分工/代码同步/后端重部署/前端构建门/冒烟门/compose 部署 mini-infra |
|
||||
| `ui-walkthrough-cdp.md` | 真 UI 走查配方(CDP on mini-desktop):studio/admin 走查 + CDP 七坑 + 信道探针 |
|
||||
| `game-e2e-cdp-harness.md` | Canvas 游戏 e2e 证据 harness:驱动器六律 + 出厂红线 + 九门真玩(A–G 假绿守卫 + H 机制/latch + I 控制手感) |
|
||||
| `cheap-model-game-generation.md` | 便宜模型生成跨路通用蒸馏:成本/前缀缓存降本/L1 纪律坑/质量三层/scale-20 模型画像(旧 gamedef/factory 路已压缩留指针,现行走 cheap-worker) |
|
||||
| `cheap-model-game-generation.md` | 便宜模型生成跨路通用蒸馏:成本/前缀缓存降本/L1 纪律坑/质量三层/scale-20 模型画像(旧 gamedef/factory 路已压缩留指针,现行走 cheap-worker)+ §11 AgentScope harness 死圈失败模式(小瑕疵→整文件重写→MiniMax 漏 path→stuck 熔断→九门没跑→ok=False;根因实证 2026-07-08) |
|
||||
| `agentic-amodel-generation.md` | 底层 A-model 生成 harness(`gen.mjs` ReAct 工具循环:scaffold→读写检构→循环外 play):8 坑 + M3 实证;现行被 cheap-worker shell-out 复用 |
|
||||
| `gen-path-parity-harness.md` | 两条生成路对照(parity)harness + 按品类 ≥80% 达标门 + auto-vs-golden 双驱动 delta 门:验换实现不回退 / 判够不够格上线 |
|
||||
| `saa-graph-orchestration.md` | SAA 图编排远期备查(SAA 降最低优先级):依赖集/接 new-api 剥 /v1 坑/checkpoint saved_at 无 tiebreaker + 显式 checkPointId 修法 |
|
||||
|
||||
@ -98,3 +98,20 @@ SAA gameDefinition 路已随 reframe 废(A-model 直写真 `src/`)。Plan B
|
||||
- **别归『模型造不出』**(呼应 §9 末红线):同档 §9 实证 flash / 九门路曾产可玩打砖块 → 非绝对天花板;只在一条配置测 2 轮就判天花板 = 伪报,根因常是模型选择 + prompt 局限。
|
||||
- **杠杆排序(复杂机制保真)**:few-shot 对复杂机制无效(LLM 无视/复现不出)< 换更强模型 / skeleton-first 确定性骨架(结构强制、LLM 只填参,绕过坍缩);简单玩法 few-shot + 保真铁律有效。
|
||||
- **质量门 ≫ gen 自评 accept**:gen 的「accept ≥80%」放过 assets=0 / 静止不可玩 / 不忠实 / 雷同 / 几何占位 的游戏——只有 real-play(帧变=真玩)+ rubric(设计保真)+ 三契约逮得住,质量门不可由 gen 自评代替(此结论跨路有效,现行便宜档九门 + LLM 丰富度验证同理)。
|
||||
|
||||
## 11. 便宜档 AgentScope harness 失败模式:小瑕疵→整文件重写→漏参熔断死圈(2026-07-08 根因实证)
|
||||
|
||||
一次真实失败运行(`amgen-dify-9da8f701`,brief=躲避掉落街机,最终 `ok=False`)暴露出一条**结构性死圈**,它不是玩法差、不是模型造不出,而是工具面缺一条增量修改路径把「可恢复的小瑕疵」推成了「整局失败」。链条是这样的:agent 写出的 `game-logic.js` 带了个小红线违规——`rng()/nowMs()` 在 ctx 不可用时回退用了 `Math.random()/Date.now()`(`game-logic.js:125/127`),`check` 的 `\bMath\.random\s*\(` 纯文本正则照样命中,判 FAIL;agent **正确地**想去修它,但便宜档六工具面只有整体覆盖的 `write_file`、没有增量 edit——于是「改三行小函数」被迫变成「重写 22KB 整文件」,而 MiniMax 在吐这么长的 tool-call 参数时**反复把 `path` 字段整个漏掉**(Service 日志 `Input validation failed for tool 'write_file': 'path' is a required property` 连撞四次,前面还先幻觉调了个根本不存在的 `edit` 工具);四次相同签名失败触发 tier2 `stuck` 熔断,`ChatService.run` 抛 `Tier2CircuitBreak` 强杀回合,**九门收口从未运行**(`_wg1-gen/<id>/` 目录不生成、无 verdict),`judge_cheap_verdict({})` 判未过 → `ok=False`。
|
||||
|
||||
几条容易误判的地方,写清避免下次栽:
|
||||
|
||||
- **`check` 工具 `state=success` ≠ 结果 PASS。** AgentScope 记的是工具执行成功,不是校验通过;`read_file` 读不到文件也返 `"ERROR: ..."` 文本、同样记 `state=success`(`cheap_toolkit.py`)。判成败要看工具的**返回内容**,不看 state。
|
||||
- **丰富度分与 `ok` 无因果。** 本局丰富度 8/12、degraded=False 仍 failed——richness 是 reply 结束后另跑的非阻塞旁路评分,`ok` 只认九门 verdict。别拿丰富度当上线判据。
|
||||
- **品类跑偏≠模板锚死,且与 `ok` 无因果。** 本局产出「按序点击」而非 brief 的「躲避掉落」,但对照另一发真运行 `amgen-dify-1783477578`(同为动作类 brief、同六工具面)成功把点圆模板改成了纵向卷轴射击——**模型有能力偏离模板**,跑偏更多是「反复找不到 brief 文件 + 无同品类范例」叠加的把握不稳,不是「克隆 _template 只改 game-logic」硬锚。且就算做对品类,红线没修 + 熔断一样 failed。
|
||||
- **读多写少(读列 : 写 ≈ 3.6~25:1)是系统性常态,不是杀手。** 九发对照全部如此,成功局比本局空转还狠。空转烧钱耗时,但不决定成败;真杀手是上面那条死圈,一旦产物带个需小修的红线就高概率复现,而带**增量 Edit 工具**的运行天然规避它。
|
||||
|
||||
**非根因清单**(别把症状当根因):不是预算/成本(¥4.32 远低于软停 ¥10)、不是上下文压缩崩、不是超时/轮数闸、不是 L1 写保护误伤(错误是「缺 path」不是「拒写」)。
|
||||
|
||||
**附带的可追溯性缺口**:brief 原文在 worker/Service 任何日志与产物里都**没落盘**(worker 只记 trace_id/gameId、Service 没记 input、agent 找的 `start.brief` 根本不存在)——生成的核心输入事后不可审计,该补落盘。
|
||||
|
||||
修法方向(不写代码,排期归便宜档生产 cutover 线):①给便宜档一条**可靠的增量 edit/apply-patch 工具** + 对「连撞同签名畸形参数」做定向纠偏(「你漏了 path,重发」)而非沉默累计到熔断——这是把「只差一个小修」的局从死圈救回的最高杠杆;②让 `_template` 的 rng/nowMs **默认合规**、check 红线报错指到行并点破「函数内回退也算裸调」;③补 brief 落盘。
|
||||
|
||||
61
docs/plans/2026-07-08-便宜档生成死圈修复-plan.md
Normal file
61
docs/plans/2026-07-08-便宜档生成死圈修复-plan.md
Normal file
@ -0,0 +1,61 @@
|
||||
---
|
||||
title: "fix: 便宜档生成死圈修复 — 增量修改路径 + 模板合规 + brief 落盘"
|
||||
date: 2026-07-08
|
||||
status: 草案 · 待评审(执行前过 Codex+Opus 双评审 · 归便宜档生成质量线排期)
|
||||
topic: 便宜档生成死圈修复
|
||||
上级: docs/plans/2026-06-30-便宜档M3-生产cutover-plan.md
|
||||
关联:
|
||||
- .agents/skills/cheap-model-game-generation.md §11(根因实证与失败模式蒸馏)
|
||||
- game-runtime/games/amgen-dify-9da8f701-e561-408b-92f4-8629219ed0d6(取证运行)
|
||||
---
|
||||
|
||||
# 便宜档生成死圈修复
|
||||
|
||||
## 为什么做这件事
|
||||
|
||||
2026-07-08 对一次真实失败运行做了第一性根因分析(全程与证据见 [`cheap-model-game-generation.md §11`](../../.agents/skills/cheap-model-game-generation.md))。结论不是"模型造不出游戏",而是工具面缺一条增量修改路径,把"可恢复的小瑕疵"推成了"整局失败":agent 写出的产物带一个小红线违规(`rng()/nowMs()` 回退用了 `Math.random()/Date.now()`),`check` 判 FAIL,agent 正确地想去修,但便宜档六工具面只有整体覆盖的 `write_file`、没有增量 edit,于是"改三行"变成"重写 22KB",而 MiniMax 吐这么长的 tool-call 参数时反复漏掉 `path` 字段,连撞四次触发 `stuck` 熔断,回合被强杀,九门收口从未运行,`ok=False`。这条死圈一旦产物带个需小修的红线就高概率复现,是当前便宜档成功率的一个结构性拖累。
|
||||
|
||||
本计划把根因收敛出的三处修复排进便宜档生成质量线,按杠杆高低排序,并给出各自的验证口径。它不改生成主线的分档架构,只补工具面与模板的两处结构缺陷加一条可追溯性缺口。
|
||||
|
||||
## 是否阻塞当前计划
|
||||
|
||||
**不阻塞已交付的内测闭环 A 段(登录/额度/dify/facade)。** 那条线与生成质量正交,已合并 dev/2.0.0 并逐环真机验证。
|
||||
|
||||
**也不构成内测(beta)启动的硬阻塞,但影响生成成功率。** 判据三条:其一,这条死圈是少数失败模式而非多数——九发同期运行对照里只有本局没跑到九门,其余都进了收口门;其二,内测阶段验收口径是"能用就行",且数据飞轮本就设计来持续改进生成质量,不要求上线即完美;其三,内测硬闭环此前已真机产出过可发布游戏(studio 路 quered→发布,quality=60)。所以内测可以在带已知生成质量注记的前提下启动,这三处修复是把成功率往 MVP ≥80% 门抬的改进项,归便宜档生产 cutover 线(本计划上级)排期,fix① 优先。
|
||||
|
||||
## 三处修复(按杠杆排序)
|
||||
|
||||
### fix① 增量修改路径 + 畸形参数定向纠偏(最高杠杆)
|
||||
|
||||
问题的要害是"改一处小函数在便宜档只能表达为重写整文件",而重写整文件恰好落在 MiniMax tool-call 参数最不稳的超长区间。两个动作:
|
||||
|
||||
- **给便宜档一条可靠的增量修改工具**(edit / apply-patch,只传一段 diff 或"旧串→新串"替换)。agent 本能就在调不存在的 `edit`(trace 里幻觉调用坐实),说明模型预期存在增量工具;补上它,让"改 rng 三行"表达为几行 diff,不再触发 22KB 整体重写的畸形高发区。
|
||||
- **对"连撞同签名畸形参数"做定向纠偏而非沉默熔断**。现在 `stuck` 熔断对"参数畸形类"失败过于刚性:agent 每次都在犯同一个 MiniMax 参数病(漏 `path`),被沉默累计到第四次直接强杀。检测到连续同签名工具失败时,给 agent 一条结构化的强提示("你漏了 path 参数,请重发"),很可能一次就破圈。这需要在 tier2 `CircuitBreakerMiddleware` 的 stuck 判定前插一层"畸形参数可纠偏"分支,便宜档复用。
|
||||
|
||||
边界与风险:增量工具的写保护(L1 plumbing 仍不可改)与 `check` 触发口径要与现 `write_file` 对齐,别开出一条绕过校验的旁路;纠偏提示要有次数上限,防止把"真死圈"拖成无界重试烧钱。
|
||||
|
||||
### fix② 模板默认合规 + check 报错无歧义(中杠杆)
|
||||
|
||||
`rng()/nowMs()` 的"ctx 不可用回退 `Math.random()/Date.now()`"是模型反复犯的同一个错——本局 agent 甚至自信到把"check 不拦函数内部"写进注释,而这理解是错的。两个动作:
|
||||
|
||||
- 在 `_template` 的 `rng()/nowMs()` 起点就钉死合规写法(回退也走注入的确定性源,或直接不给裸 `Math.random`/`Date.now` 的写法示范),让合规成为 agent 克隆的默认。
|
||||
- 让 `check` 的红线报错**指到行号**并点破"函数内回退也算裸调、正则按纯文本命中"——消除 agent 对规则的误解,减少它写出违规再去修、进而落入 fix① 死圈的概率。
|
||||
|
||||
这一处只影响质量与死圈触发频率、不影响 `ok` 判据本身,杠杆低于 fix①,但它减少 fix① 的触发面,两者叠加收益更大。
|
||||
|
||||
### fix③ brief 落盘补可追溯性(低杠杆但必要)
|
||||
|
||||
生成的核心输入 brief 原文在 worker 与 Service 的任何日志、产物里都没落盘(worker 只记 trace_id/gameId,Service 没记 input,agent 找的 `start.brief` 根本不存在)。这让"生成为什么跑偏、有没有完整拿到 brief"事后无法审计——本次根因分析里"brief 是否完整传入 agent"就是唯一的观测盲区。把 brief 原文落进 job 目录(如 `game_dir/brief.txt` 或 evidence 摘要),成本极小、对每一次失败复盘都有用。
|
||||
|
||||
## 验证
|
||||
|
||||
按便宜档生成线口径,用 **n=5 收敛环**验证,不做 n≥30 统计批:
|
||||
|
||||
- fix① 后,构造/复现"产物带一个需小修红线"的局,验证 agent 能经增量工具或纠偏提示把红线修掉、跑到九门收口,而不是熔断——n=5 里死圈复发率显著下降即收敛。
|
||||
- fix② 后,验证新生成的产物默认不带 `Math.random/Date.now` 裸调、check 首过率上升。
|
||||
- fix③ 后,验证每次运行 `game_dir` 落有 brief 原文,失败复盘可读到输入。
|
||||
- 三处都跑真环境(cheap Service :8300 真 agent loop),不用桩;收口把成功率变化记进便宜档质量线的达标账,判是否够 MVP ≥80% 门另走统计样本。
|
||||
|
||||
## 归属与排期
|
||||
|
||||
归便宜档生产 cutover 线(本计划上级 [`2026-06-30-便宜档M3-生产cutover-plan.md`](2026-06-30-便宜档M3-生产cutover-plan.md))。执行前按 AGENTS.md §6.8 过 Codex+Opus 双评审。fix① 优先,fix②/③ 随后。不在内测启动的关键路径上,但建议内测放量前完成 fix①,以免种子用户高频撞死圈。
|
||||
Loading…
x
Reference in New Issue
Block a user