L3 Открытый урок · Стажёр

L3.8. Локальная модель как второй провайдер

Зачем два провайдера, OpenAI-совместимый интерфейс, лицензии open-weights моделей и лаба: тот же код на локальной модели.

Объём
2 урока · 4 часа
Компетенции
INFER-01·F, ARCH-05·F, GOV-03·F

С L3 каждое приложение курса работает минимум с двумя провайдерами моделей, один из них — локальная open-weights модель. Зачем:

  • Независимость от поставщика. Сервис провайдера может подорожать, измениться или стать недоступным.
  • Приватность. Данные не покидают ваш компьютер или сервер.
  • Цена и оффлайн. Массовые простые задачи и разработка без сети.

Ключевая идея — OpenAI-совместимый интерфейс: POST {base_url}/chat/completions. Его поддерживают Ollama, vLLM, llama.cpp server и многие облачные шлюзы. Один провайдер в коде покрывает и локальную модель, и другого облачного вендора: меняются base_url и имя модели.

Лицензия — до первой строчки кода. Open-weights ≠ «можно всё». У моделей разные лицензии: Apache-2.0, MIT, собственные лицензии с ограничениями по числу пользователей, по сферам применения, на использование выходов для обучения других моделей. Читайте model card (GOV-03·F).

Практикум

Лаба: локальная модель как второй провайдер

Цель

Запустить тот же Research Assistant на локальной модели без изменения агента, RAG и eval: заменить только провайдера. Сравнить качество, скорость и цену с облачной моделью. Проверить лицензию выбранной модели.

Что нужно понимать до начала

OpenAI-совместимый интерфейс — де-факто конвенция: POST {base_url}/chat/completions с model и messages. Её поддерживают Ollama (по умолчанию http://localhost:11434/v1), vLLM, llama.cpp server и многие облачные шлюзы. Значит, один провайдер в коде покрывает и локальную модель, и «второго облачного вендора».

JSON-режим ≠ схема. response_format: {"type": "json_object"} гарантирует только, что ответ — JSON. Совпадение со схемой не гарантировано, особенно у малых моделей. Поэтому ответ валидируется Pydantic, а при ошибке срабатывает fail-safe — тот же паттерн, что в лабе 04.

Малые модели выдумывают инструменты. Решение агента проверяется: действие вне списка инструментов → шаг завершается (final), а не исполняется.

Шаги

1. Провайдер openai_compat (1,5 ч)

Добавьте в llm.py третью ветку рядом с echo и anthropic:

  • запрос через urllib.request из стандартной библиотеки — без нового SDK;
  • base_url, api_key, request_timeout — из конфига (RA_BASE_URL, RA_API_KEY); base_url принимается только со схемой http(s): иначе urllib откроет и file://;
  • схема ответа передаётся в промпте, ответ валидируется Answer.model_validate;
  • в decide — проверка, что action есть в списке инструментов;
  • любые сбои сети и валидации → fail_safe_answer.
pytest tests/test_openai_compat.py -q   # фейковый сервер: сеть и модель не нужны

2. Локальная модель (1 ч)

  1. Установите Ollama по инструкции с ollama.com и скачайте малую модель с поддержкой русского (1–8B).
  2. Найдите model card и лицензию модели. Запишите: лицензия, разрешено ли коммерческое использование, есть ли ограничения (по числу пользователей, по сферам, на использование выходов для обучения других моделей) (GOV-03·F).
  3. Запустите:
RA_LLM_PROVIDER=openai_compat RA_MODEL=<имя модели> make evals
RA_LLM_PROVIDER=openai_compat RA_MODEL=<имя модели> make agent-evals

3. Сравнение (1 ч)

Таблица на одном и том же golden-наборе:

Провайдер answer_match citation_match agent task_success среднее время ответа $ за прогон
echo (базлайн) 0
облачная модель
локальная модель 0 за токены

Время измерьте по трассе (total_ms). Цену облака посчитайте по usage и прайсу.

4. Вывод (0,5 ч)

Короткий ADR: где в вашем проекте локальная модель допустима (оффлайн, приватные данные, дешёвые массовые задачи), а где нет (качество, скорость на вашем железе). Что ещё пришлось бы решать в продакшене: сервинг, обновления модели, мониторинг. Это вход в L6.8–L6.9 (локальный инференс и TCO).

Definition of Done

  • [ ] pytest -q зелёный, включая тесты openai_compat на фейковом сервере.
  • [ ] Golden-набор прогнан на локальной модели; таблица сравнения заполнена честно, включая провалы.
  • [ ] Лицензия модели выписана из model card с выводом «можно ли в нашем проекте».
  • [ ] ADR «облако или локально для этой задачи».

Типичные ошибки

  • Менять агента или промпты «под локальную модель», не измерив: сначала прогон, потом решения.
  • Доверять JSON-режиму как схеме.
  • Выбирать модель по «звёздам», не прочитав лицензию.
  • Сравнивать скорость на разных вопросах или с прогретым и холодным сервером вперемешку.

Диагностика уровня

С какого уровня начать?

Оставьте контакты — свяжемся, зададим несколько вопросов об опыте и целях и подскажем уровень входа: с нуля, с середины программы или через Fast Track для разработчиков.

Или напишите: hello@superint.ru