This commit is contained in:
2026-05-08 11:44:42 +08:00
parent b08127031c
commit abf1f1ebea
249 changed files with 39411 additions and 887 deletions

View File

@@ -0,0 +1,948 @@
# 创意互动内容生成 Agent 技术方案 2026-05-05
## 1. 目标
构建一个基于 LangChain-Rust 的创意互动内容生成 Agent。用户输入文字、图片、文档或混合素材后Agent 不通过规则分类硬选玩法,而是以模型为核心完成理解、判断、规划和执行:先理解用户真正想表达的创作意图,再选择当前可用的互动内容模板,最后调用拼图模块工具把内容填入草稿契约中。
当前版本只支持拼图模板。RPG 世界、大鱼吃小鱼、抓大鹅 Match3D、方洞挑战等模板必须在 Agent 可见能力中标记为 `unsupported`,不能创建这些玩法的目标 session。即便只有拼图可用Agent 仍必须先展示多个拼图模板候选,用户选择某个模板后,再确认该模板下的关卡模式、关卡数和预计积分范围,确认后才进入草稿生成。
本方案不再把 Agent 设计成“规则路由 workflow”。规则只作为安全护栏、契约校验和成本控制。真正的模板选择、素材理解、草稿构思、行动顺序和补问判断由模型通过工具调用和反思循环完成。
## 2. LangChain-Rust 选型依据
当前可参考 `langchainrust` crate 作为 Rust 侧 Agent 编排底座。官方 crate 页面显示 `0.2.18` 支持 Agents、Tools、Memory、Chains、RAG、BM25、Hybrid Retrieval、LangGraph、Typed/JSON output parser、Function Calling、Callbacks 等能力;其中 Agent 层包括 ReActAgent、FunctionCallingAgent、AgentExecutor 和 LangGraphMemory 层包括 Buffer、Window、Summary、SummaryBuffer、Persistent。
落地时建议先以 `langchainrust = "0.2.18"` 做隔离性 PoC不直接替换现有 `platform-llm`。若 crate API 与 docs.rs 最新构建存在差异,以源码和本地编译结果为准,先封装一层 `platform-agent` adapter再接入 `api-server`
参考:
- `langchainrust` crates.io/docs.rs 页面https://docs.rs/crate/langchainrust/latest
- 仓库主页https://github.com/atliliw/langchainrust
## 2.1 Agent 模型与多模态输入
创意互动内容 Agent 的感知、思考、反思和自然语言草稿修订统一使用 APIMart OpenAI 兼容 Responses API 的 `gpt-5`。这里的 `gpt-5` 负责理解用户文字和图片、选择拼图模板、规划草稿字段和生成结构化工具调用参数;拼图图片生成仍由拼图模块图片工具使用 `gpt-image-2`,不要把“理解/规划模型”和“生图模型”混在同一个配置里。
请求协议以 APIMart 文档 `OpenAI 多模态响应接口` 为准:
```text
POST https://api.apimart.ai/v1/responses
model: gpt-5
input[].content[].type: input_text | input_image
```
Phase 1 的 `platform-agent` / `platform-llm` 必须支持下面的项目内请求结构:
```ts
export interface CreativeAgentMultimodalInputPart {
type: 'input_text' | 'input_image';
text?: string;
imageUrl?: string;
}
export interface CreativeAgentGpt5Request {
model: 'gpt-5';
input: Array<{
role: 'system' | 'user' | 'assistant';
content: CreativeAgentMultimodalInputPart[];
}>;
stream: boolean;
tools?: CreativeAgentToolSchema[];
}
```
落地约束:
1. Agent 入口支持文本 + 图片多模态输入,首版至少支持 1 张图片,协议层预留多图。
2. 图片必须先进入资产系统Agent 请求使用可访问的 `readUrl` 或受控 Data URISpacetimeDB 不保存大图 base64。
3. `platform-llm` 当前已有 Responses 协议骨架,但 Phase 1 需要把 content part 从纯文本扩展成 `input_text` / `input_image` 两类。
4. `CREATION_TEMPLATE_LLM_MODEL` 等旧文本创作模型不能作为创意互动内容 Agent 的默认模型;本 Agent 必须显式使用 `gpt-5`
5. 如果 LangChain-Rust adapter 暂时无法直接表达多模态 Responses 请求,应在 `platform-agent` 内桥接到 `platform-llm` 的多模态 Responses client不能退回纯文本摘要替代图片理解。
6. 模型工具调用可用 APIMart Responses 的 `tools` 能力承载;工具真正执行仍由 `platform-agent` 注册表和后端 typed Tool 控制。
## 3. 总体架构
Agent 由六大核心模块组成,形成“感知 -> 思考 -> 记忆 -> 行动 -> 反思 -> 协作”的闭环。
```text
用户图文输入
-> 感知 Perception
-> 思考 Reasoning
-> 记忆 Memory
-> 行动 Action
-> 反思 Reflection
-> 协作 Collaboration
-> 目标玩法草稿 / 追问 / 人工确认
```
Rust 分层建议:
```text
server-rs/crates/platform-agent
langchain_adapter.rs LangChain-Rust 封装,屏蔽第三方 API 变化
agent_graph.rs 六模块 LangGraph / AgentExecutor 编排
tools.rs 工具注册与权限边界
output_parsers.rs Typed / JSON 输出解析
callbacks.rs Trace、SSE、成本与错误事件
server-rs/crates/module-creative-agent
domain.rs Agent 会话、目标、模板语义、计划、反思记录
commands.rs 创建会话、写入输入、确认计划、保存结果
application.rs 纯领域校验、阶段迁移、契约门槛
errors.rs 字段错误与领域错误
server-rs/crates/api-server/src/creative_agent.rs
HTTP / SSE facade调用 platform-agent 和 spacetime-client
```
DDD 边界保持不变:
- `platform-agent` 负责 Agent 编排和工具调用抽象,不保存业务真相。
- `module-creative-agent` 只放纯领域类型、阶段、校验和决策记录结构。
- `api-server` 负责鉴权、SSE、LLM/视觉/工具编排。
- `spacetime-module` 保存会话、输入、记忆索引、目标玩法绑定和审计事件。
- 当前目标玩法只允许拼图。拼图模板协议、积分范围、单关卡/多关卡图片生成计划、草稿校验和工具实现全部封装在 `module-puzzle` / 拼图相关 facade 中;通用 Agent 不复制拼图字段推导逻辑。
## 4. 六大核心模块
### 4.1 感知模块 Perception
职责:把用户输入的字、图、文档和上下文变成模型可推理的多模态语义状态。
它不是关键词分类器。它要做的是“看懂素材”和“看懂用户想要什么”。
输入:
```ts
export interface CreativePerceptionInput {
text: string;
documents: CreativeTextAttachment[];
images: CreativeImageAttachment[];
currentUserProfile?: CreativeUserPreferenceSnapshot | null;
entryContext: 'creation_home' | 'puzzle_workspace' | 'gallery_remix' | 'draft_restore';
}
```
输出:
```ts
export interface CreativePerceptionState {
userIntent: string;
emotionalTone: string;
targetAudience: string | null;
sourceMaterials: CreativeMaterialSummary[];
visualUnderstanding: CreativeImageUnderstanding[];
constraints: CreativeConstraint[];
uncertainties: CreativeUncertainty[];
}
```
实现方式:
1. 文档输入复用 `creationAgentDocumentInput`,再交给 LangChain-Rust 的 text splitter / document chain 做摘要。
2. 图片输入必须先上传为资产Agent 只拿 `readUrl`、缩略图、尺寸和视觉摘要,不把大 data URL 存入 SpacetimeDB。
3. 图像理解首版直接通过 APIMart Responses API 的 `gpt-5` 多模态输入完成返回主体、场景、风格、OCR、构图线索和安全风险后续如独立 `platform-vision`,也必须保持相同的文本/图像内容块契约。
4. 模板和玩法说明通过 RAG 检索注入,而不是写死规则。检索源包括玩法模板注册表、拼图草稿契约、已有优秀作品摘要和玩法适配说明。
LangChain-Rust 对应能力:
- Document loader / splitter / summarization chain
- RAG、BM25、Hybrid retrieval
- Typed / JSON output parser
- Callback 将感知进度推给前端 SSE
### 4.2 思考模块 Reasoning
职责:让模型在可用工具、用户意图和玩法知识之间主动做计划。
思考模块不是 `if playType == puzzle` 的路由函数,而是一个 FunctionCallingAgent 或 LangGraph 中的 planner 节点。模型可以自主选择:
- 先调用拼图模板知识检索
- 先返回拼图模板目录
- 请求用户选择模板
- 用户选中模板后,再确认该模板的关卡模式、关卡数和积分范围
- 确认后生成单关卡或多关卡草稿计划
- 先调用图片理解
- 先问用户一个关键问题
- 委托拼图专家 Agent
当前版本的思考模块不能选择非拼图玩法作为行动目标。如果模型认为输入更适合 RPG、Match3D、大鱼或方洞挑战应输出“当前仅支持拼图模板”的说明并尝试给出可转化为拼图的创意方案若无法转化应进入 `waiting_user`,不能创建非拼图 session。
核心状态:
```ts
export interface CreativeReasoningState {
goal: string;
candidatePlayTypes: CreativePlayCandidate[];
selectedPlayType: CreativePlayType | null;
selectedTemplateId: string | null;
selectedPuzzleTemplate: PuzzleCreativeTemplateSelection | null;
selectedImageGenerationPlan: PuzzleImageGenerationPlan | null;
plan: CreativeAgentPlanStep[];
confidence: number;
needUserClarification: boolean;
rationale: string;
}
```
建议使用 LangChain-Rust
- `FunctionCallingAgent` 作为主决策 Agent所有玩法能力以工具形式暴露。
- `AgentExecutor` 控制最大迭代次数、超时、工具调用错误回传。
- `LangGraph` 表达长链路:`perceive -> plan -> act -> reflect -> finalize`,允许循环和人工确认。
- `JsonOutputParser` / `TypedOutputParser` 保证模型最终输出能落到 Rust/TS shared contract。
系统提示词要明确:
1. 你是创意互动内容生成 Agent不是分类器。
2. 你可以相信自己的多模态理解能力。
3. 你应选择能最大化互动体验的玩法,而不是机械匹配关键词。
4. 当前产品只开放拼图模板,非拼图模板只能解释为暂不支持,不能调用非拼图工具。
5. 即便只有拼图玩法可用,也必须先显式展示多个拼图子模板;用户选中模板后,才展示选择理由、关卡配置和预计积分范围。
6. 当输入足够明确时不要过度追问。
7. 当合规、素材权属、人物肖像或儿童内容存在风险时进入确认或降级。
### 4.3 记忆模块 Memory
职责:让 Agent 能利用当前会话、用户偏好、历史作品和反思经验,而不是每次从零判断。
记忆分四层:
```text
短期记忆:当前会话消息、工具调用、草稿状态
工作记忆:本次任务的目标、计划、候选、未解决问题
长期记忆:用户偏好、常用玩法、作品风格、发布反馈
反思记忆:过去失败原因、模板误选案例、修正策略
```
推荐结构:
```ts
export interface CreativeAgentMemorySnapshot {
shortTermSummary: string;
workingPlan: CreativeAgentPlanStep[];
retrievedUserPreferences: CreativeUserPreference[];
retrievedTemplateMemories: CreativeTemplateMemory[];
retrievedReflections: CreativeReflectionMemory[];
}
```
落地方式:
1. LangChain-Rust Memory 用于单次 AgentExecutor 内的短期上下文,可用 Buffer / Window / SummaryBuffer。
2. SpacetimeDB 保存长期真相:`creative_agent_session``creative_agent_message``creative_agent_reflection``creative_agent_target_binding`
3. 向量/混合检索保存可召回记忆:用户偏好、模板选择结果、发布后反馈、失败反思。首版可用 SQLite 或 Redis feature生产再评估 Qdrant/Redis。
4. 每次生成结束后写一条反思记忆:选择了什么模板、为什么、哪些字段由模型推断、用户是否接受、是否返回编辑。
记忆使用原则:
- 记忆给模型参考,不替代用户本轮输入。
- 用户本轮明确要求优先级最高。
- 任何长期记忆都要带来源、时间和置信度。
- 涉及个人隐私、图片内容和未发布作品时只在用户私有 namespace 检索。
### 4.4 行动模块 Action
职责:把 Agent 的计划变成可审计、可回滚、可测试的工具调用。
所有对系统产生影响的操作都必须以 LangChain-Rust Tool 的形式注册。模型通过 function calling 选择工具,工具内部再调用现有服务或 SpacetimeDB facade。
首批工具:
```text
perceive_image(imageAssetId)
retrieve_puzzle_template_catalog(query)
retrieve_user_creation_memory(userId, query)
create_puzzle_agent_session(payload)
compile_puzzle_draft(sessionId, payload)
plan_puzzle_level_images(payload)
generate_puzzle_level_images(sessionId, payload)
select_puzzle_template(payload)
confirm_puzzle_template(payload)
apply_puzzle_draft_natural_language_edit(sessionId, payload)
start_puzzle_draft_test_run(sessionId, payload)
ask_user_clarification(question, options?)
request_user_confirmation(summary, candidates)
validate_target_draft(playType, draft)
save_creative_reflection(payload)
```
工具设计要求:
1. 工具描述要清楚告诉模型何时使用,而不是由外层规则决定。
2. 工具输入必须是 JSON Schema / Rust typed struct禁止自由字符串拼接。
3. 工具只做一件事。比如“创建拼图 session”和“编译拼图草稿”分开。
4. 工具返回结构化结果,包含 `ok``summary``nextSuggestedTools``warnings`
5. 所有写操作必须鉴权,不能信任模型传入的 `ownerUserId`
6. 工具调用审计写入 SpacetimeDB便于排障和反思。
7. 当前工具注册表只能暴露拼图工具。非拼图工具即使已有实现,也不能注册给当前 Agent。
拼图草稿不是路由器手填,而是 Action 模块通过工具让 Agent 产出 typed payload。这里的“草稿字段”只指用户表单和 Agent 自然语言都共同编辑的那一组字段:
```ts
export interface CreativePuzzleDraftToolInput {
templateId: string;
templateCostRange: PuzzleTemplateCostRange;
workTitle: string;
workDescription: string;
workTags: string[];
levels: CreativePuzzleLevelDraftInput[];
}
export interface CreativePuzzleLevelDraftInput {
levelName: string;
pictureDescription: string;
pictureReference?: string | null;
}
```
工具内部负责映射到现有 `PuzzleAgentActionRequest``PuzzleResultDraft`,并调用拼图领域校验。`workTitle``workDescription``workTags``levels[].levelName``levels[].pictureDescription``levels[].pictureReference` 是 Agent 直接写入的草稿真相;`summary``anchorPack``forbiddenDirectives``imagePrompt`、候选图等都属于拼图模块内部派生或生成结果,不作为 Agent 的直接填表目标。
拼图模块必须额外暴露模板和多关卡图片协议:
```ts
export interface PuzzleCreativeTemplateProtocol {
templateId: string;
title: string;
description: string;
supportedLevelMode: 'single' | 'multi' | 'single_or_multi';
defaultLevelCount: number;
minLevelCount: number;
maxLevelCount: number;
costRange: PuzzleTemplateCostRange;
requiredDraftFields: string[];
imageGenerationPolicy: PuzzleTemplateImageGenerationPolicy;
}
export interface PuzzleTemplateCostRange {
minPoints: number;
maxPoints: number;
pricingUnit: 'point';
reason: string;
}
export interface PuzzleTemplateImageGenerationPolicy {
allowUploadedImageDirectly: boolean;
allowGeneratedImages: boolean;
allowPerLevelReferenceImage: boolean;
defaultCandidateCountPerLevel: number;
}
export interface PuzzleImageGenerationPlan {
mode: 'single_level' | 'multi_level';
levels: CreativePuzzleLevelDraftInput[];
estimatedCostRange: PuzzleTemplateCostRange;
}
```
积分范围由拼图模板协议提供Agent 只能解释和选择,不能自行发明价格。真实扣费仍以后端钱包/任务系统最终结算为准。
### 4.5 反思模块 Reflection
职责:让 Agent 在交付前检查自己的选择是否真的适合用户,而不是一次模型输出就结束。
反思节点运行在每次关键行动后:
1. 模板选择后:检查是否已经向用户显式展示拼图模板和积分范围。
2. 用户确认前:检查是否误承诺了非拼图模板或非真实价格。
3. 草稿填充后:检查字段是否完整、玩法体验是否成立。
4. 图片使用前:检查单关卡/多关卡图片计划是否与模板协议一致。
5. 最终交付前:检查是否需要用户确认。
反思输出:
```ts
export interface CreativeReflectionReport {
pass: boolean;
score: number;
issues: CreativeReflectionIssue[];
revisionInstruction?: string | null;
shouldAskUser: boolean;
shouldTryAlternativePlayType: boolean;
}
```
实现方式:
- 用 LangGraph 增加 `reflect` 节点。
- 反思模型拿到感知状态、计划、工具调用结果和目标草稿。
- 如果 `pass=false` 且迭代次数未超限,回到 `plan``act`
- 如果问题是用户偏好缺失,调用 `ask_user_clarification`
- 如果问题是契约字段缺失,调用目标玩法 draft 修复工具。
- 如果问题是未展示模板选择或积分范围,回到模板确认节点。
- 如果问题是多关卡计划超出模板 `maxLevelCount`,调用拼图计划修复工具。
硬性终止条件:
- 最大反思循环 2 次。
- 同一工具同一参数失败 2 次后停止并返回可读错误。
- 预算超限时返回当前可用草稿和补救建议。
反思记忆要沉淀:
- 模板误选原因。
- 用户是否接受模板积分范围。
- 单关卡或多关卡图片生成计划是否被用户调整。
- 用户手动改选的玩法。
- 结果页返回编辑最多的字段。
- 发布失败 blockers。
### 4.6 协作模块 Collaboration
职责:把复杂创意任务拆给多个专长 Agent而不是让单个提示词吞掉所有任务。
当前首版只开放拼图协作,不开放其它玩法子 Agent。建议四个子 Agent
```text
创意导演 Agent理解用户目标决定整体方向和互动体验。
视觉解读 Agent理解图片、构图、主体、风格和可交互线索。
拼图模板策展 Agent基于拼图模板协议和历史作品选择候选拼图模板并读取积分范围。
拼图专家 Agent生成单关卡或多关卡拼图草稿 payload 和图片生成计划。
契约审校 Agent检查字段、发布门槛、积分展示、安全边界和可恢复性。
```
LangChain-Rust 落地:
- 用 LangGraph 的 subgraph 表达子 Agent。
- 子 Agent 共享 `CreativeAgentState`,但只能写自己负责的字段。
- 主 Agent 通过 handoff 工具委托子任务。
- 必要时并行执行视觉解读和拼图模板知识检索,再由创意导演合并。
- 协作结果由契约审校 Agent 最终检查。
协作不是增加 UI 复杂度。前端仍只看到一个 Agent但后端内部有多个可观测步骤SSE 推送简短阶段即可。
## 5. Agent 状态机
LangGraph 状态建议:
```rust
pub struct CreativeAgentGraphState {
pub session_id: String,
pub owner_user_id: String,
pub perception: Option<CreativePerceptionState>,
pub memory: Option<CreativeAgentMemorySnapshot>,
pub reasoning: Option<CreativeReasoningState>,
pub tool_results: Vec<CreativeToolResult>,
pub reflection: Option<CreativeReflectionReport>,
pub target_binding: Option<CreativeTargetSessionBinding>,
pub final_response: Option<CreativeAgentFinalResponse>,
pub iteration_count: u32,
}
```
Graph 节点:
```text
load_memory
perceive_input
plan_with_agent
act_with_tools
reflect_result
collaborate_if_needed
finalize_or_ask_user
persist_memory
```
边:
```text
load_memory -> perceive_input
perceive_input -> plan_with_agent
plan_with_agent -> act_with_tools
act_with_tools -> reflect_result
reflect_result(pass) -> finalize_or_ask_user
reflect_result(revise) -> plan_with_agent
reflect_result(collaborate) -> collaborate_if_needed
collaborate_if_needed -> act_with_tools
finalize_or_ask_user -> persist_memory
```
## 6. 数据契约
新增 shared contracts
```text
packages/shared/src/contracts/creativeAgent.ts
server-rs/crates/shared-contracts/src/creative_agent.rs
```
核心 DTO
```ts
export type CreativeAgentStage =
| 'perceiving'
| 'thinking'
| 'remembering'
| 'selecting_puzzle_template'
| 'waiting_template_confirmation'
| 'planning_puzzle_levels'
| 'acting'
| 'reflecting'
| 'collaborating'
| 'waiting_user'
| 'target_ready'
| 'failed';
export interface CreativeAgentSessionSnapshot {
sessionId: string;
stage: CreativeAgentStage;
perception: CreativePerceptionState | null;
reasoning: CreativeReasoningState | null;
puzzleTemplateCatalog: PuzzleCreativeTemplateProtocol[];
puzzleTemplateSelection: PuzzleCreativeTemplateSelection | null;
puzzleImageGenerationPlan: PuzzleImageGenerationPlan | null;
reflection: CreativeReflectionReport | null;
targetBinding: CreativeTargetSessionBinding | null;
messages: CreativeAgentMessage[];
updatedAt: string;
}
export interface PuzzleCreativeTemplateSelection {
templateId: string;
title: string;
reason: string;
costRange: PuzzleTemplateCostRange;
supportedLevelMode: 'single' | 'multi' | 'single_or_multi';
selectedLevelMode: 'single_level' | 'multi_level';
plannedLevelCount: number;
requiresUserConfirmation: true;
}
```
HTTP facade
```text
POST /api/runtime/creative-agent/sessions
GET /api/runtime/creative-agent/sessions/{sessionId}
POST /api/runtime/creative-agent/sessions/{sessionId}/messages/stream
POST /api/runtime/creative-agent/sessions/{sessionId}/confirm
POST /api/runtime/creative-agent/sessions/{sessionId}/cancel
```
SSE 事件:
```text
stage
agent_message_delta
puzzle_template_catalog
puzzle_template_selection
puzzle_cost_range
puzzle_level_plan
tool_started
tool_completed
reflection
target_session
need_user_input
session
error
```
## 7. SpacetimeDB 持久化
新增表:
```text
creative_agent_session
creative_agent_message
creative_agent_input_asset
creative_agent_tool_call
creative_agent_reflection
creative_agent_target_binding
creative_agent_memory_index
puzzle_creative_template_snapshot
puzzle_creative_level_generation_plan
```
关键约束:
1. SpacetimeDB 保存结构化真相和 JSON 快照,不保存大图片 data URL。
2. 工具调用和反思必须可追溯,便于排查模型为什么选择某个模板。
3. `creative_agent_memory_index` 只保存记忆元数据和向量索引引用,不直接承担向量数据库职责。
4. 表结构变更必须同步 `migration.rs``SPACETIMEDB_TABLE_CATALOG.md` 和 bindings。
5. `creative_agent_session` 必须保存当前拼图模板目录、已确认的模板选择快照和积分范围,保证刷新后仍能恢复“先选模板、再确认配置”的两段式状态。
6. `puzzle_creative_level_generation_plan` 保存单关卡/多关卡图片生成计划,包括每关 `level_id``level_name``picture_description``image_prompt``generation_status``candidate_count``estimated_cost_points`
7. 非拼图玩法不新增 target binding避免后续误恢复到暂不支持的玩法。
8. 自然语言修订草稿字段要记录工具调用、原始用户指令、结构化 patch 和修改后的 draft 版本,便于撤销、审计和反思。
9. 试玩 run 与草稿 session 需要有绑定关系,确保“立即玩”后返回结果页能恢复同一草稿。
## 8. 拼图首版落地
拼图首版不是“规则判断为拼图”而是模型通过工具和反思得出选择。但产品边界明确当前只支持拼图模板。Agent 必须把非拼图创意转化为拼图可承接的方案,或告诉用户当前不支持该模板。
### 8.1 强制模板选择与积分展示
任何草稿生成前都必须先进入 `selecting_puzzle_template``waiting_template_confirmation`
前端至少展示:
- 拼图模板标题
- 模板缩略图或示意图
- Agent 选择理由
- 支持单关卡、多关卡或二者皆可
- 计划关卡数
- 预计积分范围,例如 `预计消耗 8 到 18 光点`
积分范围来自拼图模板协议:
```ts
export interface PuzzleTemplateCostRange {
minPoints: number;
maxPoints: number;
pricingUnit: 'point';
reason: string;
}
```
Agent 可以解释 `reason`,但不能修改 `minPoints` / `maxPoints`。如果模板协议没有积分范围,该模板不能展示为可选项。
Agent 可调用工具:
```text
retrieve_puzzle_template_catalog
inspect_puzzle_draft_contract
select_puzzle_template
confirm_puzzle_template
plan_puzzle_level_images
create_puzzle_agent_session
compile_puzzle_draft
apply_puzzle_draft_natural_language_edit
validate_puzzle_result_preview
select_uploaded_image_as_puzzle_cover
generate_puzzle_images
start_puzzle_draft_test_run
return_to_puzzle_result
```
### 8.2 拼图模板协议
拼图模板协议应封装在拼图模块,不放在通用 Agent
```text
server-rs/crates/module-puzzle/src/creative_templates.rs
server-rs/crates/module-puzzle/src/creative_tools.rs
server-rs/crates/shared-contracts/src/puzzle_creative_template.rs
packages/shared/src/contracts/puzzleCreativeTemplate.ts
```
协议至少包含:
```ts
export interface PuzzleCreativeTemplateProtocol {
templateId: string;
title: string;
summary: string;
previewImageSrc: string | null;
supportedLevelMode: 'single' | 'multi' | 'single_or_multi';
minLevelCount: number;
maxLevelCount: number;
defaultLevelCount: number;
costRange: PuzzleTemplateCostRange;
imagePolicy: PuzzleTemplateImageGenerationPolicy;
draftFieldHints: PuzzleTemplateDraftFieldHints;
}
```
模板示例:
```json
{
"templateId": "puzzle.family-keepsake",
"title": "家庭纪念拼图",
"supportedLevelMode": "single_or_multi",
"minLevelCount": 1,
"maxLevelCount": 6,
"defaultLevelCount": 3,
"costRange": {
"minPoints": 8,
"maxPoints": 24,
"pricingUnit": "point",
"reason": "按关卡数、每关候选图数量和是否使用上传图估算"
}
}
```
### 8.3 单关卡与多关卡图片生成
拼图草稿必须支持两种计划:
```ts
export type PuzzleLevelGenerationMode = 'single_level' | 'multi_level';
export interface PuzzleImageGenerationPlan {
mode: PuzzleLevelGenerationMode;
templateId: string;
estimatedCostRange: PuzzleTemplateCostRange;
levels: PuzzleImageGenerationPlanLevel[];
}
export interface PuzzleImageGenerationPlanLevel {
levelId: string;
levelName: string;
pictureDescription: string;
imagePrompt: string;
pictureReference?: string | null;
candidateCount: number;
}
```
单关卡:
- `levels.length = 1`
- 可使用上传图直出,也可生成一张候选图。
- 适合纪念照、商品图、单张海报、单主题知识图。
多关卡:
- `levels.length` 必须在模板 `minLevelCount``maxLevelCount` 之间。
- 每关有独立 `levelName``pictureDescription``imagePrompt`
- 可选择每关生成一张图,也可第一关使用上传图、后续关卡生图。
- 适合故事型照片组、知识步骤、活动流程、系列商品、节日卡片组。
生成工具建议:
```ts
export interface GeneratePuzzleLevelImagesToolInput {
sessionId: string;
plan: PuzzleImageGenerationPlan;
imageModel: 'gpt-image-2';
}
export interface GeneratePuzzleLevelImagesToolOutput {
draft: PuzzleResultDraft;
levels: PuzzleDraftLevel[];
costEstimate: PuzzleTemplateCostRange;
generatedCount: number;
uploadedCount: number;
}
```
工具内部可以复用现有 `generate_puzzle_images` action但必须以 `levelId` 为粒度逐关执行,或新增拼图后端 action `generate_puzzle_level_images` 批量处理。批量 action 仍归属拼图模块,通用 Agent 只负责调用。
### 8.5 模板草稿字段填充与自然语言修订
Agent 创作互动内容的本质就是向模板中的草稿字段填充内容。拼图模板草稿字段是唯一创作真相表单化创作页是这些字段的可视化编辑器Agent 对话是这些字段的自然语言编辑器,二者属于同一条创作流程。
通用 Agent 只负责把用户自然语言转成“草稿字段填充 / 修订意图”,真正的字段写入仍通过拼图模块 Tool 完成:
```ts
export interface PuzzleDraftFieldEditInstruction {
scope: 'work' | 'level' | 'tags' | 'cover' | 'images' | 'all';
operation: 'set' | 'append' | 'replace' | 'remove' | 'reorder';
fieldPath: string;
value: string | string[] | boolean | number | null;
rationale: string;
}
export interface ApplyPuzzleDraftNaturalLanguageEditToolInput {
sessionId: string;
userInstruction: string;
currentDraftSnapshot: PuzzleResultDraft;
}
export interface ApplyPuzzleDraftNaturalLanguageEditToolOutput {
updatedDraft: PuzzleResultDraft;
editInstructions: PuzzleDraftFieldEditInstruction[];
needsUserConfirmation: boolean;
confirmationSummary: string;
}
```
这个工具由拼图模块封装,内部要做三步:
1. 用模型把自然语言改写成结构化草稿字段 patch。
2. 用拼图领域规则校验 patch 是否会破坏草稿约束。
3. 通过现有草稿保存接口写回同一份 `PuzzleResultDraft``formDraft`
典型自然语言字段修订场景:
- “把这张图改成更适合家庭纪念。”
- “第二关再多加一张风景图。”
- “标题别太正式,轻松一点。”
- “主题标签里去掉商品感,增加温暖和节日感。”
Agent 不能直接篡改结果页 DOM也不能绕过拼图草稿字段写最终发布数据。用户在表单里手动编辑、用户用自然语言让 Agent 编辑,本质上都必须落到同一份草稿字段 patch。
### 8.6 立即玩与试玩闭环
生成好的互动内容必须能立即玩到。对拼图来说Agent 完成草稿后必须直接导向现有 `puzzle-result`,并提供明确的“立即玩”入口。
闭环要求:
1. 草稿创建成功后,结果页首屏就能看到 `Play` 或“立即玩”按钮。
2. 点击后直接启动 `puzzle-runtime`,不需要用户再手动跳过别的中间页。
3. 如果当前草稿还在生成更多关卡图片,已完成关卡可先试玩,后续图片再逐关补齐。
4. 试玩入口必须复用现有 `PuzzleRuntimeShell``startPuzzleRun` 链路。
5. 试玩后返回结果页时,仍然停留在同一草稿上下文,不丢失表单草稿状态。
结果页到运行态之间的切换不由通用 Agent 再次判断,而是由拼图模块暴露的 `start_run` / `resume_run` / `return_to_result` 工具完成。
### 8.4 拼图专家输出
拼图专家 Agent 需要产出:
```ts
export interface PuzzleCreativeDraftIntent {
templateSelection: PuzzleCreativeTemplateSelection;
imageGenerationPlan: PuzzleImageGenerationPlan;
workTitle: string;
workDescription: string;
workTags: string[];
levels: CreativePuzzleLevelDraftInput[];
}
```
字段映射仍必须对齐现有契约:
- `PuzzleResultDraft.workTitle`
- `PuzzleResultDraft.workDescription`
- `PuzzleResultDraft.workTags`
- `PuzzleResultDraft.levels[].levelName`
- `PuzzleResultDraft.levels[].pictureDescription`
- `PuzzleResultDraft.levels[].pictureReference`
领域校验仍由 `module-puzzle` 负责。Agent 可以创造内容,但不能绕过发布 blockers。表单化创作页与 Agent 自然语言修订都只是这些字段的不同编辑界面。
## 9. 前端体验
前端只呈现一个“智能创作 Agent”入口
1. 用户输入文字、上传图片或文档。
2. 前端显示 Agent 正在理解素材、构思玩法、生成草稿。
3. Agent 必须先展示拼图模板目录。
4. 用户选择模板并确认关卡模式、关卡数和预计积分范围后Agent 才能生成草稿。
5. 生成完成后进入拼图结果页,并提供“立即玩”入口,点击后直接进入拼图运行态。
6. 结果页保留原来的表单化创作能力,包括作品标题、作品描述、作品标签、关卡名称、关卡图面描述、关卡图面参考、关卡图片生成和选图;这些控件编辑的是同一份模板草稿字段。
7. Agent 对话区继续可用,用户可以用自然语言补填或修订模板草稿字段,后端通过拼图模块 Tool 生成结构化 patch 并回写同一份草稿;可写字段仅限 `workTitle``workDescription``workTags``levels[].levelName``levels[].pictureDescription``levels[].pictureReference`
8. 若 Agent 有关键不确定点,弹出独立确认面板。
9. 用户确认或回答后Agent 继续执行并进入拼图结果页或保持在当前草稿上下文。
UI 不展示大段规则说明,只展示:
- 当前阶段
- 简短 Agent 回复
- 拼图模板选择和积分范围
- 单关卡 / 多关卡计划
- 需要确认的问题
- 最终草稿入口
- 立即玩入口
- 表单化草稿字段编辑入口
- Agent 自然语言补填 / 修订入口
移动端优先,上传图片预览使用横向缩略图条,确认面板用底部抽屉。
## 10. 安全与治理
模型能力是核心,但不能没有边界:
1. 工具权限边界:模型只能调用已注册工具,不能直接写库。
2. 契约边界Typed parser 和目标玩法 validator 必须通过。
3. 成本边界AgentExecutor 设置最大迭代、最大工具调用、超时和预算。
4. 内容安全:人物肖像、儿童内容、版权图、隐私图进入确认或拒绝。
5. 记忆安全:长期记忆按用户 namespace 隔离。
6. 可观测性Callbacks 记录每个节点、工具、token、耗时和错误。
## 11. 分阶段落地
### Phase 1LangChain-Rust PoC + 拼图闭环
- 新增 `platform-agent` PoC。
- 封装 LangChain-Rust FunctionCallingAgent / AgentExecutor。
- 注册拼图相关工具。
- 只支持拼图模板;非拼图模板在 Agent 能力中标记为暂不支持。
- 强制展示拼图模板选择、选择理由和预计积分范围。
- 支持文字 + 单图输入,模型自主选择拼图模板并填入草稿字段。
- 支持单关卡图片生成计划和多关卡图片生成计划。
- 生成后的拼图内容点击“立即玩”可直接进入 `puzzle-runtime`
- 保留结果页原有表单化草稿字段编辑入口。
- 支持 Agent 自然语言补填 / 修订模板草稿字段,并通过拼图模块 Tool 回写草稿。
- SSE 推送六模块阶段。
- 结果进入现有 `puzzle-result`
### Phase 2记忆与反思闭环
- 增加 `creative_agent_tool_call``creative_agent_reflection``creative_agent_memory_index`
- 引入短期 Memory 和长期检索。
- 记录用户改选、发布失败、返回编辑等反馈。
- 反思循环支持自动修正草稿。
### Phase 3多玩法协作
- 在产品开放后再增加 Match3D、大鱼吃小鱼、方洞挑战、RPG 世界专家 Agent。
- 使用 LangGraph subgraph 做多 Agent 协作。
- 支持多候选玩法对比和人工确认。
## 12. 验收标准
功能验收:
1. 用户输入含图文材料时Agent 能说出它理解到的创作意图。
2. Agent 能调用拼图模板知识检索,而不是靠硬编码规则选模板。
3. Agent 必须显式展示拼图模板、选择理由和预计积分范围,用户确认后才生成草稿。
4. 非拼图输入不会创建其它玩法 session只能转成拼图方案或提示暂不支持。
5. Agent 能自主选择拼图模板并生成可通过契约校验的 `PuzzleResultDraft`
6. 当图片更适合直接作为拼图图面时Agent 能选择 uploaded candidate而不是强制生图。
7. Agent 能生成单关卡图片计划,也能生成多关卡图片计划。
8. 多关卡计划中每关都有独立 `levelName``pictureDescription``imagePrompt`
9. 多关卡图片生成逻辑通过拼图模块工具执行,通用 Agent 不直接拼接 `levelsJson`
10. 生成好的拼图内容点击“立即玩”后能直接进入 `puzzle-runtime`
11.`puzzle-runtime` 返回时仍恢复同一 `puzzle-result` 草稿上下文。
12. 结果页保留表单化草稿字段编辑能力,用户可以修改作品标题、作品描述、作品标签、关卡名称、关卡图面描述和关卡图面参考。
13. 用户用自然语言提出“把标题改轻松一点”“第二关加一张风景图”等请求时Agent 能生成结构化草稿字段 patch 并通过拼图模块 Tool 回写同一份草稿。
14. 自然语言修订草稿字段后必须重新通过拼图草稿校验和结果预览校验。
15. 当不确定时Agent 只问一个关键问题,而不是把所有字段丢给用户填写。
16. 反思节点能发现未展示积分范围、关卡数越界、草稿字段缺失或自然语言字段 patch 风险,并自动修正一次。
17. 工具调用、反思报告、模板选择、草稿字段 patch 和目标拼图 session 绑定能恢复和审计。
建议命令:
```bash
cd server-rs
cargo test -p shared-contracts creative_agent
cargo test -p module-creative-agent
cargo check -p platform-agent
cargo check -p api-server
```
涉及 SpacetimeDB schema 后:
```bash
npm run spacetime:generate -- --rust-only
npm run check:server-rs-ddd
```
前端:
```bash
npm run typecheck
npm run check:encoding
```
## 13. 当前实现状态
截至 `2026-05-05`,任务 C 已完成首版 PoC 落地:
1. `server-rs/crates/platform-agent` 已新增为 workspace member。
2. `platform-agent` 已提供项目自有的 `CreativeAgentExecutor`、工具注册表、回调事件、`gpt-5` 多模态请求适配器和 mock executor。
3. `platform-llm` 已支持 Responses 多模态输入块,`input_text``input_image` 会按 content part 序列化到请求体。
4. 任务 C 的验收命令已通过:`cargo check -p platform-agent``cargo test -p platform-agent``cargo test -p platform-llm responses_multimodal`
截至 `2026-05-05`,任务 E 的 API / SSE facade 已补充 Windows debug 稳定性修复:
1. `/api/runtime/creative-agent/sessions/{sessionId}/messages/stream` 不再把 Agent 执行、模型请求、会话更新和所有 SSE 事件内联到单个大型 `async_stream` 中。
2. 当前实现使用后台 `tokio::spawn` 执行业务流程,并通过 `mpsc` / `UnboundedReceiverStream` 向 Axum 返回轻量 SSE stream执行失败会更新会话为 `failed` 并发送 SSE `error`
3. 已补实际消费 SSE body 的回归测试,覆盖 `stage``puzzle_template_catalog``done` 事件;`puzzle_template_selection``puzzle_cost_range``puzzle_level_plan` 只在用户确认后进入后续快照或流程。
## 14. 本方案相对旧方案的变化
旧方案偏“规则预筛 + workflow + Adapter”。新方案调整为
1. 模型负责理解素材、整理候选和草稿构思;最终模板由用户从多个候选中主动选择。
2. LangChain-Rust AgentExecutor / FunctionCallingAgent 承担工具调用决策。
3. LangGraph 承担六模块闭环和反思循环。
4. Memory/RAG 让 Agent 学习用户偏好和模板经验。
5. 当前只开放拼图玩法,但模板选择仍是显式 Agent 步骤,不因只有一个玩法而跳过。
6. 拼图模板协议必须携带积分范围,用户选择模板并确认配置后才进入草稿生成。
7. 单关卡/多关卡图片生成通过拼图模块 Tool 和模板协议实现,不写进通用 Agent。
8. Agent 创作方式就是填充和修订模板草稿字段;表单化创作页和 Agent 自然语言修订都操作同一份 `PuzzleResultDraft`,并围绕 `workTitle``workDescription``workTags``levels[].levelName``levels[].pictureDescription``levels[].pictureReference` 这一组字段协同。
9. Adapter 从“路由实现”降级为 Agent action tool。
10. 规则只保留为安全、契约、成本和权限边界。