# Опыт: локальные auxiliary-модели для Hermes (RTX 5060 Ti 16 GB) > Дата: 2026-08-30 · Автор: Стороженко Евгений (kpa39l) · Среда: bigbox, RTX 5060 Ti 16 GB, Ubuntu > Связанная статья: [`content/posts/20260830 - local aux models hermes/index.md`](../content/posts/20260830%20-%20local%20aux%20models%20hermes/index.md) Этот документ — техническая копия опыта, описанного в статье блога. Здесь — точные конфиги, команды, замеры и грабли, чтобы можно было повторить настройку без повторного исследования. ## Проблема Агент Hermes (`/opt/hermes/.hermes/hermes-agent/`) помимо основной модели вызывает вспомогательные (auxiliary) задачи через `auxiliary_client.py`: - `vision` — описание картинок/скриншотов - `title_generation` — генерация заголовков диалогов - `web_extract` — извлечение текста из веб-страниц - `compression` — сжатие истории диалога (context compaction), **жёсткий минимум контекста 64K токенов** - `skills_hub`, `approval`, `mcp`, `triage_specifier`, `kanban_decomposer`, `profile_describer`, `curator` — служебные По умолчанию все они резолвятся в облачного провайдера (polza.ai) — тратят токены и деньги. Цель: увести на локальную Ollama то, что не требует 64K контекста. ## Выбор модели Критерии: уметь vision, влезать в 16 GB VRAM вместе с `bge-m3` (эмбеддинги), быстро отвечать (aux-задачи вызываются часто), желательно закрыть и текстовые задачи. - **qwen3-vl:8b** (~6.1 GB, контекст 262K, умеет vision) — для `vision`. Проверено: отвечает «red»/«blue» на цветные картинки 256x256 за 1–10 сек. - **qwen3:8b** (~5.2 GB, чисто текстовая) — для текстовых aux (`title_generation`, `web_extract`). На простой вопрос qwen3-vl генерит 3778 токенов reasoning и отвечает 64 сек — для текста непригодна. **compression осталась на polza.ai**: ей нужен контекст 64K+, а локальные GGUF не дотягивают: - qwen3-8b: реальный контекст 40960 (тег «64k» в названии — маркетинг) - qwen2.5-coder-14b: реально 32768 (тег «32k» честный) ## Настройка Рабочий конфиг в `/opt/hermes/.hermes/config.yaml`: ```yaml auxiliary: vision: provider: custom model: qwen3-vl:8b base_url: http://localhost:11434/v1 api_key: ollama title_generation: provider: custom model: qwen3:8b base_url: http://localhost:11434/v1 api_key: ollama extra_body: think: false web_extract: provider: custom model: qwen3:8b base_url: http://localhost:11434/v1 api_key: ollama extra_body: think: false ``` Команды CLI: ```bash hermes config set auxiliary.vision.provider custom hermes config set auxiliary.vision.model qwen3-vl:8b hermes config set auxiliary.vision.base_url http://localhost:11434/v1 hermes config set auxiliary.vision.api_key ollama # ...аналогично для title_generation и web_extract (model qwen3:8b + extra_body think:false) ``` ### Грабли 1. **`api_key` обязан быть непустым.** Пустой `api_key` = «унаследовать ключ основного провайдера» → попытка сходить в polza.ai с локальной моделью. Заглушка `ollama` подходит (Ollama её не проверяет). 2. **Ollama подключается через OpenAI-совместимый эндпоинт** `/v1/chat/completions` (именно так Hermes ходит в локальные модели). 3. **qwen3-vl:8b: держать `num_ctx` небольшим (8192).** Полный контекст 262K → KV cache ~309 GB, runner падает с EOF (`EOF on 127.0.0.1:45579`). 4. **`session_search` — НЕ auxiliary-задача** (это tool). Переопределение `auxiliary.session_search.*` из конфига нужно удалить. ## Допиливание: отключение режима размышлений (thinking) у Qwen3 Qwen3-модели по умолчанию генерируют скрытый поток reasoning перед ответом. Для aux это катастрофа: 64 сек на заголовок, пустой `content` при ограниченном `max_tokens` (весь бюджет съедает thinking). ### Что НЕ работает (проверено на Ollama) | Способ | Результат | |---|---| | `/no_think` в начале сообщения | Модель всё равно думает | | `enable_thinking: false` в extra_body | Не работает | | `thinking: {type: disabled}` (как в OpenAI API Qwen) | Не работает — reasoning продолжается | | System prompt «не думай» | Не работает | В chat template qwen3 есть команды `/think` и `/no_think`, но в Ollama они не активируются (флаг `IsThinkSet` не выставляется). ### Что работает **Единственный способ — корневой параметр `think: false` в теле запроса** (HTTP-уровень): ```bash curl http://localhost:11434/api/chat -d '{ "model": "qwen3:8b", "messages": [{"role": "user", "content": "Привет!"}], "think": false }' ``` Результат: ответ через **0.7 сек** (вместо 64), `reasoning=false`, `content` заполнен. В Hermes это передаётся через `extra_body: {think: false}` в конфиге — в коде `auxiliary_client.py` `effective_extra_body` уходит в корень JSON-тела запроса, ровно туда, куда Ollama ждёт `think`. ### E2E-замеры (реальные вызовы через Hermes `call_llm`) | Задача | Время | Результат | |---|---|---| | `title_generation` | 11.3 сек | «Настройка Ollama: локальные модели» | | `web_extract` | 7.5 сек | Извлёк главную мысль | | `vision` (картинка 256x256) | 7.6 сек | «blue» | ## VRAM / память RTX 5060 Ti 16 GB, держатся одновременно: - `qwen3-vl:8b` — ~7.2 GB (vision) - `qwen3:8b` — ~6.1 GB (текст) - `bge-m3` — ~1.2 GB (эмбеддинги) Итого ~14.5 GB — влезает, переключение vision↔текст без выгрузки (проверено через `/api/ps`). ## Откат ```bash hermes config set auxiliary..provider auto hermes config set auxiliary..model "" docker exec ollama ollama stop qwen3-vl:8b docker exec ollama ollama stop qwen3:8b ``` ## Сопутствующий фикс Hugo При сборке репозитория современным Hugo (0.145+) возникала ошибка: `config value "en" for defaultContentLanguage does not match any language definition`. Решение (коммит `1bda9e2`): добавить в `hugo.toml`: ```toml defaultContentLanguage = 'ru' ``` Потому что в `[languages]` объявлен только `ru`, а Hugo по умолчанию считает язык `en`.