Files
smart-speaker/README.md

230 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Alexander Smart Speaker
<div align="center">
Голосовой ассистент для Linux: wake word, STT/TTS, AI-диалог и полезные голосовые навыки.
[![Python 3.9+](https://img.shields.io/badge/Python-3.9%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/)
[![Linux](https://img.shields.io/badge/Platform-Linux-FCC624?logo=linux&logoColor=111)](https://www.linux.org/)
[![MIT License](https://img.shields.io/badge/License-MIT-2ea44f)](LICENSE.txt)
[![Wake Word](https://img.shields.io/badge/Wake%20Word-Porcupine-0b7285)](https://picovoice.ai/platform/porcupine/)
[![STT](https://img.shields.io/badge/STT-Deepgram-4c6ef5)](https://deepgram.com/)
[![TTS](https://img.shields.io/badge/TTS-Silero-7950f2)](https://github.com/snakers4/silero-models)
</div>
## Что это
`Alexander Smart Speaker` слушает ключевое слово `Waltron`, распознает речь, маршрутизирует команду в нужный модуль и озвучивает ответ.
Проект оптимизирован под русский язык, но поддерживает RU/EN сценарии (включая перевод и mixed-language TTS).
Проект собран как локальная голосовая колонка под Linux: активация по wake word, распознавание речи, маршрутизация команд, ответ через AI или встроенные модули и затем озвучка результата.
## Возможности
- Активация по wake word `Waltron` (Porcupine).
- Follow-up окно 4 секунды после ответа: если пользователь молчит, ассистент возвращается к ожиданию wake word.
- Распознавание речи через Deepgram (WebSocket, VAD, fast stop).
- Озвучка через Silero TTS (RU + EN, с прерыванием по wake word).
- AI-диалог через OpenRouter, OpenAI, Gemini, Z.ai и Anthropic Claude API со streaming-ответом и контекстом.
- Перевод RU -> EN и EN -> RU.
- Погода: текущий прогноз по городу по умолчанию или по названию города.
- Таймеры, будильники (включая будни/выходные), секундомеры.
- Управление громкостью системы (через `pactl`/`amixer`).
- Управление Spotify (play/pause/next/what's playing).
- Мини-игра "Города".
## Как это работает
```mermaid
flowchart TD
A[Wake Word: Waltron] --> B[STT: Deepgram]
B --> C{Маршрутизация команды}
C --> D[Feature modules]
C --> E[AI/Translation]
D --> F[TTS: Silero]
E --> F
F --> G[Follow-up режим или ожидание wake word]
```
## Что Важно В Этой Реализации
- Контекст диалога хранится в памяти текущей сессии, поэтому после первого вопроса можно продолжать разговор без потери нити.
- Системная роль ассистента и `ROLE_JSON` сохраняются для всех поддерживаемых AI-провайдеров.
- Для AI используется строго один активный API key. Если в `.env` оставить несколько ключей, ассистент покажет ошибку конфигурации вместо случайного выбора.
- Поддержка провайдеров сделана внутри одного модуля, но с разным форматом запросов для OpenAI-compatible API и Anthropic.
## Быстрый старт
### 1) Системные зависимости (Ubuntu/Debian)
```bash
sudo apt-get update
sudo apt-get install -y portaudio19-dev libasound2-dev mpg123 pulseaudio-utils alsa-utils
```
### 2) Установка Python-зависимостей
```bash
git clone <URL_ВАШЕГО_РЕПОЗИТОРИЯ>
cd alexander_smart-speaker
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
### 3) Настройка `.env`
```bash
cp .env.example .env
```
Минимально обязательные переменные:
```ini
AI_PROVIDER= # опционально; можно оставить пустым
# Раскомментируйте только один AI API KEY:
# OPENROUTER_API_KEY=...
# OPENAI_API_KEY=...
# GEMINI_API_KEY=...
# ZAI_API_KEY=...
# ANTHROPIC_API_KEY=...
DEEPGRAM_API_KEY=...
PORCUPINE_ACCESS_KEY=...
```
Если одновременно оставить несколько AI API key, ассистент вернет ошибку: он не будет выбирать провайдера наугад.
Пример:
```ini
# правильно
OPENAI_API_KEY=sk-...
# GEMINI_API_KEY=...
# ANTHROPIC_API_KEY=...
# неправильно
OPENAI_API_KEY=sk-...
GEMINI_API_KEY=AIza...
```
### 4) Запуск
```bash
make run
# или
python run.py
```
После запуска ассистент перейдет в режим ожидания фразы `Waltron`.
### Кросс-платформенный аудио режим
- Приложение автоматически подбирает рабочий микрофон/динамик через PortAudio.
- Если основное аудио-устройство не подходит, включается fallback по другим устройствам и sample rate.
- При проблемах можно явно задать устройство через `.env` (`AUDIO_*_DEVICE_NAME` или `AUDIO_*_DEVICE_INDEX`).
## Конфигурация `.env`
| Переменная | Обязательно | По умолчанию | Назначение |
|---|---|---|---|
| `AI_PROVIDER` | Нет | `openrouter` | Опциональный провайдер AI (`openrouter`, `openai`, `gemini`, `zai`, `anthropic`; также понимает `claude`) |
| `OPENROUTER_API_KEY` | Да* | - | Ключ OpenRouter API (*если выбран OpenRouter и только этот AI ключ активен) |
| `OPENROUTER_MODEL` | Нет | `openai/gpt-4o-mini` | Модель OpenRouter |
| `OPENROUTER_API_URL` | Нет | `https://openrouter.ai/api/v1/chat/completions` | Endpoint OpenRouter Chat Completions |
| `OPENAI_API_KEY` | Да* | - | Ключ OpenAI API (*если выбран OpenAI и только этот AI ключ активен) |
| `OPENAI_MODEL` | Нет | `gpt-4o-mini` | Модель OpenAI |
| `OPENAI_API_URL` | Нет | `https://api.openai.com/v1/chat/completions` | Endpoint OpenAI Chat Completions |
| `GEMINI_API_KEY` | Да* | - | Ключ Google Gemini API (*если выбран Gemini и только этот AI ключ активен) |
| `GEMINI_MODEL` | Нет | `gemini-2.5-flash` | Модель Gemini |
| `GEMINI_API_URL` | Нет | `https://generativelanguage.googleapis.com/v1beta/openai/chat/completions` | OpenAI-compatible endpoint Gemini |
| `ZAI_API_KEY` | Да* | - | Ключ Z.ai API (*если выбран Z.ai и только этот AI ключ активен) |
| `ZAI_MODEL` | Нет | `glm-5` | Модель Z.ai |
| `ZAI_API_URL` | Нет | `https://api.z.ai/api/paas/v4/chat/completions` | Endpoint Z.ai Chat Completions |
| `ANTHROPIC_API_KEY` | Да* | - | Ключ Anthropic API (*если выбран Anthropic и только этот AI ключ активен) |
| `ANTHROPIC_MODEL` | Нет | `claude-sonnet-4-20250514` | Модель Claude |
| `ANTHROPIC_API_URL` | Нет | `https://api.anthropic.com/v1/messages` | Endpoint Anthropic Messages API |
| `ANTHROPIC_API_VERSION` | Нет | `2023-06-01` | Версия Anthropic API |
| `DEEPGRAM_API_KEY` | Да | - | Ключ Deepgram STT |
| `PORCUPINE_ACCESS_KEY` | Да | - | Ключ PicoVoice Porcupine |
| `PORCUPINE_SENSITIVITY` | Нет | `0.8` | Чувствительность wake word |
| `AUDIO_INPUT_DEVICE_NAME` | Нет | auto | Подстрока имени микрофона (например `pulse`), если нужно выбрать конкретный input device |
| `AUDIO_INPUT_DEVICE_INDEX` | Нет | auto | Индекс PortAudio для микрофона (приоритетнее `AUDIO_INPUT_DEVICE_NAME`) |
| `AUDIO_OUTPUT_DEVICE_NAME` | Нет | auto | Подстрока имени динамика/выхода (например `pulse`) |
| `AUDIO_OUTPUT_DEVICE_INDEX` | Нет | auto | Индекс PortAudio для вывода (приоритетнее `AUDIO_OUTPUT_DEVICE_NAME`) |
| `TTS_EN_SPEAKER` | Нет | `en_0` | Английский голос TTS |
| `WEATHER_LAT` | Нет | - | Широта города по умолчанию |
| `WEATHER_LON` | Нет | - | Долгота города по умолчанию |
| `WEATHER_CITY` | Нет | `Ухта` | Город по умолчанию для погоды |
| `SPOTIFY_CLIENT_ID` | Нет | - | Spotify OAuth Client ID |
| `SPOTIFY_CLIENT_SECRET` | Нет | - | Spotify OAuth Client Secret |
| `SPOTIFY_REDIRECT_URI` | Нет | `http://localhost:8888/callback` | Redirect URI для Spotify |
## Примеры голосовых команд
| Категория | Примеры |
|---|---|
| Активация | `Waltron` |
| AI-диалог | `Почему небо голубое?` |
| Перевод | `Переведи на английский: как дела` |
| Погода | `Какая погода?`, `Погода в Москве` |
| Таймер | `Поставь таймер на 5 минут` |
| Будильник | `Поставь будильник на 7:30`, `Будильник по будням в 8:00` |
| Секундомер | `Запусти секундомер`, `Покажи активные секундомеры` |
| Громкость | `Громкость 7` |
| Spotify | `Включи музыку`, `Пауза`, `Что сейчас играет` |
| Игра | `Давай сыграем в города` |
| Управление диалогом | `Повтори`, `Стоп`, `Хватит` |
Память текущего диалога, история сообщений и `ROLE_JSON` системной роли сохраняются для всех поддерживаемых AI-провайдеров.
## Как Выбирается AI-Провайдер
1. Приложение проверяет, какие AI API key реально активны в `.env`.
2. Если активен ровно один ключ, используется именно он.
3. Если активны несколько ключей, ассистент возвращает ошибку конфигурации.
4. Если активных ключей нет, приложение ориентируется на `AI_PROVIDER`, но без ключа работать не сможет.
Такое поведение сделано специально, чтобы конфигурация была предсказуемой и при демонстрации не возникало скрытого переключения между сервисами.
## Полезные команды
| Команда | Что делает |
|---|---|
| `make run` | Запуск ассистента |
| `make check` | Локальная проверка проекта (`scripts/qwen-check.sh`) |
| `make qwen-context` | Сбор контекста проекта (`scripts/qwen-context.sh`) |
## Структура проекта
```text
alexander_smart-speaker/
├── run.py
├── app/
│ ├── main.py
│ ├── audio/ # wakeword, stt, tts, volume
│ ├── core/ # config, ai, command helpers, cleaner
│ └── features/ # weather, timer, alarm, stopwatch, music, cities game
├── assets/
│ ├── models/ # Porcupine keyword model (.ppn)
│ └── sounds/ # звуки уведомлений и будильника
├── data/ # persisted JSON: alarms, timers, stopwatches
└── scripts/
```
## Диагностика
| Проблема | Что проверить |
|---|---|
| Не реагирует на `Waltron` | `PORCUPINE_ACCESS_KEY`, микрофон, чувствительность `PORCUPINE_SENSITIVITY` |
| STT не распознает речь | `DEEPGRAM_API_KEY`, сетевой доступ, выбранный микрофон |
| Нет звука | корректное аудиоустройство и доступность `pactl`/`amixer` |
| `Audio input/output initialization failed` | проверить, что звук-сервер запущен (PipeWire/PulseAudio), и при необходимости задать `AUDIO_INPUT_DEVICE_NAME`/`AUDIO_OUTPUT_DEVICE_NAME` |
| Будильник/таймер не звонит | наличие `mpg123` в системе |
| Ошибка про несколько AI API | в `.env` должен остаться только один незакомментированный AI ключ |
| Spotify не управляется | заполнены `SPOTIFY_*`, есть активное устройство, Premium-аккаунт |
## Лицензия
Проект распространяется по лицензии MIT. См. `LICENSE.txt`.