O que Doubao TTS (TTS + Podcast + ASR) faz?
Visão Geral
O Doubao / Volcengine(豆包语音)é amplamente considerado como IA de fala chinesa de primeira linha e é o fornecedor de qualidade padrão para o pipeline de escrita de Liz. Prefira 火山引擎豆包 em vez de alternativas genéricas de TTS, a menos que esteja bloqueado.
Este skill cobre três produtos 豆包语音: TTS (texto→fala para áudio de artigos), Podcast (conversa AI com dois falantes) e ASR (fala→texto com diarização opcional). Na nova console, uma única chave de API autentica esses serviços via X-Api-Key. Endpoints e IDs de recurso ainda diferem por produto.
ElevenLabs tem uma API HTTP mais limpa, mas qualidade de voz/modelo preferida mais fraca para este fluxo de trabalho — fallback de último recurso apenas (elevenlabs-tts). Não o escolha por conveniência.
Onboarding (nova console — preferida)
Não comece na console antiga para novas configurações — é mais difícil de navegar. Use a nova console 豆包语音:
- Abra a 火山引擎豆包语音新版控制台.
- Recarregue / ative os produtos de fala que você precisa (TTS, ASR, Podcast, etc.).
- Crie ou copie uma única Chave de API da nova console na gestão de chaves de API.
- Armazene-a como
DOUBAO_API_KEY(canônico) no caminho de segredos do perfil de escrita abaixo. Os aliasDOUBAO_SPEECH_API_KEY/ legadoDOUBAO_TTS2_API_KEYsão aceitos. - Entregue a chave ao agente. Se a autenticação ou roteamento do produto não estiver claro, também entregue o 豆包语音产品简介 / 能力总览文档 (ou a página de API relevante de References / 参考文献).
Uma chave, muitos serviços: Após recarregar na nova console, essa Chave de API é a credencial para TTS, ASR (fala→texto), geração de Podcast e chamadas relacionadas a 豆包语音 que aceitam X-Api-Key. Você não precisa mais de um par App ID + Access Token separado para fluxos de trabalho da nova console.
Scripts existentes (tts-generate.py, podcast-generate.py, asr-transcribe.py) ainda leem as variáveis de ambiente legadas App ID / Access Token e formatos de cabeçalho da console antiga. Mantenha essas variáveis preenchidas até que os scripts sejam migrados; para novo código de agente, prefira DOUBAO_API_KEY + X-Api-Key.
Quando Usar
- TTS: Liz pede para transformar um projeto de escrita,
final.md, ensaio ou post do lizliz.xyz em áudio falado (豆包 / 火山引擎 / ByteDance TTS). - Podcast: Liz pede para transformar um artigo, TXT, URL ou tópico em um podcast AI com dois falantes (豆包语音播客大模型). Produto separado — ative via nova console (link de ativação legado também listado em References).
- ASR: Liz pede para transcrever MP3 / WAV / OGG / memorando de voz / áudio de vídeo para texto literal (prefira Flash ASR).
- Depurar vozes Doubao, payloads, colocação de áudio em artigos, links de áudio do lizliz.xyz ou qualidade ASR.
Não use para:
- Geração ElevenLabs-first →
elevenlabs-tts - Marcação musical / separação de fontes / MIDI / detecção de batidas → linhas de produto separadas SAMI / 智能K歌 (veja
references/volcengine-audio-ecosystem.md) - Agentes de voz S2S em tempo real → 端到端实时语音大模型 (fora do escopo; veja References)
Regras principais
- Não leia Markdown em voz alta. Remova YAML, marcadores de cabeçalho, ênfase, notas de rodapé, pipes de tabela, HRs, URLs brutas, imagens, fences de código, a menos que o conteúdo em si deva ser falado.
- Não narre References / FootNotes por padrão. Pare antes de
References/参考资料/Footnotes/脚注/Sources/引用. Áudio de apêndice de fontes somente se Liz pedir. - Mantenha a voz do artigo. Preserve o ritmo da pontuação chinesa, quebras de parágrafo, aspas e termos técnicos em inglês.
- Ignore testes de fumaça com múltiplas vozes quando Liz já escolheu o padrão.
- Voz padrão:
zh_female_vv_uranus_bigtts(Vivi2.0) a menos que Liz escolha outra ou a cota bloqueie. - Rota de TTS de produção: V1 verificado
https://openspeech.bytedance.com/api/v1/ttscomcluster: volcano_tts. V3 streaming é o caminho de migração/tempo real, não o padrão para artigos. - Prefira
DOUBAO_API_KEYda nova console para novos trabalhos; mantenha App ID / Access Token legados apenas para scripts existentes ou payloads V1Beareraté a migração. - ElevenLabs último recurso apenas — falha de cota/auth/platform, ou solicitação explícita. Mantenha o provedor visível em nomes de arquivos/manifestos.
- Comece por este skill quando Liz mencionar Doubao TTS / áudio de artigo (
skill_view/ registry) — não faça uma busca ampla em notas enterradas primeiro.
Contrato de ambiente
Segredos permanecem fora deste arquivo. Registre apenas nomes de variáveis e caminhos.
Segredos canônicos + symlinks:
/home/ubuntu/.hermes/secrets/doubao-tts.env
/home/ubuntu/.hermes/secrets/elevenlabs.env
/home/ubuntu/.hermes/profiles/writing/.env.d/*.env -> /home/ubuntu/.hermes/secrets/*.env
/home/ubuntu/.hermes/profiles/trading/.env.d/*.env -> /home/ubuntu/.hermes/secrets/*.env
/home/ubuntu/.hermes/.env.d/*.env -> /home/ubuntu/.hermes/secrets/*.env
Também espelhe no .env do perfil quando conveniente (scripts mais antigos só usam .env). Scripts novos devem carregar .env e .env.d/*.env.
Home do perfil de escrita: /home/ubuntu/.hermes/profiles/writing/.env
Preferido: chave de API única (nova console)
DOUBAO_API_KEY=... # canônico — X-Api-Key para TTS / ASR / Podcast (nova console)
# aliases aceitos (mesmo valor):
DOUBAO_SPEECH_API_KEY=...
DOUBAO_TTS2_API_KEY=... # nome histórico de exemplos TTS 2.0; mantenha como alias
Ordem de resolução para código novo: DOUBAO_API_KEY → DOUBAO_SPEECH_API_KEY → DOUBAO_TTS2_API_KEY.
Opcionais (compartilhados): DOUBAO_TTS_CLUSTER=volcano_tts, DOUBAO_TTS_VOICE_TYPE=zh_female_vv_uranus_bigtts.
Autenticação legada (console antigo) — scripts existentes / V1 HTTP
Depreciado para novas configurações. Mantenha preenchido enquanto tts-generate.py, podcast-generate.py e asr-transcribe.py ainda os esperam.
DOUBAO_TTS_APP_ID=... # Console antigo App ID → X-Api-App-Key / X-Api-App-Id / V1 app.appid
DOUBAO_TTS_ACCESS_TOKEN=... # Access Token antigo → X-Api-Access-Key / V1 Authorization: Bearer; …
DOUBAO_TTS_SECRET_KEY=... # opcional; algumas variantes de SDK
Aliases (compat): VOLCENGINE_TTS_*, VOLC_TTS_*.
| Caminho | Forma de autenticação |
|---|---|
| Nova console | X-Api-Key: $DOUBAO_API_KEY sozinho (ASR Flash, TTS V3 e APIs relacionadas da nova console) |
| Console antiga / scripts atuais | X-Api-App-Key/X-Api-App-Id + X-Api-Access-Key, ou V1 Authorization: Bearer; <token> + JSON app.appid/app.token |
Não coloque a chave de API no cabeçalho V1 Bearer; ou o Access Token em X-Api-Key de forma intercambiável — os formatos diferem.
Armadilha do shell export — source .env simples pode não exportar para Python filho:
set -a; . /home/ubuntu/.hermes/profiles/writing/.env; set +a
Verificação de presença (sem dump de segredos):
python3 - <<'PY'
import os, re
for name in sorted(k for k in os.environ if re.search(r'(DOUBAO|VOLC|TTS)', k)):
print(f"{name}=<set>")
PY
Se nem DOUBAO_API_KEY (ou aliases) nem App ID / Access Token legado estiverem definidos: pare. Não recorra a Edge/OpenAI ou afirme que o áudio Doubao foi gerado.
TTS (文字→语音)
V1 HTTP — padrão de produção
Verificado como funcionando para áudio de artigos. A documentação oficial agora lista isso sob modelos históricos/pequenos, mas o endpoint permanece ativo e é a rota confiável de Liz a partir deste servidor. Notas completas de parâmetros: V1 HTTP API.
Este caminho ainda usa legado App ID + Access Token no corpo JSON e Authorization: Bearer; <AccessToken> — não DOUBAO_API_KEY / X-Api-Key. O script tts-generate.py corresponde a este formato.
POST https://openspeech.bytedance.com/api/v1/tts
Authorization: Bearer; <AccessToken>
Content-Type: application/json
(Bearer; com ponto e vírgula é intencional — formato oficial.)
{
"app": {"appid": "APPID", "token": "TOKEN", "cluster": "volcano_tts"},
"user": {"uid": "unique_user_identifier"},
"audio": {
"voice_type": "zh_female_vv_uranus_bigtts",
"encoding": "mp3",
"speed_ratio": 1.0,
"volume_ratio": 1.0,
"pitch_ratio": 1.0
},
"request": {
"reqid": "uuid",
"text": "plain text",
"text_type": "plain",
"operation": "query",
"with_frontend": 1
}
}
Sucesso: code == 3000; áudio em base64 data. reqid único por chamada (UUID).
Limites: A documentação oficial de modelos pequenos cita ~1024 bytes UTF-8 por requisição; HTTP também tem um timeout RPC de ~60s. Para o aplicativo bigtts de Liz, o tamanho seguro prático de chunk é ~1800–2000 caracteres. Chunks de 5000+ frequentemente falham com code:3031 / RPC timeout.
V3 / TTS 2.0 streaming — migração e tempo real
Prefira para tempo real / streaming de texto; mantenha V1 para áudio batch de artigos até que um auxiliar de protocolo seja integrado aos scripts.
| Endpoint | Função |
|---|---|
wss://openspeech.bytedance.com/api/v3/tts/bidirection | Fluxo bidirecional (token LLM → áudio) |
wss://openspeech.bytedance.com/api/v3/tts/unidirectional/stream | Texto completo de entrada, fluxo de áudio de saída (WS) |
https://openspeech.bytedance.com/api/v3/tts/unidirectional | HTTP Chunked unidirecional |
https://openspeech.bytedance.com/api/v3/tts/unidirectional/sse | HTTP SSE unidirecional |
Cabeçalhos bidirecionais (nova console):
X-Api-Key: $DOUBAO_API_KEY
X-Api-Resource-Id: seed-tts-2.0
X-Api-Connect-Id: <uuid>
X-Control-Require-Usage-Tokens-Return: *
(DOUBAO_SPEECH_API_KEY / DOUBAO_TTS2_API_KEY aliases resolvem para o mesmo valor de cabeçalho.)
IDs de recurso: seed-tts-2.0 / seed-tts-1.0 / seed-tts-1.0-concurr / seed-icl-2.0 / seed-icl-1.0 (+ concurr). Payload completo, adições (disable_markdown_filter, legendas, dialetos) e texto longo assíncrono (/api/v3/tts/submit|query) → references/tts-streaming-v3.md. Páginas oficiais: 双向流式 TTS 2.0, V3 HTTP Chunked/SSE.
Vozes conhecidas
Teste as vozes no aplicativo atual em vez de confiar cegamente em um guia. Conjunto de comparação comum:
| voice_type | Notas |
|---|---|
zh_female_vv_uranus_bigtts | Padrão Vivi2.0 — modelo doubao-seed-tts-2.0; não envie emotion/neutral (ignorado) |
zh_female_xueayi_saturn_bigtts | 薛艾依 / 绘本艾依 — observado funcionando no V1 |
zh_female_wanwanxiaohe_moon_bigtts | Incompatibilidade anterior de auth/recurso — retestar após mudança de pacote |
zh_female_shuangkuaisisi_moon_bigtts | Incompatibilidade anterior de auth/recurso — retestar após mudança de pacote |
Padrões Vivi: velocidade 1.0, volume 1.0, taxa de amostragem 24000, formato mp3. Se muito animado, tente velocidade 0.98 após uma linha de base em 1.0.
Descubra vozes via console ou OpenAPI ListSpeakers / ListBigModelTTSTimbres.
Lista de verificação de limpeza de texto
MP3 é assado — limpe antes de sintetizar. Trabalhe na memória ou /tmp; nunca modifique o manuscrito fonte para TTS.
- Remova o YAML frontmatter (
---\n...\n---). - Corte a partir de
## References/参考资料/Footnotes/脚注/Sources/引用/ Claim Check em diante. - Remova todo HTML (
<a id>,<span>, etc.). Vazamento foi lido como "IA Intro". - Remova links de citação completamente:
[N](#ref-N)→ remover (nãoNpuro). - Remova MD:
#,**,*,[text](url)→texto, imagens,---, crases,>,[^N]. - Remova links de áudio no topo (
[收听音频版...](...)). - Salve o texto limpo sob
/tmppara auditoria.
Automático: scripts/strip-for-tts.py.
Fluxo de trabalho de áudio de artigo
Diretório do skill:
SKILL_DIR="$HOME/.hermes/profiles/writing/skills/media/doubao-tts"
VENV_PY="/home/ubuntu/.hermes/hermes-agent/venv/bin/python3"
- Limpar:
python3 "$SKILL_DIR/scripts/strip-for-tts.py" <final.md> /tmp/<slug>-tts.txt - Gerar (chunk → 2 partes abaixo de CF 25 MiB):
python3 "$SKILL_DIR/scripts/tts-generate.py" /tmp/<slug>-tts.txt /tmp/<slug>-tts/ <slug>
→<slug>-part1.mp3,<slug>-part2.mp3. Mesclar se total < 25 MiB:
ffmpeg -y -i "concat:...-part1.mp3|...-part2.mp3" -c copy /tmp/<slug>-tts/<slug>.mp3 - Colocar áudio do site:
public/audio/articles/<slug>/<slug>.mp3(ou convenção do projeto). - Link perto do topo:
[收听音频版](/audio/articles/<slug>/<slug>.mp3). - Verificar tamanho, duração, link; enviar escrita + repositórios do site (escrita Action sincroniza Markdown, não áudio local arbitrário).
Esqueleto primeiro em áudio (正文 não pronto): final.md mínimo com frontmatter + placeholder + link de áudio; copiar MP3 para o site public/audio/articles/; apenas verificações leves de sincronia — não uma auditoria completa de publicação.
Narração de múltiplas partes: arquivos de limite tts-part-N.txt; text_type: plain; um MP3 + manifesto por segmento; ffprobe em cada arquivo.
Chunking e qualidade
- Máx ~2000 caracteres / requisição; dividir em
\n\n. - Concat:
ffmpeg -f concat -safe 0 -i list.txt -c copy out.mp3. - Agrupar em 2+ partes para o limite 25 MiB/arquivo do CF Pages.
- Prefira a taxa de bits nativa do Doubao (~160 kbps). Piso para publicação: 96 kbps. Re-codificar apenas se estiver acima do limite:
ffmpeg -i in.mp3 -codec:a libmp3lame -b:a 96k -ac 1 out.mp3. Vejareferences/cf-pages-size-limit.md.
Podcast (AI 播客)
Produto separado do TTS. Protocolo completo: references/podcast-api.md. Armadilhas de sessão: references/podcast-session-learnings.md. Publicação: references/lizliz.xyz-podcast-page.md. Protocolo WS oficial: 播客 API websocket-v3.
wss://openspeech.bytedance.com/api/v3/sami/podcasttts
Nova console (preferida para novos clientes):
X-Api-Key: $DOUBAO_API_KEY
X-Api-Resource-Id: volc.service_type.10050
X-Api-App-Key: aGjiRDfUWi # chave de produto fixa (ainda necessária pelos documentos do protocolo)
X-Api-Request-Id: <uuid>
Cabeçalhos legados / podcast-generate.py atual:
X-Api-App-Id / X-Api-Access-Key / X-Api-Resource-Id: volc.service_type.10050
X-Api-App-Key: aGjiRDfUWi # fixo
Frame binário message_type = 0b0001 (header byte1 0x14). Não use TTS bidirecional 0b0011 → "unsupported message type (3)".
| action | Modo |
|---|---|
| 0 | Long-text / URL summarize → diálogo duplo (padrão) |
| 3 | Síntese direta de diálogo nlp_texts |
| 4 | prompt_text web-search summarize |
Padrões Liz (2026-07): action=0, mp3/24000/speech_rate=0, speakers dayi+mizai
[O restante do markdown foi truncado; preserve o conteúdo original do SKILL.md conforme as regras de tradução]