Что получится в результате
Соберем практическую схему выбора модели для ИИ-агента. Не будем выбирать модель по рекламному названию или общему бенчмарку. Вместо этого сделаем короткий тестовый контур: список задач агента, требования к tool calling, контексту, скорости, цене, безопасности, качеству ответов, fallback и мониторингу. На выходе будет не одна "лучшая модель", а понятная модельная конфигурация: быстрая модель для простых шагов, сильная модель для сложных решений, отдельная модель для embeddings и резервный маршрут.
В результате будет рабочий MVP:
- сценарии агента описаны в `agent_task_catalog`;
- требования к модели лежат в `model_requirements`;
- кандидаты моделей хранятся в `candidate_models`;
- capability matrix лежит в `model_capabilities`;
- тестовые задачи лежат в `eval_cases`;
- эталонные ответы лежат в `expected_outputs`;
- результаты прогонов пишутся в `eval_runs`;
- стоимость запросов пишется в `cost_log`;
- задержки фиксируются в `latency_log`;
- качество tool calling пишется в `tool_call_results`;
- ошибки JSON и schema validation пишутся в `schema_validation_log`;
- правила маршрутизации лежат в `model_routing_rules`;
- fallback-настройки лежат в `fallback_policy`;
- лимиты токенов лежат в `context_budget`;
- guardrails лежат в `safety_rules`;
- все prompts, ответы и решения пишутся в `audit_log`;
- ошибки провайдера и повторы пишутся в `error_log`.
Первая версия должна выбрать модель не для всех задач сразу, а для конкретного агента: например, агент поддержки, агент по документам, SQL-агент, агент для таблиц или агент для почты.
Что понадобится
Минимальный набор:
- описание одного ИИ-агента и его задач;
- 30-50 реальных или синтетических тестовых кейсов;
- список инструментов агента;
- схема ожидаемых JSON-ответов;
- бюджет на 1000 задач;
- допустимая задержка ответа;
- список запрещенных действий;
- 3-6 моделей-кандидатов от разных провайдеров или разных классов;
- embeddings-модель, если агент использует RAG;
- таблица или база для логов тестирования;
- человек, который проверит спорные ответы.
Для первого запуска достаточно трех кандидатов: `fast_model`, `balanced_model`, `reasoning_model`. Конкретные `model_id` храните в `candidate_models`, чтобы можно было обновить их без переписывания логики агента.
Шаг 1. Опишите агента как набор задач
Не выбирайте модель до того, как описаны задачи.
Создайте `agent_task_catalog`.
Колонки:
id
agent_name
task_code
task_name
input_type
output_type
risk_level
frequency
requires_tools
requires_reasoning
requires_long_context
Пример задач:
support_agent | classify_ticket | классифицировать обращение | text | json | low | high | no | low | no
support_agent | draft_reply | подготовить ответ | text+kb | text | medium | high | yes | medium | medium
support_agent | refund_decision | предложить возврат | text+crm | json | high | low | yes | high | medium
support_agent | escalate_case | передать оператору | text | action | medium | medium | yes | low | no
Проверка: у каждой задачи есть риск, частота, тип входа и формат выхода.
Шаг 2. Разделите задачи по классам моделей
Один агент не обязан работать на одной модели.
Типовая схема:
- `fast_model` для классификации, маршрутизации, коротких ответов;
- `balanced_model` для обычных диалогов, RAG-ответов и summary;
- `reasoning_model` для сложных решений, многошаговых задач и спорных кейсов;
- `embedding_model` для поиска по документам;
- `local_model` для приватных или дешевых внутренних задач;
- `fallback_model` на случай ошибки провайдера.
Проверка: задача `classify_ticket` не уходит в дорогую reasoning-модель без причины.
Шаг 3. Сформулируйте требования в `model_requirements`
Создайте `model_requirements`.
Колонки:
id
agent_name
task_code
must_have_json
must_have_tool_calling
must_have_vision
must_have_audio
min_context_tokens
max_latency_ms
max_cost_per_1000_tasks
min_quality_score
data_residency
safety_level
Пример:
draft_reply | yes | yes | no | no | 32000 | 6000 | 8.00 | 0.82 | any | medium
refund_decision | yes | yes | no | no | 64000 | 12000 | 15.00 | 0.90 | restricted | high
Проверка: если задача требует JSON и tools, модель без стабильного structured output не попадает в shortlist.
Шаг 4. Создайте `candidate_models`
Не храните model id в коде агента.
Колонки:
id
provider
model_id
model_role
status
input_price_unit
output_price_unit
context_window
supports_json
supports_tools
supports_vision
supports_audio
notes
updated_at
`model_role`:
- `fast`;
- `balanced`;
- `reasoning`;
- `embedding`;
- `reranker`;
- `local`;
- `fallback`.
Проверка: заменить модель можно обновлением строки в `candidate_models`, а не изменением кода workflow.
Шаг 5. Заполните capability matrix
Создайте `model_capabilities`.
Колонки:
id
model_id
capability
score
evidence
tested_at
Оценивайте:
- следование system prompt;
- стабильный JSON;
- tool calling;
- работа с длинным контекстом;
- RAG-ответы с citations;
- отказ от ответа без данных;
- качество русского языка;
- устойчивость к prompt injection;
- скорость;
- стоимость;
- качество reasoning;
- качество summary;
- качество классификации;
- мультимодальность;
- доступность API.
Проверка: у каждого score есть тест или наблюдение, а не впечатление "модель умная".
Шаг 6. Сделайте тестовый набор `eval_cases`
Без evals выбор модели будет угадыванием.
Создайте `eval_cases`.
Колонки:
id
agent_name
task_code
case_name
input_json
expected_behavior
risk_level
tags
is_active
Соберите минимум:
- 10 обычных кейсов;
- 5 сложных кейсов;
- 5 кейсов с неполными данными;
- 5 кейсов с prompt injection;
- 5 кейсов с ошибками инструментов;
- 5 кейсов, где нужно отказаться от ответа;
- 5 кейсов с большим контекстом;
- 5 кейсов на точный JSON.
Проверка: тесты покрывают реальные действия агента, а не только чатовые вопросы.
Шаг 7. Опишите эталон в `expected_outputs`
Эталон не всегда должен быть буквальным текстом.
Колонки:
id
eval_case_id
expected_json_schema
must_include
must_not_include
allowed_actions
forbidden_actions
human_review_notes
Пример:
must_include | "requires_approval": true
must_not_include | "refund_sent": true
allowed_actions | create_refund_draft
forbidden_actions | send_refund, delete_ticket
Проверка: тест может автоматически понять, что модель вызвала запрещенный tool.
Шаг 8. Проверьте structured output
Если агент работает с действиями, JSON важнее красивого текста.
Тестируйте:
- валидный JSON;
- соответствие schema;
- отсутствие лишних ключей;
- правильные enum;
- числовые типы;
- даты в ISO;
- пустые значения как `null`;
- отказ от выдуманных полей.
Создайте `schema_validation_log`.
Колонки:
id
eval_run_id
model_id
schema_name
is_valid
errors_json
raw_output_hash
created_at
Проверка: модель, которая часто ломает JSON, не подходит для агента с tools.
Шаг 9. Проверьте tool calling
Создайте `tool_call_results`.
Колонки:
id
eval_run_id
model_id
tool_name
expected_tool
actual_tool
arguments_valid
dangerous_call_detected
result_status
created_at
Проверяйте:
- модель выбирает правильный tool;
- аргументы соответствуют schema;
- модель не вызывает tool без разрешения;
- модель не повторяет tool бесконечно;
- модель корректно обрабатывает ошибку tool;
- модель просит недостающие данные, если их нет.
Проверка: на кейсе "вернуть деньги клиенту" модель создает `refund_draft`, а не вызывает `send_refund`.
Шаг 10. Проверьте RAG и citations
Для агента по документам, базе знаний, почте или внутреннему поиску модель должна отвечать по найденным фрагментам.
Проверяйте:
- использует ли модель retrieved chunks;
- указывает ли citations;
- не добавляет ли факты из памяти;
- говорит ли "не найдено", если ответа нет;
- не путает похожие документы;
- выдерживает ли длинный контекст;
- не раскрывает документы без доступа.
Проверка: если retrieval пустой, ответ не должен содержать уверенный факт.
Шаг 11. Проверьте reasoning
Reasoning нужен не всем задачам.
Используйте сильную модель для:
- сложного планирования;
- анализа противоречий;
- выбора последовательности tools;
- диагностики ошибок;
- SQL-планирования;
- юридических рисков;
- финансовых проверок;
- спорных customer support решений;
- генерации тестовых сценариев;
- проверки safety cases.
Не используйте дорогой reasoning там, где достаточно классификации или шаблонного summary.
Проверка: routing отправляет сложный кейс в `reasoning_model`, а простую классификацию в `fast_model`.
Шаг 12. Проверьте контекстное окно
Большой context window полезен, но не заменяет RAG.
Создайте `context_budget`.
Колонки:
id
task_code
system_tokens
developer_tokens
user_tokens
retrieval_tokens
tool_tokens
reserved_output_tokens
max_context_tokens
Правила:
- оставляйте резерв на output;
- не отправляйте всю базу знаний;
- режьте длинные цепочки сообщений;
- summary старого диалога храните отдельно;
- tables и документы передавайте фрагментами;
- большие файлы обрабатывайте pipeline, а не одним prompt.
Проверка: запрос не падает из-за переполнения контекста.
Шаг 13. Проверьте скорость
Создайте `latency_log`.
Колонки:
id
model_id
task_code
input_tokens
output_tokens
ttfb_ms
total_ms
status
created_at
Измеряйте:
- time to first token;
- полное время ответа;
- время tool call loop;
- время retry;
- p50;
- p90;
- p95;
- p99.
Проверка: модель для онлайн-чата укладывается в UX-лимит, а тяжелые задачи уходят в фоновую очередь.
Шаг 14. Проверьте стоимость
Создайте `cost_log`.
Колонки:
id
model_id
task_code
input_tokens
output_tokens
cached_tokens
estimated_cost
created_at
Считайте:
- стоимость одного запроса;
- стоимость 1000 задач;
- стоимость retry;
- стоимость tools;
- стоимость embeddings;
- стоимость reranking;
- стоимость fallback;
- стоимость логирования и хранения.
Проверка: модель укладывается в бюджет на 1000 задач, а не только в один красивый демо-запрос.
Шаг 15. Проверьте безопасность
Создайте `safety_rules`.
Колонки:
id
agent_name
rule_code
description
severity
action
is_active
Проверяйте:
- prompt injection;
- jailbreak;
- раскрытие system prompt;
- вызов запрещенного tool;
- вывод персональных данных;
- уверенный ответ без данных;
- обход approval;
- попытки удалить данные;
- внешнюю отправку;
- работу с секретами.
Проверка: модель не выполняет инструкцию из пользовательского файла как системную команду.
Шаг 16. Проверьте русский язык и стиль
Для русскоязычного сайта, поддержки или базы знаний качество русского важно отдельно.
Проверяйте:
- естественный русский;
- отсутствие машинной канцелярщины;
- корректные термины;
- сохранение тона бренда;
- правильное обращение к пользователю;
- способность писать коротко;
- отсутствие лишней воды;
- корректные даты, суммы и единицы.
Проверка: ответ можно отправить пользователю без переписывания человеком.
Шаг 17. Запустите eval run
Создайте `eval_runs`.
Колонки:
id
eval_case_id
model_id
prompt_version
output_text
output_json
quality_score
latency_ms
estimated_cost
passed
failure_reason
created_at
Алгоритм:
- выберите активные `eval_cases`;
- прогоните каждую модель;
- провалидируйте JSON;
- проверьте tools;
- посчитайте latency;
- посчитайте cost;
- сохраните score;
- отметьте failed cases;
- отправьте спорные ответы человеку.
Проверка: решение по модели основано на `eval_runs`, а не на одном ручном тесте.
Шаг 18. Посчитайте итоговый score
Сделайте простую формулу.
Пример весов:
quality_score | 40
tool_call_score | 20
schema_score | 15
safety_score | 15
latency_score | 5
cost_score | 5
Для рискованных агентов увеличьте вес safety и schema. Для массовых дешевых задач увеличьте вес latency и cost.
Проверка: модель с отличным текстом, но плохим tool calling не выигрывает у агента, который должен выполнять действия.
Шаг 19. Создайте правила маршрутизации
Создайте `model_routing_rules`.
Колонки:
id
agent_name
task_code
condition_json
primary_model_role
fallback_model_role
max_retries
requires_human_review
is_active
Примеры:
classify_ticket | any | fast | balanced | 1 | no
draft_reply | kb_context_exists | balanced | fallback | 1 | no
refund_decision | risk_level=high | reasoning | balanced | 0 | yes
sql_generation | database_write=true | reasoning | none | 0 | yes
Проверка: high-risk задача не идет в дешевую модель только из-за экономии.
Шаг 20. Настройте fallback
Создайте `fallback_policy`.
Колонки:
id
model_role
fallback_order_json
retry_on_errors_json
do_not_retry_on_json
human_handoff_on_fail
Fallback нужен при:
- timeout;
- rate limit;
- provider error;
- invalid JSON;
- tool call loop;
- safety uncertainty;
- low confidence;
- context overflow.
Проверка: при ошибке провайдера агент переходит на резервную модель или честно отправляет задачу человеку.
Шаг 21. Настройте human review
Не все нужно автоматизировать.
Отправляйте на человека:
- high-risk решения;
- финансовые действия;
- юридические выводы;
- отправку внешних писем;
- изменение данных;
- низкую confidence;
- конфликтующие источники;
- нарушение schema;
- повторные ошибки tool;
- жалобы пользователей.
Проверка: задача с `risk_level = high` не завершается автоматическим действием.
Шаг 22. Версионируйте prompts
Создайте `prompt_versions`.
Колонки:
id
agent_name
task_code
prompt_role
version
content
status
created_at
Правила:
- не меняйте prompt без версии;
- eval run должен хранить `prompt_version`;
- сравнивайте модель и prompt вместе;
- не выкатывайте новый prompt без регрессионного теста;
- системные правила отделяйте от пользовательского контента.
Проверка: можно понять, модель ухудшилась или prompt изменился.
Шаг 23. Сделайте наблюдение в production
Создайте мониторинг.
Метрики:
- pass rate;
- invalid JSON rate;
- tool error rate;
- fallback rate;
- human review rate;
- average cost;
- p95 latency;
- safety flags;
- user correction rate;
- answer satisfaction.
Проверка: если invalid JSON rate вырос, вы видите это до жалоб пользователей.
Шаг 24. Проведите контрольный тест
Прогоните 5 типов задач.
Тест:
- простая классификация обращения;
- RAG-вопрос по документу;
- tool call с безопасным действием;
- high-risk действие с approval;
- prompt injection внутри пользовательского текста.
Ожидаемый результат:
- классификация идет в `fast_model`;
- RAG идет в `balanced_model`;
- сложное решение идет в `reasoning_model`;
- опасное действие идет в `approval_queue`;
- prompt injection блокируется guardrails;
- все события есть в `audit_log`.
Проверка: выбранная модельная схема проходит тест целиком, а не только отвечает красиво в чате.
Шаг 25. Минимальный результат для запуска
MVP выбора модели готов, если выполнены условия:
- есть `agent_task_catalog`;
- есть `model_requirements`;
- есть минимум 3 кандидата в `candidate_models`;
- есть 30-50 `eval_cases`;
- проверены JSON и tools;
- посчитана стоимость;
- измерена latency;
- проверен RAG;
- проверен prompt injection;
- настроены routing rules;
- настроен fallback;
- high-risk задачи уходят на human review;
- production-логи пишутся в `audit_log`, `cost_log`, `latency_log` и `error_log`.
Проверка результата: вы можете объяснить, почему конкретная задача идет именно в эту модель, сколько это стоит, где fallback и какие тесты модель прошла.
Что нельзя автоматизировать в первой версии
В первой версии не автоматизируйте:
- выбор модели только по публичному бенчмарку;
- автоматическую замену модели без evals;
- high-risk действия без human review;
- tool calls без schema validation;
- работу без fallback;
- ответы по RAG без citations;
- отправку персональных данных в непроверенную модель;
- использование одной модели для всех задач;
- работу без cost limit;
- работу без latency monitoring;
- обновление prompts без версий;
- обработку prompt injection только надеждой на модель;
- хранение API keys в prompt;
- выбор локальной модели без теста качества;
- production-запуск без audit log.
Сначала выберите модельную схему для одного агента, прогоните evals и только потом переносите подход на другие агенты.
Частые вопросы
Можно ли выбрать одну модель для всего агента?
Можно для простого MVP, но чаще выгоднее разделить задачи: быстрая модель для классификации, сбалансированная для обычных ответов, сильная reasoning-модель для сложных решений и отдельная embedding-модель для RAG.
Что важнее: качество или цена?
Зависит от задачи. Для массовой классификации цена и скорость важны сильнее. Для финансового, юридического или action-агента важнее safety, structured output, tool calling и human review.
Нужна ли модель с большим контекстом?
Да, если агент работает с длинными документами, переписками или логами. Но большое окно не заменяет RAG, фильтрацию, summary и контекстный бюджет.
Как понять, что модель подходит для tool calling?
Прогоните eval cases: правильный tool, валидные аргументы, отсутствие опасных вызовов, корректная обработка ошибки tool и стабильный JSON. Если модель ломает schema, она плохо подходит для агентных действий.
Когда нужна локальная модель?
Локальная модель полезна для приватных данных, дешевых внутренних задач и автономной работы. Но ее нужно тестировать так же, как облачную: качество, JSON, tools, latency, стоимость инфраструктуры и безопасность.