# 方洞挑战 Agent LLM 超时兜底修复 2026-05-05 ## 1. 问题 现场错误: ```text 方洞挑战聊天生成失败,请稍后重试。:LLM 请求超时,累计尝试 1 次 ``` 方洞挑战创作 Agent 在同一轮流式 JSON 中需要返回 `replyText`、玩法配置、形状选项、洞口选项和图片提示词。模型可能先返回可见回复,再继续输出完整 JSON;如果上游在流式读取阶段超过通用 LLM 请求超时,后端会发送 SSE `error`,前端只能保留本地 warning 消息,本轮后端会话不会成功推进。 ## 2. 根因 `platform-llm` 的 `LlmTextRequest` 只有全局 `AppConfig.llm_request_timeout_ms`。创作 Agent 统一走 Responses 流式协议,方洞提示词扩展为视觉资产配置后,单轮输出长度明显增加;通用 30 秒超时更适合普通聊天,不适合结构化创作 Agent 的完整 JSON 流。 `request_text` 的初始 HTTP 请求会按 `max_retries` 重试,但 `stream_text` 已经进入 `response.chunk()` 读取后,当前错误路径固定记录为一次读取超时,所以用户看到“累计尝试 1 次”。 ## 3. 落地策略 1. 在 `platform-llm::LlmTextRequest` 增加请求级 `request_timeout_ms` 覆写。 2. `execute_request` 优先使用请求级超时,没有覆写时继续使用全局配置。 3. `creation_agent_llm_turn` 的流式 JSON 请求统一使用更长的创作 Agent 超时窗口。 4. 该超时窗口只影响创作 Agent 的结构化流式 turn,不改变 RPG 运行时聊天、图片生成、SpacetimeDB procedure 或方洞玩法判定。 5. 不新增 SpacetimeDB 表结构,不修改 `migration.rs`。 ## 4. 验收标准 1. `platform-llm` 测试覆盖请求级 timeout 会让慢响应提前超时。 2. `creation_agent_llm_turn` 测试覆盖流式 JSON 请求带创作 Agent timeout。 3. `cargo test -p platform-llm -p api-server creation_agent --manifest-path server-rs/Cargo.toml` 通过。 4. 后端代码变更后按项目约束运行 `npm run api-server` 并确认 `/healthz`。 ## 5. 追加:视觉资产动作 503 降级 现场后续日志: ```text status=503 method=POST uri=/api/creation/square-hole/sessions/{sessionId}/actions ``` 该请求落在方洞 `/actions`,草稿编译成功后前端会自动追加执行 `square_hole_generate_visual_assets`。视觉资产生成依赖 VectorEngine GPT-image-2 图片入口;当本地或部署环境缺少 `VECTOR_ENGINE_API_KEY` 时,后端会在 `require_openai_image_settings()` 阶段快速返回 `503 SERVICE_UNAVAILABLE`,因此日志 latency 只有个位毫秒。 这类错误只表示“图片自动生成服务不可用”,不代表方洞草稿编译失败。前端处理规则: 1. `square_hole_compile_draft` 成功后,如果自动图片生成失败,保留错误横幅。 2. 立即进入方洞结果页,展示已生成的形状/洞口配置。 3. 保留封面图、背景图、形状贴图和洞口选项图上传入口。 4. 进度页仍可通过“重新生成图片”在配置补齐后重试。 ## 6. 追加:结果页图片重生成入口 方洞结果页需要保留用户上传入口,同时提供 `AI重生成图片` 操作。该按钮先保存当前编辑内容,再复用 `/api/creation/square-hole/sessions/{sessionId}/actions` 的 `square_hole_generate_visual_assets` 动作,并额外传入 `regenerateVisualAssets=true`。 后端收到该标记后,不再按已有 `coverImageSrc`、`backgroundImageSrc` 或形状 `imageSrc` 跳过图片生成,而是重新生成封面图、背景图和所有形状贴图。自动编译后的图片补齐流程仍保持默认 `false`,只补缺失图片,避免覆盖创作者刚上传的素材。 ## 7. 追加:图片槽位查看模式与历史素材 方洞结果页的封面图、背景图、每个形状贴图和每个洞口选项图不再把上传入口直接散落在卡片上。点击任一图片槽位后打开独立查看面板,面板内负责: 1. 展示当前槽位图片。 2. 展示当前账号历史生成的方洞图片素材。 3. 提供本地上传入口,上传后只替换当前槽位。 4. 提供 `AI生成图片` 入口,触发 `square_hole_generate_visual_assets` 并带 `regenerateVisualAssets=true`、`visualAssetSlot` 与可选 `visualAssetOptionId`。 5. 后端按槽位定向生成:封面面板只替换封面图,背景面板只替换背景图,形状贴图面板只替换当前形状选项的贴图,洞口选项图面板只替换当前洞口选项图。草稿编译后的自动图片补齐仍不传槽位,保持“只补缺失图片”的原逻辑。 历史素材来源必须是真实资产索引,不允许只从前端当前草稿拼假列表。方洞图片生成成功后,API 层需要像拼图封面一样写入 OSS 与 `asset_object`: 1. 封面图使用 `asset_kind = square_hole_cover_image`。 2. 背景图使用 `asset_kind = square_hole_background_image`。 3. 形状贴图使用 `asset_kind = square_hole_shape_image`。 4. 洞口选项图使用 `asset_kind = square_hole_hole_image`。 5. 资产历史接口 `/api/assets/history` 与 SpacetimeDB 侧历史素材白名单同步放行这四类。 6. 如果 OSS 或 SpacetimeDB 资产索引不可用,本次生成仍允许以 Data URL 回写作品,历史素材列表只降级为空或缺少本次记录。 ## 8. 追加:选项图片不再局限于形状 方洞挑战的可展示图片不再只挂在 `shapeOptions`。创作者配置中的 `holeOptions` 也需要具备: 1. `imagePrompt`:洞口选项图的生成提示词,默认由题材主题和洞口标签补齐。 2. `imageSrc`:洞口选项图地址,可来自 AI 生成、历史素材套用或本地上传 Data URL。 3. 结果页需要把洞口选项图做成与形状贴图相同的图片槽位,打开查看面板后支持历史、上传和 AI 生成。 4. 运行态洞口按钮优先展示 `hole.imageSrc`,没有图片时再回落到几何剪影。 5. `visualAssetSlot = hole` 时必须携带 `visualAssetOptionId = holeId`,后端只重生成该洞口选项图;未传槽位的自动补齐需要同时补缺失的形状贴图和洞口选项图。