docs(agents): 蒸馏 tier2 服务态生成配方 + 收敛根因(§7)
本 session 服务化实测的可复用产出写回权威源:新增 skill tier2-service-generation—— ★收敛头号杠杆=真玩 driver(没 driver→F_wiring 挂+富游戏门 None+agent thrash 的假性不收敛; 默认 business-sim play_spec 通用修复·007 现成游戏带 driver 重跑 accept 全绿坐实;诊断口诀=九门前几道绿 +F_wiring 挂+富游戏门 None→查 driver 别怪生成,None≠False)+ 驱动 create_app 六集成口径(凭据 data 嵌套/ chat content 块列表/Toolkit.tool_groups 抠九工具/BYPASS+query agent_id/设计阶段接入/SSE read 超时防挂死) + 控制面有界 resume + C1 trace 字段口径。README skills 索引同步登记。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9ac0e860d1
commit
6998de77f3
@ -60,6 +60,7 @@
|
||||
| `skills/agentic-amodel-generation.md` | **agentic A-model 生成 harness(ReAct+M3 已实证·生产形态)**:scaffold→工具循环(read/write/list/check/build/done)→循环外 play;链路/5 文件/运行配方/8 坑(write 前缀·compaction·停机纪律·防假绿·bundle.tick·boot envelope·路径深度)/M3 3-玩法自闭环实证/主流定性;取代旧 gamedef 单次产线(HJ-AGI-003) |
|
||||
| `skills/gen-path-parity-harness.md` | **两条生成路对照验证(parity) harness 范式 + 按品类 ≥80% 达标门 + auto-vs-golden 同款双驱动 delta 门**:验「换实现后生成质量没回退」(Node→Python 重写/换模型/换框架)+ 判「生成质量够不够格上线」+ 判「生产自动 spec 比金标有没有驱动退化」(Node 退役授权)。对照公平铁律=驱动器 held constant(每品类金标 play-spec 喂两路)/ 金标只对 tap-targets 族公平(key-cycle 按键是生成侧自由选择不在 forensics 契约,需输入键契约)/ 注入=生成与 play 拆步+金标覆写 staged 真路径(非 evidence)/ 两层判据+逐品类绝对地板+双低标红(防 flaky 基线假等价)/ 成功定义钉死「金标 spec 下」≠生产许可/ 自动 spec 期望外生防自证(语义期望字段不从被测实际反推)/ **达标门质量口径**(编排未收敛 timeout/step_cap 剔出达标率分母、单列归编排硬化,rawPassRate 并报贴近生产交付率)/ **auto-vs-golden 门**(同款 play 两次只换驱动器、关键门容差 0 单边查「自动不比金标驱得差」、retire 三条齐 M1∧002∧auto-vs-golden;实证抓到单数 target vs 复数 targets 生成契约漂移)/ 端口池+线程前台有界并发;WU-A 后续 compare_node.py、M1 达标门(003 bake_off.py)、M2 auto-vs-golden(2026-06-27-001 auto_vs_golden.py)实证(均过双评审);**M3b 9d trace/D11/D9 parity**(换 worker 别静默退化 D11:必填七项 + `gatespec.driver` 键名坑 + `H_progress` 嵌套 + `repairs=max(0,attempts-1)`;退化判别=双峰 45/55、**逐维断言反假绿**非看区间;import 边界 tier2≠wg1 故 trace 手写镜像 + dedup vendor;真后端三值 28/45/100 实证) |
|
||||
| `skills/saa-graph-orchestration.md` | SAA(Spring AI Alibaba)裸 StateGraph 生成编排:拓扑/加节点/接 new-api(剥 /v1 坑)/checkpoint(含 saved_at 无 tiebreaker 框架坑+显式 checkPointId 修法)/observation/最小依赖集/派发契约/验证门(HJ-AGI-002 实证) |
|
||||
| `skills/tier2-service-generation.md` | **tier2 富游戏服务态生成驱动配方(create_app :8200 + 控制面有界 resume)**:★收敛头号杠杆=真玩 driver(没 driver→F_wiring 挂+富游戏门 None+agent thrash 假性不收敛;默认 business-sim play_spec 通用修复·007 现成游戏带 driver 重跑 accept 全绿坐实) + 驱动 create_app 六口径(凭据 data 嵌套/chat content 块列表/Toolkit.tool_groups 抠九工具/BYPASS+query agent_id/设计阶段接入/SSE read 超时防挂死) + 控制面 resume + C1 trace 字段口径(2026-06-24 服务化实测) |
|
||||
| `skills/doc-organizer.md` | 文档整理助手(创始人手动触发):增量(上次清理→现在)+**两阶段审批门**——发起分析 Workflow→编清理计划→评审→批准后才执行;三轴=过期档清理(归档/压缩)/核心设计档措辞对齐现行真相/主任务总账回填;底层 `tools/doc-organizer.{sh,-analyze.mjs,-state.json}`(检测自动·判断留人·脚本不自删·最新日在飞档不碰) |
|
||||
| `skills/drive-remote-claude-tmux.md` | 远程驱动交互式 Claude Code(ssh + tmux):双向通道 send-keys 派活 + capture-pane 读屏,不走 ACP/headless;每设备配置块 + onboarding 侦察配方 + 专用会话(独立 worktree 防撞树) + bypass-perms + 安全红线;**完成判据=git push 非读屏**(创始人 2026-06-18 拍板·多设备复用) |
|
||||
| `skills/architecture-diagram-atlas.md` | 架构图集生成配方:house style 规格 / 图说文档结构(金样板) / 三范式纪律(单源·防漂移门·状态双层) / 按域并行编排(克隆金样板·结构化返回) / 复验脚本 / 双评审揪出的六坑(漏域·现行远期错标·缺状态列·契约画理想·凑数配额·复制Mermaid漂移) / 分两期+跨session协调(生成引擎子树归在飞线只链不画)(2026-06-22 第一期实证) |
|
||||
|
||||
57
.agents/skills/tier2-service-generation.md
Normal file
57
.agents/skills/tier2-service-generation.md
Normal file
@ -0,0 +1,57 @@
|
||||
---
|
||||
name: tier2-service-generation
|
||||
description: tier2 富游戏服务态生成(AgentScope create_app :8200 + 控制面有界 resume)的驱动配方与收敛诊断——含 6 个集成口径、收敛头号杠杆(play_spec driver)、九门/富游戏门读法
|
||||
metadata:
|
||||
type: skill
|
||||
---
|
||||
|
||||
# tier2 服务态生成:驱动 create_app + 收敛诊断
|
||||
|
||||
tier2 富游戏线把"本地 CLI 直驱裸 Agent"(`worker/agent_loop/studio.py` 的 `run_studio`)升级成经 AgentScope 2.0.2 `create_app` 的 Agent Service:多租户、多会话、REST 触发(`POST /chat`,fire-and-forget)、SSE 事件流,session 状态与跨会话 MessageBus 走 Redis。服务跑在 `mini-desktop:8200`,由一个**控制面**(`service/control_plane.py`)从消费方侧驱动一款游戏从启动到门绿落库。
|
||||
|
||||
这份手册记录两件在 2026-06-24 服务化实测里用真证据换来的东西:**怎么正确驱动这个服务**(六个集成口径,每一个都是一次 422 / 崩溃换来的),以及**一个差点被误判成"模型太弱"的收敛假象的根因**。
|
||||
|
||||
## 收敛头号杠杆:真玩 driver,不是生成质量
|
||||
|
||||
服务态首批真跑(cp-smoke-006/007)都跑到 `budget_exhausted` 不收敛,表面看像"M3 单写产不出能过富游戏门的游戏"。**这是假象。** 拆开 verdict 看,九门里 `A_boot / B_uncaught / C_frame / D_render / E_live` 全绿——游戏能启动、能渲染、有活的状态;只有 `F_wiring` 挂,报 `calls=0 expected=[]`,而富游戏三门(tripleLink / economy / latch)的子检查全是 `None`。
|
||||
|
||||
关键区分:**`None` 不是 `False`**。`None` 意味着这些检查**根本没法评估**,而不是评估后判失败。富游戏门要靠 CDP harness 真玩游戏、观测它在玩的过程里有没有真调 `resource.addCoins` / `resource.consumeIngredient`、经济线能不能走到赢/破产、终态有没有 latch。没有真玩,这些观测一个都拿不到,于是全 `None`,门挂。
|
||||
|
||||
根因是控制面给 `run_gates` 传了 `play_spec=None`。play_spec 里装的是**真玩驱动规格**——driver(怎么玩)、`expectedEngineCallPrefixes`(该观测到哪些引擎调用)、`assertAfterPlay`(玩完该满足的状态断言)、economy 阈值。没有它,harness 把游戏渲出来就停了,从不驱动它玩。游戏永远不被玩 → 没有引擎调用 → F_wiring 挂、富游戏门 `None`。更糟的是,生成 agent 自己的 `run_gates` 工具也吃同一个 `None`,于是 agent 看到 `decision=fix` 却在"修一个根本不存在的问题",反复 thrash 直到预算耗尽。
|
||||
|
||||
**铁证**:把 007 那个"失败"的现成游戏,配上标准 business-sim driver 重跑门,直接 `decision=accept`,九门 + 富游戏三门全绿。游戏一直是好的。
|
||||
|
||||
**修复**(`worker/run.py` 的 `run_gates`):play_spec 缺 driver 时 `setdefault` 一份 `DEFAULT_BUSINESS_SIM_PLAY_SPEC`,显式 play_spec 仍优先。这份默认规格对**任何契约合规的 business-sim 游戏通用**——因为 driver 是参数化的(`{type: "business-sim", steps, stepMs, winThreshold, bankruptSteps, streakLose}`),按契约驱动而非靠逐像素坐标;bakery(feie-005)和 coffee(007)两款不同的游戏用同一份 driver 都过门。一处修复同时惠及生成 agent 自己的 `run_gates` 工具(thrash 根)和控制面评门。
|
||||
|
||||
**契约**:游戏要可被这份通用 driver 真玩,必须暴露 `resource.addCoins` / `resource.consumeIngredient` 这些 call-ID(经 `recHook`)、把终态 phase latch 成 `win`/`lose`/`gameover` 让宿主轮询、并在 scene 里接 `bindInput` 把注入的输入路由到 core 命令。M3 在设计阶段引导下已经稳定产出这套契约——所以收敛的真问题从来不是"模型写不出富游戏",而是"有没有真玩它"。
|
||||
|
||||
诊断口诀:**九门前几道绿、F_wiring 挂、富游戏门 `None` → 先查 driver,别怪生成。**
|
||||
|
||||
## 驱动 create_app 的六个集成口径
|
||||
|
||||
`create_app` 不收 agent 实例,只收装配零件(`extra_agent_tools` / `extra_agent_middlewares` 工厂),agent 由框架在每个 chat 回合内部装配。控制面/bootstrap 经现成 REST 端点驱动它。下面每一条都是实测撞出来的,直接照用:
|
||||
|
||||
1. **凭据注册**(`POST /credential/`):请求体是 `{data: {...}}`,凭据载荷整体嵌在 `data` 下,不是扁平字段。Anthropic 凭据的 `data = {type: "anthropic_credential", api_key, base_url}`——**没有 `model` 字段**(模型名在 session 的 `chat_model_config.model`)。模型类由 `get_model` 经 `CredentialFactory.from_dict(data).get_chat_model_class()` 按 `data.type` 决定,所以 `data.type` 必须对。
|
||||
|
||||
2. **chat 输入**(`POST /chat/`):`input` 是一条 `Msg`,它的 `content` **必须是内容块列表**,不能是裸字符串(裸串返 422 `Input should be a valid list`)。发 `{name, role, content: [{type: "text", text: "..."}]}`。Python 端 `UserMsg(content=str)` 的字符串自动包块只发生在构造器里,经 REST 传 JSON 不走那条。
|
||||
|
||||
3. **九工具抠取**(`extra_agent_tools` 工厂):2.0.2 的 `Toolkit` 把注册的工具按组存在 `self.tool_groups`,每组的 `.tools` 是 `list[ToolBase]`;构造器传入的 `tools` 被包进默认 `"basic"` 组(不是扁平的 `.tools` 属性)。要把九工具交给框架,从 `toolkit.tool_groups[*].tools` 收集。按扁平 `tools/_tools/function_tools` 探测会全空,每个 chat run 起手即抛、服务态生成零产出。
|
||||
|
||||
4. **BYPASS 权限**(建 session 后):tier2 九工具的 `FunctionTool` 默认 `check_permissions` 返回 `ASK`,服务态无人确认。不设 BYPASS,agent 第一次调工具就进 `ToolCallState.ASKING`、等一个永不来的确认事件,chat run 抛 `Agent is waiting for N tool calls ... but received no event`,生成零产出。修法:`PATCH /sessions/{id}?agent_id=<id>` 体 `{permission_mode: "bypass"}`(`PermissionMode.BYPASS` 值是 `"bypass"`)。注意 **PATCH 与 SSE stream 一样要 query 参数 `agent_id`**,不带返 422。等价 CLI `studio.py` 的 `_bypass_state()`。
|
||||
|
||||
5. **设计阶段接进服务路径**(建 agent 前):CLI 线 `run_studio` 先跑工作室设计阶段产出 design_text 再写,服务路径此前整段跳过、writer 拿空 design。修法:bootstrap 在建 agent 前于控制面进程内(有 agentscope + 模型)复用 `studio._design_stage`(工作室星形多 agent 团队 + 失败 degrade 回单 agent)产出 design_text,喂进 `AgentRecord.system_prompt`(`roles.writer_system` 第二参)。best-effort:设计失败返空串、不阻断生成。设计团队默认 240s 超时偏短、常 degrade 回单 agent——仍产出 design_text 可用,要让全团队跑完就调 `generation.yaml` 的 `design_team.timeout_s`(配置外置已兑现)。
|
||||
|
||||
6. **SSE 等待必须有界**(控制面消费 SSE):`create_app` 的 chat 是每回合一次、fire-and-forget,控制面订阅 `GET /sessions/{id}/stream?agent_id=<id>` 读到本回合的 `REPLY_END` / `EXCEED_MAX_ITERS` 才算这轮跑完。**坑**:超时检查不能只写在 `async for line` 的循环体内——SSE 流完全静默时(如服务端 Redis 超时打断了事件发布,既无 data 也无心跳)`aiter_lines` 永久 await,没 line 进来超时检查永不触发,控制面无限挂(实测卡死 60min)。修法:httpx `Timeout(read=idle_timeout_s)`,静默超它即 `ReadTimeout` → 兜住 → 据 on-disk 评门继续。`idle_timeout_s=300s` 远大于 agent 内部 run_gates(chrome ~60s)的正常静默间隙,不误杀正常回合。
|
||||
|
||||
## 控制面有界 resume(B1)
|
||||
|
||||
`service/control_plane.py` 的 `drive_generation` 把 CLI `run_studio:404-458` 的外层有界 resume 搬到服务消费方:`bootstrap.start_new_game` 启动 → 外层 `for attempt in range(max_resumes+1)`:消费 SSE 等本回合结束 → **独立**跑 `run.run_gates(session_id, play_spec)` 机器判门(不靠内存 session——服务态九工具每回合工厂新建 `Tier2Session`,内存态跨回合不保留)→ 门绿则据 on-disk 源工程重建七要素 + `persist_source_project` 落库 break / 否则 `verdict_feedback` 包成续跑指令 `resume_session` 续修 / 预算耗尽停。评门的 `game_id` 必须用框架分配的 `session_id`(九工具据它管工程目录 `game-runtime/games/_tier2-gen/<session_id>`)。门是机器判的,控制面绝不自评翻绿。
|
||||
|
||||
## 运维与诊断
|
||||
|
||||
- 起服务(mini-desktop):`cd /root/tier2-run/tier2/gen-worker && NEWAPI_KEY=... NO_PROXY=100.64.0.8 setsid /root/.venvs/agentscope-tier2/bin/python -m service.app >log 2>&1 </dev/null &`,单独只读 ssh 轮询 `/openapi.json`=200 确认就绪。改了 `app.py` / `worker/*`(服务端按回合 import + 缓存)要重启服务才生效;改 `control_plane.py` / `bootstrap.py`(控制面客户端、每次新进程)不必重启,同步 tier2-run 即可。
|
||||
- 真玩门(`run_gates` / chrome / esbuild)只在 mini-desktop;6c6g 禁 chrome、只做 py_compile + 裸 import 静态校验。重依赖(agentscope / redis / httpx / pymysql / minio / uvicorn)一律函数体内惰性 import,顶层零重依赖,保证 6c6g 能 import。
|
||||
- C1 轻量观测:控制面把逐帧 SSE 的结构性事件(跳过 `*_DELTA` 逐 token 噪声)记成 per-run `control-plane-trace.jsonl`,零外部依赖。事件字段口径(2.0.2):`TOOL_CALL_START` 带 `tool_call_name` + `tool_call_id`,`TOOL_RESULT_END` 带 `tool_call_id` + `state`。要在 workdir 建好(scaffold 之后)才落盘,否则刷 `FileNotFoundError`。
|
||||
- 端点 / 凭据 / 起服务铁律见 [`docs/内网凭据与端点.md`](../../docs/内网凭据与端点.md) 的「tier2 P4 服务化部署拓扑」段。
|
||||
|
||||
配套:AgentScope 2.0 架构事实见 [`../knowledge/agentscope-2.0-facts.md`](../knowledge/agentscope-2.0-facts.md);CLI 单写主链见 [`agentic-amodel-generation.md`](agentic-amodel-generation.md)(A-model/wg1 线,与本 tier2 服务态线同源不同栈);SAA 编排见 [`saa-graph-orchestration.md`](saa-graph-orchestration.md)。
|
||||
Loading…
x
Reference in New Issue
Block a user