序章:今晚讲什么故事?
开学第二天的晚上,学长学姐们看着排满了早八的课表久久无法入睡。满脑子都是枯燥的课堂与陌生的天花板。
大肥鱼说,这是“过度焦虑与优绩主义交叉失眠综合征”,只会出现在成年人身上。
也许,回归童真的心态会有助于缓解这种病症,帮助学长学姐们进入安眠?
让我们为学长学姐做一个绘本故事生成器,帮助他们减轻焦虑,好好睡觉吧!
本题希望你设计并实现一个可以持续生成的 AI 绘本系统。读者提供故事的想法,系统负责将它发展成多页图文;读者也可以在阅读后改变方向,让故事继续、出现转折,或者走向结局。
我们希望看到:人物拥有能够延续的身份,发生过的事情能够留下影响,文字与图像生动地讲述同一个故事。毕竟,绘本阅读的有趣之处,就在于画面与文字交相辉映出的童真呀!
请围绕这个核心体验,在约一周、最多 3 人的协作规模内,选择最值得验证的设计,完成一个能够现场展示的原型。
第一幕:关灯,睡觉觉
学长学姐不限制你用什么技术实现这一绘本阅读平台,他们只是想读一读绘本。
你可以自由选择编程语言、应用形式、模型服务、框架和存储方案,也可以在现有开源项目或成熟组件上进行开发。但是学长学姐想知道你复用了哪些能力,以及自己独立完成了哪些工作。
一个来自墨西哥的神秘蒙面大盗偷偷告诉你,他从工作室偷了一些算力资源出来,包括可以生成图像的小可爱模型。他说可以将这些资源免费提供给你,只要你能让学长学姐睡个好觉,在第二天的早八课堂上不再犯困。
学长学姐不要求你们为此训练或微调大模型,他们也不对故事的文学性作出严格要求。但他们希望每页都有合理的少量、易读的描述性文字,同时至少有一张大大的图片。你可以为绘本选择自己感兴趣的题材、画风、故事类型,或者交由读者决定。
学长学姐不需要任何的账号、多人协作、付费订阅和作品管理系统。他们只是想要一个独特的睡前故事。如果你无法完成整个产品,那么请你根据时间安排和能力选择最值得验证的核心设计,并向我们展示你的思路和实现。
第二幕:很久很久,很久以前……
很久很久以前,有一只怕黑的小狐狸,住在森林深处的蘑菇房里……
故事似乎总是这么开始。对于一本睡前故事来说,这似乎也是一个不错的开头。
但这不重要。故事的开头具体是什么样,应该由你来决定。在这本睡前故事里,读者只负责用简单的语言描述自己想看到的故事方向。例如上述的开头,就可能由这样的一句话展开:
我想看一只怕黑的小狐狸,为了寻找失踪的月亮,第一次离开森林。
读者不需要逐页说明人物在哪里、做了什么、画面如何构图。而你的睡前故事,需要把这个想法发展成一段故事,并自行安排事件、节奏和分页。
学长学姐建议:
- 每轮生成至少 3 页,而具体页数和节奏可以由 AI 根据本轮内容决定;
- 每页应至少包含一张配图和少量描述性文字。
- 一个复杂的想法可以展开成更多页,故事长度应服务于叙事。你可以设置合理的单轮页数上限,并说明这个限制。
一轮生成结束,只代表故事暂时停在这里。除非读者明确要求结尾,否则不应在每一轮结束时都强行解决所有问题、宣布故事完结。局部事件可以告一段落,但故事应保留继续发展的空间。
在读者读完这一段以后,他们应当可以选择:
| 操作 | 预期行为 |
|---|---|
| 继续 | 沿着已有情节、人物目标和未解决事项,自然发展下一段故事。 |
| 结尾 | 开始收束主要冲突与线索,生成一个有依据的结局。 |
| 转折 | 引入能够改变局势的新事件,同时尊重已有设定和已发生的事实。 |
| (输入自己的想法) | 将读者希望看到的人物、事件、情绪或方向融入后续故事。 |
| …… | 你认为有意义的其它操作 |
例如,读者可以在狐狸进入森林以后提出:
我希望它遇到一个看起来可怕、其实很温柔的伙伴。
你的睡前故事需要决定这个伙伴如何出现、长什么样子,以及它如何持续影响故事发展。
第三幕:给它完整的一生
随着页面增加,你的睡前故事逐渐需要维护越来越多的剧情发展、人物关系和戏剧节奏。
把所有生成过的内容保存下来当然很重要,但拥有完整的历史记录,并不等于知道故事现在处于什么状态。
一百页前“狐狸拿到了钥匙”和五十页前“狐狸把钥匙交给伙伴”,都是真实发生过的事情;但如果系统只重新找到了前一句,它就可能错误地认为钥匙仍然属于狐狸。随着故事越来越长,模型能够直接读取的上下文也终究有限,因此你需要考虑:过去发生过什么,和现在仍然成立什么,应该如何被区分、更新并重新使用?
我们把系统对这些仍然有效的设定、事实、人物状态和未解决问题的持续表示,称为持续故事世界状态(Persistent Storyworld State)。
例如,在某一页中,你的睡前故事可能需要持续关注这些信息,而可以遗忘或选择性忽略其他无关内容:
| 信息 | 例子 |
|---|---|
| 背景:相对稳定的设定 | 狐狸怕黑,伙伴的左耳有一处缺口。 |
| 状态:现在是什么样 | 灯笼已经熄灭,角色正在河岸,钥匙由伙伴保管。 |
| 历史:已经发生了什么 | 伙伴曾经救过狐狸,狐狸答应帮助它寻找家人。 |
| 悬念:还有什么没有解决 | 月亮为什么失踪,一封没有署名的信来自哪里。 |
心理学中有一个相近的概念叫作 Situation Model(情境模型)。人在理解一段叙事时,并不只是记住刚刚读过哪些句子,而会逐渐形成一份关于“故事现在是什么样”的内部表征:人物在哪里、发生了什么、事情之间有什么因果关系、人物正在追求什么目标……这份表征也会随着故事继续而不断更新。
我们希望你的系统也能做到类似的事情:不是单纯记住故事,而是知道故事此刻处于什么状态。
至于故事世界状态的具体数据结构与实现方式,这里不做限制。它可以是一份维护得很好的 JSON,也可以来自设定表、事件记录、摘要、数据库,或者多种方案的组合。
第一节:无法触碰到的真实
故事中的信息并不都具有相同的确定性。
“乌鸦说月亮被熊偷走了。”
这句话真正能够确认的,是乌鸦说过这句话,而不是“熊确实偷走了月亮”。类似地,系统计划在后面让狐狸找回月亮,也不代表当前页面的天空中已经重新出现了月亮。
因此,你需要以某种方式区分至少三类东西:既有事实、角色认知,和未来事件。
换句话说:History(历史)不等于 State(状态),Plan(计划)也不等于 Fact(事实)。
当读者的新想法与已经发生的故事冲突时,也应该有相应策略。例如,狐狸已经失去了灯笼,读者却希望它举着灯笼进入山洞。这时,你的睡前故事应该怎么处理呢?
第二节:明天的故事还没有发生
故事需要记忆,也需要规划,但二者不应混在一起。
如果读者选择继续故事,系统可能沿着已有目标自然发展;如果读者点击“转折”,未来的剧情计划就应该发生变化;而如果读者提出新的想法,系统也需要把它融入尚未发生的部分,而不是偷偷改写已经展示过的页面。
因此,你可以考虑维护一套负责安排剧情走向、规划故事情节、设计戏剧节拍的叙事引擎。
第三节:有些事情,不必一直记着
随着故事越来越长,把所有细节都塞进每一次模型调用,会变得越来越低效,也未必真的有帮助。你的睡前故事还需要考虑如何有效组织真正喂给模型的上下文。
哪些信息应该一直保留?哪些细节只与当前场景有关?很早以前出现的承诺,什么时候应该被重新想起?你可以考虑使用完整历史、滚动摘要、结构化状态、按需检索,或者组合多种方法。请说明你的方案适合多长的故事、有哪些限制,并通过跨轮续写展示前文如何影响后文。
第四幕:狐狸还是那个狐狸
绘本的图像不是故事旁边的装饰,而应该参与叙事。
如果文字描述灯笼已经熄灭,画面就不应该仍然用灯笼照亮森林;如果伙伴的左耳一直有一处缺口,它也不应该毫无原因地在下一页消失;如果角色刚刚拿到了钥匙,后续画面和文字都应该对钥匙的去向有合理交代。
我们主要关注三种连续性:
- 页内一致性:同一页的文字与画面在主要人物、动作、物品和场景上相互吻合;
- 跨页连续性:同一角色的主要外貌特征,以及重要物品和场景特征能够延续,发生变化时有合理原因;
- 情节流动性:已发生事件产生后果,人物关系和目标有所延续,后文能够使用前面留下的信息。
字模型与生图模型分别应该看到哪些信息?角色设定、参考图、当前状态、近期页面和整体画风,分别都怎么呈现给模型?同一份故事世界状态,需不需要不同形式的筛选和包装?
同一个重要角色至少应在多个页面中重复出现,并尽量保持可辨识的视觉身份。仅仅为每一页独立生成一幅风格相似但人物完全不连续的图片,不能充分满足本题对多模态连续性的要求。第五幕:「娱乐至死」
到这里,你也许已经可以生成一段连续、图文一致的绘本了。但如果读者输入一句话之后,需要等待很久,直到所有页面和图片全部生成完成才能开始阅读,那么这个故事可能还没开始,读者就已经失去耐心了。生成式产品里的等待、失败和用户控制,本身也是体验的一部分。
请尝试让故事渐进式地产生。理想情况下,读者不需要等待整轮故事全部完成,就能够开始阅读第一批页面,而后续内容继续在后台生成。
你可以思考:
- 故事是否需要一次规划完整,再开始生成?
- 文字和图片能否并行产生?
- 能否优先生成读者最先看到的页面?
- 后续页面之间哪些互相依赖,而哪些可以并行?
- 是否可以先提供较轻量的结果,再逐步完善?
我们希望系统在接收到输入后尽快产生第一份可阅读内容,而不是只显示一个“正在生成”的动画。请记录并展示你的实际响应时间,例如从用户提交输入到第一页文字出现、第一页图片出现、整轮生成完成分别需要多久。
在等待期间,你也可以向读者提供适当的进度反馈,例如”正在规划故事“、”正在生成第 X 页“、”正在绘制小狐狸的耳朵“等标签。但这些反馈应该帮助用户理解系统正在做什么,而不是用于掩盖不合理的等待。
同时你也应当考虑到:更激进的并行并不一定更好。如果后一页依赖前一页真正发生的内容,过早生成可能破坏故事连续性。速度、并发和叙事一致性之间如何取舍,也是本幕希望你思考的问题。
第六幕:山就在那里
情绪价值也是绘本阅读中必不可少的一环。在以下的方向中,你可以选择其中几个深入,或是研究并提出自己的想法。不需要将它们全部完成。
第一节:它真的是一本书!
请你尝试让作品真正具有绘本的阅读感。字体、留白、图文关系、页面切换和不同屏幕上的布局,都可以影响阅读体验。
基础部分只要求易读、可用。进阶时可以思考:界面如何配合叙事节奏,让读者愿意继续翻页?
第二节:活生生的故事
请你尝试让绘本中的内容可以对读者的操作产生响应。
例如,点击灯笼后,它亮起来并照出隐藏的脚印;翻到某一页时,一个巨大的身影逐渐从雾中显现;拖动信封,可以看到藏在里面的信……
在表现方式之外,你需要关注这些表现是否帮助讲故事,以及它们是否与当前故事状态一致。
第三节:记忆这样脆弱的东西
当故事已经很长,或者读者过了一段时间才回来,你的睡前故事可以提供简短回顾、角色关系或重要事件梳理。
第四节:好看的绘本才有市场
请你尝试提供一种或几种仔细打磨过的风格预设令读者选择,让它在故事中保持统一,并展现出舒适良好的观感,减少配图的“AI 味”。你可以多多探索不同题材与视觉风格之间的关系。
第五节:漫画感
每一页不一定只有一张矩形图片和一段文字。追逐可以通过连续小格表现,重要场景可以使用跨页大图,文字也可以融入画面。请你尝试让系统根据故事节奏安排分镜、构图和图文关系。
无论采用怎样的形式,页面仍应具有配图与少量描述性文字,并让读者能够清楚理解事件的顺序和联系。
尾声:你要怎样讲给我听呢?
以下思路仅供参考,不是指定的开发路线:
- 你可以先为本轮故事安排事件和分页,再逐页生成图文。这样可能更容易控制节奏,但也需要处理“计划中的故事”和“真正展示的故事”之间的差异。
- 你可以为角色维护设定表与参考图,让不同页面的生成共享这些信息。需要注意,相对稳定的身份特征与会变化的服装、表情、位置、持有物品,可能需要不同的处理方式。
- 你可以在生成前选择相关历史,在生成后检查图文是否与当前状态冲突。检查可以使用规则、模型或人工辅助分析,但不能假定检查一定正确。
- 你也可以记录每轮使用了哪些上下文、生成了哪些事件、更新了哪些状态。简单的日志或调试页面,就可能帮助你解释为什么故事发生了某个变化。
这些机制应当用于解决你实际遇到的问题,而不是增加项目复杂度。
最终展示时,请围绕同一本绘本完成一次完整演示:
展示过程中,请指出至少两项被系统持续维护的故事信息,以及它们如何影响后续文字或图像;同时展示至少一个你遇到过的连续性失败,以及你对它的分析或改进。
如果你使用了额外的故事状态、摘要、检索、图片参考或一致性检查机制,请说明它们在一次具体生成过程中实际发挥了什么作用。
后记(一):术语简释
| 术语 | 本题中的含义 |
|---|---|
| LLM / 大语言模型 | 用来理解读者想法、安排情节和生成文字等内容的模型。 |
| 多模态 | 系统共同处理文字、图像等不同形式的信息。 |
| 上下文 / Context | 模型在一次生成时实际获得的指令和背景信息。 |
| 上下文工程 | 决定哪些信息应当进入模型输入,以及如何组织、更新这些信息。 |
| Situation Model / 情境模型 | 心理学中用于描述读者如何形成并更新“当前故事情境”的概念。本题只借用其思想,不要求掌握相关理论。 |
| Storyworld State / 故事世界状态 | 对当前仍然有效的故事设定、事实、人物状态和未解决问题的持续表示。 |
| Story History / 故事历史 | 已经发生过的事件记录。历史中的信息不一定仍然代表当前状态。 |
| Plan / 故事计划 | 尚未正式发生的未来剧情安排,可以随着读者输入而调整。 |
| 已确认事实 | 系统作为正式故事依据保存的内容,需要与角色猜测和未来计划区分。 |
| 滚动摘要 | 随着故事发展持续更新的一份简短历史概述。 |
| 持久化 | 将页面和状态保存下来,使程序重新打开后仍能使用。 |
| 分镜 | 将事件安排成不同画面,通过顺序、大小和视角等方式组织叙事。 |
后记(二):延伸阅读
如果你对“为什么长故事不能只靠不断续写”这个问题感兴趣,可以从这些工作开始了解:
- Zwaan & Radvansky (1998), Situation Models in Language Comprehension and Memory:关于人在理解叙事时如何形成、更新情境模型的经典综述。
- PlotMachines (EMNLP 2020), Outline-Conditioned Generation with Dynamic Plot State Tracking:将动态 Plot State Tracking 引入长故事生成。
- Re³ (EMNLP 2022), Generating Longer Stories With Recursive Reprompting and Revision:把整体计划、当前故事状态与事实一致性修正结合起来生成长故事。
- DOME (NAACL 2025), Dynamic Hierarchical Outlining with Memory-Enhancement:探索可以随着故事发展调整的动态大纲,以及长期记忆与时间冲突处理。
后记(三):回顾与基本要求
学长学姐为你的睡前故事提出了五方面的要求:
本题的最低完成度为第二至四幕。来自墨西哥的神秘蒙面大盗会根据你的完成度决定是否为你发放更多的算力资源。第五幕和第六幕的实现会作为加分项,请根据个人能力和时间酌情安排。
快来用你的绘本拯救学长学姐的睡眠吧!