Агент-инженер по репозиторию · Модуль 6 · Урок 6.3

Стоимость: prompt caching и каскад моделей (haiku→sonnet)

Зачем (какую проблему чиним)

Сервис, гоняющий агента на каждую issue, быстро становится дорогим. Две главные рычага экономии без потери качества: prompt caching (не платить заново за стабильный префикс) и каскад моделей — рутину делает дешёвая модель, к дорогой эскалируем только сложное.

Решение и альтернативы

Решение: (1) cache_control на стабильном префиксе (системный промпт + список инструментов), который мы и так держали неизменным с версии v2 — теперь это окупается чтением кэша. (2) Каскад: стартуем на haiku; эскалируем на sonnet, если задача сложная (большой дифф, повторные провалы тестов, явный сигнал сложности). Это паттерн из курса pro (content/pro_module6.go), адаптированный под нашего агента.

Альтернативы: всё на дорогой модели — качество ради денег, неоправданно для рутины; всё на дешёвой — застревает на сложном, жжёт попытки. Каскад с явными критериями эскалации — управляемый баланс. (Версионная пометка: идентификаторы моделей берите актуальные из доки SDK.)

DIFF

Включаем cache_control на префиксе и каскад: выбор модели по сложности с эскалацией.

⚠ Безопасность

Экономия не должна ослаблять инварианты: каскад влияет только на выбор модели, но не на гейт, изоляцию и запрет auto-merge — они одинаковы для любой модели. Кэш строится на стабильном префиксе; любой дрейф префикса (см. урок 3.4) и кэш, и экономия исчезают.

Проверка

На рутинной задаче агент остаётся на haiku; на сложной (повторные провалы) — эскалирует на sonnet. usage.CacheReadInputTokens > 0 подтверждает чтение кэша; сравнение стоимости задачи до/после показывает экономию.

Глубже

Prompt caching, каскад моделей, бюджеты токенов, дистилляция — курс «Продакшн-разработка», Модуль 6 (гл. 12). Референс-реализация каскада — content/pro_module6.go этого проекта.

cascade.go: каскад моделей и кэш префикса (новый файл, фрагмент)
+package main
+
+// pickModel — каскад: дешёвая модель по умолчанию, дорогая для сложного.
+func pickModel(cfg Config, sig Complexity) string {
+	if sig.Hard() { // большой дифф / повторные провалы / явный сигнал
+		return cfg.ModelStrong // напр. claude-sonnet-4-6
+	}
+	return cfg.ModelCheap // напр. claude-haiku-4-5
+}
+
+// systemPrefix — стабильный префикс с кэшем. Держим байт-в-байт неизменным
+// (см. урок 3.4), иначе кэш сбрасывается и экономия пропадает.
+// В прод-адаптере (anthropic-sdk-go) на него вешается cache_control:
+//   System: []anthropic.TextBlockParam{{
+//       Text:         systemPrefix,
+//       CacheControl: anthropic.NewCacheControlEphemeralParam(),
+//   }}

Anti-patterns

Грабли экономии
ГрабляПочему плохоКак правильно
Гонять всё на дорогой моделиПлатим премию за рутину без выигрыша в качествеКаскад: дешёвая по умолчанию, дорогая по явному критерию сложности
Каскад влияет на инварианты безопасностиРазное поведение гейта/изоляции по моделям — дыраКаскад меняет только модель; гейт, изоляция, запрет auto-merge одинаковы
Дрейф стабильного префикса ради «мелких улучшений»Сбрасывает prompt cache — экономия исчезаетПрефикс байт-в-байт неизменен; cache_control на нём

Практическое задание (RA-v5)

  • Включить cache_control на стабильном префиксе; подтвердить чтение кэша по usage.
  • Реализовать каскад pickModel с явными критериями эскалации (дифф/провалы/сигнал сложности).
  • Закоммитить: git commit -m "v5: prompt caching + model cascade".

Проверка знаний

Как каскад моделей снижает стоимость без потери качества и что он НЕ должен затрагивать?

  • A Гонит всё на дешёвой модели; затрагивает и гейт верификации
  • B Рутину делает дешёвая модель, сложное эскалируется на дорогую; инварианты (гейт, изоляция, запрет auto-merge) одинаковы для любой модели
  • C Случайно выбирает модель; отключает изоляцию для скорости
  • D Каскад заменяет тесты