1
This commit is contained in:
@@ -115,3 +115,24 @@
|
||||
2. 该失败只代表登录方式配置探测失败,不代表登录功能不可用,因此不把 `读取登录方式失败` 写入登录弹窗错误条。
|
||||
3. 登录弹窗仍展示密码登录表单,玩家可继续登录后进入创作链路。
|
||||
4. 本地仍需要启动 `api-server`,否则后续 `POST /api/auth/entry` 等真实登录请求无法完成。
|
||||
|
||||
## 9. 2026-05-07 本地短信入口恢复记录
|
||||
|
||||
如果登录弹窗里短信登录页签“像是被删了”,先不要改前端表单,优先检查本地登录方式探测结果:
|
||||
|
||||
1. 仓库根目录 `.env.local` 里必须显式保留 `SMS_AUTH_ENABLED=true`。
|
||||
2. 本地启动请优先使用 `npm run api-server`、`npm run dev:rust` 或 `npm run dev`,这些脚本会按“shell 环境优先、`.env.local` 覆盖 `.env`”合并配置。
|
||||
3. 若 `GET /api/auth/login-options` 只返回 `["password"]`,说明短信入口没有被服务端配置打开,前端只是按 contract 正常降级。
|
||||
4. 当 `SMS_AUTH_ENABLED=true` 生效时,`GET /api/auth/login-options` 至少应返回 `["phone", "password"]`,短信登录页签才会重新出现。
|
||||
|
||||
## 10. 2026-05-07 前端代理端口错配修复记录
|
||||
|
||||
如果 Rust API 直连返回 `["phone", "password"]`,但从前端域名请求 `GET /api/auth/login-options` 返回 `500`,短信页签同样会消失。此时不是登录 UI 被删除,而是 `AuthGate` 按第 5.3 节降级成 `["password"]`。
|
||||
|
||||
本地排查顺序固定为:
|
||||
|
||||
1. 先请求 `http://127.0.0.1:3000/api/auth/login-options`,确认前端代理是否成功返回 JSON。
|
||||
2. 再请求当前 Rust API 目标,例如 `http://127.0.0.1:3100/api/auth/login-options` 或 `http://127.0.0.1:8082/api/auth/login-options`。
|
||||
3. 若直连 API 成功而 3000 返回 `500`,检查 `RUST_SERVER_TARGET`、`GENARRATIVE_API_TARGET`、`GENARRATIVE_RUNTIME_SERVER_TARGET` 是否指向仍在监听的 API 端口。
|
||||
4. `npm run dev` / `npm run dev:rust` 完整栈默认由脚本计算 API 端口;加载 `.env.local` 给后端使用后,脚本必须重新固定 `RUST_SERVER_TARGET`,避免 `.env.local` 中的旧代理目标覆盖本次启动的实际 API 端口。
|
||||
5. `npm run dev:web` 只启动前端,不会自动拉起 Rust API;如果单独使用它,必须同时确认其打印的 backend target 已有 `api-server` 正在监听。
|
||||
|
||||
@@ -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 和 LangGraph,Memory 层包括 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 URI;SpacetimeDB 不保存大图 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 1:LangChain-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. 规则只保留为安全、契约、成本和权限边界。
|
||||
@@ -2,17 +2,18 @@
|
||||
|
||||
## 背景
|
||||
|
||||
创作中心顶部“新建作品”入口和平台创作类型弹层都依赖同一组玩法模板。此前入口开放状态、隐藏状态和中文文案集中写在 `src/components/platform-entry/platformEntryCreationTypes.ts` 与入口组件中,后续切换玩法开放节奏时容易出现多个入口不一致。
|
||||
创作中心的模板 Tab、平台创作类型弹层和旧“新建作品”卡片配置都依赖同一组玩法模板。此前入口开放状态、隐藏状态和中文文案集中写在 `src/components/platform-entry/platformEntryCreationTypes.ts` 与入口组件中,后续切换玩法开放节奏时容易出现多个入口不一致。
|
||||
|
||||
## 落地规则
|
||||
|
||||
1. 新建作品入口配置统一放在 `src/config/newWorkEntryConfig.ts`。
|
||||
2. `visible` 控制玩法是否展示在新建作品入口和创作类型弹层中。
|
||||
2. `visible` 控制玩法是否展示在创作 Tab 模板入口、新建作品入口和创作类型弹层中。
|
||||
3. `open` 控制玩法是否允许点击创建;`open: false` 时入口保持展示但禁用。
|
||||
4. `title`、`subtitle`、`badge` 控制玩法卡片文案。
|
||||
5. `startCard` 控制创作中心顶部新建作品模块的标题、辅助文案和移动端角标文案。
|
||||
5. `startCard` 控制旧创作中心顶部新建作品模块的标题、辅助文案和移动端角标文案;当前创作 Tab 首屏标题固定在 `PlatformEntryFlowShellImpl.tsx`,不再由 `startCard` 控制。
|
||||
6. `typeModal` 控制平台创作类型弹层标题和描述。
|
||||
7. 入口排序仍遵循“可创建玩法在前,未开放玩法在后”;同组内部沿用配置顺序。
|
||||
8. `creative-agent` 可以继续保留运行链路,但默认 `visible: false`,不出现在创作 Tab 模板入口。
|
||||
|
||||
## 当前状态
|
||||
|
||||
@@ -20,16 +21,19 @@
|
||||
| --- | --- | --- | --- |
|
||||
| 角色扮演 | 否 | 是 | 暂时从创作端入口下线,既有链路与作品能力保留 |
|
||||
| 大鱼吃小鱼 | 否 | 是 | 功能仍保留,不在新建作品入口展示 |
|
||||
| 拼图 | 是 | 是 | 点击后进入拼图 Agent 共创工作台 |
|
||||
| 拼图 | 是 | 是 | 创作 Tab 默认选中并内嵌展示拼图创作表单,提交后进入拼图草稿生成 |
|
||||
| 抓大鹅 | 否 | 是 | 暂时从创作端入口下线,既有链路与作品能力保留 |
|
||||
| 方洞挑战 | 是 | 是 | 点击后进入方洞挑战 Agent 共创工作台,支持草稿、结果页、发布、试玩、作品架与广场 |
|
||||
| AIRP | 是 | 否 | 保留入口,显示敬请期待 |
|
||||
| 视觉小说 | 是 | 否 | 保留入口,显示敬请期待 |
|
||||
| 视觉小说 | 是 | 是 | 点击后进入视觉小说创作工作台 |
|
||||
| 智能创作 | 否 | 是 | 入口隐藏,既有 `creative-agent` 链路保留 |
|
||||
|
||||
## 验收
|
||||
|
||||
1. 修改 `src/config/newWorkEntryConfig.ts` 后,创作中心顶部卡带和平台创作类型弹层应同步变化。
|
||||
1. 修改 `src/config/newWorkEntryConfig.ts` 后,创作 Tab 模板入口、创作中心顶部卡带和平台创作类型弹层应同步变化。
|
||||
2. 隐藏玩法不触发入口预加载,也不出现在新建作品入口中。
|
||||
3. 未开放玩法点击态保持禁用,不应进入鉴权或创建会话链路。
|
||||
4. 已开放玩法点击后必须进入对应创建链路;若用户未登录,先走登录保护。
|
||||
5. 方洞挑战作品发布后应生成 `SH-` 作品号,并能从作品架、广场详情和试玩 runtime 回到同一作品详情。
|
||||
5. 创作 Tab 首屏应显示“10分钟创作一个精品互动玩法”,并默认展示拼图创作表单。
|
||||
6. 智能创作入口隐藏后,不应出现“Hi, 朋友”“问一问百梦”或“一句话生成闪应用”等旧首页入口。
|
||||
7. 方洞挑战作品发布后应生成 `SH-` 作品号,并能从作品架、广场详情和试玩 runtime 回到同一作品详情。
|
||||
|
||||
@@ -408,7 +408,7 @@ WASM_SOURCE="${CARGO_TARGET_DIR}/wasm32-unknown-unknown/release/spacetime_module
|
||||
并发与清理规则:
|
||||
|
||||
- 同一个 Rust 构建 Job 建议使用 `disableConcurrentBuilds()`,避免同一组件的多个 release 构建同时写入同一最终产物路径。
|
||||
- 如果 Linux agent 未安装 `sccache`,应先运行 `Genarrative-Server-Provision` 补齐缓存工具;Rust 构建流水线仍必须自动取消 `RUSTC_WRAPPER`,回退到直接使用 `rustc`,不能因为缺少可选缓存工具阻断真实构建。
|
||||
- 如果 Linux/Windows agent 未安装 `sccache`,或 `sccache --version` 无法实际执行,应先补齐缓存工具;Rust 构建流水线仍必须自动取消 `RUSTC_WRAPPER`,回退到直接使用 `rustc`,不能因为缺少可选缓存工具阻断真实构建。
|
||||
- 生产发布流水线只能消费 `build/<version>/` 或 Jenkins 归档产物,不允许从共享 `cargo-target` 目录直接发布。
|
||||
- `SCCACHE_CACHE_SIZE` 必须设置上限,避免编译缓存无限增长。
|
||||
- 对 `/var/cache/genarrative-build/*/cargo-target` 或数据盘对应目录配置定期清理,建议保留最近 14 到 30 天。
|
||||
|
||||
@@ -2,44 +2,53 @@
|
||||
|
||||
## 背景
|
||||
|
||||
拼图创作入口已经从对话式 Agent 收口为填表式表单。本次改版目标是让“点击拼图创作”后的表单更接近图像创作工具的单屏体验:先选创作模板,再补充提示词,最后直接生成首关草稿与首张拼图图。
|
||||
拼图创作入口已经从对话式 Agent 收口为填表式表单。本次改版目标是让“点击拼图创作”后的表单更接近图像创作工具的单屏体验:优先上传参考图或填写画面描述,然后直接生成首关草稿与首张拼图图。2026-05-07 起,入口表单删除 Template 模块,模板参考图只保留为历史资产,不再作为表单首屏交互。
|
||||
|
||||
## 落地范围
|
||||
|
||||
1. `src/components/puzzle-agent/PuzzleAgentWorkspace.tsx`
|
||||
- 改为顶部标题、模板横滑区、大输入框、底部操作区的布局。
|
||||
- 改为顶部标题、超大参考图上传区、大输入框、底部操作区的布局。
|
||||
- 保留参考图上传、模型切换和生成草稿。
|
||||
- 删除 Template 模块与模板卡切换入口。
|
||||
- 不再提供输入框底部的 `try` 示例入口。
|
||||
2. `src/components/puzzle-agent/puzzleCreationTemplates.ts`
|
||||
- 新增拼图创作模板数据。
|
||||
- 模板来源按社交、热点、职场学习、电商、治愈、营销、儿童教育等场景抽样。
|
||||
- 点击模板后把模板提示词写入画面描述。
|
||||
- 保留历史拼图创作模板数据,当前表单不再消费。
|
||||
- 后续若重新开放模板入口,必须先更新本文档和移动端首屏验收。
|
||||
3. `public/puzzle-creation-templates/`
|
||||
- 存放模板样例图。
|
||||
- 样例图只用于创作模板缩略图,不作为正式拼图作品资产。
|
||||
4. `.codex/skills/gpt-image-2-apimart/`
|
||||
- 存放历史模板样例图。
|
||||
- 样例图不作为正式拼图作品资产,当前也不再出现在拼图入口表单。
|
||||
4. `public/creation-type-references/`
|
||||
- 存放平台创作入口和玩法类型弹层的参考图。
|
||||
- 每个玩法一个参考图,首版用于视觉识别,不承载规则说明。
|
||||
- 当前创作 Tab 顶部玩法卡带必须直接渲染这些图片,避免参考图只出现在隐藏弹层里。
|
||||
5. `.codex/skills/gpt-image-2-apimart/`
|
||||
- 封装仓库内 `gpt-image-2` 的 APIMart OpenAI 兼容调用流程。
|
||||
- Skill 默认读取本地环境变量,不把密钥写入代码、文档或前端。
|
||||
|
||||
## UI 规则
|
||||
|
||||
1. 顶部只展示“创建拼图”和轻量状态标识,不写玩法规则说明。
|
||||
2. 模板区横向滚动,移动端优先;每个模板卡包含样例图、短标题和选中态。
|
||||
3. 点击模板时:
|
||||
- 立即选中该模板。
|
||||
- 如果输入框为空,直接填入模板提示词。
|
||||
- 如果输入框已有内容,替换为该模板提示词,避免追加后变得冗长。
|
||||
1. 顶部主标题展示“想做个什么玩法?”和轻量状态标识,不写玩法规则说明。
|
||||
2. 上传拼图图片区优先占据首屏左侧/上方的大块区域,移动端也必须完整露出。
|
||||
- 上传区自身就是图片卡片,不再额外封装为 `platform-subpanel` 模块壳。
|
||||
- 亮色主题下上传卡片必须使用白色或暖浅色卡面,不得显示整块黑色底。
|
||||
- 上传卡片固定为 1:1 正方形,避免拼图主画面在首屏出现非正方形预期。
|
||||
- 上传卡片底部不再叠加文件名 bar;卡片下方只保留 `点击上传拼图图片` 纯文字入口。
|
||||
- 上传卡片上方固定展示 `拼图画面` 标题。
|
||||
- 叠在上传卡片上的 `AI重绘` 和图标必须和卡面保持足够对比,避免浅色主题重映射后不可读。
|
||||
3. 画面描述输入框高度约为旧版大输入框的 1/2,避免移动端把上传参考图和提交区挤出首屏。
|
||||
4. 输入区保留:
|
||||
- 参考图上传按钮。
|
||||
- 上传拼图图片按钮。
|
||||
- 图片模型切换按钮。
|
||||
5. 输入区不保留:
|
||||
- `try` 文本。
|
||||
- 示例 prompt chip。
|
||||
- 画面描述输入框默认提示词或占位示例。
|
||||
- 玩法规则说明。
|
||||
- Template 模块和模板卡切换。
|
||||
|
||||
## 模板抽样
|
||||
## 历史模板抽样
|
||||
|
||||
首批模板不追求覆盖图二所有条目,而是选择高频且适合拼图主图的代表项:
|
||||
以下模板曾用于表单 Template 模块。2026-05-07 后入口表单不再展示这些模板,列表仅作为历史资产索引:
|
||||
|
||||
1. 情侣合照拼图
|
||||
2. 家庭纪念拼图
|
||||
@@ -76,12 +85,45 @@ n = 1
|
||||
|
||||
本次 Skill 只封装生成样例图和研发复用流程,不改变正式后端接口、扣费、OSS、SpacetimeDB 写入和发布链路。
|
||||
|
||||
## 2026-05-07 AI 重绘与上传直用
|
||||
|
||||
拼图入口上传区右上角新增 `AI重绘` 开关,默认打开;未上传拼图图片前不显示开关,上传成功后才显示。
|
||||
|
||||
1. `AI重绘=true`
|
||||
- 上传区文案为 `点击上传拼图图片`,上传图作为生图参考图。
|
||||
- 未上传图片时,输入框标题为 `画面描述`。
|
||||
- 已上传图片时,输入框标题为 `画面AI重绘要求(提示词)`。
|
||||
- 展示图片模型切换。
|
||||
- `compile_puzzle_draft` 携带 `aiRedraw: true`,继续走 APIMart 生图与 `PUZZLE_IMAGE_GENERATION_POINTS_COST = 2` 扣费链路。
|
||||
- 生成按钮展示 `消耗2光点`。
|
||||
2. `AI重绘=false`
|
||||
- 隐藏画面描述输入框和模型切换。
|
||||
- 必须上传拼图图片,按钮不展示 `消耗2光点`。
|
||||
- `compile_puzzle_draft` 携带 `aiRedraw: false`,后端只编译草稿和生成首关名,不调用 APIMart,不进入光点扣费 wrapper。
|
||||
- 后端把上传图片 Data URL 按拼图资产路径持久化,构造 `sourceType=uploaded` 的候选图并直接选为第一关正式图。
|
||||
3. 上传裁剪
|
||||
- 前端读取上传图原始宽高。
|
||||
- 非 1:1 图片必须先弹出正方形裁剪工具,裁剪完成后再进入表单状态和提交 payload。
|
||||
- 裁剪输出仍按参考图体积预算压缩,避免上传图撑爆 JSON body。
|
||||
|
||||
契约字段同步:
|
||||
|
||||
```ts
|
||||
CreatePuzzleAgentSessionRequest.aiRedraw?: boolean
|
||||
PuzzleAgentActionRequest.compile_puzzle_draft.aiRedraw?: boolean
|
||||
```
|
||||
|
||||
Rust 共享契约使用 `ai_redraw: Option<bool>` 并按 camelCase 序列化为 `aiRedraw`。
|
||||
|
||||
## 验收
|
||||
|
||||
1. 点击拼图创作后,表单首屏呈现模板横滑区和大输入框。
|
||||
2. 点击任一模板后,输入框填入该模板提示词。
|
||||
3. 输入框里没有 `try` 示例功能。
|
||||
4. 图片模型切换仍可打开并选择 `gpt-image-2` / `nanobanana2`。
|
||||
5. 模板样例图文件存在,并能在创作表单缩略图中显示。
|
||||
6. gpt-image-2 Skill 校验通过,且脚本 dry-run 能输出计划请求而不泄露密钥。
|
||||
7. `npm run check:encoding` 通过。
|
||||
1. 点击拼图创作后,表单首屏呈现大参考图区和半高文本输入框。
|
||||
2. 输入框里没有 `try` 示例功能。
|
||||
3. 图片模型切换仍可打开并选择 `gpt-image-2` / `nanobanana2`。
|
||||
4. 历史模板样例图文件可保留,但不出现在拼图入口表单。
|
||||
5. 当前创作 Tab 顶部的拼图、方洞挑战、视觉小说和 AIRP 卡片能看到对应 `creation-type-references` 图片。
|
||||
6. 默认 `AI重绘` 打开时,无图状态展示 `画面描述` 与 `消耗2光点`;上传图片后输入框标题改为 `画面AI重绘要求(提示词)`。
|
||||
7. 关闭 `AI重绘` 后隐藏画面描述输入框,生成按钮不展示 `消耗2光点`,后端直接应用上传图片为第一关图片。
|
||||
8. 上传非 1:1 图片时必须先完成正方形裁剪。
|
||||
9. gpt-image-2 Skill 校验通过,且脚本 dry-run 能输出计划请求而不泄露密钥。
|
||||
10. `npm run check:encoding` 通过。
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
|
||||
- [RUST_WORKSPACE_DEPENDENCY_CONSOLIDATION_2026-05-07.md](./RUST_WORKSPACE_DEPENDENCY_CONSOLIDATION_2026-05-07.md):记录 `server-rs` Cargo 依赖集中配置口径,第三方版本和 workspace 内部 crate path 统一维护在根 `server-rs/Cargo.toml`,成员 crate 只保留 feature/optional 差异。
|
||||
- [API_SERVER_EXTERNAL_SERVICE_ENV_CONFIG_2026-05-07.md](./API_SERVER_EXTERNAL_SERVICE_ENV_CONFIG_2026-05-07.md):冻结 api-server 外部服务配置边界,公共服务 URL 可保留代码默认值,非公共模型名和私有网关 URL 统一通过环境变量注入。
|
||||
- [CREATIVE_INTERACTIVE_CONTENT_AGENT_TECHNICAL_SOLUTION_2026-05-05.md](./CREATIVE_INTERACTIVE_CONTENT_AGENT_TECHNICAL_SOLUTION_2026-05-05.md):冻结基于 LangChain-Rust 的创意互动内容生成 Agent 技术方案,明确首版只支持拼图模板、必须显式展示模板选择和积分范围,通过拼图模块 Tool/模板协议填充同一份草稿字段,支持单关卡与多关卡图片生成、立即试玩、表单化编辑和 Agent 自然语言修订草稿字段。
|
||||
- [VISUAL_NOVEL_PROMPT_AND_LLM_TOOLS_VN03_2026-05-05.md](./VISUAL_NOVEL_PROMPT_AND_LLM_TOOLS_VN03_2026-05-05.md):记录视觉小说模板 `VN-03` Prompt / LLM 工具落地,包含创作底稿 Prompt、运行时 GM Prompt、repair Prompt、工具参数 schema、Responses 请求口径和定向验证结果。
|
||||
- [VISUAL_NOVEL_IMPLEMENTATION_HANDOFF_2026-05-07.md](./VISUAL_NOVEL_IMPLEMENTATION_HANDOFF_2026-05-07.md):记录视觉小说模板 `VN-13` 实现收口、当前正式入口、表目录、路由、作品 / 运行 / 资产和负向扫描口径。
|
||||
- [PROFILE_TASK_AND_TRACKING_SYSTEM_2026-05-03.md](./PROFILE_TASK_AND_TRACKING_SYSTEM_2026-05-03.md):冻结个人任务与埋点系统首版方案,明确 `tracking_event`、`tracking_daily_stat`、`profile_task_config`、任务进度、领奖记录和光点钱包流水的边界。
|
||||
- [SQUARE_HOLE_IMAGE_SLOT_AND_RUNTIME_INTERACTION_FIX_2026-05-06.md](./SQUARE_HOLE_IMAGE_SLOT_AND_RUNTIME_INTERACTION_FIX_2026-05-06.md):记录方洞挑战结果页图片槽位局部生成、洞口图历史素材、运行态拖拽与点击投放交互的修正口径。
|
||||
- [MAINCLOUD_REFERENCE_REMOVAL_POLICY_2026-05-06.md](./MAINCLOUD_REFERENCE_REMOVAL_POLICY_2026-05-06.md):冻结 Maincloud 历史残留引用禁用策略,明确后续不得新增、运行或引用 `api-server:maincloud`、`GENARRATIVE_SPACETIME_MAINCLOUD_*` 和相关测试/文档口径。
|
||||
@@ -87,6 +90,7 @@
|
||||
- [PUZZLE_IMAGE_AND_FRONTEND_RULES_ALIGNMENT_2026-04-29.md](./PUZZLE_IMAGE_AND_FRONTEND_RULES_ALIGNMENT_2026-04-29.md):记录拼图生成图片回到 1:1,运行时拖动、交换、合并与拆分由前端即时裁决,以及移动端棋盘贴近屏幕边缘的落地边界。
|
||||
- [PUZZLE_FORM_CREATION_FLOW_2026-04-29.md](./PUZZLE_FORM_CREATION_FLOW_2026-04-29.md):冻结拼图填表式创作入口、初始表单自动保存草稿、生成前退出后的表单恢复,以及草稿编译/首图生成的前后端边界。
|
||||
- [PUZZLE_PICTURE_ONLY_CREATION_AND_AI_TAGS_2026-05-03.md](./PUZZLE_PICTURE_ONLY_CREATION_AND_AI_TAGS_2026-05-03.md):记录拼图入口只填写画面描述、首关名默认作品名、作品描述和标签初始为空、AI 生成 6 个作品标签以及发布前校验的落地规则。
|
||||
- [PUZZLE_TEMPLATE_FORM_AND_GPT_IMAGE_SKILL_2026-05-03.md](./PUZZLE_TEMPLATE_FORM_AND_GPT_IMAGE_SKILL_2026-05-03.md):记录拼图入口模板样例图与 gpt-image-2 Skill 约定,2026-05-07 起表单不再展示 Template 模块,改为大参考图区 + 大输入框的单屏布局。
|
||||
- [PUZZLE_LEADERBOARD_FRONTEND_LEVEL_AND_RPG_COMING_SOON_2026-04-30.md](./PUZZLE_LEADERBOARD_FRONTEND_LEVEL_AND_RPG_COMING_SOON_2026-04-30.md):记录拼图第二关排行榜提交以前端当前关卡为准、不被 SpacetimeDB 旧 run 快照误杀,以及 RPG 创作入口改为敬请期待的落地边界。
|
||||
- [PUZZLE_NEXT_LEVEL_AND_SIMILAR_WORK_HANDOFF_2026-04-30.md](./PUZZLE_NEXT_LEVEL_AND_SIMILAR_WORK_HANDOFF_2026-04-30.md):记录拼图通关后优先同作品下一关、无下一关时按 RPG/build 标签语义相似度返回三个候选作品,并在跨作品时只切换到候选作品第 1 张图、运行时关卡序号继续累进的落地规则。
|
||||
- [PUZZLE_FAILURE_EXTENSION_AND_SAVE_ARCHIVE_2026-05-01.md](./PUZZLE_FAILURE_EXTENSION_AND_SAVE_ARCHIVE_2026-05-01.md):记录拼图失败后重新开始/付费续时,以及进入作品与过关后同步存档页投影的落地规则。
|
||||
@@ -261,7 +265,7 @@
|
||||
- [CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md#93-工作包-c前端结果页与编辑器拆分](./CREATION_FLOW_CHAIN_REFACTOR_EXECUTION_PLAN_2026-04-21.md#93-%E5%B7%A5%E4%BD%9C%E5%8C%85-c%E5%89%8D%E7%AB%AF%E7%BB%93%E6%9E%9C%E9%A1%B5%E4%B8%8E%E7%BC%96%E8%BE%91%E5%99%A8%E6%8B%86%E5%88%86):记录工作包 C 已完成的结果页壳层拆分、编辑器目标分发与 mapper 收口、角色资产工坊 section/workflow 拆分,以及仍保留的阶段性 shared 实现边界。
|
||||
- [CREATION_PAGE_MOBILE_UI_FIX_2026-04-21.md](./CREATION_PAGE_MOBILE_UI_FIX_2026-04-21.md):创作页移动端底部 Tab、亮色主题 token 与滚动权责修复记录。
|
||||
- [RPG_FOUNDATION_DRAFT_EIGHT_ANCHOR_SEED_FIX_2026-04-25.md](./RPG_FOUNDATION_DRAFT_EIGHT_ANCHOR_SEED_FIX_2026-04-25.md):记录 RPG 创作 Agent session 八锚点进入 foundation draft seed 时被旧字段压缩的根因、修复和后续约束。
|
||||
- [TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md](./TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md):把外部仓库 TXT 模式完整迁入当前项目的冻结边界、模块映射、分阶段计划与验收清单。
|
||||
- [TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md](./TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md):旧 TXT 模式迁移方案的历史参考;视觉小说模板最新落地口径以 PRD [`AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md`](../prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md) 为准,不再按外部平台工程完整迁入执行。
|
||||
- [AI_CHARACTER_ANIMATION_TECHNICAL_SOLUTION_2026-04-04.md](./AI_CHARACTER_ANIMATION_TECHNICAL_SOLUTION_2026-04-04.md):AI 生成角色形象与角色动画的技术路线。
|
||||
- [ALIYUN_NPC_IMAGE_ANIMATION_EXPERIMENT_2026-04-07.md](./ALIYUN_NPC_IMAGE_ANIMATION_EXPERIMENT_2026-04-07.md):面向编辑器的阿里云 NPC 形象与动作实验方案,按 4 条生成链路对比。
|
||||
- [PIXELMOTION_TECHNICAL_BREAKDOWN_2026-04-04.md](./PIXELMOTION_TECHNICAL_BREAKDOWN_2026-04-04.md):PixelMotion 产品形态与能力拆解。
|
||||
|
||||
@@ -30,6 +30,7 @@ spacetime sql <db> "SELECT * FROM custom_world_gallery_entry"
|
||||
| 拼图 | `puzzle_agent_session`, `puzzle_agent_message`, `puzzle_work_profile`, `puzzle_event`, `puzzle_runtime_run`, `puzzle_leaderboard_entry` |
|
||||
| 抓大鹅 Match3D | `match3d_agent_session`, `match3d_agent_message`, `match3d_work_profile`, `match3d_runtime_run` |
|
||||
| 方洞挑战 | `square_hole_agent_session`, `square_hole_agent_message`, `square_hole_work_profile`, `square_hole_runtime_run` |
|
||||
| 视觉小说 | `visual_novel_agent_session`, `visual_novel_agent_message`, `visual_novel_work_profile`, `visual_novel_runtime_run`, `visual_novel_runtime_history_entry`, `visual_novel_runtime_event` |
|
||||
| 大鱼吃小鱼 | `big_fish_creation_session`, `big_fish_agent_message`, `big_fish_asset_slot`, `big_fish_event`, `big_fish_runtime_run` |
|
||||
| 资产 | `asset_object`, `asset_entity_binding`, `asset_event` |
|
||||
| AI 任务 | `ai_task`, `ai_task_stage`, `ai_text_chunk`, `ai_result_reference`, `ai_task_event` |
|
||||
@@ -717,6 +718,78 @@ SELECT * FROM square_hole_runtime_run WHERE owner_user_id = '<user_id>' ORDER BY
|
||||
SELECT * FROM square_hole_runtime_run WHERE profile_id = '<profile_id>';
|
||||
```
|
||||
|
||||
## 视觉小说表
|
||||
|
||||
> VN-13 复核:当前视觉小说首版只保留本节 6 张表;`visual_novel_runtime_history_entry` 和 `visual_novel_runtime_event` 均不得扩展成回放数据源。维护入口见 [视觉小说模板实现收口与交接说明](./VISUAL_NOVEL_IMPLEMENTATION_HANDOFF_2026-05-07.md)。
|
||||
|
||||
### `visual_novel_agent_session`
|
||||
|
||||
- 作用:视觉小说创作 Agent 会话主表,保存创建起点、源资产、当前阶段、底稿 JSON、待执行 action 和发布 profile 指针。
|
||||
- 结构:`session_id PK: String`, `owner_user_id: String`, `source_mode: String`, `status: String`, `seed_text: String`, `source_asset_ids_json: String`, `current_turn: u32`, `progress_percent: u32`, `draft_json: String`, `pending_action_json: String`, `last_assistant_reply: String`, `published_profile_id: String`, `created_at: Timestamp`, `updated_at: Timestamp`。
|
||||
- 索引:`owner_user_id`。
|
||||
|
||||
```sql
|
||||
SELECT * FROM visual_novel_agent_session WHERE session_id = '<session_id>';
|
||||
SELECT * FROM visual_novel_agent_session WHERE owner_user_id = '<user_id>' ORDER BY updated_at DESC;
|
||||
```
|
||||
|
||||
### `visual_novel_agent_message`
|
||||
|
||||
- 作用:视觉小说创作 Agent 消息流水,保存用户输入和模型回复。
|
||||
- 结构:`message_id PK: String`, `session_id: String`, `role: String`, `kind: String`, `text: String`, `created_at: Timestamp`。
|
||||
- 索引:`session_id`。
|
||||
|
||||
```sql
|
||||
SELECT * FROM visual_novel_agent_message WHERE session_id = '<session_id>' ORDER BY created_at ASC;
|
||||
```
|
||||
|
||||
### `visual_novel_work_profile`
|
||||
|
||||
- 作用:视觉小说作品草稿 / 发布 profile 表,保存平台作品摘要字段、源资产引用、完整 `VisualNovelResultDraft` JSON、发布状态和游玩次数。
|
||||
- 结构:`profile_id PK: String`, `work_id: String`, `owner_user_id: String`, `source_session_id: String`, `author_display_name: String`, `work_title: String`, `work_description: String`, `tags_json: String`, `cover_image_src: String`, `source_asset_ids_json: String`, `draft_json: String`, `publication_status: String`, `publish_ready: bool`, `play_count: u32`, `created_at: Timestamp`, `updated_at: Timestamp`, `published_at: Option<Timestamp>`。
|
||||
- 索引:`owner_user_id`, `publication_status`。
|
||||
|
||||
```sql
|
||||
SELECT * FROM visual_novel_work_profile WHERE profile_id = '<profile_id>';
|
||||
SELECT * FROM visual_novel_work_profile WHERE owner_user_id = '<user_id>' ORDER BY updated_at DESC;
|
||||
SELECT * FROM visual_novel_work_profile WHERE publication_status = 'published';
|
||||
```
|
||||
|
||||
### `visual_novel_runtime_run`
|
||||
|
||||
- 作用:视觉小说测试或正式运行态表,保存当前场景、阶段、可见角色、旗标、指标、可选项和运行快照 JSON。
|
||||
- 结构:`run_id PK: String`, `owner_user_id: String`, `profile_id: String`, `mode: String`, `status: String`, `current_scene_id: String`, `current_phase_id: String`, `visible_character_ids_json: String`, `flags_json: String`, `metrics_json: String`, `available_choices_json: String`, `text_mode_enabled: bool`, `snapshot_json: String`, `created_at: Timestamp`, `updated_at: Timestamp`。
|
||||
- 索引:`owner_user_id`, `profile_id`。
|
||||
|
||||
```sql
|
||||
SELECT * FROM visual_novel_runtime_run WHERE run_id = '<run_id>';
|
||||
SELECT * FROM visual_novel_runtime_run WHERE owner_user_id = '<user_id>' ORDER BY updated_at DESC;
|
||||
SELECT * FROM visual_novel_runtime_run WHERE profile_id = '<profile_id>';
|
||||
```
|
||||
|
||||
### `visual_novel_runtime_history_entry`
|
||||
|
||||
- 作用:视觉小说运行时历史表,保存每轮玩家 / 模型 / 系统事实、step JSON 和快照哈希,用于继续体验与历史重生成边界;不是回放表。
|
||||
- 结构:`entry_id PK: String`, `run_id: String`, `owner_user_id: String`, `profile_id: String`, `turn_index: u32`, `source: String`, `action_text: String`, `steps_json: String`, `snapshot_before_hash: String`, `snapshot_after_hash: String`, `created_at: Timestamp`。
|
||||
- 索引:`run_id`, `owner_user_id`。
|
||||
|
||||
```sql
|
||||
SELECT * FROM visual_novel_runtime_history_entry WHERE run_id = '<run_id>' ORDER BY turn_index ASC;
|
||||
SELECT * FROM visual_novel_runtime_history_entry WHERE owner_user_id = '<user_id>' ORDER BY created_at DESC;
|
||||
```
|
||||
|
||||
### `visual_novel_runtime_event`
|
||||
|
||||
- 作用:视觉小说运行时审计事件表,用于订阅端、BFF 或排障流程感知 run 事实;该表明确不是 replay、分享回放或片段回放数据源。
|
||||
- 可见性:`public event`。
|
||||
- 结构:`event_id PK: String`, `run_id: String`, `owner_user_id: String`, `profile_id: String`, `event_kind: String`, `client_event_id: String`, `history_entry_id: String`, `payload_json: String`, `occurred_at: Timestamp`。
|
||||
- 索引:`run_id`, `owner_user_id`。
|
||||
|
||||
```sql
|
||||
SELECT * FROM visual_novel_runtime_event WHERE run_id = '<run_id>' ORDER BY occurred_at ASC;
|
||||
SELECT * FROM visual_novel_runtime_event WHERE owner_user_id = '<user_id>' ORDER BY occurred_at DESC;
|
||||
```
|
||||
|
||||
## 大鱼吃小鱼表
|
||||
|
||||
### `big_fish_creation_session`
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
更新时间:`2026-04-20`
|
||||
|
||||
> 2026-05-05 更新口径:本文保留为历史迁移参考。视觉小说模板后续落地以 [`../prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md`](../prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md) 为准;冲突时不再迁入外部平台工程、不使用 `server-node` 作为新功能落点、不保留回放,统一接入 Genarrative `server-rs + Axum + SpacetimeDB` 与平台接口。
|
||||
|
||||
## 0. 文档目的
|
||||
|
||||
这份执行方案用于指导 `Genarrative` 在**不改动外部 TXT 模式提示词正文、不改动外部 TXT 模式功能需求**的前提下,把下面两个仓库中已经跑通的 TXT 模式创作流程与运行机制完整迁入当前项目:
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
# 视觉小说模板实现收口与交接说明 2026-05-07
|
||||
|
||||
## 1. 范围
|
||||
|
||||
本文记录 `AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md` 的 `VN-13` 收口结果,作为视觉小说模板后续维护的一页式入口。
|
||||
|
||||
本文只总结当前已经落地且需要长期遵守的实现边界,不再把视觉小说描述成外部 TXT 平台迁移,也不重复旧迁移方案里的临时讨论。
|
||||
|
||||
## 2. 当前正式入口
|
||||
|
||||
后续维护时优先看这些文档:
|
||||
|
||||
1. [AI 原生视觉小说模板 PRD](../prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md)
|
||||
2. [SpacetimeDB 表说明与查询目录](./SPACETIMEDB_TABLE_CATALOG.md)
|
||||
3. [视觉小说 VN-03 Prompt 与 LLM 工具实现说明](./VISUAL_NOVEL_PROMPT_AND_LLM_TOOLS_VN03_2026-05-05.md)
|
||||
4. [视觉小说 VN-11 负向扫描报告](../audits/VN11_NEGATIVE_SCAN_REPORT_2026-05-07.md)
|
||||
5. [视觉小说模板交接与维护经验](../experience/VISUAL_NOVEL_HANDOFF_AND_MAINTENANCE_2026-05-07.md)
|
||||
|
||||
旧的 `TXT_MODE_VISUAL_NOVEL_MIGRATION_EXECUTION_PLAN_2026-04-20.md` 只保留历史参考意义,不再作为实现口径。
|
||||
|
||||
## 3. 已收口的实现边界
|
||||
|
||||
### 3.1 创作链路
|
||||
|
||||
- 创作链统一走 `/api/creation/visual-novel/*`。
|
||||
- 入口、工作台、结果页和服务端 prompt 已围绕 `visual-novel` 模板闭环对齐。
|
||||
- `VisualNovelResultDraft`、`VisualNovelCreationSessionSnapshot` 等共享契约已经成型。
|
||||
|
||||
### 3.2 运行链路
|
||||
|
||||
- 运行链统一走 `/api/runtime/visual-novel/*`。
|
||||
- 运行时只认 typed step 和快照,不让前端从 `raw_text` 猜业务真相。
|
||||
- `visual_novel_runtime_history_entry` 只用于继续体验和历史重生成边界,不是回放表。
|
||||
|
||||
### 3.3 数据链路
|
||||
|
||||
- SpacetimeDB 首版只保留 6 张视觉小说表。
|
||||
- `visual_novel_runtime_event` 是 `public event` 审计事件表,不是 replay 数据源。
|
||||
- 表结构变化必须同步 `migration.rs`、`SPACETIMEDB_TABLE_CATALOG.md` 和 Rust bindings。
|
||||
|
||||
### 3.4 作品与发布
|
||||
|
||||
- 作品架、广场和分享都复用平台现有链路。
|
||||
- 公开作品码统一使用 `VN-` 前缀。
|
||||
- 发布后要刷新作品架和公开聚合。
|
||||
|
||||
### 3.5 资产与登录态
|
||||
|
||||
- 文档、封面、背景、角色和音乐都只保留平台资产对象引用。
|
||||
- 不保存大 Data URL、不走独立对象存储、不新增视觉小说私有存档系统。
|
||||
- 退出登录时要清空视觉小说私有 session、work、run 和错误状态。
|
||||
|
||||
## 4. 长期维护规则
|
||||
|
||||
1. 看到视觉小说相关改动,先确认是不是契约改动;如果是,先同步 TS / Rust shared contracts。
|
||||
2. 看到表结构改动,先同步 `migration.rs` 和表目录,再补 bindings。
|
||||
3. 看到资产链路改动,只改平台资产引用,不回退到本地路径或二进制直存。
|
||||
4. 看到运行时历史改动,只维护 typed history 和审计事件,不把它改成回放能力。
|
||||
5. 看到旧 TXT 文档时,只把它当历史来源,不把其中的平台工程目标重新带回实现。
|
||||
|
||||
## 5. 验证口径
|
||||
|
||||
收口后建议按下面顺序检查:
|
||||
|
||||
```bash
|
||||
npm run check:encoding
|
||||
npm run check:visual-novel-vn11
|
||||
npm run typecheck
|
||||
|
||||
cd server-rs
|
||||
cargo test -p shared-contracts
|
||||
cargo test -p module-visual-novel
|
||||
cargo check -p api-server
|
||||
```
|
||||
|
||||
如果本轮没有改代码,只要编码检查和负向扫描通过,通常就说明 VN-13 的文档收口已经站稳。
|
||||
@@ -0,0 +1,111 @@
|
||||
# 视觉小说 VN-03 Prompt 与 LLM 工具实现说明
|
||||
|
||||
日期:`2026-05-05`
|
||||
|
||||
## 1. 范围
|
||||
|
||||
本文记录 `AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md` 中 `VN-03` 的工程落地口径。
|
||||
|
||||
本次只实现视觉小说模板的 Prompt / LLM 工具层:
|
||||
|
||||
1. 创作底稿生成 Prompt,目标输出 `VisualNovelResultDraft`。
|
||||
2. 运行时 GM Prompt,目标输出 `VisualNovelRuntimeStep[]`。
|
||||
3. 结构化 repair Prompt,用于解析失败后的后端修复。
|
||||
4. 创作 action 与图片生成 action 的工具参数 schema。
|
||||
5. `platform-llm` Responses 请求构造口径。
|
||||
|
||||
本次不保存数据、不新增 HTTP 路由、不写前端 UI、不触碰 SpacetimeDB schema。
|
||||
|
||||
## 2. 代码落点
|
||||
|
||||
主要实现位于:
|
||||
|
||||
1. `server-rs/crates/api-server/src/prompt/visual_novel.rs`
|
||||
2. `server-rs/crates/api-server/src/prompt/mod.rs`
|
||||
|
||||
为了让当前工作树中已有的 creative-agent / puzzle 并行改动可继续编译,本次还补了两个编译闭口:
|
||||
|
||||
1. `server-rs/crates/module-puzzle/Cargo.toml` 增加 `serde_json = "1"`。
|
||||
2. `server-rs/crates/platform-agent/src/puzzle_phase1_agent.rs` 给 `MockLangChainRustAgentExecutor` 补 `Debug` 派生。
|
||||
|
||||
## 3. Prompt 约束
|
||||
|
||||
### 3.1 创作底稿
|
||||
|
||||
创作系统 Prompt 明确要求:
|
||||
|
||||
1. 只输出一个 JSON 对象。
|
||||
2. 内容必须是中文视觉小说底稿。
|
||||
3. 补齐世界观、玩家身份、角色、场景、剧情阶段和开场。
|
||||
4. 角色必须有可生成立绘的 `appearance`。
|
||||
5. 场景必须有可生成背景图的 `description`。
|
||||
6. 不输出回放、商城、会员、后台、平台活动、促销、订单或独立账号字段。
|
||||
7. 不生成第二套存档、发布、钱包、广场或资产系统。
|
||||
|
||||
### 3.2 运行时 GM
|
||||
|
||||
运行时系统 Prompt 明确要求:
|
||||
|
||||
1. 只输出 `VisualNovelRuntimeStep[]` JSON 数组。
|
||||
2. step 数量不超过输入的 `maxAssistantStepCountPerTurn`。
|
||||
3. 场景变化必须输出 `scene_change`。
|
||||
4. 旁白、对白、转场、选项、flag、metric 分别使用契约内 step 类型。
|
||||
5. 前端不得从 `raw_text` 猜业务 step。
|
||||
6. 不输出回放、录制、商城、会员、后台、平台活动或独立存档元数据。
|
||||
|
||||
### 3.3 Repair
|
||||
|
||||
repair Prompt 只负责把坏格式修成目标 JSON:
|
||||
|
||||
1. `VisualNovelResultDraft`
|
||||
2. `VisualNovelRuntimeStep[]`
|
||||
|
||||
repair 仍失败时,由后续 `VN-05` API 接入层返回可重试错误。
|
||||
|
||||
## 4. LLM 请求口径
|
||||
|
||||
视觉小说创作、运行和 repair 请求统一使用 `platform-llm`:
|
||||
|
||||
1. model:`CREATION_TEMPLATE_LLM_MODEL`,当前为 `deepseek-v3-2-251201`。
|
||||
2. protocol:`LlmTextProtocol::Responses`。
|
||||
3. 创作底稿请求可按 API 配置开启 web search。
|
||||
4. 运行时 GM 与 repair 默认不开 web search,避免运行态引入外部噪声。
|
||||
|
||||
## 5. 工具参数
|
||||
|
||||
本次定义两个工具描述:
|
||||
|
||||
1. `visual_novel_apply_creation_action`
|
||||
- 支持 `generate_draft`、`patch_world`、`patch_character`、`patch_scene`、`patch_story_phase`、`compile_work_profile`。
|
||||
- 只写回视觉小说底稿或编译平台 work profile 草稿。
|
||||
2. `visual_novel_generate_image_asset`
|
||||
- 支持 `generate_scene_image`、`generate_character_image`。
|
||||
- 输出应接后续平台资产引用,不保存二进制或大 Data URL。
|
||||
|
||||
工具 schema 不包含 replay / Replay 字段。
|
||||
|
||||
## 6. 验证结果
|
||||
|
||||
已执行:
|
||||
|
||||
```bash
|
||||
cargo test -p shared-contracts visual_novel --manifest-path server-rs/Cargo.toml
|
||||
cargo test -p module-puzzle creative_tools --manifest-path server-rs/Cargo.toml
|
||||
cargo test -p platform-agent puzzle_phase1_agent --manifest-path server-rs/Cargo.toml
|
||||
cargo test -p api-server prompt::visual_novel --manifest-path server-rs/Cargo.toml
|
||||
```
|
||||
|
||||
结果:全部通过。
|
||||
|
||||
## 7. 后续接入点
|
||||
|
||||
`VN-05` 接 API Server 时直接复用:
|
||||
|
||||
1. `build_visual_novel_creation_llm_request`
|
||||
2. `build_visual_novel_runtime_llm_request`
|
||||
3. `build_visual_novel_repair_llm_request`
|
||||
4. `parse_visual_novel_result_draft_fixture`
|
||||
5. `parse_visual_novel_runtime_steps_fixture`
|
||||
6. `visual_novel_tool_descriptors`
|
||||
|
||||
若后续 `VN-01` 契约发生破坏性变更,必须同步更新本 Prompt 模块的 output contract、fixture 和解析测试。
|
||||
Reference in New Issue
Block a user