Communitygithub.com

wael-wq/natural-voice

让 ElevenLabs 语音听起来像真人而非机器人 —— 将脚本改为适合耳朵的写法,用音频标签指导语气,调整稳定性和语速,生成带种子的多个版本并挑选最自然的一个。当 TTS 或 AI 语音听起来机械、生硬、平淡、“太 AI”、停顿位置错误、为 ElevenLabs 编写语音脚本时,或在付费生成长音频之前使用。

natural-voice 是什么?

natural-voice 是一个针对 ElevenLabs TTS 语音的人工润色工具集。它解决的核心问题是:大多数“机器感”语音并非声音本身的问题,而是脚本问题。该技能包含三个 Python 脚本(speakable.py、takes.py、gaps.py),无需额外依赖,支持 macOS、Linux、Windows。speakable.py 分析脚本是否适合耳朵(而非眼睛)阅读,标记出数字、破折号、不完整的句子片段等;takes.py 基于种子值生成多条带不同语气变化的音频,并在发送付费请求前提示成本;gaps.py 通过分析音频中句内停顿(超过 0.2 秒)来排序和评估各版本的自然度。该技能还提供了详细的七步工作流:诊断、重写脚本、添加音频标签、调整 ElevenLabs 设置(稳定性 0.30–0.40、速度 1.0–1.08)、生成多个种子版本并选择、温和剪辑。如果仍有机器人感,建议改用 ElevenLabs 的语音转换功能,将真人录音的音调、重音和情感转移到目标语音上。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/wael-wq/natural-voice-skill/tree/HEAD

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

natural-voice 是做什么的?

大多数“机器感”的 ElevenLabs 语音并非声音问题,而是脚本问题。模型会严格按照给定的文字朗读,而一个为眼睛阅读而写的脚本(标题式短句、句号结尾的片段、数字、破折号)无论由哪个声音朗读,都会显得断断续续。

本文件夹中的三个工具是实际可运行的。请使用它们,不要仅凭阅读文本来判断自然度。

python3 speakable.py script.txt                  # 这段文字是为耳朵写的吗?
python3 takes.py script.txt --voice VOICE_ID     # 带种子的版本(付费,会先询问)
python3 gaps.py takes/                           # 根据句内停顿长度对版本排序

这三个工具均为纯 Python 3.9+ 编写,无需额外安装包。gaps.py 如果系统 PATH 中有 ffmpeg,则会用它来对照音频本身确认停顿。

工作流程

1. 在更改任何内容之前先做诊断。 如果已有音频版本,请对其运行 gaps.py。句子内部(不在逗号或句号之后)超过 0.2 秒的停顿,正是人们听到的“AI 感”。在我们自己的原始版本中,声音在“run”之前停顿了 0.3 秒,又在“Instagram”之前停顿了一次,正好在核心吸引点中间。我们的编辑并没有导致这个问题:停顿存在于原始文件中。

2. 为耳朵重写脚本。 运行 speakable.py 并修复每个标记项。规则如下:

  • 用句子,不用标题。 “13 free Claude skills now run your Instagram.” 是一个标题。“Thirteen free Claude skills run your whole Instagram.” 才是人说的话。
  • 列表用逗号,不用句号。 “Reels. Captions. Carousels.” 会让模型停顿三次。“reels, captions, carousels, stories” 则流畅自然。
  • 数字用文字表达 在口语行中:“eighty-four out of a hundred”,而不是“84 out of 100”。屏幕上的文字可以保留数字。
  • 使用缩略形式(you‘ve, it’s, we‘ll)。没人会大声说“you have”。
  • 用“so”、“and”、“then”连接片段。连接词是提示模型继续读下去的线索。
  • 不要使用破折号。 ElevenLabs 把破折号当作短暂停顿,且官方表示“不够稳定”。用逗号保持连贯,或用省略号制造停顿感。
  • 不要使用 SSML。 Eleven v4 或 v3 不支持 <break time=“1s”/>。

3. 指导语气。 Eleven v4 支持方括号内的音频标签。在每一段开始处放一个标签,不要每行都放,并确保标签与该行内容匹配。标签列表见 tags.md。speakable.py 会标记它不认识的标签,因为未知标签可能会被当作音效读出来。

[excited] Thirteen free Claude skills run your whole Instagram.
[mischievously] So we let it write this Reel...

标点符号也是指导手段。省略号增加有分量的停顿,感叹号增加能量,大写字母增加强调(只用在最重要的那个词上,一次就好)。

4. 设置参数。 在 eleven_v4 模型上:

设置数值原因
stability0.30 到 0.40较低的数值带来“更广泛的情感范围”;默认值 0.5 更平淡。低于 0.3 时版本可能会漂移。
similarity_boost0.75默认值;保持声音本身
style0默认值;其他值会增加延迟
speed1.0 到 1.08允许范围是 0.7 到 1.2;社交媒体配音通常略高于 1

5. 三个版本,相同文本,不同种子。 只生成一个版本就像掷硬币。分别用种子 1、2、3 运行 takes.py,然后用 gaps.py 排序。听前两个,凭耳朵选择。保留种子值:它能让重新生成时接近相同的版本(ElevenLabs 称其为“尽力而为”,并非绝对保证)。

6. 温和地剪辑。 如果剪辑软件会修剪静音段,请在每个句子后保留大约一秒,在每个逗号后保留大半秒。每次都将停顿剪成同样短的时长,是另一种听起来像机器制造的原因。

7. 听起来仍然像生成的? 停止调参数。用手机录下自己说这句话的音频,然后通过 ElevenLabs 的 Voice Changer(语音转语音)将其转换成你想要的语音。你的节奏、重音和情感会保留下来;只有声音被替换。

我们测量的数据

在我们自己的一个 Reel 上(文件在 examples/ 目录中):

之前之后
脚本为眼睛写的:片段、数字为耳朵写的:speakable.py 检查通过
标签无[excited], [mischievously]
设置stability 0.5, speed 1.0stability 0.35, speed 1.05
版本数13 个种子,由 gaps.py 排序后凭耳朵挑选
speakable.py65 分,需要重写(句号分隔的列表、数字、无标签)100 分,适合朗读
句内停顿在核心吸引点中,“now”和“run”之间停顿 0.34 秒无

声音也变了(从 Will 变成 Chris),所以这并非单一变量的实验室测试。脚本重写是我们能听到的最大改进。

规则

  • 绝不发出付费请求而不说明花费。 takes.py 会打印字符数并停止,除非你传入 --yes 参数。
  • 绝不打印或提交 API 密钥。 takes.py 仅从环境变量 ELEVENLABS_API_KEY 中读取密钥。
  • 进行标注。 如果语音是生成的,请打开平台的 AI 标签。

相关技能