OpenMontage 的 TTS 到底是 5 个还是 4 个:README 自己两处说法不一

2026-08-09

看 OpenMontage 的 README 找语音合成能力时,很容易先记住一个数字,然后在另一处看到另一个数字,怀疑自己看串了行。

没看串。这两个数字都在同一份 README 里。

差异在哪:两处原文

README 有一段折叠的 Supported Providers,文字转语音那一块的标题原文是 Text-to-Speech — 5 providers,展开后的表格数下来正好 5 行。

README 靠前的位置还有一张目录树式的架构图,tools/audio/ 那一行的注释写的是 4 TTS providers

一个写 5,一个写 4,两处都用了 provider 这个词。我们能确认的事实就到这里:README 内部这两处文本对不上,以仓库当前状态为准。哪个是”对的”、为什么没同步、是不是漏改了,我不打算推断,也不建议你拿这一处差异去评价这个项目。说完就停,这是写这类内容唯一稳妥的处理方式。

那 5 行分别是什么

既然折叠块里的表是 5 行,先把这 5 行摆出来。Notes 一列是 README 自己写的原文,不是我们的评价:

ProviderTypeREADME 的 Notes
ElevenLabsCloud APIPremium voice quality
Google TTSCloud API700+ voices, 50+ languages — best for localization
Kling Official TTSCloud APIOfficial Kling narration when a voice_id is known
OpenAI TTSCloud APIFast, affordable
PiperLocalCompletely free, offline

这里要拧一下措辞。“Premium voice quality”、“Fast, affordable” 这类形容词是 README 的描述,我们没有调用过其中任何一个 API,没有听过任何一段合成音,所以这张表只能当成”README 列了哪些名字”,不能当成音质排序,更不能拿来做选型推荐。README 在这一节顶部还指向 docs/PROVIDERS.md,说那里有完整配置指南含定价和免费额度——那份文档我们没有读过,不展开。

结构上能直接数出来的是:5 个里 4 个是 Cloud API,只有 Piper 一个标的是 Local。

数字之前,先问一句”这是在数什么”

视频那一节可以拿来做个对照,因为 README 在那边把口径写明白了。

折叠块标题是 “Video Generation — 15 providers”,表格实际 15 行,对得上。而架构图里 tools/video/ 那一行写的是 “13 video gen tools + compose, stitch, trim”。15 和 13 摆在一起看着也像矛盾,但这两处数的东西 README 自己就交代了不是一回事——一个在数 provider,一个在数 tool,而 tool 那边还额外把 compose、stitch、trim 算了进去。

所以在这个仓库里看到任何一个数字,第一反应应该是先确认它在数什么单位。我们把 README 的说法和实读结果逐条对过一遍,结论是分两类的:核心治理数值(七维权重、预算默认值、幻灯片风险的六个维度与阈值)文档与代码逐项吻合;对不上的基本都是计数类描述。比如 README 架构图里 schemas/ 那行标 “15 JSON Schemas”,我们实读 schemas/ 目录数出 24 个 .json 文件,两者不一致——这一处本批另有一篇专门讲,这里只作为同类现象提一句。反过来,“700+ agent skill and production-knowledge files” 这个说法,我们实读 skills/ 156 个 .md.agents/ 567 个 .md,合计 723,是对得上的。

TTS 这一处的特殊之处在于,两边写的都是 provider,没有像视频那边一样给出不同口径的说明。差异如实存在,我不往下推。

真正决定用哪个 TTS 的,是权重不是清单

纠结”5 个还是 4 个”其实收益不大,因为在 OpenMontage 的设计里,具体挑哪个 TTS 不是你在清单上圈一个名字,而是走一套评分。

README 写得很清楚:每一次工具选择——视频生成、图像生成、TTS、音乐——都会跑一个 7 维评分引擎,胜出的 provider 及其分数会连同所有考虑过的备选项一起记进决策链路。七个维度和权重是 task fit 30%、output quality 20%、control features 15%、reliability 15%、cost efficiency 10%、latency 5%、continuity 5%。

这一段值得单独核一下,因为它和上面那些计数描述不是一个待遇。我们实读 lib/scoring.py 第 38-44 行,那里是一段加权求和:

self.task_fit * 0.30
+ self.output_quality * 0.20
+ self.control * 0.15
+ self.reliability * 0.15
+ self.cost_efficiency * 0.10
+ self.latency * 0.05
+ self.continuity * 0.05

同一个文件第 57-63 行还有一份 (名称, 值, 权重) 三元组列表,权重与上面完全一致。七个权重相加等于 1.00,与 README 声称的逐项吻合。

权重本身透露的取向可以直接读出来:task_fit 一项就占 30%,比 cost_efficiency(10%)、latency(5%)、continuity(5%)三项加起来的 20% 还多出一半;controlreliability 并列 15%,是同一档。也就是说这套评分把”任务匹配度”和”输出质量”(合计 50%)放在了成本和速度前面。至于某一次具体的 TTS 选择最后花落谁家,取决于每个 provider 在这七个维度上各被打了多少分——那部分代码我们没有读,不猜。

顺带记一笔:lib/scoring.py 里还存在第二套加权评分(第 95-101 行),维度名是 quality_fit(0.20)、capability_confidence(0.15)、fallback_integrity(0.10)、budget_fit(0.10)、consistency_fit(0.05)之类,和 provider 评分那套不是同一组维度,README 完全没有提及它。它用在哪、什么时候触发、和第一套是什么关系,我们没读调用代码,一律不猜。

Piper 这一行为什么要单独看

5 行里唯一标 Local 的是 Piper,README 给它的 Notes 是 “Completely free, offline”。这一行和 README 的 “What You Get With Zero API Keys” 那节是串起来的:零密钥能力表里,旁白(Narration)一栏就是 Piper TTS;README 给的手动安装串里也确实有 python -m pip install piper-tts 这一步。

换句话说,另外 4 个都在付费 API 那一侧。你一旦从 Piper 切到云端 TTS,就跨过了预算治理这道线。config.yaml 的 budget 段实读是这样的:

budget:
  mode: warn                     # observe | warn | cap
  total_usd: 10.00
  reserve_pct: 0.10
  single_action_approval_usd: 0.50
  require_approval_for_new_paid_tool: true

几个值得看清楚的地方:默认模式是 warn 而不是 captotal_usd: 10.00 不能当成一道硬性支出上限来理解;单次动作超过 $0.50 要审批;require_approval_for_new_paid_tool: true 意味着启用一个新的付费工具默认需要你点头——你从 Piper 换到某个云 TTS,正好落在这一条上。README 的 Budget Controls 一节列了模式、总额和单次阈值,但没有写 reserve_pct: 0.10require_approval_for_new_paid_tool 这两项,它们是配置文件里有的。

要说清楚的是,把这几行配好不等于不会超支,真正拦住花销的是每个闸上的批准动作,这几个默认值只是决定了系统在什么时候开口问你。另外,云端 TTS 那几家各自要一个密钥,写进 .env 时一律用 <YOUR_API_KEY> 这种占位形式,别把真实值贴进任何笔记或文章里。

和配音直接相关的两行承诺规则

lib/delivery_promise.py 里有一张 PROMISE_RULES 表,八种交付承诺类型各一行。全表本批另有一篇专门拆,这里只取和语音直接相关的两行。

一行是 localizationstill_fallback_allowedTruerequires_video_generationFalsemin_motion_ratio0.0,description 原文是 “Translation/dubbing of existing video. Preserving source timing and clarity.”。翻译配音这类活儿,在规则层面完全允许零动效,价值取向写的是保住源片时序与清晰度。这和上面表里 Google TTS 那行 README 标的 “best for localization” 正好对得上。

另一行是 avatar_presenterstill_fallback_allowedFalserequires_video_generationTruemin_motion_ratio0.3。八种承诺里只有它和 motion_led 不允许静图回退,也只有这两种要求必须具备视频生成能力。做数字人主持这类内容,光有 TTS 是不够的。

那到底怎么知道自己这台机器上有几个

README 和 AGENT_GUIDE 给的答案是一致的:别数文档,去问 registry。

python -c "from tools.tool_registry import registry; import json; registry.discover(); print(json.dumps(registry.provider_menu(), indent=2))"
python -c "from tools.tool_registry import registry; import json; registry.discover(); print(json.dumps(registry.support_envelope(), indent=2))"

README 把这两条描述为查真实的能力边界。AGENT_GUIDE.md 的 Mandatory Preflight 一节里,这两条各带一句注释:前者是 “Full menu — grouped available/unavailable per capability.”,后者是 “Raw envelope — every tool’s full contract. Slow/firehose; use for debugging only.”,后者原文明确警告慢、输出量大、只用于调试。以上命令照抄自仓库文档,我们没有运行过,输出以你本地跑出来的为准;这两个方法返回什么结构、有哪些字段,我们没有读过 tool_registry.py,不做描述。

AGENT_GUIDE.md 的 “What Not To Do” 里有三条正好压在这个话题上:不要硬编码 provider 名、API key 名或安装 URL,要从 registry 的 install_instructionsdependencies 字段读;不要孤立地呈现单个不可用工具,要永远展示完整能力图景,用 “X of Y providers configured for this capability.” 这种说法;还有一条更直接——不要使用已删除的旧名称 tts_cloudtts_enginevideo_gen

最后这条挺有意思:TTS 相关的旧工具名已经被明令禁用了。你要是照着某篇过期教程写 tts_engine,问题不在数字对不对,而在名字已经不存在了。

绕回开头那个问题。README 折叠块说 5,架构图说 4,这两处文本的差异是客观存在的,我不判定谁对。但 “X of Y providers configured for this capability.” 里那个 Y,本来就该由 registry 在你自己的机器上算出来,而不是从 README 上数——你配了几个密钥,Y 就是几,这个数还会随你装没装 Piper 而变。文档里的清单长度,从来就不是你手上真实的能力边界。


本文依据 OpenMontage 官方仓库(github.com/calesthio/OpenMontage)的 README、 AGENT_GUIDE.mdconfig.yamlpipeline_defs/lib/ 下的治理模块整理,核对日 2026-08-09。 本文内容为仓库源码与文档口径,我们没有安装或运行过该系统,也没有调用过其中任何一个 provider API, 文中出现的成本数字均为项目方在 README 中自行标注的金额,非我们的实测结果。 该项目以 AGPL-3.0 发布,部分流水线在 manifest 中自标 stability: beta,请以仓库最新内容为准。 安全相关做法请结合自身环境评估,本文不构成安全方案建议。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。