2026-07-09 创始人方向性质疑经五路审计坐实,正式推翻两个历史结论(80% 天花板=口径混淆 +stripCode 污染;玩法坏死主因=判卷合约缺口误标),病根三条=判定语义膨胀/判卷合约反噬/ 真相层缺失。本批为纯文档批: - 诊断档 docs/brainstorms/2026-07-09-生成线harness方向性诊断与换轴方向.md(人审版) - SoT 修订×4(双评审修入、docs-gate 绿):质量模型裁定三(L1 双证据=机械预筛∧独立模型 玩法判定,fail-closed+金标校准)/图说护城河改「分层验收」/验收门 §2.4/AGENTS.md §3.1 - 执行版 plan×2:07-09 三波换轴 + 07-10 验收v2(测试agent替E/G/H,创始人已批, 含附录A SoT 修订逐字终文与波0-3 工单拆分) - 策展层定点勘误:tech-decisions/三份生成线 skill 追加 2026-07-09 勘误注记(过九门 自此只算机械预筛),feature-design-doc 固化「人审版=brainstorm/SoT、执行版=plan」定位 - 在飞板登记 W-AXIS Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
261 lines
75 KiB
Markdown
261 lines
75 KiB
Markdown
# 技术决策事实蒸馏(ADR 风格)
|
||
|
||
> 蒸馏来源:`docs/architecture/架构/README.md`(§6 决策记录、§6.6/6.7/6.8 工具链,最权威)、`docs/architecture/架构/13模块.md`(各模块技术栈/边界)、`docs/architecture/架构/README.md`、`docs/superpowers/specs/mvp-execution-spec-design.md`(执行约束)。
|
||
> 目的:让后续 Agent 一篇掌握"为什么这么选、放弃了什么、风险在哪、哪些还没拍板、哪些源档互相打架"。
|
||
> 相关:架构与模块见 [`product-and-architecture.md`](./product-and-architecture.md);范围里程碑见 [`mvp-scope-and-milestones.md`](./mvp-scope-and-milestones.md);红线约束见 [`../rules/security-and-reliability.md`](../rules/security-and-reliability.md)、[`../rules/engineering-conventions.md`](../rules/engineering-conventions.md)。
|
||
|
||
总原则(一句话):**用开源生态组合替代烧钱自研,钱与人力集中在竞品做不了的"游戏流分发 + 创作者变现闭环 + 数据驱动优化"。** 所有核心组件均开源/可替换,无单点供应商锁定。
|
||
|
||
---
|
||
|
||
## 1. 关键决策表(ADR)
|
||
|
||
> **⚠️ 回填(2026-06-10,HJ-AUDIT-001;再回填 2026-06-12;三回填 2026-06-15 HJ-AGI-002)**:下表「AI 生成引擎」行已被取代两轮——~~C2 裁定后 MVP 主线=模板驱动(LLM 直出 GameConfig+固定模板)~~ → **现行主线=agent 写码于插件库**(HJ-GEN-001 终审 2026-06-12:游戏模板/填参线随 W-CLEAN 清除退役;**「玩法模板」(品类框架·引导生成·非 pre-built 代码)未废=有效·待建但非最高优先级(最高=Tier 0 生成可靠,玩法模板排其后;HJ-DEMO-AUDIT-001 创始人 06-17,见完成度与优先级总账)**;生产生成=便宜模型经 new-api+harness 门。**~~agentic 基建=SAA(Spring AI Alibaba v1.1.2.2)裸图编排 (HJ-AGI-002;short-term SAA-only,AgentScope 降 long-term premium 独立轨)~~ — 此「SAA-only / AgentScope 降 premium」结论已被 2026-06-25 框架 reframe 推翻(superseded):框架统一收敛 AgentScope(三档共用一个 agent 框架),SAA / dify / coze 降最低优先级、留作「远期适配验证可插拔」目标。HJ-AGI-002 当时确实在产、是历史事实,但其分轨口径不再现行。**)。Dify/OpenGame 均未部署、降级远期。§1.1 Tier1 行的「OpenGame 文生代码」同此。
|
||
> **⚠️ 回填(2026-06-11,Tier1 重设计·创始人专门会话)**:下表「游戏运行时」行的 **Tier1「自研 Canvas<15KB」被二次质疑裁定取代**——自研壳实为机制演示(资产载而不绘/零 juice/只胜不败),手搓引擎=critical risk;**15KB 红线废除**(系 srcdoc 内联架构的衍生约束,前提已失效),改为三层约束框架(SLO 地板@千元机+4G P75 / 预算入场券 B1 gz≤350KB·raw≤1.5MB / 工程增强层 E1-E6),引擎=契约下可换的实现,**终裁待 LittleJS vs Phaser eval-spike**。单一事实源:`docs/brainstorms/2026-06-11-tier1-runtime-constraints-requirements.md` + `git show 6d2f8789^:docs/agent-specs/_archive/2026-06-11-Tier1运行时重设计-review.md`(已随 _archive 清理删除、git 定位)。
|
||
|
||
| 决策点 | 选择 | 理由 | 放弃的备选(why-not) | 风险 |
|
||
|---|---|---|---|---|
|
||
| **后端框架** | Huijing Cloud(Java 17 + Spring Cloud Alibaba),fork 二开 | 60%+ 后台能力开箱即用(RBAC/OAuth2/BPM/文件/通知/审计/代码生成/多租户);社区活跃(60k+ star);单体启动可平滑拆微服务 | **NestJS(Node)**:v1 验证可行但缺企业级基础设施,微服务生态弱,后台/工作流要从零建;**Go(Kratos/go-zero)**:性能好但 RBAC/BPM/代码生成无现成方案 | 绑定 Huijing 升级节奏;须守"不改 framework 层"才可升级 |
|
||
| **AI 生成引擎** | ~~Dify(自部署,DAG 编排/多模型)+ OpenGame(Python 微服务,代码生成)+ Java 壳(任务调度)~~ **(本行 1.x 蓝图态,已 supersede——现行=new-api 网关直连便宜模型 + SAA(Spring AI Alibaba v1.1.2.2)裸图编排 (HJ-AGI-002);Dify/OpenGame 降级远期、从未部署,C2/HJ-GEN-001。本行仅留 why-not 决策史)** | Dify 可视化编排/多模型热切换/可观测开箱即用;OpenGame 为 CUHK MMLab 2025 SOTA、6 阶段 pipeline 论文验证、含 benchmark;组合 4-6 周跑通 vs 自研 6-12 月 | **纯自研**:6-12 月,时间不允许;**LangGraph**:纯 Python 无可视化 UI,运营无法参与编排;**Coze**:字节闭源不可控;**n8n**:通用自动化非 LLM 原生 | LLM 不稳定/幻觉(→Fallback 兜底);OpenGame 社区停更(→fork 自维护,可退化为纯 Dify+模板);Dify 升级不兼容(→锁版本+壳层隔离) |
|
||
| **前端** | Vue3 + Element Plus(game-admin)/ Vue3 + Vant(game-studio,移动优先适配 360-430px) | Element Plus 版是 Huijing 官方主推、社区最活跃、文档最全、二开友好度最高;Vant 适配游戏流滑动体验 | **React + Next.js**:与 Huijing 前端生态不一致,二开成本高(v1 用的就是 Next.js,v2 切 Vue3) | 两端两套组件库;C 端游戏流须独立 H5,admin 风格不适用 |
|
||
| **数据库** | MySQL 8.0 | Huijing 默认,社区方案最多,迁移成本最低;需 JSONB/全文检索时再加 PostgreSQL/ES | **PostgreSQL**:JSONB/全文检索更强但 Huijing 适配成本高 | 复杂检索能力弱,靠后续叠加 ES/PG 补 |
|
||
| **消息队列** | RocketMQ 5 | Huijing 默认集成;延迟消息/事务消息/死信队列完整,适合生成任务调度、审核通知、事件摄取、结算触发 | **Kafka**:偏大数据流、运维重,MVP 过度;**Redis Stream**:可靠性不足,无死信/事务消息 | 运维复杂度高于 Redis Stream,但生产更可靠 |
|
||
| **游戏运行时**(分层,见 §1.1) | Tier1 ~~自研轻量 Canvas Runtime(<15KB)~~ **→ LittleJS 增强发行版 + Runner v2(2026-06-12 终裁,15KB 红线废除,详见 §1.1)**;**Tier2/3 复杂2D·3D·原生 用 Cocos Creator 3.8.8 + MCP**〔⚠️ 2026-06-21 纠正:Cocos 仅留 3D/渠道导出轴(编辑器+人在环);自治富 2D 生成轨改 Phaser/Pixi,见 §1.1〕 | Tier1 首屏极快(P75<3s)、AI 生成纯 JS 直接可运行、平台完全控制沙箱;~~Tier2/3 用 Cocos 因 MCP(158工具)可 AI 驱动~~(该理由已被推翻:MCP 是编辑器扩展、非 headless,AI 无法无人值守驱动)、出功能快、一栈覆盖复杂2D+3D+原生/小游戏导出 | **Three.js**:仅 web3D、与 Cocos 重复(不选);**Phaser 3 全栈**:纯 2D、导出弱(~~否决~~ 该否决仅在 Tier1 轻量档冷启动维度;Phaser 是 tier2 自治富 2D 轨选定引擎,见 §1.1);**LayaAir**:无 MCP 生态、清单无快手(否决);**Unity**:AI 适配差、启动重(否决) | Cocos web 包体较重(MB级)→Tier2/3 不进游戏流、走渠道/App 分发;~~Tier1 仍自研薄壳保首屏~~(2026-06-11 回填:Tier1 改成品轻引擎+Runner v2,见 §1.1) |
|
||
| **多渠道导出** | **以"微信小游戏格式包"为统一中转**;Tier2/3 用 Cocos 官方一键导出,Tier1(LittleJS)渠道 adapter 走 W-CH-α 竞标(~~原「自研 Canvas 自做 adapter」随自研壳退役~~,见 §1.1) | 快手无专用导出接口,标准路径=导出微信包→快手开发者工具"微信格式兼容转换";抖音有自有导出接口;导出可异步离线、不影响实时预览 | LayaAir 官方平台清单无快手,不走 LayaAir CLI 路线 | DevTool import 仍需真机验证;三平台各自真机 |
|
||
| **AI 素材工具链** | **图片/音乐现行=mmx-cli(MiniMax,2026-06-12 创始人亲验拍板默认;agent 造游戏直接 CLI 调用,免 GPU/免训练)**;~~图片/角色/场景/封面→ComfyUI(自部署)~~ **ComfyUI 退备选**;~~音乐/音效→Stability Audio API~~;语音/音色→Fish Audio / 阿里 CosyVoice | (以下为 ComfyUI 备选时的理由,留作历史)ComfyUI 节点化、可训 IP 风格 LoRA 出系列一致素材、自部署无审查/无限频、长期成本低于商用 API;Fish/CosyVoice 中文效果最佳、支持 few-shot 音色克隆 | 直接调 **Midjourney/DALL-E API**:无法训风格 LoRA、游戏场景(武器/战斗)易被拒、按次付费贵 | ComfyUI 需 GPU(无 GPU 走 CPU 慢 10x 或 mock/外部 API) |
|
||
| **内容安全** | 图片→safe-content-ai(自部署快检)+ 阿里云内容安全(高风险兜底确认);文本/音频→阿里云审核 API;AI 输出→~~Dify Guardrails 节点~~ **(Dify 未部署已 moot;现行 Prompt 注入检测+输出 schema 校验落在生成侧门禁/Prompt Registry 门,见 [`skills/prompt-governance.md`](../skills/prompt-governance.md))** | 自部署做首道快检(免费/低延迟),高风险样本二次送阿里云确认;阿里云违禁词库持续更新、语义强于规则 | 单一商用 API:成本高且首道检测延迟大 | 双层链路一致性需治理;阈值(block 0.7 / review 0.4)须在 Nacos 调优 |
|
||
|
||
补充选型(同源 §7 治理章,非主决策但已定):Nacos(注册+配置中心,Huijing 原生)、Redis 7(候选集缓存/限流/排行/熔断/分布式锁/幂等去重)、MinIO 本地·阿里云 OSS 生产(对象存储+CDN)、Flowable/BPM(审核/发布/下架流程)、Prometheus+Grafana+Sentry+Jaeger(可观测)、Flyway(DB 迁移)、Sentinel(熔断降级)、穿山甲+优量汇(广告,覆盖 80%+ 国内移动广告市场)、ClickHouse(远期,事件量爆增后从 MySQL 迁移)。
|
||
|
||
存储分层口径(技术决策版 §5.2,"先简后扩"):业务实体→MySQL 8.0;游戏包/素材/封面→MinIO/OSS;推荐候选集/热数据→Redis Sorted Set;事件流→MySQL 分区表(MVP)→ClickHouse(增长期);搜索→MySQL FULLTEXT(MVP)→Elasticsearch(增长期)。
|
||
|
||
### 1.1 分层运行时设计
|
||
|
||
> **⚠️ 引擎口径已更新(2026-06-21 · tier2 触发)**:tier2 自治富游戏生成轨的引擎定为 **Phaser/Pixi(全无头·纯代码)**、agent 框架定为 **AgentScope(Python·独立 service·自治 ReAct)**,Cocos 仅留 **3D/渠道导出轴(编辑器+人在环)**——下表与本 §1.1 凡写「Tier2/3=Cocos+MCP 锁定」「MCP 158 工具可 AI 驱动」「Phaser 否决/落选」处,均按此口径理解,详见本节末 §1.1 supersession 横幅与 tier2 富游戏设计(已并入运行时 SoT `docs/architecture/架构/生成引擎/agentic运行时架构图说.md` §4.2/§5)。**这同时澄清了 §1/§2/§4 里"AgentScope 降 long-term premium 独立轨"的旧口径**:AgentScope 不再只是悬置的远期备选,而是 tier2 富游戏线现行选定的 agent 框架(tier2 核心已落、0 号 spike 已 accept,见 §4 与运行时 SoT `生成引擎/agentic运行时架构图说.md` §4.2/§5)。**进一步:2026-06-25 框架 reframe 已把这层澄清推到底——三档统一收敛 AgentScope(不再「廉价线 SAA-only、tier2 AgentScope」两套基建并存),SAA / dify / coze 整体降最低优先级、留作「远期适配验证可插拔」目标。** 下表保留决策史、只加纠正标注,不删。
|
||
|
||
游戏产物分三层,对应不同运行时:**Tier1 = LittleJS 增强发行版 + Runner v2(agent 写码于插件库生成,HJ-GEN-001;~~原「自研 Canvas + OpenGame 生成」已废除~~,见下表);Tier2/3 统一用 Cocos Creator 3.8.8 + MCP。**(术语澄清:废的是游戏模板/填参线(W-CLEAN),「玩法模板」(品类框架)未废、待建。) MVP 仅交付 Tier1;非目标保持收敛(Tier2/3 仅远期探针,见 §7)。
|
||
|
||
| 层 | 定位 | 选型 | 生成路径 | 状态 |
|
||
|---|---|---|---|---|
|
||
| **Tier1 极轻量H5/2D** | 游戏流即点即玩,首屏 P75<3s + 点卡→可玩 S2(常态≤2s) | ~~自研轻量 Canvas Runtime(<15KB)~~ → **LittleJS + Runner v2(2026-06-12 创始人终裁,spike 85/82:冷开 0.54s vs 2.86s=4.8~5.3×/引擎 15.9KB gz/敏感性分析裁量分拉平 S2 硬差仍定向,终裁包 `git show 6d2f8789^:docs/agent-specs/_archive/2026-06-11-T1引擎终裁包.md`(已删、git 定位))**:引擎 URL 化交付享 HTTP+编译双缓存;~~模板双层架构~~ → **模板=LittleJS 能力插件/二次开发件**(2026-06-12 模板哲学重申:游戏模板/填参线废,玩法/美术/关卡/UI=agent 生成域(玩法模板=品类框架·未废·待建),好玩基线 v2 改挂评估门;**裁决①(2026-06-12):粒子/物理/后处理插件=引擎能力包装层,禁在受控面墙内平行重造引擎内建能力,β 设引擎真接线门;Q4 补裁(2026-06-13):「自研内容是引擎外的层,不是对引擎本体的替代」——「有意替代」豁免关闭,自研仅限包装层/引擎缺件补层,确定性取证诉求在 harness/门侧解决(手搓 Canvas2D 零实测证据优于引擎内建,且自揽平台渲染差异债)**);iframe 沙箱 + SDK 注入不变 | ~~LLM 填参~~ → **agent 写码于插件库**(HJ-GEN-001 终审;旧填参线随模板废除退役;美术/音乐=mmx 优先,2026-06-12 拍) | ✅ W-T1b 主门过(拔高样板「暖阳小卖部」2026-06-12 创始人亲玩判 passed),**MVP 唯一交付层**。真护城河=沙箱/SDK/契约/三容器(全保留);存量 1.x 双轨冻结;引擎复议权=拔高暴露引擎级阻塞(终裁包 §4.5-3) |
|
||
| **Tier2 复杂2D+3D** | 中重度含 3D,渠道分发 | **Cocos Creator 3.8.8 + MCP**(备选 PlayCanvas)〔⚠️ 2026-06-21 纠正:此「锁定」仅指 3D/渠道导出轴,Cocos 用编辑器+人在环;自治富 2D 生成轨改 Phaser/Pixi〕 | **Cocos-MCP** agentic 工具编排(studio 编排) | ✅ 锁定(限 3D/渠道导出轴)。~~MCP 158 工具可 AI 驱动~~ 系事实错——该 MCP 是 Cocos 编辑器扩展、需编辑器在跑、非 headless,故进不了无人值守自治生成 loop;MVP 至多 1 个探针 demo |
|
||
| **Tier3 独立App** | 打包为原生应用 | **Cocos 原生导出**(同 Tier2 引擎) | 同 Tier2 + 打包 | ✅ 锁定引擎。否决 Unity(AI 适配差、启动重);MVP 后投入 |
|
||
|
||
**自研工期评估(为什么 Tier2/3 复用 Cocos 而非自研)**:Tier1 薄壳约 0.5–1.5 人月(可行,且必须自研以控沙箱/SDK/三容器预加载);自研 3D 引擎数十人月~数年、自研原生框架数十人月——3 周窗口下绝不可行,必须复用成熟引擎。选 Cocos 因其一栈覆盖复杂2D+3D+原生/小游戏导出,~~且 MCP(158工具)使 AI 驱动可行~~(**2026-06-21 纠正:该 MCP 是编辑器扩展、非 headless,无法无人值守驱动;Cocos 此处仅指 3D/渠道导出轴的人在环作者,自治富 2D 生成轨改 Phaser/Pixi**)(与"开源组合替代烧钱自研"总原则一致)。**(2026-06-11 回填:「必须自研以控沙箱/SDK」已被推翻——控制点在沙箱/SDK/契约层,与渲染引擎解耦;Tier1 渲染层亦改复用成品轻引擎,自研壳退役,见 §1.1 表)**
|
||
|
||
**导出枢纽 = 微信小游戏格式包**:微信=引擎导出官方格式;抖音=自有导出接口;**快手=无专用接口,走"微信格式兼容转换"**(快手开发者工具)。**LayaAir 官方平台清单无快手**,不走 LayaAir CLI 路线。Tier2/3 用 Cocos 官方一键导出微信包;Tier1(LittleJS)渠道 adapter 走 W-CH-α 对比竞标(LittleJS+自研 adapter vs Cocos 导出,HJ-CH-001 §4;~~「Tier1 自研 Canvas 自做 adapter」随自研壳退役~~)。
|
||
|
||
> 选型依据:Cocos 3.8.8/MIT 一栈覆盖2D/3D/原生导出,故 **3D/原生/渠道导出轴** 选 Cocos;Three.js r184/MIT/113k★ 仅 web3D、与 Cocos 重复故不选;LayaAir 2.1k★、无 AI/MCP 生态、清单无快手(否决);Unity 启动 7-10s×2-3 与 P75<3s 冲突(否决)。
|
||
> **⚠️ supersession + 纠错(2026-06-21 · tier2 触发)**:上句原作"headless MCP(158 工具) 使 AI 驱动可行"**是事实错**——Cocos 的 MCP 是**编辑器扩展、需 Cocos Creator 在跑、非 headless**(取证级核实),故 Cocos **进不了 tier2 全自治生成 loop**。引擎重定为正交两轴:**自治生成轨(全无头:富 2D=Phaser/Pixi、轻量档=LittleJS)** vs **3D/渠道导出轴(Cocos,编辑器+人在环)**;Phaser 的"spike 落选"只在 Tier1 轻量档冷启动维度、与 headless 自治维度正交。本表其余 Tier2/3=Cocos / Phaser 否决 行均按此口径理解。详见 tier2 富游戏设计(并入运行时 SoT `docs/architecture/架构/生成引擎/agentic运行时架构图说.md` §4.2/§5,引擎选型)。
|
||
|
||
---
|
||
|
||
### 1.2 A11 调整回路(试玩后纠错 · 切片三 2026-06-29)
|
||
|
||
用户试玩生成的游戏后用自然语言提调整,这条回路在便宜档线落地。架构 = **A 两段式**:判意图(`/modify/plan` 收原话 → 便宜档 worker 取 base 源 + 一次轻 LLM 把自然语言分类成 `mode/target/payload` + 风险)与执行(用户确认后调已结构化的 `/modify`)分离成两次请求,HITL 走前端在两次调用之间的确认——绕开"自然语言进不了已结构化的执行入口"与"危险回问做成任务内暂停态却撞上内部状态机无暂停态"两道阻断(A2A 原生 input-required 暂停态留后期)。可改性的根基是生成侧**工程规范性**:资产统一在 `assets.js`、数值集中在 `core.js`,使一次修改落到"那一处",这是生成质量、不是给调整加静态门(判意图仍 LLM 驱动)。执行分两档:确定性类(换资产 / 调数值,改一处、零 LLM)+ 模块重生成(改玩法,有界单文件重写、复用续跑与三层校验)。验收 = 九门 + 三层校验 + **三断言**(改动真生效非 no-op / 非目标模块字节稳定[改前改后真比对、不信执行器自报] / 新版本血缘可查)。
|
||
|
||
**现状**:便宜档代码完成、本机逐段一手真验(真九门、真 LLM 重写、断言集成 smoke);受计费真后端 e2e 排部署窗口(创始人 2026-06-29 定不动 live);复杂档随 tier2 跟进。关键收敛:A11 后端骨架(契约 / `/modify` 编排 / `game_source_project` 血缘 / D12 配额)已大面积落地,真活在便宜档接入 + 判意图/执行/三断言。设计面 SoT = 运行时 SoT [`生成引擎/agentic运行时架构图说.md`](../../docs/architecture/架构/生成引擎/agentic运行时架构图说.md) **§六**;执行留痕 = `git show 8ea97234:docs/plans/2026-06-28-003-feat-studio-A11-对话式调整回路-plan.md`(`git show git show 8ea97234:docs/plans/2026-06-28-003-feat-studio-A11-对话式调整回路-plan.md`)。
|
||
|
||
---
|
||
|
||
## 2. 这些选型如何服务护城河(为什么"够用即可")
|
||
|
||
投资人版与技术决策版口径一致:**技术深度不追第一,生态完整度追第一。** 生成能力会被通用大模型 12-18 个月追平,故选型刻意"够用、可替换、低成本",把自研投入压在竞品的空白——游戏流分发与变现闭环。真正壁垒:① 游戏流推荐数据壁垒(真实流量积累,无法购买)② 生成质量反馈闭环(玩家数据→quality_score→优化建议→创作者迭代)③ 模板/素材/工作流资产沉淀(马太效应)④ 广告位 AI 优化(提升 eCPM)。对应的工程取舍:自研只做 feed/telemetry/SDK/变现链路/**发行版包装层与契约**(~~runtime~~ 出列:渲染循环=LittleJS,自研面只剩引擎能力包装与插件协议——2026-06-12 审计 R5 纠正「护城河预划过粗给自研免检光环」;agentic 编排自研只剩护城河件——checkpoint + 验收门;框架本身(2026-06-25 reframe 后三档统一收敛 AgentScope,SAA / dify / coze 降最低优先级、留作远期适配验证可插拔目标)采主流标准对接、不自研),其余(后台、工作流、生成、素材、安全)全用开源/商用组合。**Build-vs-Buy 硬门=[`.agents/rules/build-vs-buy.md`](../rules/build-vs-buy.md)。**
|
||
|
||
---
|
||
|
||
## 3. 待确认项(源档明确标注未拍板,勿当既定事实)
|
||
|
||
来源:架构选型审阅版 §11 + 技术决策版 §1.2 指标口径。后续若已敲定,应回填本表并注明决策时间。
|
||
|
||
| # | 待确认项 | 候选 | 出处 |
|
||
|---|---|---|---|
|
||
| 1 | ~~MVP 首选 LLM~~ → **已拍板**(D1,2026-06-08):主 DeepSeek + 备 Qwen,不接 OpenAI;**现行实际 = new-api 网关多模型可用**(2026-06-14 网关探活实测:`deepseek-v4-flash`/`deepseek-v4-pro` + `MiniMax-M2.7`/`M3` 渠道全活;W-G1 L1 冒烟用 `deepseek-v4-flash` 打底、`pro` 升难档——原「DeepSeek key 未激活」已过时) | — | `2026-06-08-mvp业务决策.md` D1 |
|
||
| 2 | v1 运行时资产移植方式 | Canvas2D 渲染 + 小游戏转换逻辑:移植为 Java 服务,还是保留 Node 微服务 | 选型审阅版 §11.2 |
|
||
| 3 | 产品端域名方案 | game-studio 与 game-admin 同域不同路径,还是不同子域名 | 选型审阅版 §11.3 |
|
||
| 4 | ~~MVP 登录方式~~ → **已拍板**(2026-06-10 七项全拍,见 `2026-06-10-真实鉴权与匿名玩家-review.md` §9.1):**C 验证码为主+邀请码旁路**、玩家开放注册(受限期凭邀请码)、创作/发布限 A2 白名单、互动即弹一键登录、实名提现前收、匿名=纯客户端 anonId+聚合侧剔除(glossary/contracts 已同步修订);待出 execution 版排建设(建议 M-b 后) | — | 鉴权评审版 §9.1 |
|
||
| 5 | Tier3 独立App 运行时引擎 | **Cocos Creator 3.8.8 + MCP 统一 Tier2/3(见 §1.1)** | 运行时选型研究 |
|
||
| 6 | ~~MVP 模板集不一致(R4)~~ → **已拍板**(2026-06-10 创始人复审):**维持 D2 集合,按 D2 改建**——M-c 建 idle/tycoon/merge runtime(clicker 保留,顺序建议 merge→idle→tycoon);dodge/runner/match schema 降 P1 保留契约不删。回填见 `2026-06-08-mvp业务决策.md` D2 复审注 | — | HJ-AUDIT-001 R4 + mvp业务决策 D2 |
|
||
|
||
---
|
||
|
||
## 4. 关键口径(落地前以此为准)
|
||
|
||
> 多份源档由不同子代理产出,下列口径已统一裁定,落地一律以本表权威单值为准。整体原则:**蓝图/选型以技术决策版(HJ-ARCH-001)为准,执行/排期以 mvp-execution-spec(HJ-MVP-SPEC-001)为准。** 投资人版(HJ-ARCH-002)仅作对外叙事,不作技术依据。
|
||
|
||
| 口径点 | 权威结论 |
|
||
|---|---|
|
||
| **运行时技术栈** | Tier1=**LittleJS(2026-06-12 终裁)**+Runner v2(原自研<15KB 壳退役、存量 1.x 冻结);Tier2/3=Cocos Creator 3.8.8+MCP〔⚠️ 2026-06-21 纠正:Cocos 仅留 3D/渠道导出轴,自治生成轨=Phaser/Pixi〕(见 §1.1)。Three.js/LayaAir/Unity 仍否决;Phaser 经 spike 竞标落选(该落选只在 Tier1 轻量档冷启动维度;Phaser 是 tier2 自治轨选定引擎——败于冷开/交付形态,工程质量合格,证据留 spike 目录) |
|
||
| **生成成功率指标** | MVP 验收按 **≥80%** 判定;**≥85%** 为远期蓝图目标,勿用 85% 卡 MVP |
|
||
| **时间线** | 双路线并存:投资人版 5 人/11 周、执行 spec 10 人/3 周;执行排期以 mvp-execution-spec 为准(含逐日计划与里程碑) |
|
||
| **MVP 范围/口径** | MVP 验收以 Doc A 的 **55 项 P0 产品功能**为准;技术实现范围经 Doc C 反查 Doc B(工作量 ≈137 技术项)。详见 [`mvp-scope-and-milestones.md`](./mvp-scope-and-milestones.md) §3 |
|
||
| **模块划分** | **13 模块**(含 game-module-studio 创作编排域,aigc 为无状态生成原子);能力清单拆为产品功能(Doc A)/技术功能(Doc B)/映射(Doc C) 三文档分离 |
|
||
| **生成主线(三档统一 AgentScope、SAA 最低优先级远期适配)** | ~~MVP=模板驱动(LLM 直出 GameConfig+固定模板)~~ → ~~现行是两条并存的生成线~~ → **2026-06-25 框架 reframe:框架统一收敛 AgentScope(三档共用一个 agent 框架),SAA / dify / coze 降最低优先级、留作「远期适配验证可插拔」目标**。三档按 **AI 参与深度**(Tier0/1/2)切分、全部高度模板化(玩法模板 + 工程骨架,不是从零写),引擎是按复杂度的实现变体(轻-中=LittleJS、最高=Phaser),**引擎不是分档轴**。**便宜档**:agent 写真 `src/`(HJ-GEN-001 终审 2026-06-12,旧游戏模板/填参线随 W-CLEAN 退役〔M-b 执行器写链语义保留复用〕),便宜模型经 new-api + harness 九门,引擎=LittleJS;gameDefinition 已废、A-model 写真 src/ 现行(无 factory/gamedef 双轨、无 cutover);per-gen 预算硬闸 <¥10(图/音另算)。已实证地板(W-G1 L1 worker + 九门真玩 + 3 款冒烟,¥0.01–0.03<¥0.15 闸;全 20 款 bake-off + 四模型横比 + Claude-free judge 门待跑,配方见 [`skills/cheap-model-game-generation.md`](../skills/cheap-model-game-generation.md))。**复杂档(tier2 富游戏)**:自治 ReAct agent 用 **AgentScope + Phaser** 造多系统富游戏(合成/经营/挂机这类,对标肥鹅美食街),产物=真 Phaser `src/` 源工程,三层校验兜底;per-gen 预算硬闸 <¥50(图/音另算)。**现状=0 号 spike 已 accept、核心已落**(见运行时 SoT `生成引擎/agentic运行时架构图说.md` §4.2/§5 与 `tier2/HANDOFF.md`)。运行时单一真相 SoT = [`生成引擎/agentic运行时架构图说.md`](../../docs/architecture/架构/生成引擎/agentic运行时架构图说.md)(§5.2 控制面 / §5.7 成本)。Dify/OpenGame=远期增强未部署 |
|
||
|
||
### 4.1 生产质量三层 reframe(创始人亲玩校准锁定,2026-06-14·WG1 review §8)
|
||
|
||
W-G1 实证后创始人亲玩校准拍定:**生产环无 Claude**,质量由**三层**兜底,各司其职、不可互相替代——
|
||
|
||
| 层 | 是什么 | 能判 / 判不出 |
|
||
|---|---|---|
|
||
| **① 确定性门**(地板/可玩性真值,Claude-free) | 九门(A–G 假绿守卫 + H 机制/latch + I 控制手感)+ 适配性真玩 driver(读 state 接球,解盲打假阴性)。手感**尽量拆成确定性门**(latch 终态驻留 / 控制跟手 / 碰撞穿透[门 J 规划]) | 能判:能跑/真接线/有进展/真结束/跟手。拆得掉的全自动判 |
|
||
| **② 便宜 player**(主观层,消费 gate-H) | M3 静态截图 + flash 运行数据,判**拆不掉的主观**好玩/美术/节奏;须人锚校准(`calibrate.py` vs 创始人 `labels.json`) | **判不出物理/碰撞/控制的交互手感**——实证把碰撞有问题的件高估为最佳(两 player 均 fun=4,text 漏控制 bug)。**有结构性天花板** |
|
||
| **③ 创始人抽检**(人锚,现阶段不可替代) | gate-H 盲打假阴性 + player 漂移的最终纠偏 | 没有它会把碰撞有问题的件当"最佳"发出去 |
|
||
|
||
- **"上下文是杠杆"实证**:同 flash 仅改接地(grounding)→ 成本 **−50%**、修复轮次 **−80%**;player rubric 锚定(1-5 分级 + 空心→≤2)把 player MAE **1.25→0.75**。结论 = 工程沉淀在 **agent harness**(任务协议/状态模型/门禁/judge 校准),单次生成是消耗品(harness 复利)。
|
||
- **Opus 定位**:builder / teacher / calibrator——**建好即退,不进生产环**(否则"生产无 Claude"前提破);SAA 框架藏在 job/callback 契约#6 后保持可替换。
|
||
|
||
---
|
||
|
||
## 5. 关键技术风险与降级(技术决策版 §8,决策落地必读)
|
||
|
||
每条决策都自带风险与"降级方案"——这是"够用即可、可替换"原则在工程上的兜底。摘录高/极高影响项:
|
||
|
||
> ⚠️ 下表「LLM 调用不稳定」行的"Dify 重试+熔断"与「OpenGame 社区停更」整行为 1.x 蓝图态:Dify/OpenGame 降级远期、从未部署(C2/HJ-GEN-001),其应对/降级机制已 moot;现行 LLM 不稳定应对=new-api 网关多模型切换 + harness 门兜底,"模板填充"措辞同 §4 已废(填参式游戏模板已废 W-CLEAN)。
|
||
|
||
| 风险 | 概率/影响 | 应对 | 降级方案 |
|
||
|---|---|---|---|
|
||
| LLM 调用不稳定(超时/限流/幻觉) | 高/高 | Dify 重试+熔断;多供应商切换 | 确定性 Fallback 生成器(退化为模板填充) |
|
||
| 生成游戏质量不可控 | 高/高 | JSON Schema 强校验 + 可玩性自动测试 + 模板约束 | 质量不达标不入库 |
|
||
| 游戏沙箱逃逸 | 低/极高 | CSP + iframe sandbox + 无网络 + postMessage 校验 | 检测异常立即销毁 iframe |
|
||
| OpenGame 社区停更 | 中/中 | fork 维护,核心 pipeline 简单可自维护 | 退化为纯 Dify + 模板生成 |
|
||
| 广告联盟审核不通过 | 中/高 | 提前申请资质 + 内容合规前置 | 延迟广告上线,先做订阅/B 端(或先用 mock 广告) |
|
||
| MQ 重复消费致数据不一致 | 中/高 | 消息幂等消费(message_id + Redis 去重) | 定时任务修复 + 告警 |
|
||
| 第三方 SDK 数据泄露 | 低/极高 | 广告/支付 SDK 宿主侧隔离 + 最小权限 | 紧急下线第三方 SDK |
|
||
|
||
### 5.1 便宜档私有方言对模型有量化成本(2026-06-28 对照实验,evidence 见 agent-specs)
|
||
|
||
便宜档让模型直接写一套私有运行时方言(L1/L2/L3 三层骨架 + `createGame` 五法 + `_forensicsView` 契约 + `ctx` 受控面 + 输入收归 L1 + 几十条红线)。母语 vs 方言对照实验(同 brief 点击得分、同模型 MiniMax-M3、各 n=5、用契约无关的 fair-verdict 五信号判据)实测:M3 在母语(标准 Canvas/rAF/addEventListener)下 **5/5 一次成型、3 步、约 14K 输入 token、约 55s**;在现状方言下产同一个能玩的游戏要 **约 26 倍 token、3–9 倍时间**,还出现母语从未有的失败模式(一局磨满 20 分钟未收敛、反复撞静态检查返工、按错路径读插件)。结论:之前记在"M3 弱"头上的低良率/高成本,**很大一部分是方言强加的税,不是模型天花板**(M3 不弱)。
|
||
|
||
⚠️ **方向修正(2026-06-29 创始人纠正,推翻"换母语"初判)**:便宜档按 SoT 定位是"AI 参与深度低的高质游戏"(轻量≠简单,见运行时 SoT §一/§4.1),**不是简单玩具**;L2 插件库是"降 AI 参与=便宜+高质"的核心载体、**不是"税"**。"换母语扔插件"会让 AI 从头写整个游戏 = **升** AI 参与,与便宜档"降 AI 参与"的核心策略正相反,故推翻。本实验测的点击得分恰是产品不做的简单玩具、对象本身无产品意义——它留下的真发现是:**当前 AI 在方言里写 game-logic.js 时,学插件 API 形状的摩擦极大(drawButton 当返按钮对象、define 想批量都是按母语直觉猜错;9 步 358K),"降 AI 参与"的设计意图没兑现**。修正方向(创始人方向 3,分阶段)= ① 保留插件库,让**插件 API 向模型母语直觉对齐**(drawButton 真返按钮对象、define 批量,消除"按直觉写就错"的坑)+ RAG/few-shot/skill 补 API 密度,把学习摩擦降到接近母语;② 扩玩法模板与工程脚手架覆盖,缩小 AI 自由写的面。地基(确定性受控面 + 九门)仍是护城河。详见 `../../docs/agent-specs/2026-06-28-母语vs方言-生成对照实验-evidence.md`(`git show git show 8ea97234:docs/agent-specs/2026-06-28-母语vs方言-生成对照实验-evidence.md`),它给 `git show bb7c2baf^:docs/agent-specs/2026-06-20-生成设计合理性-对抗审查裁决.md`(已随域化重构删除,git 定位)的"表现力硬编码"补量化证据。
|
||
|
||
✅ **落地(2026-06-29 阶段一B 改签名)**:方向①「插件 API 向母语直觉对齐」已全部完成——附 A 15 处可改签名 #1-#15 逐插件改逐插件验:drawButton 返命中矩形(#5,治"误把 void 当返回值"#1 翻车点根因)、sessionScore.add / juice.burst / gamefeel 工厂(免 new)、collision·physics 几何挂实例、Aabb 兼收 {x,y,w,h}(#12)、**ctx.random()·ctx.time() 可调用 + 保留方法双 API**(#1,单点 buildContext 包装、框架内部不破)、audioMusic 语义音名、timer·scene·juice.render doc 钉死。另修一个正交真 bug:check 的 API 静态门方法名正则漏认泛型声明 `get<T>(`、把真实存在的 `save.get` 误判不存在、误杀一整类带存档游戏(`851b86fe`)。`2a20e5e7`→`2be7b718` 共 13 提交,每处单元+确定性验、各插件测试绿、双源 prompt 一致、形状门 11/11 不破。**减摩擦端到端见效**:改签名前栽在 save.get 泛型门 bug 的打地鼠+高分游戏(2 attempts/¥6.69/失败),改后**一次过九门、¥0.64/209s、不 thrash**。剩:方向①的补密度(阶段一C few-shot/RAG)+ 方向②扩模板(数据点门控)。详见 `../../docs/agent-specs/2026-06-29-便宜档降AI参与-减摩擦与扩模板覆盖-设计.md`(在飞设计:`docs/agent-specs/2026-06-29-便宜档降AI参与-减摩擦与扩模板覆盖-设计.md`)。
|
||
|
||
✅ **方向②扩模板 数据点(2026-06-29,难品类经营,修正了假设)**:建经营黄金骨架 `game-runtime/games/_template-shop/`(蒸馏过门的 bake-shop-serve 实证 pattern + 母语化 API + 多样性参数空间 + fill-in 标记,独立过九门)+ 品类路由接入(`scaffold-saa <id> [template]` / `cheap_run.scaffold(template)` / `run_studio(scaffold_template, scaffold_desc)`,缺省回落 _template)。同一咖啡馆 brief 三路对照(n=1):**软脚手架**(给骨架 + 软提示)892 行/¥0.85——AI 把预算填进增富化(自加 combo+VIP)、对 ~890 行基线三指标全平**没降**;**强制换皮**(write_whitelist 锁 game-logic.js、只许改 core 主题数值+render 观感)696 行(-22%)/¥0.34(-51%)/tokens-64%,game-logic **0-diff**、仍过门仍 distinct。**结论:"扩模板降工作面"成立但只在"强制换皮"模式**(脚手架+锁循环只换皮)——降本杠杆不是脚手架本身、是写边界强制;软脚手架买的是质量/过门鲁棒(增富化)、不买成本。取舍:强制换皮省成本但封顶增富化,软脚手架反之。**n=5 收敛环确认(经营,5 个不同店主题 奶茶/书店/花店/拉面/冰淇淋):5/5 全过九门 · 成本均 ¥0.252(-64% vs 基线)· game-logic 全 0-diff · 全 1 轮 · 5 店菜单互异——成本腰斩稳 / 过门 100% / 多款不雷同 三件全确认**。🔴 **创始人纠正(2026-06-29,推翻 reskin 策略框)**:上面 reskin 的成本数据作留痕(锁写省成本机制为真),但**「reskin 锁循环只换皮作阶段二成本主线」= 错、越线、已废**。① **便宜 = LLM 低参与度,不是游戏低质量**;底线 = 2D 丰富游戏(进货/解锁/成长/音乐/丰富玩法),reskin 砍复杂度违背底线;"低参与" = agent 不在引擎/plumbing 上耗(脚手架+插件包了)、精力放游戏设计。② **架构红线:项目代码只做机械确定性的事;玩法/美术/音乐的「丰富生成」= 生成 agent 设计创作职责(靠 [sim-business-game-design](../skills/sim-business-game-design.md) + 组合插件),「丰富校验」= 纯 LLM 验证 agent 非阻塞——绝不写成代码校验、不进九门、不进脚手架**。故"丰富脚手架/脚手架好玩门断言"也废。**修正后下一步**:接 sim-business 设计指导到生成 agent(现 prompt 漏)+ 建 LLM 丰富度验证 agent → 喂 M1 达标门(标=过九门+丰富);脚手架保持轻起点。
|
||
|
||
✅ **切片一收口落地(2026-06-30,上面"修正后下一步"全部交付并验证)**:生成 agent 接上 sim-business 设计指导(`cheap_roles.py` + `prompt.mjs` 双源,"先设计后写码"步 + MVP-first 铁律 + 8 条好玩自检);新建纯 LLM 丰富度验证 agent `cheap_verify.py`——读产物源码逐条裁 8 条好玩清单、写进 run-summary 的 richness 字段,**非阻塞(失败降级不阻断)、不进 verdict、不改达标判定、零 code-presence 断言**(命中与否 100% 由 LLM judge 裁,代码只搬运计数——红线落地;sim-business §10 那 4 条"可机检好玩门"刻意不实现)。富游戏重验 M1 达标门(全新 gameId、三品类各 n=5):**click/whack/shop 各 5/5 = 100% 过九门、整体达标 ✅**——richness 加固没压垮达标,plan 担心的"丰富后跌破"未发生;richness 均分 shop 4.2 / click 3.4 / whack 2.4(8 条 rubric 偏经营,最贴 shop,whack 低是品类不匹配非质量差)。退役授权据新富游戏 M1 报告重算 `authorized=True`。基建线同轮交付:统一 trace 落库(tier2 `JsonlFileSink` + cheap-worker 接线 + SAA 扩展段 schema)、配置注册表运行时热取(cheap_roles 三级回落加载器、Java `@Scheduled` TTL、`check_registry.py` 一致性 CI 门)、生成控制面只读管理面(后端 3 端点 + game-admin Vue 三 card)。**两个测试坑(留给后来人)**:① bake-off 复跑同一 gameId 会复用 `_wg1-gen/<id>/play-spec.json` 旧 spec(`ensure_play_spec` 是"已存在不覆盖"语义)——旧薄游戏 spec 驱新富游戏会假失败(自动驱动器卡菜单 `phaseNow=menu`、score 0→0、E_live/G_input/H_progress 齐挂),`auto_vs_golden.py` 有 staged-spec 残留断言守卫而 `bake_off.py` 没有,故达标门复验务必 `--offset` 取全新 gameId(或先清 `_wg1-gen` 实验 staging);② `cheap_run.game_dir("base4")=games/amgen-base4` 是 load_brief 的 brief 来源依赖,清理 `amgen-*` 实验产物时**必须排除 `amgen-base*`**,否则断掉所有品类的 bake-off brief。(2026-07-09 勘误:本条两处定性已被裁定三收窄——「各 5/5 = 100% 过九门、整体达标」中「过九门」自此只算机械预筛通过,玩法层达标另需独立模型玩法判定;而当日审计正认定「LLM 丰富度非阻塞、不进 verdict、不改达标判定」这套设计是病根之一——懂玩法的模型判断被钉成旁路、判定权威落给不懂玩法的机械门,故丰富度里「玩法有无」的布尔裁决升为阻断权威(程度评分仍软)。当时测得 5/5 是历史事实,真实率按新基线重锚(W-AXIS 收尾波)。见质量 SoT《游戏质量与爆火能力》裁定三与诊断档 §2.1。)
|
||
|
||
## 6. 决策落地的关键工程参数(供选型校验,技术决策版 §4/§7)
|
||
|
||
- **AI 生成**:生成任务状态机 queued→running→succeeded/failed/timed_out/canceled;超时 120s;失败重试 ≤2 次、超时重试 ≤1 次;队列最大积压 500(超则返回 429);P50<60s、P95<180s。
|
||
- **运行时沙箱**(安全铁律):iframe `sandbox="allow-scripts allow-same-origin"` + CSP `script-src 'self'; connect-src 'none'`(游戏内零网络请求)+ postMessage 来源与 schema 双校验;资源总 ≤10MB、首屏 ≤2MB;加载超时 5s 自动跳过+降权。
|
||
- **推荐打分**(规则非 ML):`Score = w1·quality_score + w2·freshness + w3·interaction_rate − w4·skip_rate − w5·error_rate − w6·report_rate + bonus_new_creator + bonus_featured`;候选集 Redis Sorted Set、TTL 60s、cursor 分页。
|
||
- **幂等四场景**:重复点生成→idempotency_key(Redis 5min);MQ 重复→message_id 去重集合;支付回调重复→订单状态机+乐观锁(version);发布重复→version 唯一约束+状态前置校验。
|
||
|
||
## 7. 不做(明确非目标,技术决策版 §1.3)
|
||
|
||
**MVP/近期非目标(保持收敛)**:MVP 不做 3D、不做专业级游戏引擎(Unity/Unreal 级)、不做海外市场;不做完全开放式代码生成(**harness 九门约束**——agent 写码于 LittleJS 插件库,非旧"配置填参"线);不自研大模型(接入通用 LLM + 开源 Agent 框架)。
|
||
|
||
**远期分层路线(仅探针,不进 MVP)**:Tier2 复杂2D+3D、Tier3 独立App(统一 Cocos+MCP,见 §1.1)为远期方向;MVP 至多做 1 个 Cocos-MCP 探针验证链路可行性,不投入工程。**Unity 始终否决。**
|
||
|
||
## 8. 鉴权与匿名身份落点(2026-06-10 建设+e2e 收口,HJ-PASSPORT-EXEC-001)
|
||
|
||
- **落点=system 内 passport 独立子包**(非新 game-module):零 RPC 直注 SmsCodeService/OAuth2TokenService;错误码取 system 远段 `1_002_090/091`;全部新文件收敛 `*/passport/` 子包(fork 合并冲突面≈0)。跨模块校验走 `PlayerApi`(@Primary 本地化,照 OAuth2TokenApiImpl 范式)。
|
||
- **身份矩阵**:创作者=手机验证码(Debug 渠道,码落 `system_sms_code`)发 userType=MEMBER 真 OAuth2 token;陌生玩家=邀请码旁路注册(`wanxiang.passport.invite-register-enabled` 开关退役,核销=条件 UPDATE 原子恰一,并发实证);匿名玩家=纯客户端 anonId + 14 端点 @PermitAll + `game_runtime_session.player_user_id` 可空(V11);A2 创作白名单=`game_player.creator_flag` 5 个 Service 入层挂点。
|
||
- **mock 并存机制(批跑零中断的根)**:`TokenAuthenticationFilter` 先查真 token、查不到才 mock——staging `mock-enable:true` 下 `Bearer test1` 与真 token 天然并存无开关;mock 白名单豁免=PlayerApiImpl「game_player 无行∧mockEnable→放行」(生产 mockEnable=false 自动收紧)。
|
||
- **前端守卫真源=`isRealLogin()`**(仅 localStorage 真 token;既有 `isLogin()` 因 token 恒有 env/mock 兜底值**恒真不可用作守卫**);互动转正挂点=Feed.vue `onInteract` 单函数入口(share/report 是其内联分支,无独立函数)。
|
||
- **匿名写链审计列**:见 rules/engineering-conventions §1.2 红线(系统身份注入范本 + V11 漏继承审计列之雷 + TelemetryEventEnum 真守门人)。
|
||
|
||
## 9. 多模板架构落点(2026-06-10 M-c 批① merge 收口,HJ-MC-TPL-EXEC-001)
|
||
|
||
- **runtime=单 `startRuntime` 工厂内 switch(templateId) 分发**(拍板,弃「每模板独立工厂」):生命周期/`finish(score)`/loop/drawBase/cleanText 共享单份(红线代码不复制不漂移),玩法差异只在 `init<T>()`(状态+交互+draw 玩法层+finish 触发);所有函数定义在 startRuntime 体内(toString() 注入约束);空串 templateId 兼容旧包并入 clicker case;未知模板走 `game_error` 防御分支不静默错渲染。体积实测:clicker+merge 双玩法 min 后 raw=4,828B(硬线 15,360B 的 31%,软门 8,192B)。
|
||
- **后端=Loader/Validator「templateId→资源」Map 缓存**:PromptResourceLoader 逐模板装 (promptVersion, promptBody, schemaText),GameConfigSchemaValidator 逐模板编译 JsonSchema;**校验逻辑零新码**(仍 schema.validate(node)),同源铁律保持(注入 LLM 文本==校验文本,per templateId);isReady()=全模板就绪(任一缺失整体自禁用含模板名)。**模板白名单唯一同源=`AigcTemplateConstants.SUPPORTED_TEMPLATE_IDS` 编译期常量**(Properties 默认值与 validateTemplateExists 同读;不注入 executor Properties——`@ConditionalOnProperty` 关闭时 Bean 缺席)。pom maven-resources includes 已通配(新模板两资源自动进 classpath)。
|
||
- **runtime↔player 承重接口纪律**:跨进程共享公式(merge 棋盘布局)必须钉死全部参数字面双侧一致(含 spec 散文易漏的 topPad 类参数),主 agent 收口逐字符比对;运行时实证=player 按公式推演 8 产料+7 拖拽全格命中、score=2^(targetLevel-1)-1 理论值吻合。
|
||
- **新模板/新玩法接入操作配方**:见 [`littlejs-game-dev.md`](../skills/littlejs-game-dev.md)(agent 写码于插件库、终态产物 `src/` 多文件工程的作业手册;本 §9 描述的 `startRuntime` 单工厂 switch(templateId) 填参线随 gameDefinition 废除退役,仅留决策史)。
|
||
|
||
## 10. 配置控制面阶段〇生产基建(2026-07-01 落地,切片一)
|
||
|
||
Nacos / RocketMQ / Sentinel 从「已选型未部署」推进到自托管 mini-infra + game-cloud 真接入。SDD 八任务已 push `origin/dev/2.0.0`;权威 plan `docs/plans/2026-07-01-配置控制面-spike与阶段〇生产基建-plan.md`(status 带 framing 勘误),逐任务 review 与 follow-up 留痕在 `.superpowers/sdd/progress.md`。
|
||
|
||
**自托管拓扑**(mini-infra `100.64.0.8`,lean JVM、纯增量、既有 9 服务零影响):Nacos 2.4.3 standalone + MySQL 后端(512m),RocketMQ 5.3.1 NameServer + 单 Broker(1g,`brokerIP1` 须指 Tailscale 地址、否则 NameServer 返回的 broker 地址跨机不可达)。端点与密钥落 `docs/内网凭据与端点.md`。踩过的坑:mini-infra docker daemon 的 HTTP 代理曾失效导致任何镜像拉不下来,`ctr` 走 containerd daemon 不读 CLI 代理、零重启路径不成立,最终改 daemon 代理指向本机 Clash 并重启 docker(既有容器 `restart=always` 自动拉起)才恢复。
|
||
|
||
**生成准入的三层并发正交**(承重,经两轮 review 纠正):Sentinel `FLOW_GRADE_QPS` 是入口投递**速率**闸(削洪峰,不是并发权威);既有 DB 三门是 per-creator 业务**配额**;真正的「在跑生成并发 ≤15」硬上限落在**有界 worker 池**(worker / AgentScope Service 侧,N=4-6 起步压测调,创始人 2026-06-26 决策),**不在 RocketMQ 的 consumeThreadMax**。三者正交、各管一层,任何一层都替代不了另一层。
|
||
|
||
**rocketmq-spring 消费者并发的反直觉语义**(最终 review 核字节码坐实):`@RocketMQMessageListener(consumeThreadNumber, consumeThreadMax)` 在 rocketmq-client 5.x 下,`ConsumeMessageConcurrentlyService` 用**无界 `LinkedBlockingQueue`** 建 `ThreadPoolExecutor(core=consumeThreadNumber, max=consumeThreadMax)`;JDK 线程池语义下无界队列永不满、线程数永不超 core,所以 **`consumeThreadMax` 是死参数、有效并发等于 `consumeThreadNumber`,要让上限真生效必须 min=max**。而且异步投递(worker ACK 即返回、任务留 RUNNING)下它 cap 的是投递握手速率、不是在跑生成数——想用它当并发闸会双重落空。有界 worker 池 follow-up 落地时会再撞这条。
|
||
|
||
**follow-up(未做,交排期)**:有界 worker 池真并发 cap;`NacosHotConfig` 接进 middleware 替 `cheap-worker/cheap_studio.py:156` 的硬编码预算;AgentScope 2.0.3 原生 token 限制的 build-vs-buy 评估(能否替自建软预算 `on_model_call` middleware)。**窗口验证**:Part C/D 真集成(真注册 / 真限流 / 真队列 / 真连 / 真热读),以及 `namespace: public` 核对——Nacos 默认公共空间的 namespaceId 实为空串、非字面 `public`,不核对会把注册与发现落到别的空间。
|
||
|
||
## 11. 配置控制面阶段一① 护城河 middleware 线(2026-07-02 落地,切片一)
|
||
|
||
护城河三件——续修、软预算、门判——从设计落进 AgentScope 2.0.2 的 middleware 洋葱,在 tier2 富游戏路端到端跑通(本地全 mock,真门排 mini-desktop 窗口)。SDD 五个代码 commit 加 plan 已 push `origin/dev/2.0.0`(`c62143dd..07100eef`);权威 plan `docs/plans/2026-07-02-配置控制面阶段一-护城河middleware-plan.md`,逐任务 review 与 follow-up 留痕在 `.superpowers/sdd/progress.md`。
|
||
|
||
- **续修**(`RepairMiddleware`,`tier2/gen-worker/worker/middleware.py`):`on_reasoning` 钩子拦住 agent 想结束时吐的 finish(纯文本 Msg),自己独立重跑门;没绿就压制这次 finish、用 `observe(UserMsg)` 把失败反馈注入 context 让 agent 续跑修,取代了原来 control_plane 在 Agent 外的 resume 循环。放行的唯一权威是 middleware 自己重跑的门,绝不采信 agent 上报的门结果(防漏调门 / 谎报门绿的链路假绿);软预算耗尽时也保证「至少续修一次」(`repairs>0` 才因预算放行)。
|
||
- **软预算**(`CircuitBreakerMiddleware` 的 `soft_budget` 档位):¥ 越限从原来的 fail-closed 断链改成优雅收尾软停——设标记、放行本次、在 `on_system_prompt` 强提醒 agent 尽快 finish 交尽力产物。**默认 hard 档,守住 cheap 的 ¥ 硬地板**(这个类被 tier2 与 cheap 两档共用,只有 tier2 工厂显式传 soft);四道 on_reply 失控熔断(步数 / 次数飞车 / 死圈 / 超时)仍然 fail-closed,只改 ¥ 这一道。
|
||
- **门判归一**(`worker/gate_judge.py`):把 tier2 的 verdict 归一成 `GateJudgment(passed, failed_gates, feedback)`,放行判据 `decision==accept 且 L1.passed` 与既有 legacy 逐字一致、不放松。阶段二归并 cheap 时在同一文件补 `guards` map 的适配器,两档共用一套续修判据。
|
||
- **服务集成**(`service/app.py` + `control_plane.py`):工厂每回合注入 `[tracer, repair, breaker]`;`drive_generation(single_post=True)` 把整局收进一个 POST、洋葱内续修多轮,回合真结束后读服务端已落的 verdict 判落库(门绿入 store,门没绿的尽力产物只留 on-disk workdir、不进正式库),老的外层 resume 循环整段保留作 fallback。
|
||
|
||
**一个红线级的坑(已封)**:`run_gates` 起门 subprocess 之前必须先把 `verdict.json` unlink。否则 harness 失败(子进程超时、chrome 崩、端口 4330/9322 被占)没写出新 verdict 时,会读回上一次的残留 verdict,而 judge 只看 verdict、不看 rc,于是把陈旧的绿当本次结果放行加落库——这是「放行唯一权威=独立重跑门」这条红线的唯一裂缝,`f4384dc3` 已封(起跑前清残留,保证读到的必是本次真门产出)。
|
||
|
||
**follow-up(交阶段二 / 窗口)**:阶段二把 cheap-worker 从 `cheap_studio` 归并进 Service `/chat`、复用这套 middleware(**已完成,见 §12**);回滚开关(repair 注入挂一个 genconfig flag,让 `single_post=False` 加关开关=退回阶段〇前);`max_resumes` 在 single_post 下消费端 SSE 兜底要与服务端续修上限同源(否则 CLI 传小值会把合法续修局误判超时、丢产物);并发跑 `run_gates` 会撞固定端口 4330/9322,需 single-flight 锁或按 session 派生端口(现 n=5 串行不触发)。**真端到端排 mini-desktop 窗口**(要 chrome/esbuild):续修真拦 finish 且与框架前置 InboxMiddleware 并存、单 POST 不撞 breaker/SSE 超时、放行=独立重跑、软预算优雅收尾、cheap 硬地板不变,并先量真实门时延再收紧那几个 directional 的超时旋钮。
|
||
|
||
## 12. 配置控制面阶段一② cheap-worker 归并 Service /chat(2026-07-02 落地,切片一)
|
||
|
||
便宜档从「裸 HTTP `/generate` + 进程内 for-resume 循环」归并到同一套 AgentScope Service `/chat`,复用①的 `RepairMiddleware` / `CircuitBreakerMiddleware.soft_budget` / `GateJudgment`,续修判据从「check+build 绿」升成与 tier2 同构的「九门绿」。四个代码 commit 加 plan 已 push `origin/dev/2.0.0`(`10aeed3c..526e9b3d`);权威 plan `docs/plans/2026-07-02-配置控制面阶段一②-cheap归并Service-plan.md`,SDD 留痕在 `.superpowers/sdd/progress.md`。
|
||
|
||
- **判据线**(`worker/gate_judge.py` 加 `judge_cheap_verdict`):便宜档 verdict 是 `{pass, guards{门:{pass}}}`(无 tier2 的 layerResults),feedback 从各门 detail 另拼中文。放行要求顶层 `pass` **且 guards 非空**——只看 pass 会把「play 没跑出逐门却被强标 pass」当绿。`cheap_gates.run_cheap_gates` 把九门收口收成同步函数、端口由调用方派生透传,供续修 check 经 `to_thread` 调。
|
||
- **独立 Service 壳**(`cheap_service_app.build_cheap_app`):cheap 与 tier2 各起进程(credential 协议、预算档位、工具面都不同,合用的分支耦合成本高于省的资源)。cheap 走 OpenAI 兼容凭据(`openai_credential`、base+`/v1`)、软预算 `soft_budget=True`(成本上界靠 `max_repairs=6` 优雅终止,不是次数闸——`max_tool_calls`/`max_model_calls` 的 `_trip` 是无条件硬熔断、不受 soft_budget 约束,故设 150 只当纯失控兜底、绝不当贴脸成本尺)、并发端口按 session 从进程内池派生(避固定 4320/9222 撞)。
|
||
- **跨进程回收成本**(C1):续修 / 软预算 / trace 的内存态都在 Service 进程,worker 侧 driver 拿不到,靠一个 `collector` middleware 在 `ReplyEndEvent` 流经时同步落盘。框架先 yield REPLY_END 再 yield finish Msg,只在 finally 落盘会让 driver 一读到 REPLY_END 就返回、此刻盘上还空 → 成功局也上报 costRmb=0(重开 M3b 的 D11 恒中性坑);故 collector 在把 REPLY_END yield 给下游前先落盘,driver 侧再加有界轮询兜底。
|
||
- **消费方归并**(`cheap_service_driver` + `worker_service`):driver 注册凭据 → 建 agent/session → scaffold + 写会话注册表 sidecar → 发 kick → 复用 tier2 `_wait_for_turn_end` 等回合真结束 → 读九门 verdict + collector sidecar 组 run-summary → reply 外非阻塞丰富度。`worker_service` 默认 run_fn 硬切驱动 driver(无金丝雀旗,`_default_run_fn` 保留作一行回滚),`result_out` HMAC 回调链一字不动。
|
||
|
||
**session_id → 后端 gameId 的载体**(C2):AgentScope 工厂签名固定 `(user_id, agent_id, session_id)`、拿不到后端 gameId 也拿不到 session 记录,而 `AgentData`/`SessionConfig` 是严格 pydantic 无自由字段。故 driver 在 `/chat` 前把 `{external_game_id, write_whitelist, scaffold_template, restricted}` 写一份同机共享 FS 的会话注册表 `_cheap-sessions/<session_id>.json`,两工厂读它把 session_id 解析回后端 gameId——否则 prompt 指后端 gameId、六工具却锁 session_id,首轮 read 起点失败加 write 越界。受限写(reskin/modify)靠 `restricted` 标记 fail-closed:缺 `external_game_id` 回落 session_id(产物目录与 scaffold 不一致、生成响亮失败,非静默),`restricted` 为真但白名单缺失收窄成空集禁写(`restricted` 用 `write_whitelist is not None` 判、不用 `bool()`——空集会误成不收窄放开全写)。跨机部署时此载体要改(Redis 注册表或凭 storage 读 workspace_id)。
|
||
|
||
**红线③ 在 cheap 侧复现(整分支终审才抓到)**:①只在 tier2 `run.py:866` 封了「陈旧 verdict 假绿」,②把 cheap 的两条读盘路径(`cheap_gates` 起 play 前 / driver 收口读 verdict)原样带了进来、都没清残留——同 gameId 重跑局加某次门跑 harness 打嗝,或零门跑路径(setup 静默失败 / SSE 超时未跑一次 check),就会把上一局的绿 verdict 当本次结果放行加落库。这条 per-task review 结构上看不到(跨 `cheap_gates→cheap_run→serve-and-play→driver` 四层加跨任务生命周期),fable 整分支终审才揪出,按①原样两处 unlink 封死(`cheap_gates` 起 play 前 + driver scaffold 后回合前)。**教训:一条红线在一条路径上封了,不等于封完——每条共享同一脆弱模式的路径(这里是「读盘 verdict 不预清」)都要扫一遍;①的 follow-up 甚至已写到「并发 run_gates 撞端口与陈旧 verdict 复合」,却仍漏了 cheap 侧那次真正的封口,直到看整条分支的终审才补上。** 同批还修了 driver 对 Service 的 setup POST 无状态检查(合法 JSON 的错误响应会让 id=None 往下走、空等 SSE 超时约 600s 才降级——触外部交互红线,改 None 即 fail-fast)与 `acquire_ports` 在事件循环里同步阻塞(池耗尽冻死整 Service,改 `await to_thread`)。
|
||
|
||
**follow-up**:真门 e2e 排 mini-desktop 窗口(单 POST 收敛 + 续修真拦 + C2 首轮不越界 + C1 成功局 costRmb≠0 + 并发不撞端口 + 七值回调 + 代理旁路 + **盲修空转率**——最后这条是决策留的头号观测项:cheap 无九门自检工具、agent 每次纯文本终止后 check 才第一次真跑门、不过就据 feedback 盲修,空转会显著抬时延,cutover 后量真实空转率再定是否加自检工具);cheap-worker 全套有 14 个 `test_toolkit.py` 失败,是 pre-② 的测试隔离污染(某测试污染 test_toolkit 依赖的共享盘态,单文件跑与排除②新测试都复现),与配置控制面无关、待单独修;有界 worker 池真并发 cap(承①,端口池是为它设计的机制、真放开并发才用得上)。
|
||
|
||
**mini-desktop 真门窗口验证(2026-07-03,两轮)**:② 归并 cutover 三接缝真门全闭合——单 POST 收敛 / 续修真拦放行 / C2 目录一致 / 代理旁路无 502 / result_out 承重,外加窗口暴露并已修实证的两个部署接缝。其一,requirements 补 `agentscope[service,storage]==2.0.2` extras——裸钉 `agentscope==2.0.2` 缺 fastapi/uvicorn/apscheduler/redis,全新 venv 起不动 Service,而 SDD 单测只 import 到 create_app 之下、真起服务才暴露(`cheap-worker` 与 `tier2/gen-worker` 同款)。其二,成本子系统改用 per-POST 凭据的 key(`current_model.credential.api_key`,SecretStr 公开字段)取价,不再依赖 Service 进程 env NEWAPI_KEY——成功局 costRmb 从 `0.0/degraded` 变 `1.0785/active`(commit `24e558a4`,B深 per-POST 取价 + B浅 `build_cheap_app` 调 `ensure_api_key_env` 双保险)。红线③ 用植入带 marker 的绿 verdict 做受控 e2e 坐实:marker 在 M3 完成前即被 driver 侧 unlink 清掉,终局是本局自产的真 verdict(pass=False)而非假绿。**但便宜档真生成当前系统性产「菜单空壳」(E_live/G_input/H_progress 未过、输入不驱动状态),并撞 MiniMax-M3 `400 tool result's tool id not found(2013)`(崩 ChatService.run → driver idle 600s 慢失败)——这属生成质量(WU-B/C/F)与 M3 可靠性,与 ② 归并正交,但决定便宜档实际可用率、cutover 真上线前需另线解。** 归并交付面 cutover-ready,「便宜档真能上线可用」是另一条线。
|
||
|
||
## 13. 便宜档生产 cutover 窗:框架默认注入面审计 + 熔断签名对齐设计意图(2026-07-04 落地,切片一)
|
||
|
||
cutover S0–S4 与 A11 计费 e2e 在同一窗完成(证据=cutover plan §9 执行记录),窗内抓修四件全在生产真流量下坐实。两件有跨项目复用价值,记在此;另两件(studio 透传拒因、C6 族错配直指)属产品语义修,细节看 plan §9 即可。
|
||
|
||
**框架默认注入面击穿自有护城河(§12「跨路径封口」的第三例,也是最重的一例)**。AgentScope 2.0.2 Service 路的 `build_toolkit`(app/_service/_toolkit.py)把 workspace 内建工具(Bash/Edit/Glob/Grep/Read/Write)无条件并入每个 agent 的工具面,再拼我们的 extra 六工具。后果:便宜档写边界靠六工具白名单(write 越界拒 + basename 拒,I1 fail-closed),但内建 Write/Edit/Bash 根本不走白名单,Bash 甚至能以绝对路径越出工作区——护城河被框架默认面整体旁路。同时 12+ 个语义重叠的工具(Read vs read_file、Edit/Write vs write_file)对 M3 是实打实的混乱税:生产实测 80011 一局 14 次工具失败(拿内建 Bash 用相对路径 `ls` 连败、把框架 Read 的 `limit` 参数串到我们的 read_file 上、内建 Edit 的 read-first 约束连环撞),¥12.24 烧到 step_cap;关掉内建后同 brief 复跑(80012)零工具失败、¥2.13 一次过门。修法=第三块钉版本补丁 `ws_builtin_tools_patch`(monkeypatch `LocalWorkspace.list_tools` 返空;cheap Service 进程只跑便宜档 agent,进程内全局补丁作用域恰好;tier2 独立进程不受影响)。**教训升一级:接入任何框架的 Service/App 形态,必须逐项审计框架默认注入的能力面(工具/中间件/调度/团队/后台任务),与自有约束(白名单/预算/门)对账——CLI 路没有的面,Service 路可能默认全开;per-task review 结构上看不到这种「框架给的」面,要靠真流量观测或整链终审。**Planning/Team/Schedule 工具面收窄仍是 follow-up(工单 h,成本上界已有 ¥ 两段式硬地板兜)。
|
||
|
||
**stuck 熔断签名必须承载「同错」语义,且失败必须即时可归因**。四道熔断里 stuck 的设计意图是「连续 N 次同一失败签名=死圈」,但实现把签名写成了 ToolResultState 的裸状态值——恒为 "error",任意 4 次异类临时失败也会误熔断(80009 生产实证 ¥2.6 作废),而且事后四路取证全空(trace 是 D11 瘦骨架无工具名、Redis 会话崩溃不 flush、结果文件只 dump 大结果、熔断消息只有 tool_call_id)。修法=签名富化为「工具名+状态+归一化错误头」(长 hex/数字→#,同类错误仅差 id/行号仍同签名),异类连败不再误判(交 step_cap/¥ 闸/timeout 兜底,80011 实证组合兜底链正确协同),并且每次工具失败即时打印一行(名字+错误头)。**教训:熔断/告警的触发凭据里必须带上「事后归因要用的最小事实」,否则每次触发都要重放一遍现场;观测修往往当场破案——签名富化上线后第一局就把内建工具面问题钉死了。**
|
||
|
||
**运维面三条硬记**:① jar 世代升级=依赖面随升——新 jar 带上了阶段〇的 Nacos 接线,`NACOS_PASSWORD` env 缺 → 登录 403 → 注册 failFast → 进程静默退,连 boot banner 都不留;回滚资产要「旧 jar + 旧 env 面」两层,升级前先 diff 新世代多要什么 env。② 环境快照采集要验完整性——S0 的 `/proc/<pid>/environ` 快照只存到 PATH(采集半途失败没人发现),重启即 DB 密码丢;权威源是 `infra/.env`(裸赋值文件,source 前必须 `set -a`)。③ 并发争用会污染测量——bake_off conc=3 时 spec-smoke 100% 失败(Chrome/端口挤兑)→ 全场考卷回退 key-cycle,测出来的过门率是环境噪声不是生成质量;凡「测质量」的批必须串行或与基线同并发口径,且 smoke 一类哨兵失败必须打印真因(raw 尾),不能只留 PASS/FAIL 一个位。
|
||
|
||
**F-2/F-3 收敛窗补记三条(2026-07-04)**:① **双源默认值影蔽**——旋钮外置单源(genconfig)后,调用链上任何写死默认值的显式透传都会静默短路单源:`batch_run`/`run_engine` 三处 `default=40` 让「writer 提到 60」在 r3 实跑仍是 40,而 middleware 系旋钮(直读 genconfig)全部生效,同一批里真假参半最难察觉。外置旋钮的 DoD 必须含「调用链无第二默认值」(全链 grep `default=`/字面量对账),调用方一律传 None 哨兵、由消费端解析单源。② **隔离 worktree 基线不可信**——同批五个 agent worktree 全被建自错误分支(dev/1.0.0,目标文件整棵不存在);五个 agent 虽全部自查自纠(reset --hard 到 dev/2.0.0),但这依赖 agent 素质,不可赌:派单 prompt 写明目标分支,**终审第一步必验父链**(`git merge-base` 确认基于主线近点,再看 diff)。③ **pgrep 模式串自匹配是全场景坑**——不止 kill/relaunch(§旧记),连纯探活(`pgrep -f 'a|b'` 出现在自己 ssh cmdline)也会自匹配报假活进程;模式串永远用 `[x]` 括号技巧,且同一命令行里不要 echo/字符串携带模式本体。另:ssh 复合命令里 `cd` 只作用于当段,第二段后台启动要用绝对路径(worker 重拉 ENOENT 实录)。
|
||
|
||
## 14. 配置控制面阶段二五步落地窗(2026-07-04,fable 编排·opus 五单·逐波终审)
|
||
|
||
一天内把阶段二从「设计定稿待排期」推到「五步代码全落」:前置 namespace 统一(`b2b4d389`)→ 步骤4 genconfig Nacos 热源(`344330a4`+入口 `d9def7d9`)→ 步骤1+2 yudao 治理子域 V29/V30(`3ae34de1`)→ 步骤3 双路激活(`72973532`)→ 步骤5 漂移对账(`a8dd5e50`)→ 路A 复数修复(`22444fd5`)→ 收口涟漪回写(`c4e8df15`)。同窗 W-PCI prompt 四道闸 CI 当日排单当日落(`ec95faaf`)。三条新坑与两条工艺硬记:
|
||
|
||
**① 跨系统客户端的路由字面量,终审必须对框架源码逐字核——单测桩验不出 404。** C 波路A PATCH 写成 `/session/{id}` 单数,AgentScope 2.0.2 session router prefix 是 `/sessions` 复数(app/_router/_session.py:87,我方 bootstrap.py 同用复数);客户端单测断言的是自己拼的 URL,桩永远绿,对真 Service 必 404。这颗雷不是评审看代码看出来的,是 D 波写对账**只读路**时按真源码用了复数、与 C 波写路对不上才暴露。教训两层:跨系统 URL/字段名的评审凭据=框架源码或既有真跑代码,不是对称的自家测试;**同一契约的读写两路分两单实现时,「读写口径互证」本身就是一道免费的门**——排单时可以有意这么排。
|
||
|
||
**② 真外呼 IT 用「显式门旗 + fail-closed 凭据断言」双保险,拒绝静默 skip 假绿。** A/C/D 三波真库/真 Nacos IT 统一形态:默认 `@EnabledIfSystemProperty(aigc.config.e2e=1)` 跳过(常规 mvn test 不牵外网),开旗后凭据缺失不是 skip 而是**红**(「须注入 NACOS_PASSWORD」断言)。fable 复跑时先被门旗骗过一次(Skipped 2 误当绿)、又被凭据断言拦一次——两道都在防「跳过当通过」:终审复跑 IT 必须核 `Tests run` 的 Skipped 列,Skipped>0 的"绿"不是绿。
|
||
|
||
**③ Nacos publish→read 最终一致:改值后立即 GET 可能返旧值。** C 波路B e2e 实测发现;对账/断言读生效 dataId 必须带轮询容忍窗(D 波 8s 窗+800ms 步进),否则把传播延迟误判成配置漂移。同理生产侧「激活后立刻查投影」的任何面(阶段三 UI、阶段四对账巡检)都要吸收这个窗口。
|
||
|
||
**工艺硬记两条**:㋐ 激活一致性的落地形态=「sanity 前置拒发 + beginActivating 快照(单库事务)+ 双路短路下发 + 全成才 markVersionActivated + 任一步败即补偿重推回上一激活版 + 账本提交失败留 ACTIVATING(V30)由 recoverActivating 幂等向前收口」——投影撕裂由即时补偿收敛,不承诺投影层原子;「向前执行到底」与「补偿回退」两个恢复语义按失败点位分开,不混用。㋑ MyBatis-Plus 把 BIGINT 指针写回 NULL 必须 LambdaUpdateWrapper 显式 SET(updateById 跳 null 字段),激活指针/在途指针这类「NULL 有语义」的列写法要单测钉住。
|
||
|
||
**部署窗口批(2026-07-04 同窗续,opus agent 三阶段·fable SSH 独立终审)**:阶段二五步落码后在 mini-desktop(100.64.0.7 `/root/tier2-run/cheap-worker`)真机收口——Phase A 同一真 session 单数 `/session` 404 vs 复数 `/sessions` 200(curl+httpx 双证、排除 session 无效歧义)把坑①的修复 `22444fd5` 真机坐实;Phase B-deploy flag-off 快进重启 :8300/:9501 + smoke-1 succeeded(¥1.53);Phase B-enable 灌 cheap/tier2 两 dataId 各 9 键(readback 逐字零漂移)+启用旗灰度上 :8300、门阈值热改探针 `color_dist_min` 18→25→18 **亚秒生效且 :8300 未重启(纯热推)**+smoke-2 succeeded(¥4.45、¥10 闸来自 Nacos 热读)。终态 :8300 旗-ON 从 Nacos 热读路B、回退=去 `TIER2_GENCONFIG_NACOS` env 重启一处可逆。**live 变更终审工艺=SSH 只读独立核实**(pid/cmdline、`/proc/pid/environ` 的 flag env、openapi HTTP、health、`ss` 监听)与 agent 报告逐字比对,不只信报告——本窗核实全吻合=报告真实。两条部署坑:
|
||
|
||
**④ `Agent isolation:worktree` 默认基于仓库默认分支,本仓即 dev/1.0.0——错线。** `origin/HEAD→dev/1.0.0`,而 dev/1.0.0 与活线 dev/2.0.0 岔开 893 提交、仍是 TS monorepo 老世代(无 game-cloud/pom)。派 worktree agent 干 dev/2.0.0 活,prompt 必须令其先 `git reset --hard <dev/2.0.0 tip>` 或 `git checkout -b work <tip>`(linked worktree 不能直接 checkout 主树已占用的 dev/2.0.0)。本窗按「基线不对就 STOP」铁律让 agent 停在错线(未授权自行 reset)才暴露该默认;**小而精确的活基线不对时,主树直修比再派 worktree 更快更稳**(这两条测试债即主树直修 `167cedde`)。
|
||
|
||
**⑤ venv 缺「已声明但惰性 import 故建 venv 时未装」的依赖=开旗后静默失效。** `nacos-sdk-python==1.0.0` 在 `tier2/gen-worker/requirements.txt` 声明,但 `genconfig_nacos` 惰性 `import nacos`,建 venv 时没装也不报错;`TIER2_GENCONFIG_NACOS=1` 开旗后 `import nacos` 失败→热源静默不 attach(零漂移仍保、但路B 通路根本不通)。启用旗前置=`pip install -r requirements.txt` 确认关键惰性依赖在位;重建 venv 同理。惰性 import 的依赖不会在 CI/单测暴露,只在真开旗那一刻炸。
|
||
|
||
**⑥ 阶段三前端(`79264197`)= 列单人的工单也会有契约出入,executor 逐字对源核是免费的第二道门。** fable 列的阶段三工单把状态枚举名(实为 `AigcConfigStatusEnum` 非工单写的 `GenConfigSetStatusEnum`、且漏 `ACTIVATING=15`)、`/version/get` 参数(实为 `versionId`)、`/version/diff` 参数(实为三参 `versionAId`+`versionBId`)写岔;opus 执行时逐字对 controller/enum 源核出、按源修正、回报出入清单(漏 ACTIVATING 会让激活中态渲染空白、"恢复卡激活"按钮无从触发)。教训:工单/设计档里的枚举名、参数名、字段名一律标「以源为准、executor 必核」,别让列单的转述当契约真相——与 §14① 跨系统路由字面量对源码核同源:契约字面量的权威永远是源码,不是任何中间转述(设计档/工单/记忆)。**另**:game-admin 构建门是 vite build(`node ./node_modules/vite/bin/vite.js build`),`pnpm build:*` 会先跑 `runDepsStatusCheck` 触发 `pnpm install`、无-TTY/无网时中止(非编译错);终审亲跑要直调 vite 二进制绕过 pnpm wrapper,别把 wrapper 的依赖检查失败误判成构建红。
|
||
|
||
## 15. 升级 AgentScope 2.0.3(2026-07-06,创始人拍板)
|
||
|
||
框架从 2.0.2 升到 2.0.3,创始人 2026-07-06 拍板。动因不在某个新特性,而在没有道理把底座停在一个已知带并行 tool-result 缺陷的补丁版上——2.0.3 是同一大版本线上的相邻补丁版,升级面窄、收益确定,拖着只会让欠的债更难还。这条决策承 §11–§13 那套「护城河进 AgentScope 洋葱、框架件谨慎审计」的线。
|
||
|
||
兼容底气来自三条独立证据,不是「跑通就算」。一是把两版源码逐处比对:RedisMessageBus 零改动,OpenAI formatter 一字未动,Anthropic formatter 唯一的变化是修掉了并行 tool-result 的一个 bug(对我们只减风险),ModelCallEndEvent 结构不变,中间件基类 MiddlewareBase 只加性地多了个 `get_middleware_key`、既有钩子签名全不动。二是两条线的护城河补丁逐块重验锚点:上下文压缩 fail-open(`compress_context` 仍在 `_agent.py:259`)、M3 流式聚合兜底(`_parse_stream_response` 仍在 `_openai_chat/_model.py:297`、按 `tool_call.index` 分桶仍在 :417)、workspace 内建工具封口(`list_tools` 仍在 `_local_workspace.py:660`)、Planning/Team/Schedule 收窄(`get_toolkit` 装配点迁到 `_chat.py:354`,补丁替的是绑定名、本不依赖行号)——四块的依赖契约在 2.0.3 全部成立,补丁头的钉版声明与复核标记已同步到 2.0.3。三是 cheap-worker 与 dev 两个 venv 装上 2.0.3 后,便宜档 393 + tier2 140 共 533 条测试全绿、dev 三服务起来健康;两处 requirements.txt 的钉版已从 2.0.2 改到 2.0.3。
|
||
|
||
2.0.3 原生补进了几样过去判定「框架没有、只能自建」的能力,记在这里,但本期都列而不迁。其一是 `ReplyBudgetControlMiddleware`——这正是早先设计反复核验「2.0.2 源码里不存在、故预算软刹必须自建」的那个类,2.0.3 把它补了进来(`middleware/_budget.py`)。它按加权 token 预算在 `on_reply` 里累计、到顶注入一条提醒消息,是软控;我们自建的软预算是 ¥ 两段式——软停线(便宜档 ¥10 / 富档 ¥50)只许收尾,硬地板(×1.5)fail-closed 数学封顶,属护城河(见 §11、运行时 SoT §5.2)。原生的 token 软控替不了这套 ¥ 制 fail-closed 硬闸,故保持自建,原生件只在「能否给 ¥ 闸做 token 估算上游」这一层评估。其二是中间件洋葱扩到工具执行层(`on_acting` 包裹 acting、middleware 可经 `list_tools` 贡献工具)、原生 RAG 管线(`rag/` 包:KnowledgeBase + chunker + qdrant 向量库)、mem0 长期记忆适配(`middleware/_longterm_memory/_mem0/`);它们对应 tier2 未来的经验召回与检索需求,排在生成主线达标之后按需评估,不趁升级顺手迁。
|
||
|
||
follow-up:2.0.3 原生 `ReplyBudgetControlMiddleware` 能否给自建 ¥ 闸做 token 估算上游(接 §10 阶段〇留的「2.0.3 原生 token 限制 build-vs-buy」);原生 RAG 与 mem0 在 tier2 经验召回线的取舍;历史文档里「2.0.2 核验 ReplyBudgetControlMiddleware 不存在」这类句子是当时的真验证事实,按两层纪律留痕不回改,该类新事实只落在本条。
|
||
|
||
## 16. 内测闭环 A 段落地(2026-07-07,注册/额度/dify/facade 收口)
|
||
|
||
创始人把「7 月中旬内测」的开发面收敛成一条种子用户旅程:注册(用户名+密码、无短信、网关 IP 限流)→ 得 ¥100 额度 → 生成 → 试玩 → 发布到 feed → 数据飞轮回流。这条闭环的三个真开发缺口(注册登录、额度、dify 节点)已实现并在 dev 真机逐环验证,代码经 `neice/stage1-integ` 三方合并进 dev/2.0.0(merge `210ce701`,11 提交,全部 opt-in 默认关)。此处记的是过程里几个不查就会踩坑的事实与被现实推翻的方案,不是功能清单。
|
||
|
||
**额度不自建钱包,对接 new-api 的 per-user 配额——但 new-api 的管理边界逼出了预置池。** 创始人拍板额度口径 = 复用 new-api 网关原生的按用户配额,每人 ¥100,生成消耗由 new-api 权威计量,而不是在 game-cloud 里新建 credits 钱包/扣额子系统。new-api(one-api 系,`100.64.0.8:3000`,DB=`infra-postgres:5432/new-api`)的原生模型是 `users`(quota/used_quota)+ `tokens`(每个 token 属于某 user,用它调用即扣该 user 配额),配额单位是 one-api 默认的 500000/$1、DB options 未覆盖,按 usd_rate 7.3 折算 ¥100 = 6849315 quota。原本设想注册时在线调 new-api 管理 API 开户+建 token+充额,但 S0 阶段实测撞到一条硬边界:**admin/root 令牌能建用户、能 setQuota,却不能替他人建 token**——`POST /api/token/` 永远把 token 绑到令牌自认证的那个用户身上,请求体里的 `user_id` 被忽略,而 `access_token` 也无法经 API 写入。这意味着「每个玩家一把自己的 token」这一步绕不开直接写 new-api 的 postgres。据此创始人拍板改走**预置池**:离线 ops 脚本(`game-runtime/tools/newapi_pool_provision.py`,纯 stdlib,每条四步 = 建 user → 直连 postgres UPDATE access_token → 以该 user 身份建 token → setQuota ¥100)预先造好一批 user+token 对灌进 game-cloud 的 `newapi_quota_pool` 表(FREE),注册成功后由消费者 CAS 抢占 FREE→CLAIMED 把池条目绑到玩家。注册走 outbox(注册成功落 outbox → RMQ → claim 消费者)让绑定与注册事务解耦、至少一次。任何后续要给用户发独立 new-api 凭据的活,都得先认这条管理边界,别再假设在线建 token 可行。
|
||
|
||
**生成计费的权威是 new-api,不是 worker 自估。** job 组装时执行器把认领到的池 token 注入 `userToken` 位(只对真实 member 生效,系统/bake-off 局旁路),worker driver 从 `job["userToken"]` 取凭据调 new-api,new-api 就天然按该用户扣 used_quota。dev 上一次真生成后 new-api user17 的 used_quota 从 0 涨到 26651(¥0.389),而同一局 worker 自估 ¥1.03——两者不一致,正是「用 new-api 权威计量、不信 worker 自估」的实证理由。额度耗尽/凭据失效用跨契约共享枚举 `quota_exhausted` 分辨(`contracts/api-schemas/aigc.yaml` + `dify-workflow-io.json` + Java/Python 三处同批)。
|
||
|
||
**注册登录、facade 回调这两块的坑都在「防伪」细节上。** 注册加的是 `game_player` 的 username/password 列、mobile 改可空、`uk_username` 唯一约束(Flyway V31);防用户名枚举的做法是准备一个固定的假 BCrypt hash,当用户名不存在时也照样跑一次 BCrypt 校验,使「用户名不存在」与「密码错」走同一码路同一时延、返回同一错误码,避免时序侧漏;IP 限流复用 passport 既有的 Redis 计数范式、按 scene 分桶且 fail-open(Redis 挂不拦正常注册)。facade 收口的是回调验签:dev 上后端与 worker 的 callback-secret 原本都空 = 验签关闭 = 内网可伪造回调驱动落包,内测必须两端配同一把非空密钥(后端 `AIGC_CALLBACK_SECRET` / worker `--callback-secret`,HMAC-SHA256 对原始 body 算签置 `X-Callback-Signature`)。dify 走形态A:mini-infra 已部署的 dify(:18080)建一个 HTTP「游戏开发节点」直连 cheap-worker `:9501/generate`,复用现成 agentscope 生成链,后端近零改;a-min 形态不带 userToken,driver 回落全局 key,与 per-user 计费天然隔离。
|
||
|
||
follow-up:预置池当前是离线人工灌,放量前需接一条池水位告警+补池的运维线(池空则注册拿不到额度);dify 形态A 的 HTTP 节点已证 curl 可通,workflow UI 实搭是 ops 步待做;quota 单位 500000/$1 与 group 定价若日后改价需在折算处(ops 脚本 + 任何入队余额门)同步。相关活账见记忆 `neice-core-loop-e2e-live`、设计档 `docs/agent-specs/2026-07-07-内测-WU1/WU2/WU3-*.md`。
|