Перейти к основному содержимому

Голос и TTS

VibeOS поддерживает как синтез речи из текста (TTS), так и транскрибацию голосовых сообщений на всех платформах обмена сообщениями.

Подписчики Nous

Если у вас есть платная подписка Nous Portal, OpenAI TTS доступен через Tool Gateway без отдельного ключа API OpenAI. Для новых установок выполните vibeos setup --portal, чтобы войти и сразу включить все инструменты шлюза; для существующих установок выберите Nous Subscription только для TTS через vibeos model или vibeos tools.

Синтез речи (Text-to-Speech)​

Преобразуйте текст в речь с помощью десяти провайдеров:

ПровайдерКачествоСтоимостьAPI-ключ
Edge TTS (по умолчанию)ХорошееБесплатноНе требуется
ElevenLabsОтличноеПлатноELEVENLABS_API_KEY
OpenAI TTSХорошееПлатноVOICE_TOOLS_OPENAI_KEY
MiniMax TTSОтличноеПлатноMINIMAX_API_KEY
Mistral (Voxtral TTS)ОтличноеПлатноMISTRAL_API_KEY
Google Gemini TTSОтличноеБесплатный тарифGEMINI_API_KEY
xAI TTSОтличноеПлатноXAI_API_KEY
NeuTTSХорошееБесплатно (локально)Не требуется
KittenTTSХорошееБесплатно (локально)Не требуется
PiperХорошееБесплатно (локально)Не требуется

Доставка по платформам​

ПлатформаДоставкаФормат
TelegramГолосовое сообщение (воспроизводится в чате)Opus .ogg
DiscordГолосовое сообщение (Opus/OGG), при ошибке — вложение файлаOpus/MP3
WhatsAppВложение аудиофайлаMP3
CLIСохраняется в ~/.vibeos/audio_cache/MP3

Конфигурация​

# В ~/.vibeos/config.yaml
tts:
provider: "edge" # "edge" | "elevenlabs" | "openai" | "minimax" | "mistral" | "gemini" | "xai" | "neutts" | "kittentts" | "piper"
speed: 1.0 # Глобальный множитель скорости (переопределяется настройками провайдера)
edge:
voice: "en-US-AriaNeural" # 322 голоса, 74 языка
speed: 1.0 # Преобразуется в процент скорости (+/-%)
elevenlabs:
voice_id: "pNInz6obpgDQGcFmaJgB" # Adam
model_id: "eleven_multilingual_v2"
openai:
model: "gpt-4o-mini-tts"
voice: "alloy" # alloy, echo, fable, onyx, nova, shimmer
base_url: "https://api.openai.com/v1" # Переопределение для совместимых с OpenAI TTS эндпоинтов
speed: 1.0 # 0.25 - 4.0
minimax:
model: "speech-2.8-hd" # speech-2.8-hd (по умолчанию), speech-2.8-turbo
voice_id: "English_Graceful_Lady" # См. https://platform.minimax.io/faq/system-voice-id
speed: 1 # 0.5 - 2.0
vol: 1 # 0 - 10
pitch: 0 # -12 - 12
mistral:
model: "voxtral-mini-tts-2603"
voice_id: "c69964a6-ab8b-4f8a-9465-ec0925096ec8" # Paul - Neutral (по умолчанию)
gemini:
model: "gemini-2.5-flash-preview-tts" # или gemini-3.1-flash-tts-preview
voice: "Kore" # 30 предустановленных голосов: Zephyr, Puck, Kore, Enceladus, Gacrux и др.
audio_tags: false # Включить скрытую вставку аудиотегов Gemini 3.1 TTS
persona_prompt_file: "" # Необязательный Markdown/текстовый файл с описанием голоса Gemini
xai:
voice_id: "eve" # или пользовательский ID голоса — см. документацию ниже
language: "en" # Код ISO 639-1
sample_rate: 24000 # 22050 / 24000 (по умолчанию) / 44100 / 48000
bit_rate: 128000 # Битрейт MP3; применяется только при codec=mp3
# base_url: "https://api.x.ai/v1" # Переопределение через переменную окружения XAI_BASE_URL
neutts:
ref_audio: ''
ref_text: ''
model: neuphonic/neutts-air-q4-gguf
device: cpu
kittentts:
model: KittenML/kitten-tts-nano-0.8-int8 # 25MB int8; также: kitten-tts-micro-0.8 (41MB), kitten-tts-mini-0.8 (80MB)
voice: Jasper # Jasper, Bella, Luna, Bruno, Rosie, Hugo, Kiki, Leo
speed: 1.0 # 0.5 - 2.0
clean_text: true # Раскрывать числа, валюты, единицы измерения
piper:
voice: en_US-lessac-medium # Имя голоса (автоматически загружается) ИЛИ абсолютный путь к .onnx
# voices_dir: '' # По умолчанию: ~/.vibeos/cache/piper-voices/
# use_cuda: false # Требует onnxruntime-gpu
# length_scale: 1.0 # 2.0 = вдвое медленнее
# noise_scale: 0.667
# noise_w_scale: 0.8
# volume: 1.0 # 0.5 = вдвое тише
# normalize_audio: true

Управление скоростью: Глобальное значение tts.speed применяется ко всем провайдерам по умолчанию. Каждый провайдер может переопределить его своей настройкой speed (например, tts.openai.speed: 1.5). Скорость, указанная для конкретного провайдера, имеет приоритет над глобальным значением. По умолчанию — 1.0 (нормальная скорость).

Персональные подсказки Gemini​

Gemini TTS может следовать инструкциям по исполнению на естественном языке. Установите tts.gemini.persona_prompt_file на локальный Markdown или текстовый файл, описывающий голосовую персону. Файл может включать разделы в стиле Gemini, такие как AUDIO PROFILE, SCENE, DIRECTOR'S NOTES, SAMPLE CONTEXT и TRANSCRIPT.

Если файл содержит {transcript} или {{ transcript }}, VibeOS заменяет этот плейсхолдер на текущий текст TTS. В противном случае VibeOS автоматически добавляет раздел TRANSCRIPT с меткой. Персональная подсказка остается локальной и не отображается в ответе чата.

tts:
provider: gemini
gemini:
voice: Algieba
persona_prompt_file: ~/.vibeos/tts/butler-voice.md

Аудиотеги Gemini​

Gemini 3.1 Flash TTS поддерживает аудиотеги в квадратных скобках на естественном языке, такие как [whispers], [excitedly], [very slow], [laughs] и другие выразительные ремарки. Включите tts.gemini.audio_tags, чтобы VibeOS выполнял скрытый проход перезаписи перед Gemini TTS. Перезапись вставляет встроенные теги только в скрипт TTS; видимый ответ чата остается неизменным.

tts:
provider: gemini
gemini:
model: gemini-3.1-flash-tts-preview
audio_tags: true

Перезапись использует auxiliary.tts_audio_tags и по умолчанию использует вашу основную модель чата. Переопределите эту вспомогательную задачу, если хотите, чтобы вставка тегов обрабатывалась более дешевой или быстрой моделью.

Ограничения длины ввода​

Каждый провайдер имеет документированное ограничение на количество символов в одном запросе. VibeOS обрезает текст перед вызовом провайдера, чтобы запросы никогда не завершались ошибкой из-за длины:

ПровайдерЛимит по умолчанию (символов)
Edge TTS5000
OpenAI4096
xAI15000
MiniMax10000
Mistral4000
Google Gemini32000
ElevenLabsЗависит от модели (см. ниже)
NeuTTS2000
KittenTTS2000
Piper5000

ElevenLabs выбирает лимит на основе настроенного model_id:

model_idЛимит (символов)
eleven_flash_v2_540000
eleven_flash_v230000
eleven_multilingual_v2 (по умолчанию), eleven_multilingual_v1, eleven_english_sts_v2, eleven_english_sts_v110000
eleven_v3, eleven_ttv_v35000
Неизвестная модельВозврат к лимиту провайдера по умолчанию (10000)

Переопределение для каждого провайдера с помощью max_text_length: в разделе провайдера вашей конфигурации TTS:

tts:
openai:
max_text_length: 8192 # увеличить или уменьшить лимит провайдера

Принимаются только положительные целые числа. Ноль, отрицательные, нечисловые или логические значения приводят к использованию лимита провайдера по умолчанию, поэтому сломанная конфигурация не может случайно отключить обрезку.

Голосовые сообщения Telegram и ffmpeg​

Голосовые сообщения Telegram требуют аудиоформата Opus/OGG:

  • OpenAI, ElevenLabs и Mistral изначально выдают Opus — дополнительная настройка не требуется
  • Edge TTS (по умолчанию) выдает MP3 и требует ffmpeg для конвертации:
  • MiniMax TTS выдает MP3 и требует ffmpeg для конвертации в голосовые сообщения Telegram
  • Google Gemini TTS выдает сырой PCM и использует ffmpeg для прямой кодировки в Opus для голосовых сообщений Telegram
  • xAI TTS выдает MP3 и требует ffmpeg для конвертации в голосовые сообщения Telegram
  • NeuTTS выдает WAV и также требует ffmpeg для конвертации в голосовые сообщения Telegram
  • KittenTTS выдает WAV и также требует ffmpeg для конвертации в голосовые сообщения Telegram
  • Piper выдает WAV и также требует ffmpeg для конвертации в голосовые сообщения Telegram
# Ubuntu/Debian
sudo apt install ffmpeg

# macOS
brew install ffmpeg

# Fedora
sudo dnf install ffmpeg

Без ffmpeg аудио от Edge TTS, MiniMax TTS, NeuTTS, KittenTTS и Piper отправляются как обычные аудиофайлы (воспроизводятся, но отображаются в виде прямоугольного плеера вместо голосового сообщения).

подсказка

Если вы хотите получать голосовые сообщения без установки ffmpeg, переключитесь на провайдера OpenAI, ElevenLabs или Mistral.

Пользовательские голоса xAI (клонирование голоса)​

xAI поддерживает клонирование вашего голоса и его использование в TTS. Создайте пользовательский голос в консоли xAI, затем установите полученный voice_id в вашей конфигурации:

tts:
provider: xai
xai:
voice_id: "nlbqfwie" # ваш пользовательский ID голоса

Подробнее о записи, поддерживаемых форматах и ограничениях см. в документации xAI по пользовательским голосам.

Piper (локально, 44 языка)​

Piper — это быстрый локальный нейросетевой TTS-движок от Open Home Foundation (сопровождающие Home Assistant). Он полностью работает на CPU, поддерживает 44 языка с предварительно обученными голосами и не требует API-ключа.

Установка через vibeos tools → Voice & TTS → Piper — VibeOS выполнит pip install piper-tts за вас. Или установите вручную: pip install piper-tts.

Переключение на Piper:

tts:
provider: piper
piper:
voice: en_US-lessac-medium

При первом вызове TTS для голоса, который не кэширован локально, VibeOS выполняет python -m piper.download_voices <name> и загружает модель (~20-90 МБ в зависимости от уровня качества) в ~/.vibeos/cache/piper-voices/`. Последующие вызовы используют кэшированную модель.

Выбор голоса. Полный каталог голосов охватывает английский, испанский, французский, немецкий, итальянский, нидерландский, португальский, русский, польский, турецкий, китайский, арабский, хинди и другие — каждый с уровнями качества x_low / low / medium / high. Примеры голосов на rhasspy.github.io/piper-samples.

Использование предварительно загруженного голоса. Установите tts.piper.voice в абсолютный путь, заканчивающийся на .onnx:

tts:
piper:
voice: /path/to/my-custom-voice.onnx

Расширенные настройки (tts.piper.length_scale / noise_scale / noise_w_scale / volume / normalize_audio, use_cuda) соответствуют 1:1 SynthesisConfig Piper. Они игнорируются в старых версиях piper-tts.

Пользовательские провайдеры команд​

Если нужный вам TTS-движок не поддерживается изначально (VoxCPM, MLX-Kokoro, XTTS CLI, скрипт клонирования голоса или что-либо еще, имеющее CLI), вы можете подключить его как провайдера командного типа без написания Python-кода. VibeOS записывает входной текст во временный UTF-8 файл, выполняет вашу команду оболочки и читает аудиофайл, созданный командой.

Объявите одного или нескольких провайдеров в разделе tts.providers.&lt;name&gt; и переключайтесь между ними с помощью tts.provider: <name> — так же, как вы переключаетесь между встроенными провайдерами, такими как edge и openai.

tts:
provider: voxcpm # выберите любое имя в tts.providers
providers:
voxcpm:
type: command
command: "voxcpm --ref ~/voice.wav --text-file {input_path} --out {output_path}"
output_format: mp3
timeout: 180
voice_compatible: true # попытаться доставить как голосовое сообщение Telegram

mlx-kokoro:
type: command
command: "python -m mlx_kokoro --in {input_path} --out {output_path} --voice {voice}"
voice: af_sky
output_format: wav

piper-custom: # родной Piper также поддерживает пользовательские .onnx через tts.piper.voice
type: command
command: "piper -m /path/to/custom.onnx -f {output_path} < {input_path}"
output_format: wav

Пример: Doubao (китайский seed-tts-2.0)​

Для высококачественного китайского TTS через двунаправленный потоковый API ByteDance seed-tts-2.0 установите пакет PyPI doubao-speech и подключите его как командного провайдера:

pip install doubao-speech
export VOLCENGINE_APP_ID="your-app-id"
export VOLCENGINE_ACCESS_TOKEN="your-access-token"
tts:
provider: doubao
providers:
doubao:
type: command
command: "doubao-speech say --text-file {input_path} --out {output_path}"
output_format: mp3
max_text_length: 1024
timeout: 30

Учетные данные берутся из вашего окружения оболочки (VOLCENGINE_APP_ID / VOLCENGINE_ACCESS_TOKEN) или ~/.doubao-speech/config.yaml. Выберите голос, добавив --voice zh-female-warm (или любой другой псевдоним из doubao-speech list-voices) в команду. doubao-speech также включает потоковое ASR — см. раздел STT ниже для интеграции с VibeOS. Исходный код и полная документация: github.com/Hypnus-Yuan/doubao-speech.

Плейсхолдеры​

Ваш шаблон команды может ссылаться на эти плейсхолдеры. VibeOS подставляет их во время выполнения и экранирует каждое значение для соответствующего контекста (голый / в одинарных кавычках / в двойных кавычках), поэтому пути с пробелами и другими чувствительными для оболочки символами безопасны.

ПлейсхолдерЗначение
{input_path}Путь к временному UTF-8 текстовому файлу, созданному VibeOS
{text_path}Псевдоним для {input_path}
{output_path}Путь, по которому команда должна записать аудио
{format}mp3 / wav / ogg / flac
{voice}tts.providers.&lt;name&gt;.voice, пусто, если не задано
{model}tts.providers.&lt;name&gt;.model
{speed}Разрешенный множитель скорости (провайдера или глобальный)

Используйте {{ и }} для литеральных фигурных скобок.

Необязательные ключи​

КлючПо умолчаниюЗначение
timeout120Секунды; дерево процессов убивается по истечении времени (Unix killpg, Windows taskkill /T).
output_formatmp3Один из mp3 / wav / ogg / flac. Автоматически определяется из расширения вывода, если VibeOS выбирает путь.
voice_compatiblefalseЕсли true, VibeOS конвертирует вывод MP3/WAV в Opus/OGG через ffmpeg, чтобы Telegram отображал голосовое сообщение.
max_text_length5000Ввод обрезается до этой длины перед выполнением команды.
voice / modelпустоПередаются в команду только как значения плейсхолдеров.

Примечания по поведению​

  • Встроенные имена всегда побеждают. Запись tts.providers.openai никогда не заменяет родной провайдер OpenAI, поэтому никакая пользовательская конфигурация не может незаметно заменить встроенный.
  • Доставка по умолчанию — документ. Командные провайдеры доставляют аудио как обычные вложения на всех платформах. Включите доставку в виде голосового сообщения для каждого провайдера с помощью voice_compatible: true.
  • Сбои команд передаются агенту. Ненулевой код возврата, пустой вывод или тайм-аут возвращают ошибку с stderr/stdout команды, чтобы вы могли отладить провайдера из диалога.
  • type: command — значение по умолчанию, если задан command:. Явное указание type: command — хорошая практика, но не обязательна; запись с непустой строкой command обрабатывается как командный провайдер.
  • {input_path} / {text_path} взаимозаменяемы. Используйте тот, который лучше читается в вашей команде.

Безопасность​

Командные провайдеры выполняют любую команду оболочки, которую вы настроили, с вашими правами пользователя. VibeOS экранирует значения плейсхолдеров и обеспечивает заданный тайм-аут, но сам шаблон команды является доверенным локальным вводом — относитесь к нему так же, как к скрипту оболочки в вашем PATH.

Плагины-провайдеры на Python​

Для TTS-движков, которые нельзя выразить в виде одной команды оболочки — Python SDK без CLI, потоковые движки, API со списком голосов, аутентификация с обновлением OAuth — зарегистрируйте плагин Python через ctx.register_tts_provider(). Плагин сосуществует с (не заменяет) реестром пользовательских командных провайдеров; выберите тот интерфейс, который подходит для вашего движка.

Когда что выбирать​

Ваш бэкенд имеет…Используйте
Один CLI, читающий текст из файла/stdin и записывающий аудио в файл/stdoutКомандный провайдер (Python не нужен)
Два или три CLI, объединенных конвейером оболочкиКомандный провайдер
Только Python SDK — без CLIПлагин
Потоковые байты, которые вы хотите доставлять частями (голосовые сообщения во время генерации)Плагин (переопределить stream())
API со списком голосов, используемый vibeos setupПлагин (переопределить list_voices())
Поток обновления OAuth (не статический токен Bearer)Плагин

Встроенные всегда побеждают, а командные провайдеры побеждают плагины с тем же именем — поэтому плагины безопасно регистрировать под любым не встроенным именем, не беспокоясь о замене существующей конфигурации.

Минимальный плагин​

Поместите это в ~/.vibeos/plugins/my-tts/:

plugin.yaml:

name: my-tts
version: 0.1.0
description: "Мой пользовательский Python TTS-бэкенд"

__init__.py:

from agent.tts_provider import TTSProvider


class MyTTSProvider(TTSProvider):
@property
def name(self) -> str:
return "my-tts" # соответствует tts.provider

@property
def display_name(self) -> str:
return "My Custom TTS"

def is_available(self) -> bool:
# Верните False, если отсутствуют учетные данные/зависимости — средство выбора пропустит
# эту строку, но диспетчер все равно направит сюда при явной конфигурации.
import os
return bool(os.environ.get("MY_TTS_API_KEY"))

def synthesize(self, text, output_path, *, voice=None, model=None,
speed=None, format="mp3", **extra) -> str:
# Запишите аудиобайты в output_path, верните путь.
# Вызовите исключение при сбое — диспетчер преобразует исключения в
# стандартный конверт ошибки.
import my_tts_sdk
client = my_tts_sdk.Client()
audio_bytes = client.synthesize(text=text, voice=voice or "default")
with open(output_path, "wb") as f:
f.write(audio_bytes)
return output_path


def register(ctx):
ctx.register_tts_provider(MyTTSProvider())

Включите его (vibeos plugins enable my-tts), укажите tts.provider на него (tts.provider: my-tts в config.yaml), и инструмент text_to_speech будет направляться через ваш плагин.

Необязательные хуки​

Переопределите эти методы в вашем классе провайдера для более богатой интеграции:

  • list_voices() → список словарей {id, display, language, gender, preview_url}, отображаемых в vibeos tools.
  • list_models() → список словарей {id, display, languages, max_text_length}.
  • get_setup_schema() → вернуть {name, badge, tag, env_vars: [{key, prompt, url}]} для строки выбора в vibeos tools / vibeos setup. Без этого плагин все равно работает, но его строка в средстве выбора минимальна.
  • stream(text, *, voice, model, format, **extra) → итератор, возвращающий аудиобайты для потоковой доставки (по умолчанию вызывает NotImplementedError).
  • Свойство voice_compatible → установите True, если ваш вывод совместим с Opus и шлюз должен доставлять его как голосовое сообщение (по умолчанию False = обычное аудиовложение).

См. agent/tts_provider.py для полного ABC, включая строки документации.

Транскрибация голосовых сообщений (STT)​

Голосовые сообщения, отправленные в Telegram, Discord, WhatsApp, Slack или Signal, автоматически транскрибируются и вставляются в виде текста в диалог. Агент видит транскрипт как обычный текст.

ПровайдерКачествоСтоимостьAPI-ключ
Локальный Whisper (по умолчанию)ХорошееБесплатноНе требуется
Groq Whisper APIХорошее–ЛучшееБесплатный тарифGROQ_API_KEY
OpenAI Whisper APIХорошее–ЛучшееПлатноVOICE_TOOLS_OPENAI_KEY или OPENAI_API_KEY
Нулевая конфигурация

Локальная транскрибация работает «из коробки», если установлен faster-whisper. Если он недоступен, VibeOS также может использовать локальный CLI whisper из стандартных мест установки (например, /opt/homebrew/bin) или пользовательскую команду через VIBEOS_LOCAL_STT_COMMAND.

Конфигурация​

# В ~/.vibeos/config.yaml
stt:
provider: "local" # "local" | "groq" | "openai" | "mistral" | "xai"
local:
model: "base" # tiny, base, small, medium, large-v3
openai:
model: "whisper-1" # whisper-1, gpt-4o-mini-transcribe, gpt-4o-transcribe
mistral:
model: "voxtral-mini-latest" # voxtral-mini-latest, voxtral-mini-2602
xai:
model: "grok-stt" # xAI Grok STT

Детали провайдеров​

Локальный (faster-whisper) — Запускает Whisper локально через faster-whisper. Использует CPU по умолчанию, GPU, если доступен. Размеры моделей:

МодельРазмерСкоростьКачество
tiny~75 МБСамая быстраяБазовое
base~150 МББыстраяХорошее (по умолчанию)
small~500 МБСредняяЛучше
medium~1.5 ГБМедленнееОтличное
large-v3~3 ГБСамая медленнаяНаилучшее

Groq API — Требует GROQ_API_KEY. Хорошее облачное резервное решение, когда вам нужен бесплатный хостинг STT.

OpenAI API — Сначала принимает VOICE_TOOLS_OPENAI_KEY, затем OPENAI_API_KEY. Поддерживает whisper-1, gpt-4o-mini-transcribe и gpt-4o-transcribe.

Mistral API (Voxtral Transcribe) — Требует MISTRAL_API_KEY. Использует модели Voxtral Transcribe от Mistral. Поддерживает 13 языков, диаризацию говорящих и временные метки на уровне слов. Установка: cd ~/.vibeos/vibeos-agent && uv pip install -e ".[mistral]".

xAI Grok STT — Требует XAI_API_KEY. Отправляет запрос на https://api.x.ai/v1/stt как multipart/form-data. Хороший выбор, если вы уже используете xAI для чата или TTS и хотите один API-ключ для всего. Порядок автоопределения ставит его после Groq — явно укажите stt.provider: xai, чтобы принудительно его использовать.

Пользовательское резервное решение локального CLI — Установите VIBEOS_LOCAL_STT_COMMAND, если хотите, чтобы VibeOS напрямую вызывал локальную команду транскрибации. Шаблон команды поддерживает плейсхолдеры {input_path}, {output_dir}, {language} и {model}. Ваша команда должна записать транскрипт .txt где-нибудь в {output_dir}.

Пример: Doubao / Volcengine ASR​

Если вы используете doubao-speech для Doubao TTS (см. выше), тот же пакет обрабатывает распознавание речи через интерфейс локальной команды STT:

pip install doubao-speech
export VOLCENGINE_APP_ID="your-app-id"
export VOLCENGINE_ACCESS_TOKEN="your-access-token"
export VIBEOS_LOCAL_STT_COMMAND='doubao-speech transcribe {input_path} --out {output_dir}/transcript.txt'
stt:
provider: local_command

VibeOS записывает входящее голосовое сообщение в {input_path}, выполняет команду и читает файл .txt, созданный в {output_dir}. Язык определяется автоматически эндпо