# Cosmo — локальный голосовой ассистент Полностью локальный голосовой ассистент на Python. Не использует облачные API, всё работает на твоём железе. ## Архитектура ``` Микрофон → Wake Word → STT → LLM-агент → TTS → Динамики ↓ ↓ ↓ openWakeWord Whisper smolagents (hey_jarvis) (cuda) + Ollama ↓ Инструменты: run_shell, find_program, open_browser, read/write_file, memory_get/set ``` **Поток работы:** 1. `wake_word.py` — непрерывно слушает микрофон, детектирует слово-триггер 2. `transcriber.py` — записывает команду, транскрибирует через Whisper 3. `agent.py` — отправляет текст в Ollama, LLM вызывает инструменты в цикле пока не решит задачу 4. `tts.py` — озвучивает ответ через Silero ## Структура файлов ``` cosmo/ ├── main.py — точка входа, класс Cosmo ├── wake_word.py — детект wake word (openWakeWord + onnxruntime) ├── transcriber.py — STT (RealtimeSTT + faster-whisper + Silero VAD) ├── agent.py — LLM-агент (smolagents ToolCallingAgent + Ollama) ├── tools.py — инструменты агента для Windows (Git Bash) ├── tools_mac.py — инструменты агента для macOS (нативный bash) ├── memory.py — персистентная память (data/memory.json) └── tts.py — TTS (Silero V4 через torch.hub + sounddevice) config/ ├── config.yaml — настройки для Windows └── config_mac.yaml — настройки для macOS (CPU, int8) train_wakeword/ ├── record_samples.py — запись голосовых примеров ├── cosmo_config.yaml — конфиг обучения wake word ├── Dockerfile — среда Python 3.11 для обучения ├── entrypoint.sh — шаги обучения внутри Docker └── train.sh — главный скрипт обучения data/ └── memory.json — долгосрочная память агента (создаётся автоматически) models/ └── *.onnx — кастомные wake word модели (после обучения) ``` ## Железо (Windows машина) - CPU: Intel i5-13400F (10 ядер / 16 потоков) - RAM: 32 ГБ DDR5 6000 - GPU: RTX 4060 8 ГБ VRAM - OS: Windows 11, Python 3.13 ## Стек технологий | Компонент | Технология | Версия | |---|---|---| | Wake word | openWakeWord + onnxruntime | 0.6.0 | | STT | RealtimeSTT + faster-whisper | 0.3.104 / 1.1.1 | | VAD | Silero VAD (внутри RealtimeSTT) | — | | LLM | Ollama + qwen2.5:7b | ollama 0.6.1 | | Agent | smolagents ToolCallingAgent | 1.11.0 | | TTS | Silero V4 (torch.hub) + sounddevice | — | | Shell | Git Bash (Windows) / bash (macOS) | — | ## Запуск ### Windows ```bash bash install.sh # первый раз bash run.sh ``` ### macOS ```bash bash install_mac.sh # первый раз bash run_mac.sh ``` При первом запуске автоматически скачаются: - Whisper модель (~1.5 ГБ на Windows / ~150 МБ на Mac) - Silero TTS модель (~38 МБ) ## Активация Сейчас: говори **"Hey Jarvis"** — это fallback пока нет кастомной модели. После обучения кастомной модели: говори **"Hey Cosmo"**. После активации говори команду на русском: *"открой браузер"*, *"найди в гугле погоду"*, *"запусти WebStorm"*. ## Конфиг (config/config.yaml) ```yaml whisper: model_size: "distil-large-v3" # Windows GPU # model_size: "small" # Mac CPU device: "cuda" # "cpu" для Mac compute_type: "float16" # "int8" для CPU ollama: model: "qwen2.5:7b" # модель должна быть скачана: ollama pull qwen2.5:7b max_agent_steps: 10 # макс. шагов агента на одну команду tts: silero_speaker: "eugene" # голоса: xenia (ж), baya, aidar, eugene, kseniya ``` ## Память агента Агент автоматически запоминает информацию в `data/memory.json`: ```json { "facts": { "app.webstorm": "C:/Program Files/JetBrains/WebStorm.../webstorm64.exe", "user.name": "Даниил" }, "history": [...] } ``` **Ключи памяти:** - `app.<название>` — пути к программам - `user.<поле>` — данные о пользователе - `pref.<что>` — предпочтения После первого поиска программы агент запомнит её путь и больше не будет искать. ## Инструменты агента | Инструмент | Описание | |---|---| | `run_shell` | Выполнить bash команду | | `find_program` | Найти программу (PATH, Program Files, реестр / Spotlight на Mac) | | `open_browser` | Открыть URL или поиск Google | | `read_file` | Прочитать файл | | `write_file` | Записать файл | | `memory_get` | Получить факт из памяти | | `memory_set` | Сохранить факт в память | | `memory_list` | Показать все факты | ## Обучение кастомной wake word "Hey Cosmo" Требования: Docker Desktop, ~25 ГБ свободного места. ```bash # Опционально: запиши свой голос (30 примеров) python train_wakeword/record_samples.py # Запусти обучение (~1 час) bash train_wakeword/train.sh ``` Датасет (~20 ГБ) скачается в `train_wakeword/docker_data/` и сохранится для повторного использования. После обучения `.onnx` модель автоматически появится в `models/` и `wake_word.py` подхватит её. ## Известные ограничения - Wake word только английский ("Hey Jarvis" / "Hey Cosmo") — openWakeWord не поддерживает русский TTS для обучения - На Mac нет CUDA — Whisper работает на CPU, латентность выше (~2-3 сек вместо ~0.5 сек) - smolagents требует модель с поддержкой tool calling — qwen2.5:7b, llama3.2, mistral v0.3+ ## Добавление новых инструментов В `cosmo/tools.py` (Windows) или `cosmo/tools_mac.py` (Mac): ```python @tool def my_tool(param: str) -> str: """ Описание что делает инструмент — LLM читает это. Args: param: описание параметра """ # реализация return "результат" ``` Добавь в список `ALL_TOOLS` в конце файла — агент автоматически получит доступ. ## TODO / Идеи - [ ] **ChatterBox TTS вместо Silero** — более живой голос с эмоциями и клонированием голоса (10-30 сек сэмпла). Источник: [vndee/local-talking-llm](https://github.com/vndee/local-talking-llm). Параметр `exaggeration` (0.0–1.0) управляет экспрессивностью. Заменить `cosmo/tts.py`, интерфейс `say()`/`say_async()` не меняется. Проверить латентность на M1 CPU. - [ ] **Ollama Modelfile** — запечь системный промпт и параметры (короткие ответы, русский язык) прямо в модель через Modelfile, вместо передачи в каждом запросе. ## Разработка Логи пишутся в `logs/cosmo.log`. Уровень логирования меняется в конфиге (`logging.level: DEBUG`). Для тестирования агента без голоса: ```bash python -c " import yaml, sys sys.path.insert(0, '.') from cosmo.memory import Memory from cosmo.agent import Agent config = yaml.safe_load(open('config/config.yaml')) agent = Agent(config, Memory()) print(agent.run('открой браузер')) " ```