第 X 章(待编号) / StoryCam 开发叙事

从“像原型”到“真实生成”:设计对齐、Provider 接入与 Mock 根因排查

本 session 记录了 StoryCam 从规划后的增量实现,进入前端设计还原、Step 2 真实文本生成、角色/场景资产生成交互,以及“为什么明明重启了还是 mock”的根因排查过程。

TL;DR

本章学习目标

学会把设计稿变成验收标准不要只问“页面能不能用”,还要问它是否继承了设计原型里的层级、尺寸、交互节奏和产品意图。
学会识别 mock 与真实生成的边界AI 产品里“看起来像结果”不等于“调用了真实模型”,必须用诊断字段、网络请求和服务端配置验证。
学会用结构化输出约束 LLM剧本生成不是自由文本续写,必须把模型输出压进 schema,失败时可重试、可 redacted 报错。
学会把调试经验沉淀到文档一旦发现环境变量覆盖、provider 混用、mock 默认值这些坑点,就应该更新长期文档,而不是只靠口头记忆。

工具、参考图和可视化证据

本 session 的关键不是单一代码文件,而是多个证据源叠加:技能、模板、设计原型、浏览器截图、网络面板和 provider 文档共同推动了判断。

使用到的技能与工作方式
  • $planning-and-task-breakdown:前置规划已经完成。
  • $incremental-implementation:用于继续按小步实现和验证。
  • subagent 并行:用户授权后用于加速 Step 3-7 UI 调整。
  • 本地 Supabase CLI、Next.js dev server、浏览器网络面板。
参考项目与文档
  • .temp/Next-js-Boilerplate-main
  • .temp/nextjs-approuter-supabase-boilerplate-main
  • docs/references/shanyin-director-master
  • 三个 Seedance 官方参考文件:教程、提示词指南、视频生成教程。

聊天中还出现了多张截图:包括进度条放在 hero 上方不协调、Step 2 多余侧栏、角色/场景资产浮窗参考、Chrome Network 中 /api/story-world 返回 201 但内容仍像 mock。这些截图在本章中作为设计与调试证据描述,不臆造截图外的信息。

沿时间排列的原始 Prompt

1. 从规划进入实现,并引入模板基建
现在已经做完了 [$planning-and-task-breakdown](/Users/vc3vc3/.codex/skills/planning-and-task-breakdown/SKILL.md) ,需要使用 [$incremental-implementation](/Users/vc3vc3/.codex/skills/incremental-implementation/SKILL.md) 开始项目代码的实现,实现前可以先 commit 之前的代码
给你一个全面的Next-js-Boilerplate 作为参考, .temp/Next-js-Boilerplate-main,充分利用模板里的基础,你可以把基础结构搭建起来
.temp/nextjs-approuter-supabase-boilerplate-main,可以再参考这个项目迭代,这里有不少可以参考的基建
教师批注:这组 prompt 的价值在于把“做功能”前置成“先选工程起点”。读者可以学到:项目早期不要急着写业务页面,先确认模板、认证、数据、环境和目录骨架,后续迭代会省掉大量返工。
2. 把官方资料放进 docs,准备后续视频生成能力
你现在合适 docs 位置建立两个 seedance 的 md 文件,我把官方的文档写进去
还需要个“视频生成教程”的 md
继续未完成的开发计划,关于视频生成这块可以参考刚刚的三个官方参考文件
教师批注:这里体现的是“先保存权威资料,再做实现”。视频生成链路成本高、provider 细节多,先把官方文档归位,可以让后续 prompt、参数和限制有源可查。
3. 设计对齐成为前端实现的硬约束
我现在发现一个很大的问题,docs/design-docs/stitch_storycam_cinematic_workstation 这个是最终的设计稿,有设计要求,和不同步骤的界面样式与代码,你并没有按这个开发项目的前端呀?
继续未完成的开发计划,如果设计前端 ui 开发,记得看docs/design-docs/stitch_storycam_cinematic_workstation里的设计规范和设计基础代码
教师批注:这是本 session 第一个产品转折点。用户没有只说“改好看点”,而是明确指定最终设计源。读者可以学到:UI 开发要有可验证的 design source of truth,否则很容易做出“可用但不对”的页面。
4. Step 1 与流程导航的验收反馈
这个进度条放在 hero 区的上方不好看,改到整个区域的左边竖着放吧,整体调整下
现在第一步的主卡片填写区太大了,参考截图中的布局,调整“私人小剧场相机”这个组件
- 我觉得第一步的时候不应该有左边的进度条,到后面步骤的时候有比较合适。 - 整个布局居中 - 顶光指导下的默认四个选项是如何设计的,为什么有 - 保存到你的账号,这个组件是不是不应该有
如图所示,灯光指导指导几个选项和上面输入框下的参数没有联动
教师批注:这些反馈把“视觉问题”拆成了产品逻辑:第一步是输入创意,不该被流程导航压迫;选项不是装饰,必须与参数状态联动;账号保存组件在本地免登录测试阶段会干扰主路径。
5. Step 2 路由、原型和布局尺寸
进入步骤 2 后,没有办法通过左侧的进度条点击回到选择的那一步
docs/design-docs/stitch_storycam_cinematic_workstation/step_2_story_world_culture_engine/screen.png 注意看下 step2 的设计原型图,现在的不对,不应该有“保存到你的账号”、“当前流程”、“故事世界”、“片段时间线”这几个板块。 与此同时,我试了下左侧的进度条,点回第一步后,并不是刚才修改后的第一页,还有就是每一步不应该有自己的路由么?
虽然板块与原型图保持一致了,但是整体布局的尺寸非常不合理,你可以再对齐下布局尺寸docs/design-docs/stitch_storycam_cinematic_workstation/step_2_story_world_culture_engine/code.html
教师批注:这里的关键是把页面状态问题提升为路由和信息架构问题。多步骤产品不能只靠局部 state 切换,用户需要可回退、可定位、符合浏览器心智的步骤路由。
6. Step 3-7 并行对齐与模型策略
按照这个逻辑,对照原型图和参考代码,调整 step3-7 剩下的这几个产品界面,可以使用 subagent 并行
3-7 有五步,你是不是启动 5 个 subagent 更快
继续未完成的开发计划 ,剧本类型的文本模型我建议用 openrouter 里的deepseek/deepseek-v4-pro,分镜相关的生图模型建议用openai/gpt-5.4-image-2
教师批注:用户在这里同时做了两件事:给 UI 执行提速授权,并给模型选型方向。读者可以学到:并行不是为了炫技,而是在步骤界面互相独立时,用明确边界换速度。
7. OpenRouter Step 2 故事世界计划
现在步骤二的剧本不是根据步骤一输入的文本生成的,这个后端服务要用文本模型,对应的提示词应该是参考docs/references/shanyin-director-master 设计出来
PLEASE IMPLEMENT THIS PLAN: # OpenRouter 文本模型生成 Step 2 故事世界 ## Summary - 目标:让步骤二“故事世界/剧本”真实根据步骤一输入文本和“拍法倾向”生成,而不是返回固定 mock fixture。 - 范围:本次只接入文本 + 轻选项;上传照片仍只作为 referenceMediaIds 保留,不做照片内容理解。 - 默认:支持混合 provider,本地可设置 STORYCAM_TEXT_PROVIDER=openrouter,其他图像/视频 provider 继续 mock。 ## Key Changes - 新增 OpenRouter story-world 文本 provider,复用现有 createOpenRouterTextProvider + Vercel AI SDK generateObject,输出仍严格校验为现有 script / characterAssets / sceneAssets schema。 - 新增 StoryCam 专用 story-world prompt builder,参考 docs/references/shanyin-director-master。 - 更新 /api/story-world 服务接线,provider 选择只由服务端 env 决定。 - 更新 config 语义:允许 STORYCAM_GENERATION_MODE=mock 搭配 STORYCAM_TEXT_PROVIDER=openrouter。 ## Test Plan - Unit/provider、Service/API、Config、Regression。 ## Assumptions - 本次不做照片内容理解;API response shape 不变;deepseek/deepseek-v4-pro 作为默认文本模型写入文档和 .env.example。
教师批注:这是工程实现最完整的 prompt。它同时限定范围、配置语义、测试计划和不做什么。好的实现 prompt 不只是“加一个功能”,而是把边界、默认值、失败策略和验收方式一起给出。
8. 测试反馈、结构化输出和 mock 根因
你测试下是通的么
可是我在 step1 的前端输入文本后点击发送,在 step2 界面我看到的我的剧本文本像是 mock
我测试了下,显示故事雏形生成失败,请稍后再试。
模型返回的故事格式不稳定,请再试一次。 你要用 sdk 带的结果化 json 控制
这种坑点或技巧、细节要沉淀到对应的文档里
现在好像在 step1 发送后,没有调用相对应的 api,瞬间就返回了一个剧本,多试几次都是这个剧本内容
我看到了,还是 mock,为什么,我已经重启了服务
教师批注:这组反馈展示了真实 AI 产品调试链路:先怀疑前端没调 API,再确认 API 调了但返回像 mock,最后追到 provider/env 诊断。读者要学会从症状拆假设,而不是看到“生成失败”就只改 prompt。
9. 角色/场景资产生成交互和顶层文档同步
图一是现在step2 角色资产和场景资产的布局,但我希望这个布局上有点击生成的交互,点开后有个浮窗来承载生成的具体角色资产(参考图 2)和具体场景资产(参考图 3),这个生成过程是靠生图模型(openrouter 里的 gpt5.5)
左侧的进度条不需要太显眼,可以见参考图,做局部调整
现在改了不少 docs,但是我看 AGENTS.md 和 ARCHITECTURE.md 没有动态的调整
教师批注:这里强调了两类一致性:界面一致性和文档一致性。资产卡片必须成为可操作对象;长期规则不能只散落在局部 docs,入口文档也要指向最新事实。

时间线

“已经做完 planning-and-task-breakdown,需要使用 incremental-implementation 开始项目代码的实现,实现前可以先 commit 之前的代码。”
Codex 将工作模式切换为增量实现:先稳定已有状态,再按可验证的小步推进 StoryCam MVP。
结果 / 影响:项目进入从计划到代码落地的阶段,后续每步都围绕“继续未完成开发计划”推进。
“给你一个全面的 Next-js-Boilerplate 作为参考……再参考 nextjs-approuter-supabase-boilerplate-main。”
Codex 参考两个模板,复用 Next.js App Router、Supabase、本地 env、认证和基础目录结构思路。
结果 / 影响:StoryCam 的工程起点从“裸写页面”变成“借鉴成熟基建搭骨架”。
“合适 docs 位置建立两个 seedance 的 md 文件……还需要个‘视频生成教程’的 md。”
Codex 在 docs 中为 Seedance 官方教程、提示词指南和视频生成教程预留文档位置,方便用户补充官方内容。
结果 / 影响:后续视频生成能力有了官方资料入口,不把 provider 知识埋在聊天记录里。
“docs/design-docs/stitch_storycam_cinematic_workstation 这个是最终的设计稿……你并没有按这个开发项目的前端呀?”
Codex 接受设计源纠偏,后续 UI 改为对照该目录下每个 step 的原型图和基础代码进行校准。
结果 / 影响:设计稿从“参考资料”升级为“验收标准”,这是本 session 的第一个关键转折。
“进度条放在 hero 区的上方不好看,改到整个区域的左边竖着放吧。”
Codex 调整流程导航位置,并在后续根据反馈继续弱化左侧进度条,让它成为辅助导航而非主视觉。
结果 / 影响:多步骤工作台开始形成更接近设计稿的空间结构。
“第一步的时候不应该有左边的进度条……整个布局居中……灯光指导选项和参数没有联动。”
Codex 重新审视 Step 1:隐藏首屏流程条、收窄主输入卡片、移除不适合本地免登录测试的账号保存组件,并把轻选项与输入参数状态联动。
结果 / 影响:Step 1 回到“私人小剧场相机”的核心任务:让普通用户先表达一个私密故事念头。
“进入步骤 2 后,没有办法通过左侧的进度条点击回到选择的那一步……每一步不应该有自己的路由么?”
Codex 将步骤导航改为可点击,并把步骤页面路由化,避免回到 Step 1 时出现旧版页面或状态错位。
结果 / 影响:多步骤产品获得了更清晰的浏览器导航心智,也为后续恢复和分享打基础。
“Step2 不应该有‘保存到你的账号’、‘当前流程’、‘故事世界’、‘片段时间线’这几个板块。”
Codex 删除偏离原型的侧边板块,并继续按设计图和参考代码调整 Step 2 尺寸、资产区域和底部操作条。
结果 / 影响:Step 2 的信息架构从通用后台面板回到“确认故事世界”的产品场景。
“按照这个逻辑,对照原型图和参考代码,调整 step3-7……可以使用 subagent 并行。3-7 有五步,你是不是启动 5 个 subagent 更快。”
Codex 将 Step 3-7 拆成相对独立的 UI 对齐任务,通过 subagent 并行推进,同时保留主线程做整合和验证。
结果 / 影响:并行执行被用于加速独立界面的对齐,而不是让多个代理改同一块代码产生冲突。
“剧本类型的文本模型建议用 openrouter 里的 deepseek/deepseek-v4-pro,分镜相关的生图模型建议用 openai/gpt-5.4-image-2。”
Codex 将模型策略写入 provider 语义:文本可用 OpenRouter DeepSeek,图像/分镜可独立选择 image provider,允许混合 provider。
结果 / 影响:系统不再只有全局 mock/real 二选一,而是可以按文本、图像、视频分层切换。
“步骤二的剧本不是根据步骤一输入的文本生成的……提示词应该参考 shanyin-director-master。”
Codex 新增 story-world prompt builder 和 OpenRouter 文本 provider,将用户输入、轻选项和导演方法转成可拍短剧本、角色资产和场景资产。
结果 / 影响:Step 2 的核心价值从固定 fixture 变成真实生成链路。
“模型返回的故事格式不稳定……你要用 sdk 带的结果化 json 控制。”
Codex 将自由文本式输出收紧为 SDK 结构化 JSON 输出,并用现有 schema 校验 script / characterAssets / sceneAssets
结果 / 影响:模型失败从“页面随机坏掉”变成“可重试、可 redacted 报错、可测试”的 provider 行为。
“我在 step1 输入文本后……看到的剧本文本像是 mock。” “现在好像没有调用 API,瞬间就返回了一个剧本。”
Codex 增加 provider 诊断、检查 Network 中 /api/story-world 请求,并区分“没调 API”“调了 API 但服务端仍在 mock”“真实 provider 失败后 fallback”的不同可能。
结果 / 影响:问题定位从前端观感推进到服务端配置和环境变量优先级。
“我看到了,还是 mock,为什么,我已经重启了服务。”
Codex 记录并解释关键坑点:Next dev 重启不一定等于配置生效,shell-exported STORYCAM_TEXT_PROVIDER=mock 会覆盖 .env.local
结果 / 影响:根因被沉淀到 provider/local-dev 文档和 AGENTS 规则:测试真实生成时必须看诊断字段,不要只看响应像不像。
“角色资产和场景资产布局上要有点击生成交互,点开后有浮窗承载具体资产……生成过程靠生图模型。”
Codex 将资产卡片升级为可点击生成入口:角色资产和场景资产各自打开更大的详情浮窗,承载生成图、描述和复核动作。
结果 / 影响:Step 2 不再只是确认剧本文本,也开始连接后续图像资产生成流程。
“现在改了不少 docs,但是我看 AGENTS.md 和 ARCHITECTURE.md 没有动态的调整。”
Codex 同步顶层入口文档:AGENTS 保持短规则和导航,ARCHITECTURE 更新 provider、mock 显式化和诊断相关语义。
结果 / 影响:临时修复上升为项目长期知识,后续 agent 进入项目时不会重复踩同一类坑。

关键时刻

转折点 1:设计稿从“参考”变成“验收标准” 当时的问题是前端虽然在推进,但没有贴合最终设计稿。它重要是因为 StoryCam 的产品感很依赖每一步的仪式感和视觉节奏。最终处理方式是回到 docs/design-docs/stitch_storycam_cinematic_workstation,逐步校准 Step 1-7。
转折点 2:Step 2 必须由 Step 1 输入驱动 当时的问题是用户多次输入后看到的剧本仍像固定 mock。它重要是因为 StoryCam 的核心承诺是把私人念头变成个人故事世界。最终接入 OpenRouter 文本 provider,并让 provider 由服务端 env 决定。
关键发现:结构化输出不是锦上添花 当时的问题是模型返回格式不稳定。它重要是因为后续 UI 依赖 script、角色资产、场景资产的稳定结构。最终使用 SDK 的结构化 JSON 控制,并用 schema 校验输出。
Bug 根因:重启服务不等于清空环境 当时的问题是用户已经重启服务,但 provider 诊断仍显示 mock。它重要是因为开发者很容易只盯页面。最终判断为 shell-exported env 覆盖 .env.local,并把这个坑点写入文档。
产品方向:资产卡片从展示变成交互 当时的问题是 Step 2 的角色/场景资产只是布局占位。它重要是因为确认故事世界之后,用户需要看到可生成、可复核的视觉资产。最终加入点击生成浮窗,把 Step 2 连接到图像生成链路。

关键决策表

方案 当时看起来的好处 为什么放弃或保留 最终选择
直接按现有前端继续开发 速度快,可以快速串流程。 放弃。用户确认最终设计稿已存在,继续偏离会造成整体返工。 以设计目录和 step 原型作为验收标准。
第一步也显示完整侧边进度条 流程感明确,看起来像工作台。 放弃。Step 1 的核心是输入私密创意,过早展示流程导航会显得沉重。 第一步隐藏或弱化进度条,后续步骤再显示轻量流程导航。
所有 provider 跟随全局 generation mode 配置简单,mock/real 一键切换。 部分放弃。StoryCam 需要文本先真实生成,图像/视频仍可 mock,以降低本地成本和调试复杂度。 允许混合 provider:STORYCAM_TEXT_PROVIDER=openrouter,其他 provider 可继续 mock。
让模型输出自然语言后再解析 prompt 简单,模型更自由。 放弃。输出格式不稳定,会让 UI 和测试都脆弱。 使用 SDK 结构化 JSON 输出,并严格校验现有 schema。
看到像 mock 的内容就从前端继续查 符合用户直接看到的问题表象。 放弃单一路径。Network 已显示 API 请求存在,必须继续追服务端 provider 诊断。 用“请求是否发出 -> provider 是否真实 -> env 是否被覆盖”的链路定位。
把角色/场景资产作为静态卡片 实现简单,与 Step 2 文本确认解耦。 放弃。资产是后续分镜和视频生成的基础,只展示不生成会断链。 资产卡片可点击,弹出详情浮窗承载生成结果和复核。

可复用方法

AI 产品的“单位对齐”检查法 先问每一步的产物单位是什么:Step 1 是私人念头,Step 2 是故事世界,Step 3 是核心分镜组,后续才是片段和视频。只要 UI 板块、按钮或 provider 输出不服务这个单位,就容易偏离产品主线。
设计还原的“三层对照” 不只看截图颜色。第一层看信息架构,第二层看尺寸和留白,第三层看交互状态。StoryCam 的 Step 2 就是先删掉不该有的板块,再校准布局尺寸,最后补足资产点击生成。
LLM 调试的“结构优先”原则 当输出要喂给 UI 或数据库时,不要依赖自然语言稳定性。先定义 schema,再让 SDK 产生结构化对象,失败时重试并 redacted 报错,最后用测试覆盖 malformed output。
Mock 排查链路 看到“像 mock”的结果时,按顺序验证:前端是否发请求、请求 payload 是否带用户输入、服务端诊断显示哪个 provider、env 是否被 shell 覆盖、是否存在 fallback。不要只凭响应文本判断。
文档漂移修复法 如果一次调试产生了长期规则,就同步三处:具体参考文档记录细节,索引文档提供入口,AGENTS/ARCHITECTURE 只保留短规则和导航。这样不会让入口文件膨胀,也不会丢知识。
并行 subagent 的边界法 只有当任务能按页面、模块或文件所有权拆开时才并行。Step 3-7 适合,因为每步界面相对独立;provider 核心接线则更适合主线程把关,避免多人同时改同一契约。

工程证据

仓库与发布状态
  • Project: storycam
  • Branch: 本地工作区记录为 main 或当前开发分支,需以实际 git 状态为准。
  • PR: 本 session 未记录新 PR。
  • Deploy: 本 session 未记录生产部署。
  • Sensitive data: provider key、cookie、签名 URL、原始 payload 均应写作 [REDACTED]
本 session 记录到的提交
  • f597041 ui: soften workflow stepper
  • 0403a5f feat: generate story world asset images
  • 5f189de fix: stabilize openrouter story world output
  • 168e274 docs: record openrouter structured output gotchas
  • bb4ad84 fix: expose story world provider for debugging
  • 1b3c120 fix: surface story world provider diagnostics
  • 8ad6c4c docs: update provider guidance in top-level maps
验证命令与调试证据

本 session 中出现或被记录用于验证的命令如下。具体输出未完整保留在本章中,因此这里不凭空补写 CI 结果,只记录用途。

pnpm lint
pnpm typecheck
pnpm test -- --run storyWorld
pnpm test -- --run openrouter
pnpm test -- tests/api/storyWorld.test.ts --runInBand
curl --noproxy '*' http://localhost:3000/api/story-world
  • Chrome Network 证据:用户截图显示 /api/story-world POST 返回 201 Created,说明至少存在 API 请求。
  • 关键诊断:如果响应仍显示 mock,需要检查服务端 provider diagnostics,而不是只看页面文案。
  • 环境变量证据:shell-exported env 会覆盖 .env.local,这解释了“重启后仍是 mock”的可能根因。
涉及的文件或文档区域
  • docs/design-docs/stitch_storycam_cinematic_workstation/:Step 1-7 前端设计对齐来源。
  • docs/references/shanyin-director-master:Story-world prompt builder 的导演方法参考。
  • docs/references/providers.md:provider 配置、诊断、mock/real 语义。
  • docs/references/local-dev.md:本地 env 与真实 provider smoke 的注意事项。
  • AGENTS.mddocs/ARCHITECTURE.md:入口规则与架构事实同步。

后续事项

已完成

  • 将 StoryCam 前端实现重新对齐到最终设计稿目录。
  • Step 1 输入体验、参数联动和首屏流程导航逻辑完成调整。
  • Step 2 去除多余板块,并对齐故事世界、角色资产、场景资产布局。
  • Step 2 story-world 接入 OpenRouter 文本 provider,并引入结构化输出控制。
  • 角色/场景资产卡片增加点击生成与浮窗承载思路。
  • Provider 诊断、env 覆盖坑点和顶层文档入口完成同步。

待确认

  • 本章编号需要在总项目叙事文档中按时间顺序补齐。
  • Google OAuth 本地配置在本 session 中被允许暂不测试,后续仍需确认真实登录路径。
  • OpenRouter 文本模型的成本、延迟、稳定性需要继续通过真实样例评估。
  • Step 3-7 的视觉对齐需要用浏览器截图逐步验收,尤其是移动端与滚动区域。

后续开发

  • 将 Seedance 官方视频生成资料转化为真实视频 provider 和任务队列实现。
  • 补充从 Step 1 不同输入到 Step 2 动态剧本的端到端 smoke,并避免误判 mock。
  • 让角色/场景生图 provider 的成本、失败重试、资产缓存和权限边界变成可测试契约。
  • 完善发布前 gate:本地检查、AI review、部署验证、回滚说明和运营监控。
  • 把这份 session chapter 按时间顺序并入总 HTML 项目开发过程讲解文档。