Введение в проблему раздувания контекста и избыточных вызовов
Когда ваш AI-агент начинает уверенно ориентироваться в кодовой базе и дергать десяток внешних API, счета за токену внезапно начинают стремиться в космос. Представьте продакшн-систему поддержки клиентов: вы добавляете новые модули интеграции с CRM, платежными шлюзами и складскими базами, а модель внезапно начинает путать эндпоинты и сливать бюджет на банальный перебор сотен JSON-схем. Прямо сейчас это главная головная боль разработчиков умных систем, и решать её нужно до того, как проект станет убыточным (и бухгалтерия начнет задавать очень странные вопросы).
Современные языковые модели (LLM) стали фундаментом для создания интеллектуальных агентов, автоматизированных систем поддержки и сложных рабочих процессов (workflows). Однако по мере роста возможностей агентов растет и стоимость их эксплуатации. Главными драйверами этой стоимости являются два фактора: колоссальный объем потребляемых токенов при передаче контекста и частые вызовы внешних инструментов (tool calling или function calling).
Типичный агентный цикл выглядит следующим образом: пользователь задает вопрос, система собирает системный промпт, добавляет историю сообщений и передает модели полный список доступных ей инструментов (API-функций, баз данных, поисковых систем) с их схемами (JSON Schema). Когда у вас есть 3–5 инструментов, это работает эффективно. Но что делать, если ваша экосистема насчитывает 50, 100 или 500 специализированных функций? Передача всех описаний в каждом запросе не только съедает тысячи токенов еще до начала генерации ответа, но и снижает точность самой модели — феномен, известный как «засорение контекста» (context pollution), когда LLM начинает путаться в сигнатурах функций.
Решением этой архитектурной проблемы становится локальное индексирование (Local Indexing). В этой статье мы подробно разберем, как внедрение локального поискового индекса поверх описаний инструментов и документации позволяет кардинально снизить расход токенов, минимизировать количество ошибочных вызовов и сделать ваших AI-агентов по-настоящему масштабируемыми.
Архитектура проблемы: почему полный перебор инструментов не масштабируется
Чтобы понять ценность локального индексирования, давайте посмотрим на стандартный подход к вызову функций (Tool/Function Calling), который используют популярные фреймворки. Когда вы отправляете запрос к API OpenAI, Anthropic или открытой модели через Ollama, вы передаете параметр tools. Пример базовой схемы:
[
{
"type": "function",
"function": {
"name": "get_user_billing_history",
"description": "Retrieves past invoices and payment methods for a specific user ID.",
"parameters": {
"type": "object",
"properties": {
"user_id": {"type": "string"}
},
"required": ["user_id"]
}
}
}
// ... еще 49 подобных описаний
]
Каждое такое описание весит от 100 до 300 токенов. Если вы передаете 50 функций, только на инфраструктурный оверхед уходит до 15 000 токенов на каждый пользовательский запрос. Учитывая, что пользователь может спросить простую вещь вроде прогноза погоды, передача биллинговых систем, баз данных логистики и CRM-инструментов является абсолютным расточительством (примерно как выкатывать Kubernetes кластер для лендинга из одной странички).
Более того, эксперименты показывают прямую корреляцию: чем больше инструментов доступно модели «в лоб», тем выше вероятность галлюцинаций. Модель может попытаться вызвать функцию, аргументы которой она не до конца понимает, или перепутать похожие эндпоинты.
Избежать этой слепой зоны помогает отказ от монолитного контекста в пользу точечной фильтрации, к разбору которой мы и переходим.
Концепция локального индексирования инструментов
Идея локального индексирования заключается в том, чтобы уйти от парадигмы «показать модели всё» к концепции «динамического поиска релевантных инструментов». Вместо того чтобы передавать LLM полный список схем, мы испо