1. 从一句提示词到一条成片这个项目到底在做什么第一次看到“扣子AI Agent 生成AI诗词视频”这个标题我脑子里冒出来的第一个念头是这事儿到底卡在哪一步写诗不难大模型随手就能来一首配音也不难TTS工具满地跑难的是把“写诗—配图—配音—合成—导出”这一整条链路串起来而且要做到输入一个主题词几分钟后直接拿到一条能发出去的成片。这才是这个项目真正有价值的地方。我前后用扣子搭过几个不同方向的智能体有做资讯聚合的有做客服问答的也有做内容批量生产的。诗词视频这条线是我个人觉得最适合拿来练手、也最容易做出效果的一个方向。原因很简单它的输入极简一个主题词或者一句描述就够了它的输出很直观一条带画面、带配音、带字幕的短视频好不好一眼就能看出来它的中间环节足够多能让你把扣子的工作流、插件、大模型节点、代码节点这些核心能力都摸一遍。这篇文章我打算把整个搭建过程拆开来讲从整体架构怎么设计到每个节点的参数怎么配再到我实际跑的时候踩过的坑和最后怎么绕过去的。不管你是刚接触扣子、还没搭过完整工作流的新手还是已经用过一段时间、想找一个综合性强一点的练手项目的朋友应该都能从里面找到对自己有用的东西。我尽量不堆术语该解释的地方用大白话讲清楚该给参数的地方直接给数值能抄作业的地方绝不让你自己猜。2. 整体架构设计为什么我选择工作流而不是纯对话2.1 纯对话模式为什么撑不起这个需求扣子里面搭智能体有两种主要形态一种是纯对话式的Bot你一句我一句地聊另一种是工作流你把整个处理链路画成一张流程图每个节点干一件事数据顺着连线往下走。很多人刚开始会想诗词视频嘛我直接跟Bot说“帮我写一首关于秋天的诗再配个视频”不就行了我试过不行。问题出在纯对话模式有三个硬伤。第一它没法稳定地调用外部工具链。你让大模型写诗它很擅长但你让它去调一个图像生成接口、再调一个语音合成接口、再把两段结果拼到一起它经常会在中间某一步“忘记”自己要干什么或者把参数传错。第二纯对话的输出格式不可控。你希望它最后给你一个视频文件的链接它可能给你一段描述视频的文字。第三纯对话没法做条件分支。比如图像生成失败了要不要重试配音时长和画面时长对不上要不要调整这些逻辑在对话模式里很难表达。工作流就不一样了。工作流本质上是一张有向图每个节点是一个确定性的操作连线决定了数据的流向。大模型节点负责“创作”这种不确定的部分代码节点和插件节点负责“执行”这种确定的部分两者各司其职。这是我最终选择工作流形态的核心原因。2.2 整条链路的节点拆解我把整个诗词视频生成的工作流拆成了六个核心环节按执行顺序排列主题解析节点接收用户输入的主题词用大模型扩展成一首完整的诗词同时输出画面描述关键词。画面生成节点根据画面描述关键词调用图像生成能力产出若干张配图。语音合成节点把诗词文本转成配音音频控制语速和情感。字幕生成节点把诗词按句切分生成带时间轴的字幕文件。视频合成节点把图片、音频、字幕按时间轴对齐合成视频。结果返回节点把视频链接和诗词文本一起返回给用户。这六个环节里第1步和第3步是扣子原生能力就能搞定的第2步和第5步需要借助外部工具或插件第4步和第6步用代码节点处理最灵活。下面我逐个展开讲。2.3 为什么把“写诗”和“画面描述”放在同一个节点里做这里有一个设计上的取舍值得说一下。写诗和生成画面描述理论上可以拆成两个独立的大模型节点一个专门写诗一个专门根据诗的内容生成画面描述。但我实测下来放在同一个节点里做效果更好。原因是诗词的意境和画面是强关联的。如果拆成两步第二步的大模型只能看到第一步输出的诗文本它需要重新理解一遍诗的意境这个过程中很容易丢失细节。比如诗里写“孤舟蓑笠翁”第一步的模型心里想的是一个老人在雪中钓鱼的画面但第二步的模型可能只抓到了“舟”和“雪”把“蓑笠翁”这个关键人物漏掉了。放在同一个节点里模型在写诗的时候就已经在脑子里构建了画面输出的画面描述会更准确。具体做法是在提示词里要求模型输出一个结构化的JSON包含poem诗词正文和scenes画面描述数组两个字段。这样后续节点直接解析JSON就行不用再做额外的文本提取。3. 核心节点配置详解每个参数都有它的道理3.1 主题解析节点提示词怎么写才稳定这个节点是整个工作流的起点它的输出质量直接决定了后面所有环节的天花板。我用的是扣子的大模型节点模型选的是豆包系列里偏创作向的那个版本。选它的理由很简单诗词创作对模型的文学素养要求比较高偏通用对话的模型写出来的东西容易大白话偏创作向的模型在遣词造句上明显更讲究。提示词我改了大概七八版才稳定下来。最开始写得太简单就一句“请根据主题写一首诗”结果模型有时候写五言有时候写七言有时候写现代诗格式完全不统一。后来我把要求写死了你是一位精通古典诗词的创作者。请根据用户提供的主题创作一首七言绝句。 要求 1. 严格遵循七言绝句的格律四句每句七个字。 2. 押平声韵韵脚统一。 3. 意境优美避免生僻字和典故堆砌。 4. 同时为每一句诗生成一个画面描述用于AI绘画。 5. 画面描述要具体包含主体、环境、光线、色调四个要素。 输出格式为JSON { poem: 四句诗用换行分隔, scenes: [ {line: 第一句诗, prompt: 画面描述}, ... ] }这里有几个细节是我踩坑之后加上的。第一明确指定“七言绝句”而不是笼统说“古诗”否则模型的选择空间太大输出不稳定。第二画面描述要求包含“主体、环境、光线、色调”四个要素这是我从大量AI绘画提示词里总结出来的最小充分集缺了任何一个生成的图都容易显得单薄。第三要求输出JSON格式这样后面的代码节点可以直接解析不用做正则匹配。提示大模型节点里有一个“输出格式”的选项可以选JSON。但即使选了模型偶尔还是会输出带markdown代码块包裹的JSON。稳妥的做法是在代码节点里做一层清洗把json和去掉再解析。3.2 画面生成节点图像风格的一致性怎么保证画面生成这一步我用的是扣子插件市场里的图像生成插件。市面上能用的图像生成能力不少选哪个主要看两点一是能不能通过参数控制风格二是生成速度能不能接受。诗词视频一般需要四张图如果每张图生成要等半分钟整个流程跑下来就太慢了。风格一致性是这一步最大的难点。四张图如果风格不统一一张水墨风、一张写实风、一张卡通风拼到一起会非常违和。我的做法是在每个画面描述的prompt前面统一加一段风格前缀。比如我想要水墨风格就在每个prompt前面加上“中国水墨画风格淡雅色调留白构图宣纸质感”。这段前缀对四张图是一样的这样即使每张图的具体内容不同整体风格也能保持一致。另外一个技巧是控制画面比例。诗词视频一般是竖屏的比例9:16。如果图像生成插件支持指定尺寸一定要设成竖屏。如果不支持生成横屏图之后在视频合成阶段做裁剪也行但会损失一部分画面内容不如一开始就生成对的尺寸。参数推荐值说明风格前缀统一添加保证四张图风格一致画面比例9:16适配竖屏短视频生成数量4张对应四句诗负面提示词文字、水印、畸形避免画面出现乱码文字3.3 语音合成节点语速和停顿的控制语音合成这一步看起来简单其实也有讲究。诗词的朗读和普通文本不一样它需要有节奏感句与句之间要有明显的停顿。如果直接用默认参数合成出来的音频往往语速偏快四句诗念完才十几秒配上画面会显得很赶。我的做法是在诗词的每句之间插入停顿标记。不同的TTS引擎停顿标记不一样有的用break time1s/有的用标点符号控制。我用的那个插件支持通过SSML标记来控制我就在每句诗后面加一个1.5秒的停顿。这样四句诗加上停顿总时长大概在25到30秒之间配上四张图每张图展示6到7秒节奏就比较舒服了。语速参数我一般设在0.9倍速左右比默认稍慢一点。音色选的是偏沉稳的男声或者偏温婉的女声具体看诗词的主题。如果是豪放派的主题用男声更合适如果是婉约派的女声更搭。这个可以在工作流里加一个条件判断根据主题解析节点输出的风格标签来动态选择音色。3.4 字幕生成节点时间轴怎么对齐字幕这块我是用代码节点自己算的。思路很简单先拿到音频的总时长然后按诗句的字数比例分配每句的显示时间。比如第一句7个字第二句7个字四句总字数28个字音频总时长28秒那每句就显示7秒。当然实际不会这么精确因为每句的朗读速度可能略有差异但作为近似方案已经够用了。代码逻辑大概是这样def generate_subtitles(poem_lines, total_duration): total_chars sum(len(line) for line in poem_lines) subtitles [] current_time 0 for line in poem_lines: duration (len(line) / total_chars) * total_duration subtitles.append({ text: line, start: round(current_time, 2), end: round(current_time duration, 2) }) current_time duration return subtitles这个方案的好处是不依赖任何外部工具纯计算稳定可靠。缺点是没有考虑实际的语音停顿如果某句诗朗读时停顿特别长字幕和语音会对不齐。要更精确的话可以用语音识别的方式反向获取每句的时间戳但那需要额外调一个识别接口流程会变长。对于诗词视频这种对精度要求不是特别高的场景按字数比例分配已经足够了。3.5 视频合成节点图片、音频、字幕怎么拼视频合成是整个工作流里最重的一步。扣子本身不直接提供视频编辑能力需要借助外部工具。我试过两种方案一种是用剪映的草稿文件格式把素材和编辑指令写成一个剪映能识别的草稿然后手动导入剪映导出另一种是直接调一个视频合成接口把图片、音频、字幕传进去接口返回合成好的视频。第一种方案的好处是剪映的编辑能力强转场、特效、滤镜都能用缺点是没法完全自动化最后一步还是要人工操作。第二种方案能全自动但合成效果受限于接口的能力转场效果比较基础。我目前用的是第二种方案为主、第一种方案为辅。日常批量生成用接口方案追求效率偶尔做精品的时候用剪映方案手动调一下转场和特效。两种方案的素材准备阶段是一样的区别只在最后合成那一步。4. 实操全流程从零搭一条能跑的工作流4.1 创建智能体和工作流打开扣子之后先在个人空间里创建一个新的智能体。名字随便起我一般叫“诗词视频生成器”。创建完之后在智能体的编排页面里找到“工作流”选项卡新建一个工作流。工作流建好之后你会看到一个空白的画布。左边是节点面板有各种类型的节点可以拖进来右边是属性面板选中某个节点之后在这里配置参数。整个操作逻辑跟画流程图差不多拖节点、连线、配参数三步走。我建议在开始拖节点之前先在纸上或者脑子里把整个流程的节点顺序想清楚。因为工作流一旦节点多了连线会变得很乱如果中途改结构可能要重新连很多线。我自己的习惯是先画一个简单的草图标清楚每个节点干什么、输入输出是什么然后再动手搭。4.2 配置开始节点和主题解析节点开始节点是工作流的入口它定义了用户需要提供哪些输入。这个项目里用户只需要提供一个主题词所以开始节点就配一个字符串类型的输入变量名字叫theme描述写“请输入诗词主题如秋天、思乡、边塞”。开始节点后面接主题解析节点。把开始节点的theme变量连到主题解析节点的输入上。主题解析节点选大模型类型模型选创作向的版本提示词用我前面给的那段。输出格式选JSON这样后面解析起来方便。这里有一个容易忽略的点大模型节点的温度参数。温度越高输出越随机温度越低输出越确定。写诗这件事需要一定的创造性但格式又需要稳定所以我一般把温度设在0.7左右。太低了写出来的诗很死板太高了格式容易乱。4.3 接画面生成和语音合成主题解析节点输出的是一个JSON里面包含poem和scenes两个字段。接下来要分两条线走一条线去生成画面一条线去合成语音。画面生成这条线需要先把scenes数组里的每个prompt取出来加上风格前缀然后逐个调图像生成插件。这里可以用一个循环节点或者用代码节点批量处理。我用的方式是代码节点先把四个prompt拼好然后并行调四次图像生成这样比串行快很多。语音合成这条线就简单一些把poem字段的文本传给TTS插件配上选好的音色和语速参数拿到音频文件的URL。两条线都完成之后需要一个汇合节点把结果收集起来。扣子里可以用一个代码节点做汇合把图片URL数组和音频URL拼成一个对象传给后面的视频合成节点。4.4 视频合成与结果返回视频合成节点拿到图片数组、音频URL和字幕数据之后调合成接口。合成接口一般需要指定每张图的展示时长、转场类型、背景音乐等参数。展示时长我一般设成和音频总时长除以图片数量相等这样图片切换和语音节奏能对上。转场类型选淡入淡出比较符合诗词的调性不会太跳。合成完成之后接口会返回一个视频文件的URL。把这个URL和诗词文本一起返回给用户整个流程就结束了。用户看到的就是一条完整的诗词视频可以直接下载或者分享。注意视频合成接口一般都有超时限制如果合成时间太长可能会失败。我的经验是把视频控制在60秒以内图片不超过6张这样合成成功率最高。5. 常见问题与排查技巧实录5.1 大模型输出格式不稳定怎么办这是最常见的问题。即使你在提示词里明确要求输出JSON模型还是有可能输出带markdown代码块的JSON或者在JSON前后加一些解释性文字。我的处理方式是在代码节点里做一层清洗import json import re def clean_json(raw_text): # 去掉markdown代码块标记 raw_text re.sub(rjson\s*, , raw_text) raw_text re.sub(r\s*, , raw_text) # 找到第一个{和最后一个}之间的内容 start raw_text.find({) end raw_text.rfind(}) if start ! -1 and end ! -1: raw_text raw_text[start:end1] return json.loads(raw_text)这段代码能处理绝大多数格式异常的情况。如果还是解析失败那说明模型输出的内容本身就有问题需要在提示词里再加强格式约束或者换一个更听话的模型。5.2 图像生成风格不统一怎么调风格不统一通常有两个原因一是风格前缀不够具体二是图像生成插件本身对风格的控制能力有限。我的建议是风格前缀尽量写详细不要只写“水墨风”要写“中国水墨画风格淡雅色调大量留白宣纸纹理墨色浓淡变化”。描述越具体生成结果越可控。如果换了详细的风格前缀还是不统一那可能是插件的问题。可以试试换一个支持风格参考图style reference的插件传一张风格基准图进去让所有生成都参考这张图的风格。这种方式比文字描述更可靠。5.3 音频和字幕对不齐怎么排查先检查音频总时长是不是准确获取到了。有些TTS插件返回的时长是估算值不是精确值。如果时长不准后面按比例分配的字幕时间轴肯定也是错的。解决办法是拿到音频文件之后用代码节点读一下音频的实际时长用实际时长来做计算。如果时长是准的但还是对不齐那可能是每句诗的朗读速度差异比较大。这种情况下可以改用语音识别的方式把合成好的音频再识别一遍从识别结果里拿到每个字的时间戳然后按诗句切分。这个方案更精确但多了一步识别流程会长一些。5.4 视频合成失败的常见原因视频合成失败的原因比较多我整理了一个速查表现象可能原因解决办法合成超时视频太长或图片太多控制在60秒内图片不超过6张音频丢失音频URL不可访问检查音频文件是否已上传到可公开访问的存储字幕乱码编码格式不对统一用UTF-8编码画面黑屏图片格式不支持用JPG或PNG格式音画不同步时间轴计算错误检查音频实际时长和字幕时间轴5.5 几个我踩过的坑第一个坑是变量命名。扣子工作流里的变量名如果用了中文或者特殊字符在某些节点里会识别不了。我现在的习惯是全部用英文小写加下划线比如poem_text、image_urls、audio_url这样最稳妥。第二个坑是节点之间的数据传递。扣子的工作流里上游节点的输出要显式地连到下游节点的输入上不是自动传递的。我刚开始搭的时候经常忘记连线跑起来发现下游节点拿不到数据排查半天才发现是线没连。第三个坑是测试的时候用太复杂的主题。我一开始测试用的是“红楼梦”结果模型写出来的诗引用了大量典故画面描述也很抽象生成的图完全看不懂。后来换成“秋天”“月亮”这种简单的主题效果立刻就好了。建议测试阶段用最简单的主题等流程跑通了再尝试复杂的。6. 进阶玩法让这条工作流更实用6.1 批量生成一次产出多条视频单条生成跑通之后很自然会想到批量生成。比如输入十个主题词一次性产出十条视频。这个用扣子的批量处理能力可以实现把主题词做成一个列表工作流对列表里的每个元素执行一遍。但批量生成有两个问题要注意。一是并发限制很多插件和接口都有并发数限制同时跑太多会报错。我的做法是加一个延时节点每生成一条之后等几秒再生成下一条。二是成本控制图像生成和视频合成都是按次计费的批量生成之前最好先算一下成本别跑着跑着额度用完了。6.2 风格切换让用户选风格现在的工作流是固定一种风格如果要支持多种风格可以在开始节点加一个风格选项让用户选“水墨”“油画”“卡通”“写实”等。然后根据用户的选择动态拼接不同的风格前缀。这个改动不大但实用性提升很明显。实现方式是在代码节点里做一个映射表style_prefixes { 水墨: 中国水墨画风格淡雅色调留白构图, 油画: 古典油画风格厚重笔触丰富色彩, 卡通: 扁平卡通风格明快色彩简洁线条, 写实: 超写实摄影风格自然光线细腻质感 } prefix style_prefixes.get(user_style, style_prefixes[水墨])6.3 背景音乐让视频更有氛围诗词视频加上背景音乐氛围感会强很多。可以在视频合成节点里指定一个背景音乐文件设置音量低于配音音量这样不会盖过人声。背景音乐的选择可以根据诗词的风格来定豪放派的配古筝或琵琶婉约派的配笛子或古琴。背景音乐的来源要注意版权问题。我一般用免版税的音乐库或者用AI生成的音乐。扣子插件市场里也有音乐生成的插件可以根据关键词生成一段背景音乐虽然质量参差不齐但胜在方便。6.4 发布与分享怎么让更多人看到工作流跑通之后可以把智能体发布到扣子的应用市场或者生成一个分享链接发给朋友。如果要做成公开的服务还可以把工作流部署成一个API用其他平台来调用。发布之前记得把测试用的临时数据清理掉把提示词里的调试信息删掉确保用户看到的是一个干净、完整的体验。另外建议在智能体的描述里写清楚它能做什么、怎么用这样别人第一次打开就知道该怎么操作。7. 关于工具选型的一些个人看法扣子、Dify、n8n这几个工作流平台我都用过各有各的适用场景。扣子的优势在于和国内的大模型、插件生态结合得比较紧密中文支持好上手门槛低适合快速验证想法。Dify在模型接入的灵活性上更强一些适合需要接多种模型的场景。n8n更偏向通用自动化适合把各种SaaS服务串起来。做诗词视频这个项目我选扣子主要是因为它的插件市场里有现成的图像生成和语音合成能力不用自己从头接API。而且扣子的大模型节点对中文创作的支持确实不错写出来的诗词质量比我试过的其他方案要好一些。如果你已经熟悉了扣子的基本操作想找一个综合性强一点的项目来练手诗词视频这个方向我觉得挺合适的。它涉及的节点类型多但每个节点的逻辑都不复杂搭一遍下来能把工作流的核心概念都过一遍。而且做出来的东西看得见摸得着比单纯跑一个文本处理的工作流有成就感得多。最后分享一个小技巧搭工作流的时候每加一个节点就测试一次不要等全部搭完再测。因为一旦出问题你很难判断是哪个节点的问题。逐个节点测试每个节点的输入输出都确认没问题了再往下接这样排查起来会轻松很多。我在最开始搭的时候就是一口气搭完再测结果一个变量名写错了排查了快一个小时才找到。