Files
cosmo-voice-assistant/CLAUDE.md
d.klimov 6010816f1d Initial commit: Cosmo voice assistant
Полностью локальный голосовой ассистент на Python.

Стек:
- Wake word: openWakeWord (onnxruntime)
- STT: RealtimeSTT + faster-whisper + Silero VAD (CUDA)
- LLM-агент: smolagents ToolCallingAgent + Ollama qwen2.5:7b
- TTS: Silero V4 (torch.hub) + sounddevice
- Shell: Git Bash (Windows) / bash (macOS)

Поддерживает Windows и macOS. Агент с памятью и tool calling —
находит программы самостоятельно, запоминает пути, выполняет
произвольные shell-команды.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 15:58:12 +03:00

209 lines
8.0 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.
# 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` в конце файла — агент автоматически получит доступ.
## Разработка
Логи пишутся в `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('открой браузер'))
"
```