1. 从一句主题到成片:Claude Code 编排 GLM-5.1 短剧智能体的真实场景
短视频短剧智能体,说白了就是你把一句主题丢进去,它自己完成编剧、分镜、台词、配音、合成这一整条链路,最后吐出一个能直接发平台的 mp4。听起来像现成平台就能干的事,但真上手你会发现两个问题:一是生成结果不受控,人物、节奏、BGM 全是黑盒,改都没法改;二是对想研究实现过程的人来说,中间环节被封装得太死,你根本不知道分镜提示词长什么样、台词是怎么切分的。
我这次的做法是用 Claude Code 当编排层,把 GLM-5.1 当内容生成大脑,再通过 TaoToken 的统一 Key 把模型调用收敛到一个入口。Claude Code 负责跑智能体的目录结构、调度各个步骤、读写中间产物;GLM-5.1 负责把主题扩写成剧本、拆成分镜、生成每个镜头的提示词和台词;TaoToken 负责让这些调用不用来回换 Key、换 Base URL。适合谁?适合已经会用命令行、想自己掌控短剧生成全流程、并且希望后续能改代码迭代的人。
整个智能体的核心思路是「分阶段落盘」:每一步的产物都写成文件,而不是全塞在内存里。这样你随时能停下来看剧本对不对、分镜合不合理,出问题也能定位到具体哪一步。下面我按实际搭建顺序拆开讲,包括目录结构、GLM-5.1 的调用参数、TaoToken 的配置方式,以及一键出片的验证和排错。
2. TaoToken 统一 Key 前置准备:Base URL、API Key 与模型 ID 三件套
在动手写智能体之前,先把模型调用这条链路打通。TaoToken 的作用是给你一个统一的接入点,Claude Code 里所有对 GLM-5.1 的请求都走同一个 Base URL 和同一个 Key,不用为每个模型单独配环境变量。官网入口是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 地址是 https://taotoken.net/api 。
你需要准备的三件套是:
- Base URL:
https://taotoken.net/api - API Key:在控制台创建,形如
sk-xxxx - Model ID:GLM-5.1 对应的模型标识,填到配置里
创建 Key 的路径是控制台里的 API Keys 页面,进去新建一个,复制出来存好。这里注意一点,Key 只在创建时完整显示一次,后面再进列表只能看到前缀,所以复制完先贴到你的.env或者配置文件中。
为什么强调「统一 Key」?因为短剧智能体在跑一条视频时会发起很多次模型调用:剧本扩写一次、分镜拆分一次、每个镜头的提示词各一次、台词润色可能又一次。如果每次调用都要切换不同的 Key 或 Base URL,代码里会到处是判断分支,维护成本极高。统一到一个入口后,你只需要在配置里改一处,全流程生效。
配置方式我推荐用环境变量加一个config.toml,这样 Claude Code 读取时不会把 Key 硬编码进代码。先建一个项目根目录,然后在里面放配置文件。下面这段是config.toml的写法,路径放在项目根的config/config.toml:
[llm] base_url = "https://taotoken.net/api" api_key = "sk-你的Key" model_id = "glm-5.1" timeout = 120 max_retries = 3 [agent] script_max_tokens = 4096 shot_max_tokens = 2048 temperature = 0.8对应的读取代码用 Python 写,Claude Code 里跑脚本时直接加载:
import tomllib from pathlib import Path def load_config(path="config/config.toml"): with open(Path(path), "rb") as f: cfg = tomllib.load(f) return cfg cfg = load_config() base_url = cfg["llm"]["base_url"] api_key = cfg["llm"]["api_key"] model_id = cfg["llm"]["model_id"]如果你用的是 Claude Code 自带的模型配置,也可以在它的 settings 里指定 Base URL 和 Key,让 Claude Code 自身的推理请求也走 TaoToken。这样编排层和生成层用的是同一套凭证,排查问题时只需要看一个入口的日志。把这一步做完,后面所有对 GLM-5.1 的调用都能直接复用这份配置。
3. 可复制的智能体目录结构与 GLM-5.1 调用配置
目录结构决定了这个智能体好不好维护。我踩过的坑是一开始把所有逻辑写在一个main.py里,跑到第三步就分不清哪个变量是分镜、哪个是台词。后来改成按阶段分目录,每个阶段只负责一件事,产物落盘,下一步读上一步的文件。下面是可直接复制的结构:
shortdrama-agent/ ├── config/ │ └── config.toml ├── prompts/ │ ├── script.txt │ ├── storyboard.txt │ └── shot_prompt.txt ├── src/ │ ├── llm_client.py │ ├── step1_script.py │ ├── step2_storyboard.py │ ├── step3_shot_prompts.py │ ├── step4_tts.py │ └── step5_compose.py ├── workspace/ │ ├── script.json │ ├── storyboard.json │ ├── shots/ │ └── output/ └── run.shworkspace是运行时产物目录,script.json存剧本,storyboard.json存分镜,shots/存每个镜头的提示词和素材,output/存最终合成的视频。prompts里放各阶段的提示词模板,改文案不用动代码。
llm_client.py是统一调用入口,所有对 GLM-5.1 的请求都从这里走:
import requests from config_loader import load_config cfg = load_config() BASE_URL = cfg["llm"]["base_url"] API_KEY = cfg["llm"]["api_key"] MODEL_ID = cfg["llm"]["model_id"] def chat(messages, max_tokens=2048, temperature=0.8): url = f"{BASE_URL}/v1/chat/completions" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } payload = { "model": MODEL_ID, "messages": messages, "max_tokens": max_tokens, "temperature": temperature, } resp = requests.post(url, json=payload, headers=headers, timeout=120) resp.raise_for_status() return resp.json()["choices"][0]["message"]["content"]注意MODEL_ID要和你在 TaoToken 控制台看到的模型标识一致,填错会直接报模型不存在。temperature在剧本阶段可以高一点(0.8 到 0.9),让剧情有发散;到分镜提示词阶段建议降到 0.5 左右,保证镜头描述稳定。
step1_script.py负责把主题扩写成带场次的剧本,读prompts/script.txt模板,把主题和时长塞进去,调用chat(),结果写workspace/script.json。step2_storyboard.py读剧本,拆成一个个镜头,每个镜头带时长、景别、台词。step3_shot_prompts.py为每个镜头生成视频生成用的提示词。step4_tts.py处理配音,step5_compose.py用 ffmpeg 把镜头素材、音频、BGM 合成。
run.sh是一键入口:
#!/bin/bash set -e python src/step1_script.py --topic "$1" --duration "$2" python src/step2_storyboard.py python src/step3_shot_prompts.py python src/step4_tts.py python src/step5_compose.py echo "成片已生成:workspace/output/final.mp4"跑的时候bash run.sh "都市逆袭" 60,主题和时长作为参数传进去。每个步骤失败会中断,方便你定位。这套结构的好处是,你想换视频生成模型,只改step3和step5,前面的剧本和分镜逻辑完全不用动。
4. 验证请求与一键出片:从主题到 final.mp4 的完整跑通
配置和结构都就位后,先别急着跑全流程,单独验证一次 GLM-5.1 的调用是否通。写一个最小测试脚本:
from src.llm_client import chat resp = chat([ {"role": "user", "content": "用一句话写一个都市短剧的开场。"} ], max_tokens=128, temperature=0.8) print(resp)跑通会看到模型返回一句开场白。如果这一步就报错,先别往下走,去第 5 节对照报错排查。这一步通了,说明 Base URL、Key、Model ID 三件套没问题。
接着跑剧本阶段:
python src/step1_script.py --topic "外卖小哥逆袭" --duration 60成功后workspace/script.json里会出现结构化的剧本,类似:
{ "title": "外卖小哥逆袭", "scenes": [ {"scene_id": 1, "duration": 8, "summary": "主角在雨中送餐被刁难"}, {"scene_id": 2, "duration": 12, "summary": "主角捡到神秘订单"} ] }检查场次数量和总时长是否接近你传入的 60 秒。如果偏差太大,说明提示词里对时长的约束不够,回去改prompts/script.txt,明确写「总时长控制在 60 秒,每场 8 到 15 秒」。
然后依次跑分镜和提示词:
python src/step2_storyboard.py python src/step3_shot_prompts.pyworkspace/storyboard.json会给出每个镜头的景别、台词、时长,workspace/shots/下每个镜头一个 json,里面是视频生成提示词。你可以打开其中一个看,比如:
{ "shot_id": 1, "prompt": "雨夜街道,外卖员骑车,中景,冷色调,电影感", "duration": 4, "dialogue": "这单再超时就白干了" }确认提示词和台词合理后,跑配音和合成:
python src/step4_tts.py python src/step5_compose.pystep5用 ffmpeg 把shots/下的视频片段按顺序拼接,叠加step4生成的音频和 BGM,输出到workspace/output/final.mp4。跑完你会看到终端打印成片路径。用播放器打开检查:画面是否连贯、台词和口型是否大致对上、BGM 音量是否盖过人声。如果 BGM 太响,在step5_compose.py里调 ffmpeg 的volume参数,把人声轨设成 1.0,BGM 轨设成 0.3 左右。
整套跑通一次大概几分钟,取决于镜头数量和视频生成服务的速度。第一次建议用 30 秒、3 到 4 个镜头的小样验证链路,别一上来就 60 秒十几个镜头,出问题不好定位。
5. 常见报错排查清单:401、local proxy failed、reading choices 与 OAuth
跑智能体最容易卡在调用环节,下面这几个报错我基本都遇到过,按顺序对照。
401 Unauthorized:Key 不对或没带上。检查config.toml里的api_key是不是完整的sk-开头字符串,有没有多余空格。如果你把 Key 放在环境变量里,确认脚本读取的环境变量名和设置的一致。还有一种情况是 Key 被删了或过期,去控制台 API Keys 页面确认状态。
local proxy failed / connection refused:请求根本没发出去。先确认base_url写的是https://taotoken.net/api,没有多余斜杠或拼错。再确认本机网络能正常访问外网,curl https://taotoken.net/api看有没有响应。如果公司网络有出口限制,换一个网络环境再试。
reading choices 报错(KeyError: 'choices'):请求发出去了,但返回结构里没有choices字段。通常是模型 ID 填错,服务端返回了错误信息而不是正常补全结果。打印完整响应体看error字段:
resp = requests.post(url, json=payload, headers=headers) print(resp.status_code) print(resp.text)如果resp.text里写着模型不存在,就去控制台核对 GLM-5.1 的准确标识,填回config.toml。
OAuth 相关报错:如果你在 Claude Code 里配置了走 OAuth 的登录方式,又同时想用 TaoToken 的 Key,两者可能冲突。解决办法是在 Claude Code 的配置里明确指定用 API Key 模式,把 Base URL 指向https://taotoken.net/api,不要同时启用 OAuth 登录。配置项通常在 settings 文件里,把认证方式改成 key 即可。
ffmpeg 合成失败:报No such file or directory多半是shots/下某个片段没生成成功,检查step3的输出是否完整。报编码错误就在 ffmpeg 命令里显式指定-c:v libx264 -c:a aac。BGM 文件路径写错也会导致合成中断,确认assets/bgm.mp3存在。
台词和画面对不上:不是报错,但很常见。原因是分镜时长和 TTS 音频时长不一致。在step4_tts.py里生成音频后,读取音频实际时长,回写到storyboard.json,让step5按音频时长裁剪画面,而不是按预设时长硬切。
排查顺序建议:先单独测chat()通不通,再测单步脚本,最后跑全流程。哪一步失败就停在哪一步看产物文件,别盲目重跑整个链路。
6. 后续迭代与接入入口
这套智能体跑通后,最值得改的地方有三个:一是把视频生成从占位替换成你实际用的服务,step3输出的提示词直接对接;二是加一层人物一致性校验,把每个镜头的角色描述固定成同一段文本,减少换脸感;三是把run.sh包成带进度条的 CLI,长视频跑起来心里有数。
如果你还没配好 Key,先去控制台创建:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。想先验证模型返回质量,可以直接在模型对话页试:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。如果你打算长期跑编码和 Agent 任务,Coding Plan 更划算:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。
我实测下来,把配置收敛到一处之后,改模型、换 Key、调参数都只动一个文件,迭代速度比之前快很多。你先用 30 秒小样把链路跑通,再逐步加镜头和特效,比一上来就追求完整成片稳得多。