基于AI agent的童话编剧与绘本生成器(一)环境搭建与SD生成图像初步实现
环境搭建
1. 安装Stable Diffusion WebUI
我通过拉取github里的SD仓库并运行完成了Stable Diffsuion本地的初步部署。
2. 下载模型和ControlNet
在图像生成的模型选择上,我选择了ToonYou模型,原因是:
这个项目做的是童话绘本,不是写实照片,也不是二次元动漫。ToonYou的风格介于迪士尼和儿童绘本之间——色彩温暖、线条柔和、角色表情丰富,非常适合这个场景。
如果选写实模型,生成的“小男孩”可能会像真人照片,不符合绘本的预期风格。如果选动漫模型,又太“日系”,少了绘本的质感。、
除此之外,我安装了controlnet的插件,controlnet可以在不破坏原有SD模型能力的前提下,给它加一个“额外的输入通道”,让SD模型在生成图像是会参考controlnet传入的图片。
ControlNet模型:ip-adapter-plus_sd15(这里因为ToonYou是基于SD1,5的模型,所以IP-adapter也要相应版本)
-
用于保持角色一致性,这是实现"同一个主角"的关键
3. 启动API服务
在WebUI启动时添加 --api 参数:
python launch.py --api --listen
这样就完成了本地的部署并能够调用相应api了!
初步生成图像
完成环境搭建后,接下来就是如何调用SD的API来生成图像。我把代码分成四个文件,各司其职:
| 文件 | 职责 |
|---|---|
config.py |
集中管理所有配置参数 |
generator.py |
核心生成器类,封装SD API调用 |
Image_generator.py |
对外接口层,提供简洁的调用函数 |
test.py |
测试脚本,验证功能 |
一、配置文件:config.py
config.py 是整个模块的“控制面板”。因为我会生成各种不同的角色,所以提示词不能写死具体特征,而是要从“风格”和“质量”两个维度来约束:
1. 通用风格提示词
GENERIC_STYLE = """
high quality, detailed, beautiful composition, vibrant colors,
clear subject, well-lit, appealing characters
"""
这个风格提示词的核心作用是定调。它告诉SD:我要的是高质量、细节丰富、色彩鲜艳、构图美观的图片。无论生成什么角色、什么场景,这个“画风基线”都要保持。
为什么不用“children's book illustration style”这类具体风格?因为后续可能生成不同风格的绘本,把风格写死在config里反而限制了扩展性。所以我只保留了通用画质要求,具体的风格描述由调用时的prompt传入。
2. 通用负向提示词
GENERIC_NEGATIVE = """
blurry, low quality, ugly, distorted, bad anatomy, watermark, text,
cropped, out of frame, extra fingers, mutated hands, missing fingers,
extra limbs, bad proportions, duplicate, weird colors
"""
负向提示词的作用是排除常见缺陷。SD在生成图像时经常出现畸形手指、多余肢体、模糊、水印等问题,把这些统统写进负向提示词,可以大幅提高生成质量。
这里面有几个关键项:
-
bad anatomy, extra fingers, mutated hands:针对SD最著名的“画手难题” -
watermark, text:避免生成带有版权标记或乱码文字的图 -
blurry, low quality:强制要求清晰度
二、核心生成器:generator.py
generator.py 里的 ImageGenerator 类负责所有与SD API的交互。其中最关键的就是ControlNet的集成。
调用ControlNet的核心步骤
在 generate 方法中,如果调用时传入了 character_id,就去读取对应的参考图,然后构建一个ControlNet单元:
-
读取参考图并转base64:SD API要求图片以base64字符串形式传递,不能直接传文件路径。
-
指定module和model:
ip-adapter_auto是预处理模块,ip-adapter-plus_sd15是具体模型。注意模型版本要和SD主模型匹配——ToonYou基于SD1.5,所以IP-Adapter也要用sd15版本。 -
设置weight权重:控制参考图的影响力。weight=1.0表示正常参考,调高会让角色更像参考图但可能动作僵硬,调低则角色容易变形。
-
设置guidance_start和guidance_end:都设为0.0和1.0,表示ControlNet在整个生成过程中全程生效。
三、对外接口:Image_generator.py 的封装
Image_generator.py 是对外提供的调用入口,采用单例模式——整个应用只有一个Generator实例,避免重复初始化SD连接。它对外暴露的函数都很简洁,调用方不需要知道ImageGenerator类的内部细节。
这里重点说一下提示词的封装思路。
如果让调用方直接拼接完整的prompt字符串,会带来两个问题:
-
调用方必须了解SD提示词的写法规范(比如哪些词在前、权重怎么加)
-
角色动作和场景描述的拼接逻辑会散落在各个调用处,难以统一修改
所以我设计了两层封装:
第一层:将生成参数结构化
对外提供的 generate_image 函数不接收完整的prompt,而是接收两个独立参数:action 和 scene。
def generate_image(action: str, scene: str, character_id: str = None, ...):
prompt = f"{action}, {scene}"
# 再自动追加通用风格提示词
full_prompt = f"{prompt}, {config.GENERIC_STYLE}"
...
调用方只需要说“做什么动作”和“在什么场景”,比如:
-
action = "a cute cat sitting" -
scene = "on a chair, cartoon style"
函数内部会自动拼接成完整的prompt,并追加配置中的通用风格。这样做的好处:
-
调用方不需要学习提示词工程,只需要描述画面内容
-
风格控制集中在配置文件中,换风格不用改业务代码
-
动作和场景分离,后续如果要从AI Agent生成的剧本中自动提取,解析起来也更方便
第二层:批量生成的结构化输入
批量生成函数 generate_batch 接收一个 pages 列表,每个元素是一个字典:
pages = [
{"action": "a little boy standing", "scene": "in a magical forest"},
{"action": "the same boy running", "scene": "through a flower field"},
]
这种结构化的输入格式,天然对接后续AI Agent的输出——大语言模型生成的剧本可以直接转换成这个格式,无需额外解析。
单例模式的考虑
_get_generator() 函数确保全局只有一个 ImageGenerator 实例。这是因为SD API的连接和模型切换有一定开销,重复初始化没有必要。同时,角色参考图保存在实例的目录属性中,单例可以保证多次调用之间参考图路径一致。
至于test脚本是目前测试用,故不作介绍。
总结与后续计划
当前成果回顾
到这一步为止,我已经完成了绘本生成器的图像模块基础建设:
-
环境搭建:Stable Diffusion WebUI 本地部署,ToonYou 模型配置,ControlNet IP-Adapter 安装,API 服务启动
-
代码架构:config(配置管理)、generator(核心生成逻辑)、Image_generator(对外接口)、test(测试验证)四个模块分层清晰
-
基础功能:单张图像生成、角色参考图上传与管理、ControlNet 初步集成、批量生成接口
目前已经可以实现:给定一段提示词,生成一张质量尚可的图片;如果上传了角色参考图,同一角色的多张生成结果在长相上有一定的相似度。
但这个“一定的相似度”离真正的角色一致性还有距离。后续需要在三个方向上深入优化。
一、角色控制的优化
当前问题
虽然 ControlNet 已经接入了,但同一个角色在不同画面中仍然会出现特征飘移——比如这一页的男孩头发偏棕,下一页偏黑;这一页眼睛大而圆,下一页眼睛细长。
二、提示词架构的优化
当前问题
目前的提示词是“通用风格 + 用户传入的动作和场景”简单拼接。这种方式的缺点是:
-
不同场景需要重复写相同的画质要求
-
难以针对不同角色类型动态调整提示词
-
提示词过长可能稀释关键信息
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)