8.9 KiB
DEV TASK — ORCH-41: Конфигурируемые модели LLM per-agent + per-project
Контекст / корень
Сейчас модель агентов зашита в коде src/agents/launcher.py (AGENT_CONFIGS):
- architect, reviewer →
"model": "opus" - analyst, developer, tester, deployer → модели НЕТ (CLI берёт дефолт)
- Алиас
opusв CLI 2.1.142 резолвится в opus-4-7 (подтверждено логами runs/102,103).
Слава хочет: модель выбирается в настройках, под каждого агента, с возможностью задать per-project. Это первый шаг к мультипровайдерности (ORCH-13). НЕ хардкодить версию — вынести в конфиг.
Расширено (решение Славы 05.06): 4.7 и 4.8 стоят одинаково → дефолт = claude-opus-4-8.
Дополнительно конфигурируем режим работы модели --effort (low/medium/high/xhigh/max) —
это рычаг «качество vs стоимость/время», per-agent + per-project, тем же резолвингом.
Опционально: --fallback-model (авто-фолбэк при overloaded, работает с --print).
Репозиторий / ветка
- Репо:
orchestrator, базаmain(HEAD8da571d) - Ветка:
feat/ORCH-41-agent-models, PR в main, НЕ мержить. - Сервер:
sshpass -p 'motoZ@yaz2010' ssh slin@82.22.50.71, контейнерorchestrator.
Архитектура (изучено лично — используй эти точки)
src/config.py—class Settings(BaseSettings)(pydantic-settings, env-driven, префиксORCH_). Паттерн уже есть:plane_bot_analyst..deployer. Делай модели по аналогии.src/projects.py—@dataclass(frozen=True) class ProjectConfig(поля: plane_project_id, repo, work_item_prefix), парсится изsettings.projects_json. Сюда добавляем per-project модели.src/agents/launcher.py—AGENT_CONFIGS(dict по агентам) + сборкаmodel_flag(строки ~88,99,207-208):model = config.get("model", "") model_flag = f"--model {model} " if model else ""
Что сделать
1. Глобальные дефолты модели per-agent — в Settings (src/config.py)
Добавить поля (env ORCH_AGENT_MODEL_<AGENT> и ORCH_AGENT_EFFORT_<AGENT>).
Дефолт модели = claude-opus-4-8 (цена 4.7==4.8, решение Славы).
# Per-agent LLM model (ORCH-41). Empty -> agent_model_default. Resolution order:
# project-override > ORCH_AGENT_MODEL_<AGENT> > agent_model_default > CLI default.
agent_model_default: str = "claude-opus-4-8"
agent_model_analyst: str = ""
agent_model_architect: str = ""
agent_model_developer: str = ""
agent_model_reviewer: str = ""
agent_model_tester: str = ""
agent_model_deployer: str = ""
# Per-agent effort / reasoning level (ORCH-41): low|medium|high|xhigh|max.
# Empty -> agent_effort_default. Same resolution order as model.
# Раскладка по умолчанию: думающие агенты — high, механические — medium.
agent_effort_default: str = "high"
agent_effort_analyst: str = "high"
agent_effort_architect: str = "high"
agent_effort_developer: str = "high"
agent_effort_reviewer: str = "high"
agent_effort_tester: str = "medium"
agent_effort_deployer: str = "medium"
# Optional per-agent fallback model when primary is overloaded (--fallback-model).
agent_fallback_model: str = ""
2. Per-project override — в ProjectConfig (src/projects.py)
Добавить опциональные поля agent_models: dict[str,str] И agent_efforts: dict[str,str]
(агент→модель / агент→effort), парсить из projects_json. Пример записи реестра:
{"plane_project_id":"...","repo":"orchestrator","work_item_prefix":"ORCH",
"agent_models":{"developer":"claude-opus-4-8","reviewer":"claude-sonnet-4-6"},
"agent_efforts":{"developer":"xhigh","tester":"low"}}
Оба поля опциональны → старые записи работают (default = {}).
ВНИМАНИЕ: dataclass frozen=True + mutable default → используй field(default_factory=dict).
3. Резолвинг — helper(ы) (где удобнее: launcher или projects)
resolve_agent_model(agent, project_id) -> str с приоритетом:
ProjectConfig.agent_models[agent](per-project override)settings.agent_model_<agent>(глобальный per-agent env, если непусто)settings.agent_model_default- (пусто) → без
--model, CLI-дефолт
Аналогично resolve_agent_effort(agent, project_id) -> str (тот же приоритет, через
agent_efforts / agent_effort_<agent> / agent_effort_default). Валидировать значение
по множеству {low,medium,high,xhigh,max}; невалидное → лог-warning + опустить флаг.
Желательно общий приватный резолвер, чтобы не дублировать логику приоритета.
4. Применить в launcher.py
- Убрать хардкод
"model": "opus"из AGENT_CONFIGS (architect, reviewer) — модель теперь резолвится. - При сборке команды:
и подставить
model = resolve_agent_model(agent, project_id) effort = resolve_agent_effort(agent, project_id) model_flag = f"--model {model} " if model else "" effort_flag = f"--effort {effort} " if effort else "" fb = settings.agent_fallback_model fb_flag = f"--fallback-model {fb} " if fb else ""{model_flag}{effort_flag}{fb_flag}в cmd. project_idуже доступен в потоке запуска (передаётся в launch — проверь сигнатуру, протяни если надо).
5. Тесты (tests/)
test_resolve_agent_model.py: все 4 уровня приоритета (project > env > default > пусто), отсутствие проекта, неизвестный агент, frozen-dataclass с agent_models.test_resolve_agent_effort.py: те же уровни + валидация значения (невалидное → опускается).- Проверить, что
--model/--effort/--fallback-modelкорректно подставляются/опускаются в собранной команде (по флагу присутствия).
6. Документация
- Обновить
docs/(конфиг-референс орка): новые envORCH_AGENT_MODEL_*,ORCH_AGENT_EFFORT_*,ORCH_AGENT_FALLBACK_MODEL, поляagent_models/agent_effortsв projects_json. - Кратко описать значения effort (low|medium|high|xhigh|max) и дефолтную раскладку по агентам.
- CHANGELOG.md.
Команды проверки (ОБЯЗАТЕЛЬНО до отчёта)
# из клона ветки в окружении прод-образа орка:
docker exec -w <clone> -e PYTHONPATH=<clone> orchestrator python3 -m pytest tests/ -q -p no:cacheprovider
# Ожидаемо: 0 failed (>=402 passed + новые)
# Проверь резолвинг руками:
python3 -c "from src.agents.launcher import resolve_agent_model; print(resolve_agent_model('developer','<orch_proj_id>'))"
Off-limits / грабли
- НЕ менять логику гейтов, webhook, HMAC, очередь.
- НЕ хардкодить версию модели в коде (вся суть задачи — конфигурируемость).
- frozen dataclass + dict →
field(default_factory=dict), иначе TypeError. - Тесты НЕ в docker-образе → гонять из клона репо.
- После push:
git log origin/main..origin/feat/ORCH-41-agent-modelsпоказывает коммит ДО отчёта. - Не регистрировать раннеров, не nohup.
- ⚠️ Бюджет (ORCH-38): дефолт 4-8 может быть дороже 4-7. НЕ менять дефолт на проде сам — только в коде как default; реальное переключение прода/env делаю я после ОК Славы.
Результат
PR feat/ORCH-41-agent-models → main. Модель агентов конфигурируема: глобально (env per-agent),
с per-project override в projects_json. 0 failed. Отчёт:
tasks/orchestrator/reports/dev-2026-06-05-orch41-agent-models.md + краткое резюме мне
(что добавил, вывод pytest, ссылка на PR, пример конфига).