- commands.yaml с рабочими примерами: медиа, громкость, поиск, папки, блокировка; перечитывается автоматически, ошибки не ломают остальные команды - Действия run / open / http / keys; вывод и ответы возвращаются модели - Вызов через модель (tool calling) и мгновенно по точным фразам, в том числе с параметрами - Подтверждение «да/нет» для опасных команд, после голосового вопроса микрофон включается сам - Безопасность: запуск без оболочки, защита аргументов cmd/PowerShell/.bat, переменные окружения раскрываются только в шаблоне - Вкладка «Команды» в настройках - Тесты разбора, действий, фраз и полных сценариев через Assistant Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
146 lines
10 KiB
Markdown
146 lines
10 KiB
Markdown
# agr-assistent
|
||
|
||
Минимальный AI-ассистент, живущий в системном трее.
|
||
|
||
- LLM: локальные модели (Ollama, LM Studio, llama.cpp) или OpenRouter — через единый OpenAI-совместимый API
|
||
- Каждый запрос отдельный — без бесконечной истории диалога; короткие уточнения («а завтра?»)
|
||
в течение пары минут после ответа видят предыдущие вопросы
|
||
- Журнал запросов и ответов со стримингом
|
||
- Долговременная память: «запомни…», «забудь…», а устойчивые факты о вас модель сохраняет сама
|
||
- Настраиваемые команды: запуск программ и скриптов, ссылки и папки, HTTP-запросы (Home Assistant),
|
||
клавиши и медиа — через модель или мгновенно по точной фразе, опасные — с подтверждением
|
||
- Озвучка ответов голосом Silero: фразы проговариваются по мере генерации, блоки кода пропускаются
|
||
- Голосовой ввод по глобальной горячей клавише: faster-whisper на видеокарте, конец фразы по паузе (Silero VAD)
|
||
- Слово активации («ассистент») через Vosk — без нажатия клавиш
|
||
|
||
## Запуск
|
||
|
||
Нужен [uv](https://docs.astral.sh/uv/).
|
||
|
||
```bash
|
||
uv sync
|
||
uv run agr-assistent
|
||
```
|
||
|
||
При первом запуске рядом создаётся `config.yaml` (путь можно переопределить переменной
|
||
`AGR_ASSISTENT_CONFIG`). В нём выбирается провайдер и модель:
|
||
|
||
```yaml
|
||
llm:
|
||
provider: openrouter
|
||
providers:
|
||
openrouter:
|
||
api_key: ${OPENROUTER_API_KEY} # или ключ напрямую
|
||
model: openai/gpt-4o-mini
|
||
```
|
||
|
||
Для Ollama достаточно запустить сервер и скачать модель: `ollama pull qwen2.5:7b`.
|
||
|
||
Модель Silero (~145 МБ) скачивается при первом запуске в `%LOCALAPPDATA%\agr-assistent\models`.
|
||
Голос и модель задаются в секции `tts` конфига; озвучку можно выключить в меню значка.
|
||
Silero читает только кириллицу: числа переводятся в слова, латиница пропускается.
|
||
|
||
### Память
|
||
|
||
Скажите «Запомни, что у меня Škoda Octavia» или «Забудь про машину». Если включено
|
||
автоматическое запоминание (`memory.auto_save`), модель сама сохраняет устойчивые факты:
|
||
имя, близких, технику, предпочтения. Факты хранятся локально в
|
||
`%LOCALAPPDATA%\agr-assistent\memory.sqlite3` и добавляются к каждому запросу; посмотреть,
|
||
исправить и удалить их можно в настройках на вкладке «Память».
|
||
|
||
Память работает через вызов инструментов, поэтому модель должна их поддерживать
|
||
(например, `qwen2.5:7b` в Ollama или большинство моделей OpenRouter). С другими моделями
|
||
ассистент просто отвечает без памяти и один раз предупреждает об этом.
|
||
|
||
### Команды
|
||
|
||
Команды описываются в `commands.yaml` рядом с `config.yaml`: при первом запуске он создаётся
|
||
с рабочими примерами (пауза, громкость, поиск, папка «Загрузки», блокировка) и
|
||
закомментированными шаблонами для скриптов, Home Assistant и выключения компьютера.
|
||
После сохранения файл перечитывается сам; список команд и ошибки видны в настройках.
|
||
|
||
```yaml
|
||
commands:
|
||
- name: room_light
|
||
description: Включить или выключить свет в комнате
|
||
phrases: ["свет {state}"] # мгновенно, без модели
|
||
parameters:
|
||
state: {type: string, enum: ["on", "off"]}
|
||
confirm: false # true — спросить «да/нет» перед выполнением
|
||
action:
|
||
type: http
|
||
method: POST
|
||
url: http://homeassistant.local:8123/api/services/light/turn_{state}
|
||
headers: {Authorization: "Bearer ${HA_TOKEN}"}
|
||
json: {entity_id: light.room}
|
||
```
|
||
|
||
Как команда выполняется:
|
||
|
||
- **Модель** выбирает команду по описанию и подставляет параметры («сделай потише на десять
|
||
шагов»). Результат (вывод скрипта, ответ сервера) возвращается модели, и она отвечает.
|
||
- **Точная фраза** выполняется сразу, без модели и даже без интернета, если запрос совпал
|
||
с ней целиком (регистр, «ё» и знаки препинания не важны).
|
||
- **Подтверждение** (`confirm: true`): ассистент спрашивает «Выполнить …?» и ждёт «да» или «нет»;
|
||
если вопрос был голосовым, микрофон включается сам.
|
||
|
||
Безопасность: модель может только выбрать команду из файла и передать параметры, которые
|
||
проверяются по описанию. Программы запускаются без командной оболочки; для `cmd`, PowerShell
|
||
и `.bat`/`.cmd` значения со спецсимволами отклоняются. `${ПЕРЕМЕННЫЕ}` подставляются только
|
||
из шаблона, поэтому секреты не попадают ни в модель, ни в параметры.
|
||
|
||
### Голосовой ввод
|
||
|
||
Нажмите `Win+Alt+Space` (настраивается в `voice.hotkey`), дождитесь короткого сигнала и говорите —
|
||
запись закончится сама после паузы, или нажмите клавишу ещё раз. Если ассистент в этот момент
|
||
отвечает, он замолкает и слушает.
|
||
|
||
Распознаёт faster-whisper (`large-v3-turbo`, ~1.6 ГБ, скачивается при первом запуске).
|
||
При наличии видеокарты NVIDIA используется она: библиотеки CUDA ставятся pip-пакетами
|
||
`nvidia-cublas-cu12` и `nvidia-cudnn-cu12`, отдельно устанавливать CUDA Toolkit не нужно.
|
||
Без видеокарты распознавание идёт на CPU — тогда лучше выбрать модель `small` или `medium`.
|
||
|
||
### Слово активации
|
||
|
||
Включается пунктом меню значка или `wake_word.enabled: true` в конфиге. Скажите «Ассистент»,
|
||
дождитесь сигнала и произнесите команду. Фразы задаются в `wake_word.phrases`, все слова должны
|
||
быть в словаре модели — иначе приложение сообщит, каких слов не хватает.
|
||
|
||
Пока ассистент слушает команду, думает или говорит, слово активации не отслеживается:
|
||
микрофон не занят дважды, и ассистент не реагирует на собственный голос. Перебить его во время
|
||
ответа можно горячей клавишей.
|
||
|
||
Используется маленькая модель Vosk (~45 МБ) со свободным распознаванием: в простое она почти
|
||
не нагружает процессор. Слова, начинающиеся с ключевого («ассистентка»), могут давать ложные
|
||
срабатывания.
|
||
|
||
### Настройки
|
||
|
||
Окно настроек открывается из меню значка или кнопкой «Настройки» в чате: провайдер и модель
|
||
(список моделей подгружается с сервера), голос, горячая клавиша, модель Whisper, слово активации,
|
||
автозапуск с Windows. Изменения сохраняются в `config.yaml` с сохранением комментариев;
|
||
ключи вида `${ПЕРЕМЕННАЯ}` остаются ссылками. Настройки модели и переключатели применяются сразу,
|
||
для смены моделей, голоса и горячей клавиши приложение предложит перезапуститься.
|
||
|
||
Закрытие окна сворачивает приложение в трей. Клик по значку открывает чат. Повторный запуск
|
||
не создаёт второй экземпляр, а показывает окно уже запущенного.
|
||
|
||
Лог пишется в `%LOCALAPPDATA%\agr-assistent\logs`. Путь к конфигу можно передать аргументом:
|
||
`agr-assistent --config D:\path\config.yaml`.
|
||
|
||
## Сборка exe
|
||
|
||
```bash
|
||
uv run pyinstaller agr-assistent.spec --noconfirm
|
||
```
|
||
|
||
Результат — папка `dist\agr-assistent` (~2.8 ГБ, из них ~2 ГБ — библиотеки CUDA) с
|
||
`agr-assistent.exe`; её можно переносить целиком. `config.yaml` создаётся рядом с exe, модели
|
||
скачиваются в `%LOCALAPPDATA%\agr-assistent\models` при первом запуске.
|
||
|
||
## Разработка
|
||
|
||
```bash
|
||
uv run pytest
|
||
```
|