Как сэкономить на токенах при анализе кода с помощью LLM: опыт hh.ru
Команда hh.ru рассказала, как оптимизировала расходы на LLM-анализ тестового покрытия кода. Основные приёмы: не отправлять на анализ тривиальный код и неизменившиеся данные, использовать tree-sitter вместо LLM для парсинга, кэшировать результаты по хешу метода, сохранять прогресс после каждого батча и делить проблемные запросы пополам при ошибках.
Статья показывает конкретные инженерные практики экономии на LLM-токенах в продакшене. Для команд, внедряющих AI-анализ кода, эти подходы могут снизить расходы в разы без потери качества.
Как сэкономить на токенах при анализе кода с помощью LLM: опыт hh.ru
Команда hh.ru поделилась практическим опытом оптимизации расходов на LLM-анализ тестового покрытия кода. Их бот еженедельно анализирует непокрытые методы в SonarQube и составляет отчёты для команд разработки.
Главный принцип: не тратить токены вообще
Первый уровень оптимизации — фильтрация на входе. Бот не отправляет на анализ: - Методы короче трёх строк (кроме Kotlin, где однострочники могут быть сложными) - Deprecated-код - Конструкторы, геттеры/сеттеры и автосгенерированный код
Детерминированный парсинг вместо LLM
Вместо дорогого LLM-парсинга код разбирается с помощью tree-sitter — быстрого парсера для Java и Kotlin, который работает за ноль токенов. Методы длиннее 8000 символов обрезаются с пометкой об усечении.
Важная деталь: весь код оборачивается в теги <method>...</method>, а в системный промпт добавлена инструкция игнорировать команды внутри кода — защита от prompt injection.
Трёхуровневое кэширование
Система кэширования работает на трёх уровнях: 1. Сервис: если lastAnalysisDate не изменился, сервис пропускается целиком 2. Файл: неизменившиеся файлы не переанализируются 3. Метод: для каждого метода вычисляется SHA-256 хеш (сигнатура + модификаторы + тело). Если хеш совпадает, берётся закэшированное описание
Отказоустойчивость и минимизация потерь
Система сохраняет прогресс после каждого шага:
- LLM-ответы флашатся на диск после каждого батча (10 методов)
- Состояние сервисов пишется в state.json после каждого обработанного сервиса
- Данные синхронизируются с MinIO между CI-раннерами
Если бот падает на 40-м сервисе из 200, при перезапуске он продолжит с места падения, а не начнёт сначала.
Умная обработка ошибок
При невалидном JSON от модели бот не ретраит весь батч из 10 методов, а делит его пополам рекурсивно, пока не изолирует проблемный метод. Это экономит токены на повторных запросах.
Приоритизация по важности
Дополнительно бот скорит методы по важности: точки входа (REST-контроллеры, Kafka-листенеры) получают +10 к приоритету, ветвящийся код — x2, публичные методы — +3. Это экономит когнитивную нагрузку команд, показывая сначала действительно важное.
Ключевые выводы
- Детерминированные парсеры (tree-sitter) могут заменить LLM для структурного анализа кода, экономя 100% токенов на этом этапе
- Трёхуровневое кэширование (сервис-файл-метод) с SHA-256 хешами позволяет избежать повторного анализа неизменившегося кода
- Частый flush результатов на диск и синхронизация через объектное хранилище делают систему отказоустойчивой без потери оплаченных токенов
- Рекурсивное деление батчей при ошибках парсинга JSON экономичнее полного ретрая всего батча
- Фильтрация тривиального кода на входе (геттеры, короткие методы, deprecated) может отсеять до 30-40% методов до отправки в LLM
Автор: Павел Заславский · Источник: habr.com
Редкий случай, когда опытом оптимизации LLM делятся без хайпа и с конкретным кодом. Ребята из hh.ru показали, что экономия токенов — это не про жадность, а про инженерную культуру: кэширование по хешам, детерминированный парсинг вместо LLM где возможно, отказоустойчивость через частый flush.
Особенно зацепил трюк с рекурсивным делением батчей при ошибках парсинга JSON — вместо тупого retry всего запроса система изолирует проблему за O(log n) попыток. Это не просто экономия токенов, это правильная работа с вероятностной системой. Единственное, чего не хватает — цифр: насколько реально снизились расходы после внедрения всех этих оптимизаций? Но в целом статья — отличный чеклист для тех, кто запускает LLM в продакшн и не хочет получить счёт с четырьмя нулями.
Комментарии