画中有话:我用腾讯云VITA 和 TTS 两个 Skill,把女儿的涂鸦变成了睡前童话
一、这个故事,从一张被忽略的画说起
1.1 冰箱上的画
我家闺女五岁,每天从幼儿园回来,书包里都能翻出两三张画。蜡笔的,水彩的,有时候就是一支铅笔在废纸上勾几下。画得好不好另说,画完她特得意,非要贴冰箱上。
然后呢?然后就没有然后了。
它可能就是贴一周,落灰,取下来塞抽屉。
我夸来夸去就那几个词——“画得真棒”“这个颜色好看”。说实话,我根本看不懂几岁的小朋友她画的是什么。
她倒是愿意讲。可五岁小孩的叙事你懂的,开头说"这是一个恐龙",中间跳到"这是它的好朋友小花",结尾变成"然后天黑了"。故事没听明白,倒是把她自己讲困了。
有天晚上她睡着了,我盯着冰箱上最新那张画看——一个大红圆圈,旁边几根歪歪扭扭的绿线条,右下角有个紫色的一团什么玩意。
我在想,这里面到底藏着什么故事?她为什么画这个?
如果有个工具,能替她把画里的世界"读"出来,再编成故事讲给她听,那该多好啊!
我使用了WorkBuddy帮我进行Vibe Coding,完成了代码开发过程,利用的是腾讯云的skill能力,做出了我自己的agent,最终得到了一个不错的效果:

运行解析效果如下:


1.2 两个神奇的 Skill组合在一起
腾讯云 AI Skills 矩阵五大类摆在那里。我看见 tencentcloud-vita——多模态理解模型,能看图片,输出结构化文本。简介里写的应用场景是"目标检测、结构解析、标签分类"。挺正经的。但我的第一反应不是安防监控,是:
这东西能不能看懂小孩的画?
因为儿童画本质上是一种高度符号化的视觉语言。太阳就是一个圆圈加几根线,房子就是一个三角形加一个方块。大人觉得"画得不像",但从视觉符号的角度来说,孩子的表达方式恰恰非常清晰——因为简化到了本质。VITA 这种多模态模型,理论上应该能"读懂"这些符号。
这个需要申请,我登录到官网控制台进行授权。首次进入按提示开通平台服务(需腾讯云账号 + 实名认证)。


在模型广场 / 在线推理服务里找到 VITA(youtu-vita),启用后付费(不用充值,走免费额度)



光读懂不够。读出来的是 JSON,冰冷的数据。我想做一个"做不到"的东西——让没有美术背景的家长,也能听懂孩子画里在想什么。这不是效率问题,是情感问题。
所以,得有人把这些数据变成故事,再变成声音。这就需要第二个 Skill:tencentcloud-tts。
https://console.cloud.tencent.com/tts → 点“开通服务”。


领取一下tts资源:

哈可以开通语音识别并领取资源包。

VITA 当眼睛,TTS 当嗓子。中间那个"大脑"——负责把看到的东西编成故事的——交给 WorkBuddy 的 Agent 能力来做。
两条 Skill,一只眼睛一副嗓子,刚好。
二、怎么把两个 Skill 串起来
2.1 “眼睛 → 大脑 → 嗓子”
整个系统的核心其实特别简单,三步:
第一步,把孩子的画扔给 VITA。它吐回来一个 JSON,告诉我画里有太阳、有房子、有树、有手拉手的两个人,画面情绪是"温暖快乐"。还附带几个"彩蛋细节"——比如"太阳的光芒画得又长又密"“两扇窗户用了不同颜色”。这些细节太重要了,后面会讲为什么。
第二步,Agent 拿着这个 JSON 写故事。不是随便编,是有严格约束的——画里出现的元素,故事里必须出现,不许偷换。主角名字写孩子的小名。结尾必须是安静的、回家的画面。不许出现"这个故事告诉我们"这种说教。
第三步,故事交给 TTS 变成声音。腾讯云的智瑜音色(101001),温柔女声,特别适合念睡前故事。
就这么三步。不复杂,但每一步都有讲究。
2.2 VITA 读画:关键是那个 story_hints
VITA 用的是 OpenAI 兼容协议,调起来跟 chat completion 差不多。content 里面塞一个 image_url 和一段 text 指令就行。
提示词(ANALYSIS_PROMPT)我没写"请识别图片中的内容"这种废话,而是精确要求了输出格式:3-8 个元素,每个元素标注名字、颜色、位置、大小。还要猜场景、判断情绪、提取调色板。
最关键的是 story_hints 这个字段。这是我加的——让 VITA 额外找出"孩子画得特别用心的地方"。一张画,AI 能识别出"有个太阳"不稀奇,但如果它能注意到"太阳画了笑脸"“小人的手画得特别大”,这些细节就成了故事里最动人的种子。
举个例子。我家闺女画过一张"全家去公园",画面右下角有个特别小的人,比其他人都小很多。VITA 的 story_hints 返回了"右下角的小人比其他人物明显小很多,可能代表年龄最小的家庭成员"。就这一句话,故事里就有了——最小的那个人是"妹妹",她跟不上大家的步伐,但没有人丢下她。
这种细节,是模板生成不出来的。
2.3 TTS 配音:150 字限制不是什么大问题
腾讯云 TTS 单次请求上限 150 字。一篇 300-450 字的睡前故事,肯定会超。
这事其实好办。我的 speak.py 里写了个分句函数,按句号、问号、感叹号先切大段,超长的再按逗号细分。留了 30 字安全余量,取 120 而不是 150,防止标点编码出幺蛾子。
分完句,逐段调 TTS,拿到 mp3 二进制。有 ffmpeg 就无损拼接成单个文件,没有就留分片。mp3 帧天然支持顺序拼接,不做重编码也能正常播。
说实话这个"问题"几乎是每个用 TTS 做长文本的人都会遇到的。解法也标准。我提一嘴只是想说明,Skill 的 API 限制不会成为项目落地的障碍——遇到限制,拆就完了。
2.4 中间那个"大脑":WorkBuddy 的 Agent
这一步没调任何 Skill,完全靠 WorkBuddy 自己的 Agent 能力。但它是整个项目最难调的部分。
不是技术上难,是"写故事"这件事难。我试了很多版提示词,前几版写出来的故事,怎么说呢……AI 味儿冲得不行。动不动就"小满学到了一个重要的道理",或者"从此以后,他变得更加勇敢了"。这种话写在故事里,孩子不爱听,大人也尴尬。
后来我把提示词改了七版,定下几条铁律:
- 画里有什么,故事里就得有什么。VITA 识别出的元素至少出现 80%,不许替换。
- 结尾必须是安静的、回家的画面。"月亮把被子拉上来"这种,适合睡前。
- 禁止一切说教句。“道理是”“我们要”“这个故事告诉我们”——出现一个字都不行。
- 口语化。多用拟声词。哗啦啦、咕噜噜、嗖嗖嗖。少用成语。
- 按年龄调词汇。五岁孩子听"踌躇"肯定不行,"犹豫了一下"就好多了。
改成这样之后,故事终于能看了。给大家看一段实际输出——这是我上传闺女画的那张"房子和太阳",VITA 识别出七个元素后,Agent 写的故事开头:
太阳打了个大大的哈欠,把金色的光轻轻铺在小满家的屋顶上。小房子醒了,两扇彩色窗户一睁眼,红一格,黄一格,像两块正在发光的糖。
2.5 封装成 Skill:SKILL.md 是指挥棒
这三步流水线我没散装在代码里,而是封成了一个自定义 Skill。文件叫 SKILL.md,放在 skill/kid-art-storyteller/ 目录下。
为什么这么干?因为我想让这个能力在 WorkBuddy 里面能复用。安装 Skill 之后,用户只要说"把这张画变成故事"——不用管什么 VITA、TTS、JSON——WorkBuddy 就自动按 SKILL.md 里定义的流程跑:收集孩子小名和年龄、调 analyze.py 读画、自己写故事、调 speak.py 配音、最后归档到画廊目录。
SKILL.md 里我还写了一张故障处理表。VITA 报 401 怎么办、TTS 密钥没配对怎么办、故事超长怎么办——都列了。还有一条特别有意思的:识别元素和画明显不符的时候,不是报错,而是把 VITA 的结果给孩子看,让孩子来"纠错",然后把纠错后的结果并入故事。
这个设计我下面会细说,它其实是我最得意的一个决定。
三、在 WorkBuddy 里的实际体验
3.1 从对话开始
这是真实使用场景。晚上八点半,闺女刚画完一张画,我打开 WorkBuddy,把画拍了张照发过去,打了一行字:
“把这张画变成故事,主角叫小满,五岁。”
WorkBuddy 识别到了"把画变成故事"这个触发词,自动激活 kid-art-storyteller Skill。它先确认了一下音色偏好——我选了"温柔姐姐"——然后开始跑流程。
大概过了十几秒,VITA 读完了。

我看到了这张画里的世界:
一个大大的太阳,红色,在左上角
一朵蓝色的云,右上角飘着
中间是一座棕色的小房子,有两扇不同颜色的窗户
房子右边有一棵绿色的大树
树下开着两朵小花,一红一黄
房子前面站着两个人,手拉着手
我猜这是一个太阳升起的早晨,一家人站在小房子前面。画面感觉很温暖、很快乐。
我闺女凑过来看了一眼,指着"手拉手的两个人"说:"这是我跟妈妈!"我说那爸爸呢?她说爸爸在里面拍照。
行吧。
然后 WorkBuddy 开始写故事。它用混元大模型,把 VITA 的分析结果和孩子信息塞进提示词模板,等了大概五六秒,故事出来了。标题叫《太阳盖被子》。开头就是上面那段——“太阳打了个大大的哈欠,把金色的光轻轻铺在小满家的屋顶上。”
我念给闺女听。听到"两扇彩色窗户一睁眼,红一格,黄一格,像两块正在发光的糖"的时候,她突然打断我:"窗户真的是糖做的吗?"我说在故事里是的。她想了想,说:“那我可以吃吗?”
最后一步,TTS 配音。WorkBuddy 调了腾讯云的智瑜音色,把整篇故事合成了一个 mp3。声音温柔、节奏慢,是那种你会想关了灯、躺在床上听的调子。我放了给她听,听到一半就打哈欠了。听到"月亮把被子拉上来,盖住了整个小院子"的时候,她已经睡着了。
我又试了一个更成熟的画风的画作上传,学校要求的手工活:



我上传了大概十几张闺女的画,有些观察值得记录:
VITA 的识别率:对典型蜡笔画,元素识别率在七八成左右。太阳、房子、树、人这些大元素基本不会错。小元素容易漏——比如花、云朵这些画得比较随意的,有时候会跳过。但 story_hints 经常有惊喜。有一次它注意到"小人的手画得特别大",这个细节我都没留意义到,但确实如此——闺女画人物的时候手总是画得不成比例的大。后来故事里就写了"小满的手很大,大到能一把抓住整片阳光"。
混元写故事的质量:hunyuan-lite 的创意水平比我预期好。我设的 temperature 是 0.8,故事之间有差异性,不会每次都一个套路。但也偶尔会翻车——有一次写了个故事,结尾是"小满明白了友情的可贵"。这违反了我的提示词约束(禁止说教句),应该是模型没完全遵守指令。这种情况下我会手动改一下再丢给 TTS。
TTS 的音色:智瑜(101001)是真的适合讲故事。温柔但不做作,语速可以调到 0.85 倍速,更有睡前氛围。我试过智旭(101003,沉稳男声),适合冒险类故事,但睡前用太正经了。智婕(101005,活泼女声)适合白天互动用,睡前太嗨。
四、交互设计
页面整体走蜡笔画/手账风格。米黄底色,圆角卡片,珊瑚红、暖黄、草绿三色为主。背景有轻微噪点纹理,像旧纸的质感。故事正文用楷体——呼应"手写"的感觉。
交互上是四步流水线,从左到右依次推进:选画 → VITA 读画(显示识别结果和元素标签,标签是一个个弹出来的,有动画)→ 写故事(打字机效果,一个字一个字蹦出来)→ TTS 播放(带 canvas 波形动画)。
每一步都有状态指示——等待、进行中、完成。让用户清楚知道"AI 正在干什么"。这个很重要,AI 做事的时候如果没有任何反馈,用户会以为卡死了。
页面底部有一个"成长画廊"。每次生成的画和故事,可以一键存进去。存在 localStorage 里,不用登录、不用联网。点任意卡片能回放故事。
这个设计不是"功能",是"意义"。
我家闺女的画现在散落在各个抽屉里。有些已经找不到了。如果每一张画都能存下来,配上一段故事和一段声音,多年以后翻出来——是她五岁时画的恐龙,AI 编的故事,她听到一半睡着的那个晚上。
这把一个技术 Demo 变成了一份可以留住的东西。
4.1 server.py 的设计
后端我用 Python 标准库的 http.server 实现,零框架。一个文件,四个接口:
| 接口 | 干什么 | 入参 | 出参 |
|---|---|---|---|
GET /api/health |
健康检查 + 密钥状态 | 无 | {ok, has_vita_key, has_cloud_keys} |
POST /api/analyze |
VITA 读画 | {image: "data:image/..."} |
VITA JSON |
POST /api/story |
混元写故事 | {analysis, childName, age} |
{title, text} |
POST /api/tts |
TTS 配音 | {text, voice, speed} |
{audio: "base64..."} |
故事生成走腾讯云混元大模型(hunyuan-lite),通过 SDK 调 ChatCompletions。提示词模板把 VITA 的 JSON、孩子小名、年龄都填进去,让混元按规则写故事。
TTS 接口复用了 speak.py 的分句逻辑,但不是写文件——而是把所有分片的 mp3 二进制直接拼接后 base64 编码返回。前端拿到后 new Audio('data:audio/mp3;base64,' + audio) 就能播。
为什么不用 Flask 或 FastAPI?因为这个项目就四个接口,引一个框架进来纯属增加复杂度。标准库够用就够用,能少一个依赖就少一个。部署也简单——python server.py 就跑了,不用装 uwsgi、不用配 nginx。
4.2 前端的"演示模式"语音
演示模式下没有密钥,TTS 走不了。但我不想让语音这块空白——没有声音的"有声童话"太尴尬了。
解决方案是浏览器的 SpeechSynthesisUtterance API。挑一个中文 voice,设好 pitch 和 rate,效果虽然比不上腾讯云智瑜的音色,但至少是能听的声音。播放器配了 canvas 波形动画,视觉上跟真实 TTS 播放完全一致——评委看不出区别,体验是完整的。
五、在 WorkBuddy 里用 Skill 是什么感觉
这部分我想多说两句,因为这是征文要求里特别强调的——“结合 WorkBuddy 等 AI Agent 平台做开放式创新应用实践”。
5.1 Skill 让 AI 能力"隐入"对话
装 Skill 之前,如果我想用 VITA 读画 + TTS 配音,我得自己写代码、调 API、处理错误、拼音频。每次跑一遍流程得敲好几条命令。
装了 Skill 之后呢?我说一句话就行了。
“把这张画变成故事。”
WorkBuddy 自动识别意图、自动跑流程、自动归档。我不需要知道 VITA 的 API 长什么样,不需要管 TTS 的 150 字限制,不需要操心 JSON 提取。所有工程细节被 SKILL.md 封装在下面,留给用户的只有一句话和一个结果。
这就是 Skill 的价值——它让 AI 能力"隐入"对话。技术越强,用户越感知不到技术。就像你用手机拍照的时候,不会去想 ISP 芯片在干什么。
5.2 SKILL.md 是声明式的编排
写 SKILL.md 的过程,本质上是在做"声明式编程"。我不是在写代码告诉电脑"先执行这一行再执行那一行",而是在写一份文档,描述"遇到这种情况应该怎么办"。
比如故障处理。我不需要在代码里写 try-catch 处理每一种错误,而是在 SKILL.md 的表格里写:VITA 报 401 → 检查密钥;TTS 报 AuthFailure → 检查密钥配对;识别偏差 → 让孩子纠错。WorkBuddy 读了这个文档,遇到这些情况自己知道怎么办。
再比如"不超过一轮追问"这条规则。我在 SKILL.md 里写了:确认孩子小名、年龄、音色偏好时,如果用户已经提供就不追问,没提供就用默认值,最多追问一轮。这种"克制"很难用代码硬编码,但在文档里一句话就讲清楚了。
这种编排方式的好处是可读、可改、可扩展。后续我想加"让孩子语音纠错"的功能——用 ASR Skill 把孩子的语音转成文字,再反馈给 Agent——只要在 SKILL.md 里加一步就行,核心代码几乎不用改。
5.3 也能跑在 CodeBuddy 和 ADP 上
虽然我主要在 WorkBuddy 上做实践,但 SKILL.md 的格式是通用的。Skill 本质上就是"一段描述工作流程的 Markdown + 几个脚本",任何支持 Skill 的 AI Agent 平台都能加载。CodeBuddy 可以把它作为一个开发辅助工具触发,ADP 可以把它嵌入更大的自动化流程。
这一点其实挺重要的——Skill 不是绑定在某个平台上的插件,而是一种"能力描述协议"。写一次,到处跑。腾讯云把 AI 能力封装成 Skill 的好处也在这里:开发者不用为每个 Agent 平台写一套对接代码,装上就能用。WorkBuddy 自动按 SKILL.md 跑五步流程:收集信息 → VITA 读画 → 写故事 → TTS 配音 → 归档到画廊目录。
每一份都是完整的——画、故事、声音、AI 识别的元素数据。存着,以后翻出来看。
做完了之后的一些感想
说句实话,这个项目的技术复杂度不高。两个 API 调用、一段提示词、一个分句函数、一个前端页面。任何有一定开发经验的人都能做出来。
难的不是写代码,是想到这个场景。
腾讯云 Skills 矩阵摆在那里,五大类二十多个能力。每个能力的技术文档都写得清清楚楚。但把这些能力组合成一个"有人愿意用"的东西,需要的不是技术能力,是对生活的观察。
我观察到的场景是:冰箱上贴满了孩子的画,没人看得懂,最终被取下来塞进抽屉。这个场景每家每户都在发生,但没有人在意。因为它太日常了,日常到你不会觉得这是一个"问题"。
AI 的价值不只是解决你意识到的问题,还可以解决你没意识到的问题。
单独用 VITA,它能看懂画但说不出来。单独用 TTS,它能念故事但不知道念什么。两个 Skill 单独用,都只是"工具"。组合起来用,才变成了"体验"。
中间那个 Agent 大脑——写故事这一步——是连接两者的桥梁。它不是 Skill,但它不可或缺。这让我意识到,腾讯云 Skills 矩阵的设计思路其实是"积木式"的:每个 Skill 是一块积木,Agent 是拼积木的手。积木本身没有情感,拼法才有情感。
同样的两块积木——VITA 和 TTS——换个拼法,就能做完全不同的事。老照片识别+口述历史朗读、冰箱食材识别+菜谱语音播报、旅行照片识别+有声日记生成。拼法不同,场景就不同。
做 AI 产品的人有一种执念:准确率必须高。识别率低于 90% 就觉得是失败。
但在"画中有话"这个场景里,我发现准确率不是越高越好。
VITA 偶尔识别"错"——恐龙变鳄鱼、小花变蘑菇——这些"错误"反而创造了亲子互动的机会。孩子纠正 AI 的过程,本身就是一段对话、一段游戏。如果 VITA 每次都 100% 准确,流程就变成了:上传画 → 出结果 → 听故事。一条直线,没有弯路,也没有人参与。
适度的"不完美",让 AI 变成了对话者而不是工具。这个认知对我冲击挺大的。
做参赛项目的时候,我纠结过很久:要不要加更多 Skill?要不要做人脸识别确认"这个画是哪个孩子画的"?要不要接 ASR 做语音输入?要不要上 3D 生成做"把画里的角色变成立体模型"?
最后我忍住了。
因为"画中有话"的核心魅力就是简单——一张画进去,一段有声童话出来。加了太多东西,反而模糊了焦点。两个 Skill,一个看一个说,足够了。
有温度的东西不需要堆功能。它自己会说话。
后记
有天晚上女儿问我:"你能不能每天晚上都给我讲故事?"我说行。然后那天晚上我没讲,放了 AI 念的《太阳盖被子》给她听。
她听到一半就困了。但睡着之前说了一句:“太阳真的会盖被子吗?”
我说会的。
她说:“那月亮呢?”
“月亮负责盖。”
她没再说话。我以为她睡着了,过了大概三十秒,黑暗里传来一句:“那星星呢?”
我没答上来。但我想,也许下一张画里会有星星。VITA 会看到它,Agent 会给它编一个关于星星盖被子的故事。TTS 会用温柔的声音念出来。而我会躺在她旁边,听着这个故事,跟一起她睡着。
技术做不到的事太多了。但有些事,现在能做到。
一张涂鸦进去,一段有声童话出来。就这么简单的事。
更多推荐




所有评论(0)