docs(config/sot): 阶段二收口涟漪回写(上级档§7表行1-4十三处+§6收口标记/阶段二档status=已实施+六步落地标注+§8执行终局三口径修正/全档/sessions复数)+ 运行时SoT阶段二改真 + W-DSGN文本债四条(evalflow指git存档/消费面三态改真/T-AGC-09随gamedef历史化/验收门SAA承接项冻结)
Some checks failed
contract-gates / contract-gates (push) Has been cancelled
docs-gate / docs-gate (push) Has been cancelled

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
lili 2026-07-04 11:56:37 -07:00
parent 22444fd5e8
commit c4e8df15b2
5 changed files with 51 additions and 41 deletions

View File

@ -21,7 +21,7 @@ sot-impact: 修订 生成引擎运行时(SoT §5.2/§5.8/ADR-4 按本设计修
(图0 概览 SVG 待补)
- **核心思想**:生成统一走 AgentScope Service(`/chat`),配置(prompt / 模型 / 参数 / max_iters)经 `/agent`+`/session` 由框架**原生 per-POST 热重载**——改完下一次生成即生效、零重启(每 POST 从存储现装配 agent 与 model,无进程缓存,已读源码验证)。**配置中心是它之上的版本化层**:game-cloud 的 **yudao 管治理(鉴权/creator/BPM/编辑 UI)+ Nacos 管版本化存储与下发**(版本历史/回滚/灰度/推送),改→版本→激活时 PATCH 进 `/agent`+`/session`(prompt/模型)或经 Nacos listener 推给 middleware(预算/阈值)。生产基建采 **Spring Cloud Alibaba 原生三件套**——Nacos(配置+服务发现)、RocketMQ(异步 gen 队列)、Sentinel(Java 准入侧流控 ≤15):**Java 管准入+队列,Python 只服务 `/chat`**(见 §3.7)。护城河(九门 / 预算 / 续修)不另起框架外的编排,而是**做成 AgentScope 洋葱里的 middleware 与 MCP 工具**、留自建(无现货品类)。成品源工程归档保留自建 `store.py`(MySQL+MinIO)。
- **核心思想**:生成统一走 AgentScope Service(`/chat`),配置(prompt / 模型 / 参数 / max_iters)经 `/agent`+`/session` 由框架**原生 per-POST 热重载**——改完下一次生成即生效、零重启(每 POST 从存储现装配 agent 与 model,无进程缓存,已读源码验证)。**配置中心是它之上的版本化治理层**:game-cloud 的 **yudao 管治理(鉴权/creator/BPM/编辑 UI)与版本账本(版本行落 MySQL、含 prompt 正文)**,改→定版→激活时**双路下发**——prompt/模型这一路 PATCH 进 `/agent`+`/sessions`(写 AgentScope Redis),预算/阈值那一路 publish 进 Nacos 生效 dataId、由 worker 经 genconfig 门面(NacosHotConfig 作热源)热读。Nacos 在此只承预算/阈值那一路的生效下发,不再是版本账本(创始人 2026-07-02 拍方向 B:prompt 正文放不进 Nacos 100KB 上限、定版要原子,账本挪回 MySQL,详见阶段二设计)。生产基建采 **Spring Cloud Alibaba 原生三件套**——Nacos(配置+服务发现)、RocketMQ(异步 gen 队列)、Sentinel(Java 准入侧流控 ≤15):**Java 管准入+队列,Python 只服务 `/chat`**(见 §3.7)。护城河(九门 / 预算 / 续修)不另起框架外的编排,而是**做成 AgentScope 洋葱里的 middleware 与 MCP 工具**、留自建(无现货品类)。成品源工程归档保留自建 `store.py`(MySQL+MinIO)。
- **边界**:管热配置策略类(模型路由 / 预算 / max_tokens / thinking / prompt / skills / 可热阈值)。**SAA 11 roles 不接**(非 MVP runtime);硬代码机制、版本化安全件、phase-3 拖拽建图不进;受治理发版审批 + 运营 DB 审计归放量后。
- **成功**:本会话手改过的每个旋钮(模型 M3↔glm-5.2、预算 ¥10↔¥49、max_tokens、prompt)都能在配置中心改一版、激活、下一次生成即生效、可回滚、可查谁何时改;一组协同旋钮作一个配置集成组激活(静默期语义)。
@ -89,13 +89,13 @@ sot-impact: 修订 生成引擎运行时(SoT §5.2/§5.8/ADR-4 按本设计修
**配置面有三个,不止 /agent+/session**:工具 / MCP / skill 不在 AgentData 或 ChatModelConfig 里(两个数据模型无此字段),它们挂在 **workspace** 上(`workspace.list_tools/list_mcps/list_skills` 每 POST 现取;REST `/workspace/mcp``/workspace/skill` 热管,或 manager `default_mcps`/`skill_paths` 给新 workspace 缺省 seed)。故配置中心热配聚焦 **/agent+/session + middleware 薄读参数**;workspace 上的 MCP/skill **wiring** 属稳定基建、随 Service 部署,不做每局热旋钮。skill 的**内容**(`.agents/skills/*.md`)仍热——agent 运行时 read_file 现读(cheap-worker 每次 fresh、无缓存),改文件下次生成即生效。
### 3.3 配置中心 = yudao 治理 ⊕ Nacos 版本化存储
### 3.3 配置中心 = yudao 治理与版本账本 ⊕ Nacos 生效下发
AgentScope 的存储只有"当前配置"(Redis),没有版本历史。配置中心补这一层,职责劈成两半:**yudao 管治理**(鉴权 + `creator` 归因、放量后 BPM 审批复用 `huijing-module-bpm`、配置编辑 UI),**Nacos 管版本化存储与下发**(版本历史 / 一键回滚 / diff / 灰度发布 / 长轮询推送 / namespace 隔离——都是 Nacos 打磨多年的生产件,自建 Flyway 版本表 12 个月后就是重造它,build-vs-buy R2 命中,见 §3.7)。流向:创始人在 yudao UI 改 → yudao 校验鉴权/走 BPM → 激活时以服务身份把版本写进 Nacos(`creator` 戳进 metadata)→ Nacos 承版本/回滚/灰度/推送 → 消费方按语言各取(game-cloud 经 SCA、Python worker 经 nacos-sdk-python)。**prompt/模型/参数这一路**:激活时由 yudao 编排层把 active 版 PATCH 进 `/agent`+`/session`,写进 AgentScope 自己的 Redis,下一次 POST 现装配——Nacos 是版本账本、AgentScope Redis 是生效投影。SAA 不接 → Python 侧消费方经 Service 或 SDK,无跨栈倒置。
AgentScope 的存储只有"当前配置"(Redis),没有版本历史。配置中心补这一层,职责劈成两半:**yudao 管治理与版本账本**(鉴权 + `creator` 归因、放量后 BPM 审批复用 `huijing-module-bpm`、配置编辑 UI,连同每次定版落下的版本行——版本历史 / 一键回滚 / diff 全借 yudao CRUD/审计原生能力就地做),**Nacos 管生效下发**(长轮询推送 / 客户端磁盘快照兜底 / namespace 隔离,预算/门阈值那一路的热推全靠它)。版本账本早稿曾放 Nacos,创始人 2026-07-02 拍方向 B 挪回 yudao MySQL 版本行——Nacos 单配置默认 100KB 上限扛不住会随 few-shot 长大的 prompt 正文,且定版须同库同事务原子落一行(prompt 正文随行存 `MEDIUMTEXT`),内容出库即成跨系统写;详见阶段二设计 §3.1。这不推翻 build-vs-buy 的"下发机制全买"结论:推送/快照/回滚灰度仍全靠 Nacos,挪回 MySQL 的只是版本行这张普通 yudao 业务表。流向:创始人在 yudao UI 改 → yudao 校验鉴权/走 BPM → 定版落 MySQL 版本行(`creator`/时间随行)→ 激活时把 active 版双路下发。**prompt/模型/参数这一路**:激活编排 PATCH 进 `/agent`+`/sessions`、写进 AgentScope 自己的 Redis,下一次 POST 现装配——MySQL 版本行是账本、AgentScope Redis 是生效投影。SAA 不接 → Python 侧消费方经 Service 或 SDK,无跨栈倒置。
**成组激活(静默期语义,非机制级原子)**:激活一个配置集时,配置中心把涉及的 `/agent`+`/session` 作一批 PATCH。但两次独立 PATCH = 两次独立 Redis 写,读侧 `/chat` 又是两次独立 GET(且在 `session_run` 锁之前),机制上给不了真原子——并发一局理论上能读到"新 agent prompt + 旧 session model"的撕裂组合。故激活取**静默期语义**:激活时确保无在跑生成、或新配置只对下一批新生成生效(MVP 单操作者 + 创作页置灰,blast radius 小、够用)。配置中心记"当前激活版"为权威、Service 为投影;一批 PATCH 须幂等,失败即整批判未生效、可重试,不留半生效态。真机制级原子(给 `/agent`+`/session` 盖 epoch 戳、读到版本不一致就重读或拒绝)留放量后。
**middleware 热参经 Nacos 直读(消灭原自建薄读接口)**:预算目标、门阈值这类不在 `/agent`+`/session` 的 middleware 参数,写进 Nacos 独立 dataId,Python worker 的 middleware 用 nacos-sdk-python `add_listener` 订阅,Nacos 长轮询**推送**即热更(非轮询)。fail-safe 由 SDK 内建本地磁盘快照兜底(Nacos 挂了读快照 + 内置默认,不连累生成),正好兑现"强缓存 + 安全默认 + 抖动回落",且省掉原设计那一跳生成热路上的外呼。除此之外的配置走框架原生 per-POST 热配。
**middleware 热参经 genconfig 门面读、NacosHotConfig 作热源(消灭原自建薄读接口)**:预算目标、门阈值这类不在 `/agent`+`/sessions` 的 middleware 参数,激活时 publish 进按档隔离的 Nacos 生效 dataId;worker 侧不让 middleware 直连 Nacos,而是把 NacosHotConfig(v1 `add_config_watcher` 长轮询推送)接成既有 genconfig 门面的热源,middleware 仍照旧 `genconfig.get(area, key)` 取值、调用面一行不改。fail-safe 由 NacosHotConfig 本地磁盘快照兜底,再回落 env / 本地 YAML / 内置默认(Nacos 挂了不连累生成),正好兑现"强缓存 + 安全默认 + 抖动回落"。除此之外的配置走框架原生 per-POST 热配。接线细节见阶段二设计 §3.4。
### 3.4 护城河 = middleware + MCP(框架洋葱内,不另起外层)
@ -115,10 +115,11 @@ AgentScope 的存储只有"当前配置"(Redis),没有版本历史。配置中
```mermaid
flowchart LR
UI["配置编辑 UI<br/>game-admin(yudao)"] -- 带身份:改→版本 --> CC[(yudao 治理<br/>鉴权/creator/BPM)]
CC -- 写版本(creator 入 metadata) --> NACOS[(Nacos<br/>版本/回滚/灰度/推送)]
NACOS -- 激活:PATCH /agent+/session(静默期成组) --> SVC["AgentScope Service<br/>Redis 当前配置"]
NACOS -. listener 推送:预算目标/门阈值 .-> MW[middleware]
UI["配置编辑 UI<br/>game-admin(yudao)"] -- 带身份:改→定版 --> CC[(yudao 治理<br/>鉴权/creator/BPM<br/>MySQL 版本账本)]
CC -- 激活·prompt/模型:PATCH /agent+/sessions(静默期成组) --> SVC["AgentScope Service<br/>Redis 当前配置"]
CC -- 激活·预算/阈值:publish 生效 dataId --> NACOS[(Nacos<br/>路B 生效下发)]
NACOS -. 长轮询推送 .-> HC["NacosHotConfig<br/>→ genconfig 门面"]
HC --> MW[middleware]
SVC -- 每 POST 现装配(热) --> GEN["/chat 生成回合"]
GEN -- on_model_call --> MW2["软预算 middleware"]
GEN -- on_reasoning 拦 finish --> MW3["续修 middleware → run_gates(MCP)"]
@ -142,10 +143,10 @@ flowchart LR
采购 / 互补 / 自建:
- **采购**:Nacos(配置版本化存储 + 下发 + 服务发现,一套供两需求)· RocketMQ(gen 队列,Java 生产+消费)· Sentinel(Java 准入侧流控 ≤15,规则源 Nacos)。全 Apache-2.0、SCA 原生、自托管 mini-infra,增量成本趋 ¥0(约束是 RAM 余量 ~4-5GB JVM、非现金)。
- **互补**:yudao(鉴权/creator/BPM/编辑 UI)⊕ Nacos(版本/回滚/灰度/推送),前者治理、后者存储下发;AgentScope 原生 per-POST 热重载不动,Nacos 作版本账本、AgentScope Redis 作生效投影。
- **互补**:yudao(鉴权/creator/BPM/编辑 UI + MySQL 版本账本)⊕ Nacos(生效下发:长轮询推送/快照兜底/namespace 隔离),前者治理并持账本、后者只承预算/门阈值那一路的热推;AgentScope 原生 per-POST 热重载不动,MySQL 版本行作账本、AgentScope Redis 作 prompt/模型那一路的生效投影。
- **自建(护城河,R5(a) 豁免)**:九门 MCP / 续修 middleware / 门判定逻辑——没有对应现货品类,是域特定的生成验收链,买不到也不该买。
生产形态 = Java 管准入+队列,Python 只服务。这个分工不是偏好,是被两个事实逼出来的:Sentinel 无 Python 端口、RocketMQ 的 Python 客户端(Boost.Python over C++)长期低维护。于是限流与队列都落 Java 侧,Python worker 只负责服务 `/chat` 与经 nacos-sdk-python 直读热参——RocketMQ Python 客户端的成熟度问题因此变成非问题:
生产形态 = Java 管准入+队列,Python 只服务。这个分工不是偏好,是被两个事实逼出来的:Sentinel 无 Python 端口、RocketMQ 的 Python 客户端(Boost.Python over C++)长期低维护。于是限流与队列都落 Java 侧,Python worker 只负责服务 `/chat` 与经 genconfig 门面读热参(NacosHotConfig 作热源)——RocketMQ Python 客户端的成熟度问题因此变成非问题:
```mermaid
flowchart LR
@ -153,10 +154,10 @@ flowchart LR
SENT -->|过闸| MQ[(RocketMQ<br/>gen 队列)]
MQ --> CONS["Java 消费者<br/>有界并发结构性≤15"]
CONS -->|调| CHAT["AgentScope Service /chat<br/>(Nacos discovery 定位)"]
CHAT --> MW["Python middleware<br/>nacos-sdk-python 直读预算/阈值"]
CHAT --> MW["Python middleware<br/>经 genconfig 门面读预算/阈值<br/>(NacosHotConfig 热源)"]
```
nacos-sdk-python 是官方 SDK,`add_listener` 走 Nacos 长轮询推送触发 async 回调、天然做 middleware 热读,客户端本地磁盘快照兜底(Nacos 不可达不连累生成)。实现里写死三条:listener 需活跃 event loop、回调 try/except 兜住别掀翻 worker、Nacos 不可达回落快照 + 内置默认。
热参不由 middleware 直连 Nacos,而是经 NacosHotConfig 投影进 genconfig 门面:NacosHotConfig 用 nacos-sdk v1 `add_config_watcher` 走长轮询推送、客户端本地磁盘快照兜底(Nacos 不可达不连累生成),middleware 照旧从 genconfig 取值。实现里写死三条:watcher 回调 try/except 兜住别掀翻 worker、语义非法值(负预算/超小超时)保旧值 + 告警不覆盖热参、Nacos 不可达回落快照 → env → 本地 YAML → 内置默认。
## 4 步骤计划(全 foundation 先行 · 有序)
@ -174,8 +175,8 @@ flowchart LR
```
**阶段〇 · 生产基建 = SCA 三件套自托管(前置)**
- 交付:mini-infra 起 Nacos(standalone,配置中心 + 服务发现)+ RocketMQ(NameServer + 单 Broker,gen 队列);game-cloud 接 Sentinel(Java 准入侧流控 ≤15 + 按用户配额,规则源 Nacos 热推)+ RocketMQ 生产/消费(有界并发结构性保证 ≤15);AgentScope Service 注册进 Nacos discovery(替硬编码 @8200);Python worker 的 middleware 接 nacos-sdk-python listener 读预算/阈值
- 验证:改 Nacos 配置→listener 热推到 Python middleware;请求过 Sentinel 准入(击穿 ≤15 被拦)→入 RocketMQ→Java 有界消费→调 `/chat`;三件自托管、mini-infra RAM 余量够;数据不出内网。
- 交付:mini-infra 起 Nacos(standalone,配置中心 + 服务发现)+ RocketMQ(NameServer + 单 Broker,gen 队列);game-cloud 接 Sentinel(Java 准入侧流控 ≤15 + 按用户配额,规则源 Nacos 热推)+ RocketMQ 生产/消费(有界并发结构性保证 ≤15);AgentScope Service 注册进 Nacos discovery(替硬编码 @8200);建好 NacosHotConfig(v1 `add_config_watcher` 长轮询热源、本地快照兜底,单测绿),接进 genconfig 作预算/阈值热源留阶段二
- 验证:NacosHotConfig 能连 Nacos 收到配置变更(接进 genconfig 由阶段二验);请求过 Sentinel 准入(击穿 ≤15 被拦)→入 RocketMQ→Java 有界消费→调 `/chat`;三件自托管、mini-infra RAM 余量够;数据不出内网。
- 依赖:mini-infra(已有 Docker/MySQL/Redis)。
- 风险:mini-infra RAM 余量(新增 ~4-5GB JVM)——吃紧则压 `-Xmx` / 不部 Sentinel 面板(规则直存 Nacos);RocketMQ Python 客户端弱 → 队列生产消费全在 Java 侧、Python 不碰(见 §3.7)。
@ -185,11 +186,11 @@ flowchart LR
- 依赖:AgentScope Service(tier2 已部署 @8200)、`run_gates`(已存在)。
- 风险:**middleware 拦 finish + 注入续跑的确切机制没在项目里验过**——先做一个小 spike 坐实(§6);cheap-worker 归并是主要工作量。
**阶段二 · 配置中心 = yudao 治理 ⊕ Nacos 版本化**
- 交付:game-cloud 里一个 yudao 模块做治理前台(编辑 UI + 鉴权 + `creator` + BPM 挂点)+ 激活时把 active 版写进 Nacos 并 PATCH `/agent`+`/session` 的编排;middleware 热参(预算/阈值)进 Nacos dataId、Python 侧 listener 直读;Nacos 承版本/回滚/灰度/推送(取代自建 Flyway 版本表 + 薄读接口)
- 验证:改任一旋钮→新版本→激活→PATCH→下一次生成生效;配置集成组激活(静默期)、并发两局不读撕裂组合;回滚旧版本即恢复;改动随版本可查 creator/时间/diff。
- 依赖:阶段一(生成走 Service,配置才有 PATCH 落点)。
- 风险:配置中心↔Service 的 PATCH 一致性(激活失败要可重试、可回滚到上一激活版)
**阶段二 · 配置中心 = yudao 治理与版本账本 ⊕ Nacos 生效下发**
- 交付:game-cloud 落一个 yudao 治理子域(编辑 UI + 鉴权 + `creator` + BPM 挂点 + 版本行 + 生命周期状态机 + 当前激活版指针 + 激活编排);版本行落 MySQL、承版本历史/回滚/diff(借 yudao 原生);激活时双路下发——prompt/模型/参数 PATCH 进 `/agent`+`/sessions`,预算/门阈值 publish 进按档隔离的 Nacos 生效 dataId;把阶段〇建好未接线的 NacosHotConfig 接进 genconfig 作热源(middleware 调用面不改)。Nacos 收窄为预算/阈值那一路的生效下发通道,不再承版本账本
- 验证:改任一旋钮→定版→激活→下一次生成生效;配置集成组激活(静默期)、并发两局不读撕裂组合;回滚旧版本即恢复;改动随版本可查 creator/时间/diff;NacosHotConfig 接线后 cheap 与 tier2 经 genconfig 数秒热读到新预算/阈值、不重启。详见阶段二设计 §4/§5
- 依赖:阶段一(生成走 Service,配置才有 PATCH 落点);阶段〇 NacosHotConfig 已建未接线
- 风险:激活一致性是本阶段最重风险——一批 PATCH+publish 跨系统非原子、投影写即被读,靠值域校验前置 + 幂等 + 失败即整批判未生效并立即补偿重推已成功路回上一激活版收敛;详见阶段二设计 §6
**阶段三 · 配置编辑·版本 UI**
- 交付:game-admin(标准 admin-api,不用独立 axios)配置面:浏览 / 改→版本 / 单条或配置集激活 / 回滚 / 历史 / diff;agent 配置表单消费 `/agent/schema`
@ -221,6 +222,7 @@ flowchart LR
- **配置中心↔Service PATCH 一致性 + 并发撕裂**:激活是一批独立 PATCH,机制上非原子;须幂等 + 失败即整批判未生效可重试 + 记"当前激活版"为权威(Service 为投影)、不留半生效态。并发一局读到跨 `/agent`+`/session` 撕裂组合的风险,MVP 由**静默期激活**规避(见 §3.3);真机制级原子(epoch 戳 + 读到不一致重读/拒绝)留放量后。
- **门 MCP 必须与生成 Service 同驻 / 共享 workspace**:门要读 agent 刚写进 workspace 的 `src/`,而 chrome/esbuild 只在 mini-desktop;若跨机、跨 FS 则门读不到文件。钉:Service + 门 MCP 同驻 mini-desktop 或共享工作区。
- **SoT 收口必须扩全**(否则触 canonical-uniqueness 红线门):须同步修 SoT 的**三处**偏离——① GitOps 口径(§5.2 表行+正文 / ADR-4 / A13 / §二补④ / §5.8)改为配置中心版本化;② §5.2"管理面用 /agent CRUD 做配置管理"的假设不完整(源码证:/agent 不含 model、context_size/stream 透不进、生成原走进程内),据本设计的"配置中心版本层 + 原生 per-POST 热配 + 护城河 middleware"修正;③ **resume 机制叙述**:现有 SoT 与代码注释(`bootstrap.py``app.py``control_plane.py:19`、tier2 架构图说 + close-out)把 resume 讲成"消费方决定是否再 POST"的**框架外层**机制;本设计改成 `on_reasoning` 洋葱内 resume,那些叙述须降级标注为 fallback,否则两份自称 canonical 触门。
- **阶段二方向 B 涟漪已收口(2026-07-04)**:创始人 2026-07-02 拍方向 B——版本账本从 Nacos 挪回 yudao MySQL 版本行、Nacos 收窄为预算/阈值那一路的生效下发、middleware 经 genconfig 门面读(NacosHotConfig 作热源)。本设计 §0 / §3.3 / §3.6 图 / §3.7 / §4(阶段〇 listener 口径、阶段二节)已随之回调,与阶段二设计 §7 挂账表逐条对齐;运行时 SoT(架构图说 §5.2/§5.8/ADR-4/A13)已同步(2026-07-03)。`/session` 路径按 22444fd5 修复口径应为 `/sessions`,本次仅在已回调段落更正,其余机制描述段(§1.1/§3.1/§3.2)未一并统一,待后续 doc-sync。
- **预算网关侧做不了每局硬顶**:每局预算是 agent 侧软限(网关只 key 级兜底);这是事实约束、非本设计缺陷。
## 附 图清单与状态

View File

@ -1,7 +1,7 @@
---
date: 2026-07-02
topic: 配置控制面-阶段二
status: 定稿 · 创始人已拍方向 B(维持 yudao⊕Nacos;prompt 移出 Nacos→MySQL 版本行,2026-07-02)· Codex+Opus 双评审 11 条已回并全修收口(2026-07-02)· 已排期(实施工单=§8,2026-07-04 fable 列单)
status: 已实施(2026-07-04,fable 编排·opus 执行·逐波终审)· 创始人已拍方向 B(维持 yudao⊕Nacos;prompt 移出 Nacos→MySQL 版本行,2026-07-02)· Codex+Opus 双评审 11 条已回并全修收口(2026-07-02)
sot-impact: 修订 生成引擎运行时(SoT §5.2 管理面配置管理 / §5.8 配置三类"受治理发版" / ADR-4 配置热取 / A13 配置注册表:把 GitOps/Langfuse 式口径收敛为 yudao 配置中心版本化(版本账本落 MySQL 版本行)+ 双路激活,与上级设计 §6 pending 同一收口面,已回写(2026-07-03,W-DSGN doc-sync);对上级设计四处口径 + SoT 回写的回调挂账见本档 §7)
上级: docs/agent-specs/2026-06-30-配置控制面一次性按序实现-设计.md
关联:
@ -11,7 +11,7 @@ sot-impact: 修订 生成引擎运行时(SoT §5.2 管理面配置管理 / §5.8
- tier2/gen-worker/worker/middleware.py:173(CircuitBreakerMiddleware 软预算,预算/阈值经 genconfig 读)· worker/gate_judge.py(门判 GateJudgment)
- tier2/gen-worker/worker/store.py(成品源工程归档的后端 seam:BackendStore 定义 MySQL manifest + MinIO 源文件接口、当前为占位,真正在用的是 LocalFsStore 本地实现 —— §3.1 prompt 存储选型佐证)· cheap-worker/cheap_roles.py 30499B(≈30KB)/ tier2 worker/roles.py 24539B(≈24KB)/ contracts/prompts/04-config/cheap-system.md 14695B(≈14.7KB,外置 prompt 最大单条)(prompt 尺寸画像依据)
- cheap-worker/cheap_service_app.py:213(`_cheap_middlewares_factory` 每回合工厂)· :300(`build_cheap_app`)
- tier2/gen-worker/service/app.py(AgentScope Service `/chat` + `/agent` + `/session`)
- tier2/gen-worker/service/app.py(AgentScope Service `/chat` + `/agent` + `/sessions`)
- agentscope==2.0.2:app/_router/_agent.py:138(`update_agent` PATCH)· app/_router/_session.py:291(`update_session` PATCH,部分字段更新语义)
- game-cloud huijing-module-bpm(审批,放量后)· huijing-module-system(操作日志 + 权限,yudao 原生)· game-module-aigc(生成配置治理落点)· huijing-module-infra(Nacos SCA 通路 + infra_config KV 参照)
- game-admin/src/views/wanxiang(配置编辑面,阶段三消费)
@ -25,7 +25,7 @@ sot-impact: 修订 生成引擎运行时(SoT §5.2 管理面配置管理 / §5.8
(图0 概览 SVG 待补)
- **核心思想**:阶段一已经让生成配置能热改——prompt/模型/参数经 `/agent`+`/session` 由 AgentScope 每 POST 现装配、下一次生成即生效,预算/门阈值经 genconfig 从本地 YAML 热取。但热改缺一层治理:改动没有版本历史、没有归因、不能一键回滚、没有激活闸。阶段二在这层热配之上补一个**版本化治理层**:创始人在 game-cloud 的 yudao 侧编辑一组生成配置,走"改 → 定版 → 审核挂点 → 激活",激活时**双路下发**——prompt/模型/参数这一路 PATCH 进 AgentScope Service(写它的 Redis,下一次 POST 现装配即生效),预算/门阈值这一路 publish 进 Nacos、由 worker 的 genconfig 经 Nacos 热读投影。版本历史、回滚、diff 落 yudao 侧的 MySQL 版本行(prompt 正文随行存 `MEDIUMTEXT`、**不进 Nacos**——Nacos 单配置默认上限 100KB,扛不住会长大的 prompt,创始人已拍);Nacos 收窄为预算/门阈值那一路的生效下发通道;鉴权、creator 归属、审计、审批全部复用 yudao 原生。
- **核心思想**:阶段一已经让生成配置能热改——prompt/模型/参数经 `/agent`+`/sessions` 由 AgentScope 每 POST 现装配、下一次生成即生效,预算/门阈值经 genconfig 从本地 YAML 热取。但热改缺一层治理:改动没有版本历史、没有归因、不能一键回滚、没有激活闸。阶段二在这层热配之上补一个**版本化治理层**:创始人在 game-cloud 的 yudao 侧编辑一组生成配置,走"改 → 定版 → 审核挂点 → 激活",激活时**双路下发**——prompt/模型/参数这一路 PATCH 进 AgentScope Service(写它的 Redis,下一次 POST 现装配即生效),预算/门阈值这一路 publish 进 Nacos、由 worker 的 genconfig 经 Nacos 热读投影。版本历史、回滚、diff 落 yudao 侧的 MySQL 版本行(prompt 正文随行存 `MEDIUMTEXT`、**不进 Nacos**——Nacos 单配置默认上限 100KB,扛不住会长大的 prompt,创始人已拍);Nacos 收窄为预算/门阈值那一路的生效下发通道;鉴权、creator 归属、审计、审批全部复用 yudao 原生。
- **边界**:管**业务生成配置**的版本化治理(prompt/context/max_iters/模型/参数/预算/门阈值);**基建配置**(game-cloud 的 Spring 配置、Sentinel 流控规则、RocketMQ 参数)不进本治理层——那条是阶段〇已接的 Nacos SCA 原生通路,运维改、即时热生效。BPM 审批**放量后启用**(架构预留挂点,MVP 由创始人本人直接激活);配置编辑 UI 属阶段三;观测属阶段四;机制级激活原子性留放量后(MVP 取静默期语义)。
- **成功**:本会话手改过的每个旋钮(模型 M3↔glm-5.2、预算 ¥10↔¥49、max_tokens、prompt)都能在配置中心改一版、激活、下一次生成即生效、一键回滚,并可查谁在何时改了什么、diff 是什么;一组协同旋钮作一个配置集一次激活;激活失败、Service 不可达、配置漂移都有明确兜底。
@ -33,7 +33,7 @@ sot-impact: 修订 生成引擎运行时(SoT §5.2 管理面配置管理 / §5.8
### 1.1 意图
配置控制面这条线的痛点在上级设计里已经讲透:本会话调一款便宜档游戏,四个旋钮里三个要改代码重启,而且是在 live worktree 上 SSH 手敲。阶段〇到阶段一②把"能不能热改"这半解决了——生产基建三件套自托管进 mini-infra,护城河续修/软预算/门判做成 AgentScope 洋葱里的 middleware,cheap 与 tier2 两档都归并到同一套 Service `/chat`,prompt/模型/参数经 `/agent`+`/session` 每 POST 现装配、预算/门阈值经 genconfig 从 `generation.yaml` 热取。
配置控制面这条线的痛点在上级设计里已经讲透:本会话调一款便宜档游戏,四个旋钮里三个要改代码重启,而且是在 live worktree 上 SSH 手敲。阶段〇到阶段一②把"能不能热改"这半解决了——生产基建三件套自托管进 mini-infra,护城河续修/软预算/门判做成 AgentScope 洋葱里的 middleware,cheap 与 tier2 两档都归并到同一套 Service `/chat`,prompt/模型/参数经 `/agent`+`/sessions` 每 POST 现装配、预算/门阈值经 genconfig 从 `generation.yaml` 热取。
剩下的是"改动能不能管"这半。今天改一个旋钮,要么直接 PATCH Service、要么 scp 一份新的 `generation.yaml` 上去,两条路都没有版本账本:改错了没有上一版可回滚,改过了查不出是谁在什么时候改的、和上一版差在哪,更没有一个"激活"的闸把"编辑中"和"已生效"分开。放量后这些配置要过审批才能上生产,现在连挂审批的地方都没有。阶段二就是把这层治理补上,让配置从"能热改的散落旋钮"变成"可版本、可回滚、可归因、可审批的受治理资产"。
@ -121,7 +121,7 @@ stateDiagram-v2
flowchart LR
ACT["yudao 激活编排<br/>(取选定版内容)"]
ACT -- "路A:prompt/context/max_iters" --> PA["PATCH /agent"]
ACT -- "路A:模型/参数/thinking/temp" --> PS["PATCH /session"]
ACT -- "路A:模型/参数/thinking/temp" --> PS["PATCH /sessions"]
PA & PS --> REDIS[("AgentScope Redis<br/>当前配置")]
REDIS -- "每 POST 现装配(热)" --> GEN["/chat 生成回合"]
ACT -- "路B:软预算目标/门阈值" --> PUB["publish Nacos 生效 dataId"]
@ -131,8 +131,8 @@ flowchart LR
ACT -- "记当前激活版 + 操作日志" --> YU[("yudao 治理表")]
```
- **路 A(prompt/模型/参数)**:激活编排把内容 PATCH 进 AgentScope Service 的 `/agent`(system_prompt / 压缩比例 / tool_result 截断 / max_iters)与 `/session`(模型 / 协议 type / credential / max_tokens / thinking / reasoning_effort / temperature)。`/session` 的 PATCH 在顶层是部分字段更新语义(`exclude_unset`,只改本次带上的顶层字段),但模型与参数都封在 `chat_model_config` 这一个子对象里,而该子对象一旦出现即被**整体替换**——顶层 `exclude_unset` 不深合并它内部的 `parameters`,且 `type`/`model` 是必填字段。所以激活编排改任一模型参数(哪怕只动 max_tokens 或 thinking)都必须从版本行组装出完整的 `chat_model_config`,把 `type`/`credential_id`/`model`/`parameters` 全带齐,不能只发局部对象,否则未带上的字段会被清空。写进 Service 的 Redis 后,下一个 POST `/chat` 现装配即生效。
- **路 B(软预算目标 / 门阈值)**:这些参数不在 `/agent`+`/session` 里,它们是 worker 的 middleware 在构造时从 genconfig 读的。激活编排把内容 publish 进 worker 监听的 Nacos 生效 dataId,NacosHotConfig 经长轮询推送热读进进程内,genconfig 从它取到新值,下一次 middleware 构造时读到。这里有一处 dataId 粒度要定死:cheap-worker 与 tier2 gen-worker 是两个独立进程、各接一个 NacosHotConfig,两档 key 命名本就不同(cheap 用 `cheap_rmb_hard_limit`、tier2 用 `rmb_hard_limit`)。**路 B 生效 dataId 按档隔离**——cheap 与 tier2 各用一个专属 dataId,而不是共用一个 `gen-hot-params` 整体替换;否则激活一档的配置集会把另一档的 key 从该 dataId 上冲掉(publish 是整内容替换,worker 初读/重启即缺 key)。激活哪一档,就只 publish 那一档的 dataId。
- **路 A(prompt/模型/参数)**:激活编排把内容 PATCH 进 AgentScope Service 的 `/agent`(system_prompt / 压缩比例 / tool_result 截断 / max_iters)与 `/sessions`(模型 / 协议 type / credential / max_tokens / thinking / reasoning_effort / temperature)。`/sessions` 的 PATCH 在顶层是部分字段更新语义(`exclude_unset`,只改本次带上的顶层字段),但模型与参数都封在 `chat_model_config` 这一个子对象里,而该子对象一旦出现即被**整体替换**——顶层 `exclude_unset` 不深合并它内部的 `parameters`,且 `type`/`model` 是必填字段。所以激活编排改任一模型参数(哪怕只动 max_tokens 或 thinking)都必须从版本行组装出完整的 `chat_model_config`,把 `type`/`credential_id`/`model`/`parameters` 全带齐,不能只发局部对象,否则未带上的字段会被清空。写进 Service 的 Redis 后,下一个 POST `/chat` 现装配即生效。
- **路 B(软预算目标 / 门阈值)**:这些参数不在 `/agent`+`/sessions` 里,它们是 worker 的 middleware 在构造时从 genconfig 读的。激活编排把内容 publish 进 worker 监听的 Nacos 生效 dataId,NacosHotConfig 经长轮询推送热读进进程内,genconfig 从它取到新值,下一次 middleware 构造时读到。这里有一处 dataId 粒度要定死:cheap-worker 与 tier2 gen-worker 是两个独立进程、各接一个 NacosHotConfig,两档 key 命名本就不同(cheap 用 `cheap_rmb_hard_limit`、tier2 用 `rmb_hard_limit`)。**路 B 生效 dataId 按档隔离**——cheap 与 tier2 各用一个专属 dataId,而不是共用一个 `gen-hot-params` 整体替换;否则激活一档的配置集会把另一档的 key 从该 dataId 上冲掉(publish 是整内容替换,worker 初读/重启即缺 key)。激活哪一档,就只 publish 那一档的 dataId。
**为什么静默期语义在这个模型下几乎是自然的**:两路生效都发生在"下一次生成"的边界上——路 A 的 Redis 在 `/chat` 进 session 锁之前读、路 B 的 genconfig 在 middleware 构造时读,正在跑的那一局早已经读过配置了,新配置只影响此后新起的 POST。所以并发引起的撕裂窗口只剩一个:一个配置集的多次 PATCH/publish 之间非原子,理论上并发一局能读到"路 A 新、路 B 旧"的组合。MVP 单操作者 + 创作页置灰把这个并发窗口的影响面压到零,取静默期语义即可;真机制级原子留放量后(上级 §3.3)。
@ -171,10 +171,10 @@ flowchart LR
激活是一批跨系统的非原子写(PATCH Service + publish Nacos + 更新 yudao 指针),这里的失败模式要正面处理,不能让配置中心把生成链路带崩。
- **激活失败即时补偿(账本语义,不作投影强承诺)**。一批下发里任一步失败(某个 PATCH 返错、Nacos publish 超时),整批判**未激活**:yudao 当前激活版指针**不前移**,保留上一激活版为账本权威。但双路投影是"写即被读"、两路间无事务,已成功下发的那一路在投影层已经生效——指针不前移只保住账本、保不住投影。所以失败处置不能停在"判未激活",必须**立即补偿**:把本批已成功下发的那一路(PATCH 或 publish)重推回上一激活版的内容,再标为可重试。补偿与重放都要幂等(同一版本重推无副作用)。这样账本与投影一起收敛回上一激活版,不留"路 A 新、路 B 旧"的持续撕裂;而不是把"绝不留半生效态"写成投影层做不到的强承诺、再靠定期对账慢慢兜。
- **MySQL 不可达 / 指针写失败**。激活还含"读版本行、写激活尝试、前移当前激活版指针、记审计"这几步 yudao 库内写,两种情形分开处置:(a) 起步读版本行时 MySQL 不可达——直接拒绝激活、不发起任何下发,生成继续用旧投影。(b) 三路投影(PATCH `/agent`、PATCH `/session`、publish Nacos)都成功、最后前移指针或写审计时 MySQL 失败——此刻投影已是新版、账本仍指旧版,是确定漂移。处置:激活状态先持久化为 `ACTIVATING`(下发前落、全部成功后才转 `ACTIVE`),恢复任务按激活尝试幂等地二选一执行到底——要么补提交指针(投影既已是新版,对齐账本),要么补偿重推旧版回投影并回滚该尝试,不停在中间态。
- **MySQL 不可达 / 指针写失败**。激活还含"读版本行、写激活尝试、前移当前激活版指针、记审计"这几步 yudao 库内写,两种情形分开处置:(a) 起步读版本行时 MySQL 不可达——直接拒绝激活、不发起任何下发,生成继续用旧投影。(b) 三路投影(PATCH `/agent`、PATCH `/sessions`、publish Nacos)都成功、最后前移指针或写审计时 MySQL 失败——此刻投影已是新版、账本仍指旧版,是确定漂移。处置:激活状态先持久化为 `ACTIVATING`(下发前落、全部成功后才转 `ACTIVE`),恢复任务按激活尝试幂等地二选一执行到底——要么补提交指针(投影既已是新版,对齐账本),要么补偿重推旧版回投影并回滚该尝试,不停在中间态。
- **配置值本身非法(合法但语义错)**。激活链是"改 → 定版 → 激活",对预算写错单位(元/分混)、预算填成天文数、超时给到过小、`max_tokens ≤ thinking_budget`、模型协议 type 与 credential type 不匹配这类**类型正确但语义错**的值,若无校验会一路激活、下一局生效——预算是成本红线旋钮,配错直接让软预算失效、成本超支。所以激活前加一道**值域 sanity 校验**:预算为正数且落在合理区间、单位固定;超时有下限;`max_tokens > thinking_budget`;模型协议 type 与 credential type 匹配;prompt 非空。校验不过直接拒绝激活。NacosHotConfig 读侧再兜一道(§3.4:语义非法值保旧值 + 告警);仍漏过的错值挂阶段四观测(成本异常告警)事后发现。
- **Service 不可达**。路 A 依赖 Service 在线才能 PATCH。Service 不可达时激活判失败,按上面的补偿口径处置(路 A 尚未成功、无需补偿路 A;若路 B 已 publish 成功则补偿重推路 B 回旧版),保留上一激活版;Service 上跑的还是它 Redis 里的旧配置,生成不中断,只是新配置没生效。Service 恢复后重放激活即可。
- **配置漂移检测**。Service 的 Redis 投影可能与"当前激活版"漂移——Service 重启若 Redis 未持久化会丢配置回落缺省、或有人绕过治理直接改了 Redis/Nacos、或某次激活部分失败没补偿干净、或机器上遗留 env 压过了本该生效的激活值。配置中心提供一个对账:激活后与定期,拉 Service 的 `/agent`+`/session` 当前配置比对当前激活版的路 A 内容;拉 worker 的生效投影比对路 B 内容(含 env 覆盖口径:实际生效值来自 env 而非激活版时也算漂移);对不上即告警,并支持一键重推(重放激活把投影拉回激活版)。这道对账是"配置中心为权威、Service 与 worker 为投影"这个定位的兜底闸,但不是失败的第一道防线——第一道是上面的即时补偿。
- **配置漂移检测**。Service 的 Redis 投影可能与"当前激活版"漂移——Service 重启若 Redis 未持久化会丢配置回落缺省、或有人绕过治理直接改了 Redis/Nacos、或某次激活部分失败没补偿干净、或机器上遗留 env 压过了本该生效的激活值。配置中心提供一个对账:激活后与定期,拉 Service 的 `/agent`(AgentScope 无单个 GET `/agent/{id}`,用列表端点按 id 过滤)+`/sessions` 当前配置比对当前激活版的路 A 内容;拉 worker 的生效投影比对路 B 内容(含 env 覆盖口径:实际生效值来自 env 而非激活版时也算漂移;Nacos publish→read 最终一致,读带 8s 容忍窗、避开刚激活的收敛中间态);对不上即告警,并支持一键重推(重放激活把投影拉回激活版)。这道对账是"配置中心为权威、Service 与 worker 为投影"这个定位的兜底闸,但不是失败的第一道防线——第一道是上面的即时补偿。
- **命名空间错配**。见 §3.4:写读两侧的 namespaceId 必须是同一个真实值,默认空间是空串非 "public",且现状代码的 `public` 字面量偏差要作前置任务先修。这条在接线时一次性核对确认,避免配置静默推不到。
## 4 步骤计划
@ -198,36 +198,42 @@ flowchart LR
- 交付:把现状代码里的 `namespace: public` 字面量偏差统一成同一个真实 namespaceId(走默认公共空间就置空、而非填 "public"),覆盖 Java `application.yaml`(两处)、Python `nacos_registry.py` 默认值、`test_nacos_registry.py` 断言与凭据档 `docs/内网凭据与端点.md`(见 §3.4)。
- 验证:写侧(yudao publish)与读侧(worker NacosHotConfig、game-cloud SCA)落在同一真实 namespaceId;既有服务发现/注册不回归。
- 风险:不先修这项,路 B 写读会静默错空间、步骤 4 接线无从验证。
- 落地(`b2b4d389`):namespace 口径统一,Java/Python/测试/凭据档已对齐同一真实值。
**步骤 1 · 配置集建模 + yudao 治理骨架**
- 交付:在 game-module-aigc 落一个生成配置治理子域(复用 yudao 的鉴权/creator/审计框架,不塞进 infra_config 的 KV 表——生成配置是结构化配置集、不是键值对)。定义配置集的数据模型(一个配置集含哪些旋钮、映射到哪些 `/agent`+`/session` 字段与哪些 Nacos 生效 key)、版本与当前激活版指针、生命周期状态机、creator 与操作审计。
- 交付:在 game-module-aigc 落一个生成配置治理子域(复用 yudao 的鉴权/creator/审计框架,不塞进 infra_config 的 KV 表——生成配置是结构化配置集、不是键值对)。定义配置集的数据模型(一个配置集含哪些旋钮、映射到哪些 `/agent`+`/sessions` 字段与哪些 Nacos 生效 key)、版本与当前激活版指针、生命周期状态机、creator 与操作审计。
- 验证:能建/改/定版一个配置集,creator 与时间随版本落库;权限门挡住无权写;状态机流转符合 §3.2。
- 依赖:yudao(game-cloud 已在)。
- 风险:配置集与 AgentScope agent/session 的字段映射要对齐 `/agent`+`/session` 的真实 schema(消费 `/agent/schema`),映射错则激活 PATCH 无效。
- 风险:配置集与 AgentScope agent/session 的字段映射要对齐 `/agent`+`/sessions` 的真实 schema(消费 `/agent/schema`),映射错则激活 PATCH 无效。
- 落地(`3ae34de1`):配置集建模 + yudao 治理骨架 + 版本行(步骤 1、2 同提交,MySQL 治理子域 Flyway V29/V30)。
**步骤 2 · 版本行与历史(MySQL)**
- 交付:定版落版本行——配置集全量内容(prompt 存 `MEDIUMTEXT` + 模型/参数/预算/阈值)与元数据同库同事务一次写成一行;历史列表、任一历史版取回、两版 diff;当前激活版指针只由激活动作前移(定版不动它)。
- 验证:定多版后能列历史、取任一版、diff 两版;定版是单库事务、无跨系统写;30KB 级 prompt 正文完整存取无截断,并加一个 **64KB 边界样本**(越过 `TEXT` 上限、验证 `MEDIUMTEXT` 存取无截断)与 **utf8mb4 字节数校验**(`content_bytes` 按字节而非字符计,含多字节中文/emoji 时口径正确)。
- 依赖:步骤 1。
- 风险:版本行只增不删,量级 = 人工定版频次(每天几次),多年不清理也只是几千行——留一个归档策略位即可,不做提前优化。
- 落地(`3ae34de1`):版本行与历史/回滚/diff(步骤 1、2 同提交)。
**步骤 3 · 双路激活编排**
- 交付:激活动作先做值域 sanity 校验(§3.6),通过后把选定版双路下发——路 A PATCH `/agent`+`/session`(模型/参数从版本行组装完整 `chat_model_config`,§3.3),路 B publish 进 worker 监听的按档隔离生效 dataId;更新当前激活版指针 + 记操作日志;成组下发幂等、任一步失败即整批判未生效并立即补偿重推已成功路回上一激活版、再判可重试(见 §3.6);静默期语义(只对下一批新生成生效)。
- 交付:激活动作先做值域 sanity 校验(§3.6),通过后把选定版双路下发——路 A PATCH `/agent`+`/sessions`(模型/参数从版本行组装完整 `chat_model_config`,§3.3),路 B publish 进 worker 监听的按档隔离生效 dataId;更新当前激活版指针 + 记操作日志;成组下发幂等、任一步失败即整批判未生效并立即补偿重推已成功路回上一激活版、再判可重试(见 §3.6);静默期语义(只对下一批新生成生效)。
- 验证:改任一旋钮 → 定版 → 激活 → 下一次生成生效;并发两局不读到路 A 新/路 B 旧的撕裂组合(静默期);回滚旧版即恢复;一批下发中途失败时指针不前移、已成功路被补偿重推回旧版、可重试;非法值(负预算等)在激活前被拒。
- 依赖:步骤 1、2;阶段一②(两档已归并 Service,PATCH 有落点)。
- 风险:激活一致性是本阶段最重的风险(§3.6);Service PATCH 与 Nacos publish 跨系统,须幂等 + 判未生效可重试。
- 落地(`72973532`):双路激活编排;路 A `/sessions` 复数端点修复 `22444fd5`(早稿单数 `/session` 与真实路由不符)。
**步骤 4 · NacosHotConfig 接进 genconfig**(依赖上方 namespace 口径统一前置)
- 交付:genconfig 的读取后端提升到 Nacos,落地阶段〇 D2 建好未接线的 `nacos_hotconfig.py`,拆两件。(1) 新增 worker 启动期的 **HotConfig 单例工厂**:`nacos_hotconfig.py` 明确只消费已建好的 v1 `NacosClient`、不自建 client,所以工厂负责把 client 构造齐——server 地址、鉴权(账号密码)、`NO_PROXY`(内网直连绕系统代理,阶段〇同款坑)、真实 `namespaceId``group`、按档隔离的 `dataId`,再注入进 NacosHotConfig 并接进 genconfig。(2) genconfig.get 的取值链前端接热源:优先查 NacosHotConfig,再依次回落 env、本地 `generation.yaml`、内置默认(优先级见 §3.4)。middleware 调用面一行不改。
- 验证:改 Nacos 生效 dataId → worker 数秒内经 genconfig 读到新预算/阈值(不重启);单测覆盖四条异常/回落路径——**未 start**(工厂没起 NacosHotConfig → genconfig 回落 env/YAML/默认)、**Nacos 不可达**(NacosHotConfig 磁盘快照兜底,再回落本地)、**namespace 配错**(写读不同空间时读不到,佐证前置任务的必要)、**YAML 回落**(热源无值时取本地 YAML 与默认);cheap 与 tier2 两档各读各的 dataId、软预算目标与门阈值都吃上热读。
- 依赖:阶段〇 Nacos + NacosHotConfig(已建);阶段一①(middleware 经 genconfig 读预算/阈值);namespace 口径统一前置。
- 风险:genconfig 现有缓存与 NacosHotConfig 的推送时序要理顺(别让本地 YAML 缓存盖住 Nacos 热值);回落链优先级(Nacos > env > YAML > 默认)要测到位。
- 落地(`344330a4`):NacosHotConfig 接进 genconfig 作热源;worker 启动期 HotConfig 单例工厂入口装配 `d9def7d9`
**步骤 5 · 失败兜底 + 漂移对账**
- 交付:激活失败整批判未生效 + 保留上一激活版 + 可重试;Service 不可达兜底;配置漂移对账(拉 Service/worker 投影比对当前激活版)+ 一键重推。
- 验证:模拟 PATCH 中途失败/Service 不可达 → 指针不前移、生成用旧配置不中断、重放激活恢复;篡改 Redis/生效 dataId 后对账能检出漂移并重推拉回。
- 依赖:步骤 3、4。
- 风险:漂移对账要区分"真漂移"与"正在激活的中间态",避免误报。
- 落地(`a8dd5e50`):失败兜底 + 漂移对账(对账读带 8s 容忍窗避开激活收敛中间态)。
**后续阶段(划界,各自出 plan)**:阶段三 = game-admin 配置编辑面(浏览/改/定版/激活/回滚/历史/diff,表单消费 `/agent/schema`),依赖阶段二;阶段四 = 观测(Studio + genMonitor,trace 回放/成本对账/在跑监控),依赖 trace 事件流。两者不在本设计展开。
@ -246,7 +252,7 @@ flowchart LR
- **Service 不可达 / Redis 未持久化丢配置**:激活判失败保留旧版;Service 恢复后由漂移对账检出并一键重推。Service Redis 的持久化策略需与运维确认(丢配置是否需 Service 启动即从配置中心拉激活版自愈,可作后续增强)。
- **NacosHotConfig 接线破坏 middleware 读参**:回落链(Nacos → env → 本地 YAML → 内置默认,优先级见 §3.4)是保命绳,先在两档单测里锁死整条回落链再上;真接线灰度——先只把一个低风险旋钮(如门阈值)切到 Nacos 热读、验稳再推预算目标。回退 = genconfig 后端切回纯本地 YAML(改一处开关)。
- **命名空间错配**:默认空间是空串非 "public";现状代码的 `public` 字面量偏差作前置任务先修(§3.4 / §4 前置),写读两侧 namespaceId 一次性核对对齐,否则配置静默推不到(阶段〇同款坑)。
- **配置集字段映射漂移**:配置集到 `/agent`+`/session` 字段的映射依赖 AgentScope schema,框架升版可能变;映射以 `/agent/schema` 为准、加一致性校验,别硬编码字段名。
- **配置集字段映射漂移**:配置集到 `/agent`+`/sessions` 字段的映射依赖 AgentScope schema,框架升版可能变;映射以 `/agent/schema` 为准、加一致性校验,别硬编码字段名。
- **SoT 收口**:本阶段落地后,须把 SoT 里 GitOps/Langfuse 式的旧口径收敛为 yudao 配置中心版本化(账本落 MySQL 版本行)——§5.2 管理面配置管理、§5.8 配置三类的"受治理发版"、ADR-4 配置热取、A13 配置注册表四处,与上级设计 §6 pending 是同一收口面,收口时一并回写,避免两份自称权威触 canonical 门;对上级设计本身的口径回调逐条挂账在 §7,由编排层另单收口、本档不动上级档。
## 7 收口涟漪清单(挂账,由编排层另单收口)
@ -257,7 +263,7 @@ flowchart LR
|---|---|---|---|
| 1 | 上级设计 §0 / §3.3 / §3.7"互补"行 | "Nacos 管版本化存储与下发(版本历史/回滚/diff/灰度/推送),取代自建 Flyway 版本表 + 薄读接口" | 版本账本落 yudao MySQL 版本行(prompt 100KB 上限 + 定版原子性所迫,§3.1);Nacos 收窄为路 B 生效下发;"消灭薄读接口"结论不变(NacosHotConfig 仍替它);"灰度发布"收窄为路 B 生效 dataId 层能力、MVP 不启用 |
| 2 | 上级设计 §4 阶段二节(交付/验证/风险) | "激活时把 active 版写进 Nacos 并 PATCH""Nacos 承版本/回滚/灰度/推送(取代自建 Flyway 版本表 + 薄读接口)" | 交付 = yudao 治理子域(版本行 + 状态机 + 激活编排)+ 双路激活 + NacosHotConfig 接 genconfig;验证/风险按本档 §4/§6 |
| 3 | 上级设计 §3.6 mermaid(UI→yudao→NACOS 写版本→激活 PATCH) | 版本写进 Nacos、激活自 Nacos 侧发出 | yudao(MySQL 账本)→ 激活编排双路下发(PATCH `/agent`+`/session` · publish 生效 dataId);图随文改 |
| 3 | 上级设计 §3.6 mermaid(UI→yudao→NACOS 写版本→激活 PATCH) | 版本写进 Nacos、激活自 Nacos 侧发出 | yudao(MySQL 账本)→ 激活编排双路下发(PATCH `/agent`+`/sessions` · publish 生效 dataId);图随文改 |
| 4 | 上级设计 §3.3(middleware 用 nacos-sdk-python `add_listener` 订阅)/ §3.7 生产图(Python middleware 直读预算/阈值)/ §4 阶段〇(middleware 接 nacos-sdk-python listener 读预算/阈值) | middleware 经 nacos-sdk-python `add_listener` 直读 Nacos | middleware 经既有 genconfig 门面读、NacosHotConfig(v1 `add_config_watcher` 长轮询推送)作 genconfig 热源(§3.4);middleware 调用面不变,底层由"直读 Nacos"改为"genconfig 门面 + 热源"。上级核心结论(middleware 从 Nacos 热读预算/阈值、fail-safe 靠 SDK 快照兜底)不变,回调的是实现路径口径;此偏差实由阶段〇引入、阶段二继承 |
| 5 | SoT 回写口径(架构图说 §5.2 / §5.8 / ADR-4 / A13;上级 §6 已挂"GitOps 口径"收口项) | GitOps / Langfuse 式热取叙述 | "配置中心版本化"的落点 = yudao MySQL 版本行 + 双路激活(本档 frontmatter sot-impact 申报);与上级挂的收口单合并执行 |
@ -277,6 +283,8 @@ flowchart LR
**自审**:每步交付附真实 commit hash + 真跑验证输出(hash 会被 rev-parse 核验,伪造必露);没全绿报 BLOCKED、不谎报 DONE;激活一致性(§6 首条)是本单最重风险——实施中若发现投影层补偿语义做不到,停下挂问题、不许绕;收口时随上级 §6 收口单一并回写 §7 涟漪清单,不双开。
**执行终局(2026-07-04)**:§4 五步连同 namespace 前置全部代码落地(前置 `b2b4d389`、步骤 1+2 `3ae34de1`、步骤 3 `72973532`、步骤 4 `344330a4`+入口 `d9def7d9`、步骤 5 `a8dd5e50`),cheap 与 tier2 两档的 Service 入口都已接上双路激活的 PATCH 落点与 NacosHotConfig 热源;启用旗默认关,生产灰度与路 A 对真 Service 的 PATCH 排部署窗口(先门阈值、验稳再切预算目标)。实施中坐实三处口径修正、已就地回写正文:① AgentScope 没有单个 GET `/agent/{id}`,漂移对账改用 `/agent` 列表端点按 id 过滤(§3.6 早稿"拉 `/agent`"口径随此改真);② Nacos 是 publish→read 最终一致、非即时,对账读带 8s 容忍窗,避开刚激活尚未收敛的中间态被误报成漂移;③ 机器上遗留 env 覆盖压过激活值这类漂移从 game-cloud 侧看不见(env 只活在 worker 进程内),当前对账探不到,挂阶段四观测补——由 worker 暴露一个 effective 配置端点、把真正生效值连同来源吐出来供对账。§7 涟漪清单第 14 行已回写上级设计档(§0 / §3.3 / §3.6 图 / §3.7 / §4),收口标记见上级 §6;第 5 行 SoT 回写已随架构图说 doc-sync(2026-07-03)完成。余下待办承 §4 后续阶段:阶段三管理面 UI、阶段四观测、部署窗口灰度。
## 附 图清单与状态
| 图 | 角色 | 状态 |

View File

@ -1,6 +1,6 @@
---
title: agentic 生成运行时架构 — 可插拔 agent 平台
status: 架构演进中 · tier2 核心已落 + 0 号 spike feie-005 accept(首跑;收敛环 n=5 真跑判 conditional)· §4.2/§5.x 已按 2026-06-24 HANDOFF doc-sync(2026-06-25)· "采标准"方向 §6.8 双评审已过(采纳但修),已收口定稿:成熟度五列(§二补二)+ 6 条 build-vs-buy ADR(§二补三)已补、§三 定级已冻 · **2026-06-25 核心 reframe(创始人)**:框架收敛 AgentScope(SAA/dify 降最低优先级、留作远期适配验证可插拔)+ 三档按 AI 参与深度(去超休闲、全模板化非从零)+ per-gen 预算闸 <¥10/<¥50(图音另算)· **2026-07-03 doc-sync(实现对账回写)**:配置口径反转为 yudao 配置中心版本化 ⊕ Nacos 下发 ⊕ AgentScope per-POST 热重载(Langfuse 式退历史备选)、便宜档核心已 Python 化(cheap-worker)、tier2 收敛环真跑判 conditional(瓶颈在 agent 层 win-balance)、续修原语迁入 RepairMiddleware finish 点续修、预算两段式已裁(软停线 ¥10/¥50 + 硬地板 ×1.5)、C5/C6 判分契约已立位——详见各面「现 / 建」
status: 架构演进中 · tier2 核心已落 + 0 号 spike feie-005 accept(首跑;收敛环 n=5 真跑判 conditional)· §4.2/§5.x 已按 2026-06-24 HANDOFF doc-sync(2026-06-25)· "采标准"方向 §6.8 双评审已过(采纳但修),已收口定稿:成熟度五列(§二补二)+ 6 条 build-vs-buy ADR(§二补三)已补、§三 定级已冻 · **2026-06-25 核心 reframe(创始人)**:框架收敛 AgentScope(SAA/dify 降最低优先级、留作远期适配验证可插拔)+ 三档按 AI 参与深度(去超休闲、全模板化非从零)+ per-gen 预算闸 <¥10/<¥50(图音另算)· **2026-07-03 doc-sync(实现对账回写)**:配置口径反转为 yudao 配置中心版本化 ⊕ Nacos 下发 ⊕ AgentScope per-POST 热重载(Langfuse 式退历史备选;阶段二 genconfig Nacos 热源 + yudao 版本层 + 双路激活五步 2026-07-04 已代码落地、启用旗默认关待部署窗口灰度)、便宜档核心已 Python 化(cheap-worker)、tier2 收敛环真跑判 conditional(瓶颈在 agent 层 win-balance)、续修原语迁入 RepairMiddleware finish 点续修、预算两段式已裁(软停线 ¥10/¥50 + 硬地板 ×1.5)、C5/C6 判分契约已立位——详见各面「现 / 建」
canonical: true # 生成运行时架构唯一 SoT,收敛原 16 份图说/详设/接口协议草案
topic: 生成引擎运行时
date: 2026-06-24
@ -224,7 +224,7 @@ agentscope 2.0.2 内置 Workspace 三后端(源码实证 `LocalWorkspace` / `Doc
| **A10** | 玩法模板协议 | templateId 白名单(generic / business-sim / narrative / puzzle / trpg / heritage)+ prompt md + bundle 校验 schema;`getTemplateList()->TemplateRespVO`;模板 schema 与 A5 的 structureOk 耦合 | 现·部分(编译期常量)+ 建(结构 schema) | skill 采 SKILL.md;注册迁 A13 |
| **A11** | 试玩 / HITL 迭代 | 装载复用 A4;`StudioModify{ baseVersionId, mode:deterministic/regenerate-module, target, payload }`;判意图两段式(`/modify/plan` 判 → 前端确认 → `/modify` 执行)+ 两档执行 + 三断言(见 **§六**) | 现·便宜档代码完成(切片三,本机逐段真验)+ 建(受计费 e2e 待部署 / 复杂档随 tier2 / 整体重设计后期) | 自研 |
| **A12** | 通用检查门协议 | 提交侧(prompt 内容安全,fail-closed)+ 产物侧(体积门 / 逻辑扫描 / CSP),两时相、共用一道引擎无关门外壳 | 现·散三处 + 建(收成一门) | 自研 |
| **A13** | 配置注册表协议 | model / prompt / skill / mcp 四类统一注册;分流判据 = 影响生成质量/安全(prompt、生成门阈值)走受治理发版(yudao 审批)不可随手热改,运营降级开关/阈值走热改 | 建·部分(阶段〇+一① 已落地:Nacos/RocketMQ/Sentinel + 护城河 middleware;阶段二 yudao 版本层在飞) | (2026-07-01 反转)采 yudao 配置中心版本化 ⊕ Nacos 下发 ⊕ per-POST 热重载(见 ADR-4) |
| **A13** | 配置注册表协议 | model / prompt / skill / mcp 四类统一注册;分流判据 = 影响生成质量/安全(prompt、生成门阈值)走受治理发版(yudao 审批)不可随手热改,运营降级开关/阈值走热改 | 建·部分(阶段〇+一①+二 已落地:Nacos/RocketMQ/Sentinel + 护城河 middleware + genconfig Nacos 热源/yudao 版本层/双路激活;阶段三管理面 UI 与阶段四观测在飞) | (2026-07-01 反转)采 yudao 配置中心版本化 ⊕ Nacos 下发 ⊕ per-POST 热重载(见 ADR-4) |
| **C5** | PlaySpec 考卷契约(判分闭环 · 2026-07-03 Δ1 新立) | 游戏声明"怎么玩我以便判我":起局仪式、驱动器族、输入指令表、赢/输可观测量;`derivedFrom.sourceHash` 把考卷绑到源工程内容,源变即算陈旧、必须重生 | 现·schema + 校验器 + 负样本已立(`contracts/play-loop/play-spec.schema.json`)· 生产接线在途 | 自研(附机器校验器,Δ5 立宪) |
| **C6** | VerdictFeedback 判卷反馈契约(判分闭环 · 2026-07-03 Δ1 新立) | 每次未过门必带:哪道门 / 卡在哪个 phase(phaseNow)/ 判卷用哪个 driver / 证据指针(console·log·截图)/ 疑似失败面 / 修复方向类 | 现·schema + 校验器 + 负样本已立(`contracts/play-loop/verdict-feedback.schema.json`)· 生产接线在途 | 自研(附机器校验器) |
@ -340,7 +340,7 @@ tier2(最高深度档)的运行时按 AgentScope 2.0.2 的真实对象结构落
各档生成共用一层治理面——让 agent 自治生成游戏还不够,平台还得能配置它(改 prompt、换模型、调 skill 不发版)、看见它(每次生成到底发生了什么)、审计它(谁改了哪条配置)、在入口拦住它(配额、并发、降级)。这就是创始人最早提的"像 Dify 一样可视化、可追踪、可审计地管 agent 平台"。控制面四个组件对各档暴露同一套契约(读配置、写轨迹、过门),生成线只照契约办事、不感知管理面长什么样。
**配置注册表**是配置的唯一事实源,回应"改 prompt、模型、skill、mcp 还要重新部署"那句话:凡是现在"要改就得发版"的东西,都搬进一个版本化、可回滚的注册表,节点是 prompt、model、skill、tool、mcp 五类。这里有一处必须诚实的现状——今天的 prompt 注册表**不是热加载地基**,而是构建期被 maven 插件复制进 classpath 的快照,改一条 prompt 等于改原文件、升版本号、过四道闸,下次构建部署才带新版。这正是 §二对标判定的反模式。**目标态(2026-07-01 反转后)是生态原生的三段配置面**:治理与版本账本落 game-cloud 的 yudao 配置中心(版本行进 MySQL、`huijing-module-infra` 作宿主、`huijing-module-bpm` 走审批),运行时下发交 Nacos(已随 RocketMQ、Sentinel 进 MVP 生产 runtime),生成侧的 prompt 与 model 参数由 AgentScope 的 per-POST 热重载现装配——生成走 Service `/chat`,每次 POST 从存储取当前已激活版本、现装配 agent 与 model,改完下一次生成即生效、零重启。这取代了早稿"采 Langfuse 式按 `id@label` 运行时热取"的口径(退为历史备选、不在 MVP runtime)。tier2 那条 Python 线的 genconfig 已是热配雏形,阶段二把它的读取后端从本地 yaml 提升到 Nacos。但推广前有一条硬纪律不变:别在裂的地基上盖更大的注册表——先补一道一致性 CI(每条配置都有对应文件、每个硬编码加载的 id 都登记、占位条目要么补正要么标为不可上线),地基自洽了推广才有意义。prompt 这一类的完整治理(第 8 契约、四道闸、HITL、热取加载)是独立 SoT,见 [`prompt治理.md`](prompt治理.md)。
**配置注册表**是配置的唯一事实源,回应"改 prompt、模型、skill、mcp 还要重新部署"那句话:凡是现在"要改就得发版"的东西,都搬进一个版本化、可回滚的注册表,节点是 prompt、model、skill、tool、mcp 五类。这里有一处必须诚实的现状——今天的 prompt 注册表**不是热加载地基**,而是构建期被 maven 插件复制进 classpath 的快照,改一条 prompt 等于改原文件、升版本号、过四道闸,下次构建部署才带新版。这正是 §二对标判定的反模式。**目标态(2026-07-01 反转后)是生态原生的三段配置面**:治理与版本账本落 game-cloud 的 yudao 配置中心(版本行进 MySQL、`huijing-module-infra` 作宿主、`huijing-module-bpm` 走审批),运行时下发交 Nacos(已随 RocketMQ、Sentinel 进 MVP 生产 runtime),生成侧的 prompt 与 model 参数由 AgentScope 的 per-POST 热重载现装配——生成走 Service `/chat`,每次 POST 从存储取当前已激活版本、现装配 agent 与 model,改完下一次生成即生效、零重启。这取代了早稿"采 Langfuse 式按 `id@label` 运行时热取"的口径(退为历史备选、不在 MVP runtime)。tier2 那条 Python 线的 genconfig 已是热配雏形,阶段二(2026-07-04 已落地)把它的读取后端从本地 yaml 经 NacosHotConfig 提升到 Nacos 热源。但推广前有一条硬纪律不变:别在裂的地基上盖更大的注册表——先补一道一致性 CI(每条配置都有对应文件、每个硬编码加载的 id 都登记、占位条目要么补正要么标为不可上线),地基自洽了推广才有意义。prompt 这一类的完整治理(第 8 契约、四道闸、HITL、热取加载)是独立 SoT,见 [`prompt治理.md`](prompt治理.md)。
**观测 / 审计仓**回答两个独立问题:运行轨迹(每步推理、每次工具调用、每道门裁决、每次成本,落统一 trace 契约,详见 §5.7)和配置审计日志(谁、何时、改了哪条配置、前后 diff——这条线现在完全没有、是全新建的)。配置改动按性质分流:prompt、model 参数这类影响生成质量与安全的版本化资产走**受治理发版**(yudao 配置中心的版本行加审批流,改配置提交变更、审批通过才激活,审计天然、可回滚),运营开关类(降级、配额数值)走热改、即时生效、复用现成通路。这条分流判据正是 A13 配置注册表最该先定的核心——影响生成质量与安全的配置走受治理发版、不可随手热改,运营降级开关与阈值走热改。早稿此处写"走 GitOps 四闸",2026-07-01 反转后治理主路改 yudao 审批发版,GitOps 退为 config-as-code 可选。
@ -348,7 +348,7 @@ tier2(最高深度档)的运行时按 AgentScope 2.0.2 的真实对象结构落
**管理面 UI** 是注册表与观测仓的视图与编辑器,不是真相本身——配置才是真相。它不从零造一个 Dify 式可视化建图器,因为裸图的节点是 Java 代码、ReAct 的工具也是代码,真相在代码与配置里,靠 UI 拖拽生成代码是另一套不可靠的范式。但"配置驱动地建并部署一个 agent"这件事 **AgentScope Service 原生就给**:`/agent` 全 CRUD + `GET /agent/schema`(返回 agent 配置表单的 JSON Schema、专给配置 UI 用)——填表单(身份 / 模型 / 上下文 / 选哪些已注册的 skill·tool)→ `POST /agent` → Service 注册上线该 agent。管理面 phase-1 的配置管理直接建在它上、不用自造,这是统一到 AgentScope 的一个红利(SAA 裸图无此能力、只能配置值热取);但能配的永远是"选已注册的能力",新工具 / 新拓扑两边都得写代码、不拖拽生成。还要分清两种"发布":**非关键配置**(运营开关、非关键 agent 装配)经 `/agent` CRUD 或热取即时生效、**不重新部署服务代码**;但**重要配置**(关键 agent、关键玩法模板、质量与安全配置如 prompt 正文与生成门阈值)的发布**必须走配置发布流程审批**——它影响生产环境的稳定与质量,所以即便不重新部署服务代码,也是一次**受治理的「发版」**:提交变更 → 审批 → 通过才发布。这道审批发布**复用 game-cloud 现成的 yudao 能力**(`huijing-module-bpm` 工作流 + `huijing-module-infra` 配置管理),不自研(build-vs-buy 现货优先),**后期阶段做**。但"配置是真相、UI 是视图"不等于第一期什么都不做,管理面按三档诚实命名地落:phase-1 是配置管理加运行可观测(含一个纯只读、不依赖任何前置、立刻能给创始人看见的最小切片——看各角色当前用什么模型、回放任意一次生成的全轨迹、按 new-api 口径对账成本;其上再加配置编辑,改完落 Git 加审计、不直接热生效),phase-2 是限定范围的图编辑(节点启停、参数、版本 diff、轨迹回放,但渲染的拓扑来自运行时自报、不让用户拖拽改结构),phase-3 是完整可视化建图(拖拽改拓扑,远期不投)。一条贯穿约束:管理面对拓扑只渲染框架运行时自报的结构,绝不在管理面这侧另持一份拓扑模型——廉价线是静态图、tier2 的 ReAct 没有静态图,两套异构范式用同一个管理面,只能靠"渲染运行时自报"这个共同口径,而硬编码的拓扑模型在换框架时反而成为阻力。这也是反锁死(§一)在管理面的落点。
> **现 / 建(2026-07-03 更新)**:D12 现行已落(默认关闭,在 game-cloud 后端);配置口径 2026-07-01 反转为 yudao 配置中心版本化 ⊕ Nacos 下发 ⊕ AgentScope per-POST 热重载(取代早稿的 Langfuse 式热取 + GitOps 四闸)。**已代码落地**:阶段〇 生产基建(Nacos / RocketMQ / Sentinel 自托管 mini-infra、game-cloud 已接入)、阶段一 护城河 middleware(统一门判 GateJudgment + 续修 RepairMiddleware + 软预算软停)、cheap-worker 归并 Service `/chat`;AgentScope 原生 per-POST 现装配是生成侧热配的现成机制。**在飞 / 待建**:阶段二把 `genconfig` 读取后端从本地 yaml 提升到 Nacos、yudao 配置中心版本层与双路激活、配置审计日志、管理面三 phase。控制面/管理面对 tier2 的完整接入(D12 入口、管理面 UI)按 plan 决策⑤ 仍在推进。
> **现 / 建(2026-07-03 更新)**:D12 现行已落(默认关闭,在 game-cloud 后端);配置口径 2026-07-01 反转为 yudao 配置中心版本化 ⊕ Nacos 下发 ⊕ AgentScope per-POST 热重载(取代早稿的 Langfuse 式热取 + GitOps 四闸)。**已代码落地**:阶段〇 生产基建(Nacos / RocketMQ / Sentinel 自托管 mini-infra、game-cloud 已接入)、阶段一 护城河 middleware(统一门判 GateJudgment + 续修 RepairMiddleware + 软预算软停)、cheap-worker 归并 Service `/chat`;AgentScope 原生 per-POST 现装配是生成侧热配的现成机制;**阶段二五步(2026-07-04)**——`genconfig` 读取后端经 NacosHotConfig 提升到 Nacos 热源、yudao 配置中心治理子域(版本行落 MySQL、Flyway V29/V30)、双路激活编排、漂移对账——亦已代码落地,启用旗默认关。**在飞 / 待建**:阶段三管理面 UI、阶段四观测(配置审计日志 + effective 配置对账端点)、部署窗口灰度(生产灰度与路 A 对真 Service 的 PATCH)。控制面/管理面对 tier2 的完整接入(D12 入口、管理面 UI)按 plan 决策⑤ 仍在推进。
![图 B1 · 控制面四组件](assets/t2-B-01-控制面四组件.svg)
![图 B2 · 反锁死五协议](assets/t2-B-02-反锁死五协议.svg)

View File

@ -81,7 +81,7 @@ flowchart LR
读这张图抓住三点就够了:
- **供给侧是只读的、轻量的。** 生成链路的每个节点要 prompt 时,经 `PromptRegistryLoader`(加载器)按编号从 Registry 取文本、填入变量、注入给模型。Registry 是一份**文件契约,不是一个服务**——所以它不引入新的跨模块强耦合,也不会成为一个会宕机的依赖。
- **治理侧是闭环的、有门的。** 任何人想改 prompt,都得提一个 PR(Pull Request,代码改动的评审请求),并且**必须升 version**(改了不升版号该被拒)。设计目标是 PR 一提就由持续集成(CI)自动跑"四道闸"——这是本体系最核心的质量门,§4 详述。**现状(2026-07-04 已接线)**:四道闸已焊成 CI,按成本分两段落地。**段 A 离线版本闸**兜闸 0"改正文必升 version",随每次提交自动跑(`contracts/prompts/check_version_bump.py`,挂 pre-commit 与 contract-gates 服务端门,秒级、零成本、不可绕);**段 B 真模型闸**跑闸 1~4(Schema成功率回归 diff成本延迟),对改动的 prompt 拿其金标集真调 MiniMax-M3 判定,由 `prompt-eval` 工作流手动触发(workflow_dispatch),单跑预算硬上限 ≤¥5。判定逻辑是按 registry 契约重建的薄版(早期 W-G1 批跑编排 `evalflow.py` 曾跑出数据,此处不整套复活)。纪律不变:prompt 改动合入前至少真跑一次段 B、四闸全绿再交人工抽检批准,才允许合入并同步到生产。**段 B 只焊 live 消费面**——现行真被生成路径喂 LLM 的是 `01-safety`(合规门)、`09-tier2-richgame` 八条、`04-config/cheap-system`;已下架的 gamedef 四策划模板(clickermergeidletycoon)与 generic-coder STUB 等化石条目显式豁免、不花真模型钱,逐条三态见 [`registry.yaml`](../../../../contracts/prompts/registry.yaml) 头部消费面对账总表。
- **治理侧是闭环的、有门的。** 任何人想改 prompt,都得提一个 PR(Pull Request,代码改动的评审请求),并且**必须升 version**(改了不升版号该被拒)。设计目标是 PR 一提就由持续集成(CI)自动跑"四道闸"——这是本体系最核心的质量门,§4 详述。**现状(2026-07-04 已接线)**:四道闸已焊成 CI,按成本分两段落地。**段 A 离线版本闸**兜闸 0"改正文必升 version",随每次提交自动跑(`contracts/prompts/check_version_bump.py`,挂 pre-commit 与 contract-gates 服务端门,秒级、零成本、不可绕);**段 B 真模型闸**跑闸 1~4(Schema成功率回归 diff成本延迟),对改动的 prompt 拿其金标集真调 MiniMax-M3 判定,由 `prompt-eval` 工作流手动触发(workflow_dispatch),单跑预算硬上限 ≤¥5。判定逻辑是按 registry 契约重建的薄版(早期 W-G1 批跑编排 `evalflow.py` 曾跑出数据,已随 agent-loop-v1 归档、`git show 6d2f8789^:docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/evalflow.py` 可查,此处不整套复活)。纪律不变:prompt 改动合入前至少真跑一次段 B、四闸全绿再交人工抽检批准,才允许合入并同步到生产。**段 B 只焊 live 消费面**——现行真被生成路径喂 LLM 的是 `01-safety`(合规门)、`09-tier2-richgame` 八条、`04-config/cheap-system`;已下架的 gamedef 四策划模板(clickermergeidletycoon)与 generic-coder STUB 等化石条目显式豁免、不花真模型钱,逐条三态见 [`registry.yaml`](../../../../contracts/prompts/registry.yaml) 头部消费面对账总表。
- **数据回流让 prompt 越改越准。** 线上的 telemetry(遥测,即用户真实行为埋点数据)会反哺回来:哪类 prompt 产出的游戏没人玩、留存差,就成为下一轮改 prompt 的依据。这一条把"治理"从被动防退化,升级成主动求进步。
依赖方向很干净:**壳层 → Registry(读);CI → Registry(读)+ 模型(跑样本);运行时构建流水线 → 测试原子(执行)。** 没有任何一条引入新的服务级强耦合。
@ -107,7 +107,7 @@ contracts/prompts/
> 阶段编号的完整规划是 `01-safety 02-intent 03-template 04-config 05-asset 06-quality 07-fix 08-meta`;上面只列出当前已落地的几个。其余阶段随生成链路演进逐步迁入,Registry 的设计本就允许增量入库。
>
> **"已入库"≠"已接 live 生成路径",两者要分清**:① 已接 live 后端生成路径的是 01-safety 与 04-config 的四个策划模板(clicker / merge / idle / tycoon——由 `PromptResourceLoader` 在进程内渲染注入);其余 04-config 模板(generic-coder 等)与 06-quality / 07-fix,目前仅被 W-G1 批跑编排(`evalflow.py``orchestrator/*.py`)消费,尚未接入 live game-cloud 服务。② generic-coder 还额外是 STUB:`registry.yaml` 标其 `version 0.0.1 ⚠️ STUB 占位骨架`(仅 frontmatter + 三要点提纲,非正式 prompt),后端入库它只为让加载器 `isReady()` 通过、schema 进校验缓存,**不在进程内拿它喂 LLM**。
> **"已入库"≠"已接 live 生成路径",两者要分清**——逐条三态以 [`registry.yaml`](../../../../contracts/prompts/registry.yaml) 头部消费面对账总表为准。① **live 消费面**(真被生成路径喂 LLM)= `01-safety` 合规门、`04-config/cheap-system` 便宜档系统提示、`09-tier2-richgame` 八条富游戏提示。② **化石**:gamedef 时代的四个策划模板(clicker / merge / idle / tycoon)随 gamedef 路线作废已下架,后端模板白名单 `SUPPORTED_TEMPLATE_IDS` 收敛为 `["generic"]`、不再走"填参选模板"那条线;它们连同 06-quality / 07-fix 只留库里作历史留痕,早期由 W-G1 批跑编排(`evalflow.py``orchestrator/*.py`,已随 agent-loop-v1 归档、`git show 6d2f8789^:docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/evalflow.py` 可查)消费,不接 live game-cloud、不花真模型钱。③ generic-coder 是 **STUB**:`registry.yaml` 标其 `version 0.0.1 ⚠️ STUB 占位骨架`(仅 frontmatter + 三要点提纲,非正式 prompt),后端入库它只为让加载器 `isReady()` 通过、schema 进校验缓存,**不在进程内拿它喂 LLM**。
**每条 prompt 的构造 = 一段 frontmatter 契约头 + 模板体。** frontmatter(前置元数据,写在文件顶部 `---` 之间的结构化字段)就是这条 prompt 的"契约头",声明它的身份、版本、归属和绑定的 schema/eval。模板体则是真正发给模型的文本,里面带变量槽(运行时填入)。一个示意:
@ -200,7 +200,7 @@ TestScript generate(GameConfig config) # 输入游戏配置 → 输出测试
它的意义在于:生成出来的游戏**在入库发布之前,应先被一段自动生成的测试脚本验证"真的能跑"**——能不能启动、按键有没有响应、边界条件会不会崩。跑不过就拒绝入库,并对失败原因分类。这是 prompt 治理体系规划在"产物侧"埋的一道闸:**prompt 把关的是"怎么生成",T-AGC-09 要把关的是"生成出来的到底能不能玩"。**
> **现状口径**:当前真正生效的入库实拦是生成引擎的**九门 harness**(把产物放进真实运行环境自动检验的九道确定性门——见同目录 [README §3.2 区](README.md));T-AGC-09 是产物侧的**规划门**,与九门是同一种工程哲学的延伸(宁可显式拦截,绝不让坏产物进库),待落地后补强 GameConfig 模板这条路的产物自测
> **现状口径**:当前真正生效的入库实拦是生成引擎的**九门 harness**(把产物放进真实运行环境自动检验的九道确定性门——见同目录 [README §3.2 区](README.md));T-AGC-09 是产物侧的**规划门**,与九门是同一种工程哲学的延伸(宁可显式拦截,绝不让坏产物进库)。它原设想的落点是 GameConfig 模板这条路的产物自测,而 gamedef/GameConfig 线已废;规划门"产物侧自动验证真能跑"的意图保留,但落到现行 A-model 真 `src/` 产物形态上需重新定义,当前入库实拦仍由九门 harness 承担
---

View File

@ -286,7 +286,7 @@ G1 验的是 GP9 这道合规门在真环境里到底挡不挡得住。结论很
1. **开闸放行决策本身。** 焊死门已就绪,放行与否由创始人裁定(此决策优先于任何自动门)。
2. **待创始人拍的数值。** 组A 只落了 `level` 列加门结构,具体数值是占位的,需要拍板:会员档 L1 / L2 / L3 的每日配额与并发数(组A 占位)、D11 的评分权重(§3.2 占位)、D9 的模糊近似阈值——v0 只做了"精确撞重 + 归一化完全相等",模糊相似度怎么量,要等真实数据观察到分布之后再定。
3. **产品轨。** admin 的 aigc 任务列表页要不要近期就排上"就绪分"展示(后端契约已经透出了,前端需要新建 aigc 列表页,或在 review 页 join 取这个分)。
4. **承接自 SAA 治理(round3)的两项。** F3 = SAA 的成本字段目前只落 token 数、还没折算成人民币金额;早期 boot 阶段 SAA 图的前几次派发会瞬态失败、需要预热。F5 已修复(即 §3.3 那个 `5f6cdd0c`)。
4. **承接自 SAA 治理(round3)的两项(已随 SAA 冻结)。** 这两项挂在 SAA 裸图那条线上:F3 = SAA 成本字段只落 token 数、未折人民币;早期 boot 阶段 SAA 图前几次派发瞬态失败需预热。SAA 已降为最低优先级远期(非 MVP runtime),这两项随之冻结、不再是活残留;现行 cheap/tier2 线的成本已按 new-api quota 折 ¥ 落 trace.cost(Anthropic 路由 `RecordingChatModel` 补齐取证,见运行时 SoT §5.7)。F5 早已修复(即 §3.3 那个 `5f6cdd0c`)。
---