6.9 KiB
拼图 Agent 聊天接入大模型设计
日期:2026-04-23
1. 背景
当前拼图创作链已经具备:
PuzzleAgentWorkspace前端聊天壳层- Rust
api-server的submit / stream / actionHTTP facade spacetime-module的puzzle_agent_session / puzzle_agent_message真相表module-puzzle的锚点推断、草稿编译、发布校验与运行态规则
但 submit_puzzle_agent_message 仍然是 deterministic 占位逻辑:
- 用户发言后,
spacetime-module直接推断anchor_pack - 同一事务里直接写入固定 assistant 总结文案
- SSE
/messages/stream只是把last_assistant_reply一次性回放给前端
这导致拼图 Agent 看起来有聊天面板,但没有真实 LLM 共创能力。
2. 目标
本轮只恢复拼图 Agent 聊天主链的真实 LLM 接入,不扩到图片模型和复杂多阶段编排:
- 用户发消息后,assistant 回复必须来自 LLM
- LLM 输出必须同时产出:
replyTextprogressPercentnextAnchorPack
- SSE
reply_delta必须来自真实流式增量解析 - finalize 后一次性回写最新 session 真相
- LLM 不可用或解析失败时,不再写固定 assistant 假回复
3. 分层边界
3.1 module-puzzle
只负责:
PuzzleAnchorPack、PuzzleCreatorIntent、PuzzleResultDraft纯领域模型- 锚点清洗、草稿编译、发布校验
- 运行态拼图规则
明确不负责:
- 网络请求
- LLM prompt 组织
- SSE 推流
3.2 spacetime-module
只负责:
submit_puzzle_agent_message- 校验 session / ownership / message id
- 只写入 user message
- 不再直接写 assistant message
- 不再直接推进
current_turn / progress_percent / anchor_pack_json
finalize_puzzle_agent_message_turn- 追加 assistant message
- 覆盖
anchor_pack_json - 回写
current_turn / progress_percent / stage / last_assistant_reply / updated_at
3.3 api-server
负责:
- 读取拼图 session 快照
- 组织 LLM prompt
- 流式截取
replyText - 回合结束后组装 finalize 输入
- 调用 SpacetimeDB finalize procedure
4. 目标链路
4.1 阶段 A:提交消息
submit_puzzle_agent_message
职责:
- 写入 user message
- 返回 submit 后的 session 快照
- 该快照中尚未新增 assistant message
- 该快照中的
anchorPack / progressPercent / currentTurn保持提交前真相
4.2 阶段 B:完成单轮推理
finalize_puzzle_agent_message_turn
职责:
- 追加 assistant message
- 回写:
current_turnprogress_percentstageanchor_pack_jsonlast_assistant_replyupdated_at
- 若已存在
draft_json,允许继续保留,不在聊天 finalize 中改写结果页草稿
5. LLM 输出契约
拼图聊天不需要复刻 Custom World 那么重的多层结构,本轮冻结为单个 JSON:
{
"replyText": "我已经收住画面方向了,接下来你更想强调夜雨反光,还是猫咪本身的奇幻感?",
"progressPercent": 46,
"nextAnchorPack": {
"themePromise": {
"key": "themePromise",
"label": "题材承诺",
"value": "雨夜中的奇幻探索",
"status": "confirmed"
},
"visualSubject": {
"key": "visualSubject",
"label": "画面主体",
"value": "发光猫咪站在遗迹台阶上",
"status": "confirmed"
},
"visualMood": {
"key": "visualMood",
"label": "视觉气质",
"value": "潮湿、梦幻、带轻微悬疑",
"status": "confirmed"
},
"compositionHooks": {
"key": "compositionHooks",
"label": "拼图记忆点",
"value": "台阶透视、倒影、远处遗迹门洞",
"status": "inferred"
},
"tagsAndForbidden": {
"key": "tagsAndForbidden",
"label": "标签与禁忌",
"value": "雨夜、猫咪、神庙遗迹;禁止文字水印",
"status": "inferred"
}
}
}
要求:
- 只能输出 JSON
progressPercent范围固定0..100nextAnchorPack必须是完整对象,不允许只给增量 patch
6. Prompt 设计
本轮不追求“复杂创作状态识别器”,只做拼图场景最小可用 prompt:
- system prompt 明确模型角色是“拼图视觉共创策划”
- 明确 5 个锚点:
- 题材承诺
- 画面主体
- 视觉气质
- 拼图记忆点
- 标签与禁忌
- 明确回复必须:
- 自然中文
- 一次只推进一个最关键问题
- 不提“字段”“锚点”“JSON 结构”等内部词
- user prompt 携带:
- 当前 turn / progress
- 当前 anchor pack
- 最近聊天记录
- 输出 JSON 契约
7. SSE 口径
POST /api/runtime/puzzle/agent/sessions/:sessionId/messages/stream
成功时按顺序输出:
- 多个
reply_delta - 一个
session - 一个
done
失败时输出:
error
要求:
reply_delta.text来自真实流式累计replyTextsession必须来自 finalize 后重新读取的最新 session
8. 错误策略
- 如果
llm_client未配置:- 普通接口返回
502 - SSE 返回
error - 不写 assistant message
- 普通接口返回
- 如果 LLM 响应解析失败:
- 普通接口返回
502 - SSE 返回
error - 只保留 user message
- 普通接口返回
- 如果 finalize 失败:
- 普通接口返回
502 - SSE 返回
error - 以前端重新拉 session 为准
- 普通接口返回
8.1 anchor pack 解析边界
nextAnchorPack 是 LLM 输出契约的一部分,字段名固定采用前端与 prompt 侧一致的 camelCase:
themePromisevisualSubjectvisualMoodcompositionHookstagsAndForbidden
Rust 领域模型 PuzzleAnchorPack 仍保持 theme_promise / visual_subject / visual_mood / composition_hooks / tags_and_forbidden,不把 LLM 契约命名扩散到 module-puzzle。因此 api-server 的 puzzle_agent_turn.rs 必须在 LLM 边界显式把 camelCase anchor pack 翻译为 Rust 领域结构,再序列化给 SpacetimeDB finalize。
验收补充:真实 LLM 返回符合本文 nextAnchorPack 示例时,不应再触发“拼图 anchor pack 解析失败,请稍后重试。”。
9. 实现清单
module-puzzle- 新增
PuzzleAgentMessageFinalizeInput
- 新增
spacetime-module/src/puzzle.rs- 新增
finalize_puzzle_agent_message_turn - 修改
submit_puzzle_agent_message
- 新增
spacetime-client- 刷新 Rust bindings
- 新增
finalize_puzzle_agent_message(...)
api-server- 新增
puzzle_agent_turn.rs puzzle.rs的普通消息与 SSE 改接 turn service
- 新增
docs/technical/README.md- 补入本文档索引
10. 验收
- 拼图 Agent 普通发送接口不再返回固定 assistant 文案
- 拼图 Agent SSE 可看到逐步增长的
reply_delta - finalize 后
session.messages中新增 assistant chat 消息 session.anchorPack / progressPercent / currentTurn / lastAssistantReply已真实更新- LLM 关闭时不会再写入伪造 assistant 回复