Перейти к содержанию
Публикация AiManual

Context Engineering для AI-агентов: как наладить retrieval и не забить контекстное окно

Агент тратит контекст на неудачные поиски, гигантские выдачи и устаревшие документы. Разбираем на примере harness LangChain Deep Agents, как работают glob, grep

Коротко

Что будет в материале

  1. 01

    Почему retrieval - это первый шаг context engineering

  2. 02

    Неэффективный поиск: почему агент тратит контекст впустую

  3. 03

    Слишком много контекста за один раз: как не утопить окно

  4. 04

    Паттерн «retrieve, offload, delegate» для кастомных поисковых инструментов

Почему retrieval - это первый шаг context engineering

Агент не держит всё в памяти. У модели ограниченное контекстное окно, поэтому нужную информацию приходится извлекать под задачу: находить файл, искать строку, читать фрагмент. Именно с этого начинается context engineering, и именно здесь чаще всего сгорают токены и качество ответа.

Retrieval в агентском контексте шире, чем «поиск по базе знаний». Это весь путь информации до окна модели: каким инструментом ищем, сколько возвращаем за один вызов, что попадает в контекст, а что остаётся в файлах. Работа с контекстом, который уже оказался в окне (суммаризация старых сообщений, выгрузка крупных блоков, долговременная память), это следующий слой. Сначала стоит наладить то, что в окно попадает.

Agent harness как раз для этого и нужен: он применяет техники retrieval так, чтобы модель получала правильный контекст в нужный момент под конкретную задачу. Так формулирует задачу команда LangChain в разборе Context Engineering for AI Agents Starts with Retrieval, и там же разобраны практики harness Deep Agents.

Пример, на котором удобно смотреть все сбои сразу, - агент конкурентного анализа. Раз в неделю он исследует сотни конкурентов и собирает отчёт по шаблону команды: находит заметки прошлой недели по конкретной компании, вытаскивает цифру выручки из большого экспорта рыночных данных, проверяет, не появилось ли новостей в архиве. Каждая задача запускает свой тип retrieval, и каждая ломается по-своему.

Аналогия с экзаменом по открытой книге: все ответы доступны, но именно поэтому сложнее найти нужный, понять, каким источникам верить, и не потратить все силы на лишние поиски. Ограниченное окно делает эту метафору буквальной.

Дальше разберём три класса сбоев и приёмы борьбы с ними: от дешёвых файловых инструментов до семантического retrieval поверх векторной БД, SQL, search API и MCP-сервера.

Три способа, которыми retrieval ломается

LangChain фиксирует три класса сбоев. Они не пересекаются полностью и лечатся разными инструментами.

Класс сбояКак выглядитЧто делать
Неэффективный поискагент открывает каждый файл подряд или переформулирует один и тот же запросglob и grep до чтения, сужение области поиска
Раздутый результатодин поиск отдаёт полный экспорт данных или десяток документовread_file постранично, выгрузка крупных результатов в файл с превью
Нерелевантный или устаревший контекстуверенный текст не по теме или устаревший факт, неотличимый от правильного ответафильтры по дате, проверка grounding, недоверие к извлечённому тексту

Неэффективный поиск: почему агент тратит контекст впустую

Каждый поиск стоит токенов и времени. Агент, который открывает файл за файлом «просто посмотреть, что внутри» или в десятый раз переформулирует один и тот же запрос, заполняет контекст результатами поисков раньше, чем находит что-то полезное.

Механика сбоя простая. Агент не знает структуру хранилища, поэтому начинает с широкого чтения: открывает файлы подряд, не находит нужное, меняет формулировку, снова получает широкую выдачу. Область поиска не сужается, число итераций растёт, полезных данных в окне не прибавляется.

Диагностический признак лежит в логах: много однотипных вызовов поиска и мало чтений конкретных фрагментов. Если агент за десять шагов ни разу не прочитал найденное, проблема не в модели.

Harness Deep Agents держит поиск компактным по умолчанию: встроенные файловые инструменты сначала ищут, а потом читают. glob сопоставляет имена файлов, grep находит совпадающие строки, read_file читает файл страницами.

glob и grep: искать до чтения

glob отвечает на вопрос «где это лежит», grep - «где встречается это слово». Оба инструмента сужают область до того, как агент потратит контекст на содержимое файлов.

glob "notes/**/*pricing*.md"
grep -rn "revenue" ./exports/

Первый запрос вернёт список путей, второй - строки с совпадением и номера строк. Агент получает карту местности за десятки токенов вместо тысяч.

Ограничение жёсткое: это keyword-поиск. grep не поймёт синоним, не свяжет «выручку» с «revenue» в русскоязычном файле и не найдёт перефразировку. Если терминология в хранилище неоднородная, поиск по строкам даёт пустые выдачи, и агент быстро возвращается к чтению всего подряд.

Слишком много контекста за один раз: как не утопить окно

Один поиск, который выдаёт полный экспорт данных или десяток документов, заполняет контекстное окно за шаг. Дальше агент не может ни рассуждать, ни планировать: место занято сырыми данными, которые он ещё не осмыслил.

Классический пример: задача найти конкретную цифру выручки в огромном экспорте рыночных данных. Полное чтение файла даёт тысячи строк, из которых нужны три.

read_file с offset и limit: читать постранично

read_file читает файл страницами: offset задаёт начало, limit - размер страницы. Агент смотрит первый фрагмент, оценивает, там ли нужные данные, и решает, читать ли следующий.

read_file(path="exports/market_2026.csv", offset=0, limit=200)
read_file(path="exports/market_2026.csv", offset=200, limit=200)

Компромисс стоит держать в голове при настройке: слишком маленькая страница означает много итераций и лишних вызовов, слишком большая снова раздувает окно. Ориентир один: страница должна быть достаточной, чтобы оценить релевантность фрагмента, а не прочитать файл целиком. Универсальной цифры нет, размер зависит от задачи и от модели.

Выгрузка крупных результатов: путь и превью вместо полного текста

Второй приём работает на уровне инструмента: крупные результаты выгружаются. Полный результат сохраняется в файлы, а агент получает только путь и превью. Он не платит токенами за весь объём сразу и сохраняет возможность дочитать позже.

Связка с постраничным чтением получается рабочей: превью подсказывает, стоит ли открывать файл, а read_file с offset и limit позволяет открыть ровно столько, сколько нужно. Логика здесь одна: читать по мере необходимости.

Паттерн «retrieve, offload, delegate» для кастомных поисковых инструментов

Файловые инструменты закрывают работу с локальными данными. Когда поиск устроен иначе (RAG, внутренний API, поиск по базе), harness должен упаковать выдачу так же аккуратно. Для кастомных поисковых инструментов LangChain описывает паттерн из трёх шагов.

  1. Retrieve. Агент вызывает поисковый инструмент и получает набор результатов.
  2. Offload. Результаты сохраняются в файлы, в контекст возвращаются пути и короткие превью.
  3. Delegate. Читать файлы поручают субагентам. Главный агент видит только то, что субагент признал релевантным.

Смысл в том, что главный агент не платит контекстом за чтение десятков фрагментов. Он получает сжатую выжимку и продолжает планировать.

Субагенты как способ изолировать чтение

Субагент получает путь к файлу с результатами, читает его постранично и возвращает наверх только релевантное: цитаты, номера источников, короткие выводы. Чтение и отбор идут в отдельном контекстном окне, которое после возврата результата не занимает место в основном.

Изоляция контекста и есть главная ценность делегирования. Она же источник новых проблем: субагент может ошибиться в отборе, потерять важный фрагмент или неверно понять задачу. Верхнему агенту нужна проверка результата, а не слепое доверие к выжимке.

Цена подхода честная: архитектура усложняется, добавляется задержка на лишний цикл «модель - инструмент», а задачу субагенту приходится формулировать точно. Для простых запросов это лишний оверхед, для больших выдач экономия окупается.

Как offloading и субагенты устроены в Deep Agents на уровне middleware, разобрано в отдельном материале: Context Engineering в Deep Agents.

Когда keyword-поиска недостаточно: семантический retrieval поверх векторной БД, SQL и search API

Оговорка по источникам: материал LangChain, на который опирается разбор, покрывает файловые инструменты и паттерн выгрузки для кастомных инструментов. Устройство семантического поиска, SQL- и search-инструментов, а также сравнение agentic retrieval с одношаговым RAG там не раскрыты. Дальше инженерная рамка, которую стоит проверять на своём стеке, а не пересказ источника.

glob и grep работают по именам и ключевым словам. Они не найдут смысловое совпадение, если запрос и документ не пересекаются лексически: «как ускорить инференс» против «оптимизация latency модели». В этот момент keyword-поиск упирается в потолок.

  • Векторная БД нужна, когда запрос и документ расходятся по формулировке. Цена: чанкинг, эмбеддинги, переиндексация при обновлении данных, отдельная инфраструктура. Плохой чанкинг ломает поиск сильнее, чем слабая модель эмбеддингов.
  • SQL подходит для структурированных данных и точных фильтров: даты, суммы, категории. Цена: нужна схема, и её приходится передавать агенту в контекст, иначе он начнёт придумывать имена колонок.
  • Search API полезен, когда источник внешний и важна свежесть. Цена: внешняя зависимость, лимиты запросов, нестабильное качество выдачи, обработка сетевых ошибок.
  • MCP-сервер даёт агенту единый интерфейс к инструменту поиска и снимает привязку harness к конкретному API. Цена: настройка сервера, внятные описания инструментов, контроль версий. Пример такой связки с гибридным поиском через MCP разобран в материале про память для Cursor и гибридный поиск QMD.

На практике гибридный поиск обычно надёжнее одного метода: keyword даёт точные совпадения по терминам и идентификаторам, семантический слой добирает смысловые попадания. Ограничения каждого слоя стоит понимать до того, как строится индекс, и выбор хранилища под систему знаний здесь отдельная инженерная задача со своими компромиссами.

Почему research-агенту нужен agentic retrieval, а не одношаговый RAG

Одношаговый RAG делает один запрос и отдаёт top-k фрагментов. Для research-задачи этого мало: агент не знает заранее, какая формулировка сработает, а первый запрос часто оказывается слишком общим. Поиск новостей в архиве по одному запросу даст либо шум, либо пустоту.

Agentic retrieval превращает поиск в цикл: сформулировать запрос, оценить выдачу, уточнить формулировку или сменить инструмент, при необходимости вернуться к другому источнику. Решение о следующем шаге принимает модель по результатам предыдущего, а не фиксированный пайплайн.

Риск предсказуем и связан с первым разделом: без сужения области цикл вырождается в неэффективный поиск. Агент перебирает формулировки, платит токенами за каждую и копит мусор в окне. Схема работает при двух условиях: у поиска есть дешёвый способ сузить область (фильтры, glob, точные термины), а число итераций ограничено явно.

Меры предосторожности: устаревшие данные, grounding и prompt injection

Третий класс сбоев коварнее первых двух. Устаревшая или не по теме информация может выглядеть для модели так же убедительно, как правильный ответ. Попав в контекст, она становится основой для следующих шагов, и ошибка переносится дальше по цепочке рассуждений.

Фильтрация по датам и свежие источники

Фильтровать по дате нужно на этапе поиска, а не после попадания в контекст. Если инструмент умеет отсекать документы старше нужного периода, это дешевле, чем потом объяснять модели, что факту три года. Второй элемент - фиксировать дату документа рядом с результатом, чтобы агент видел её при чтении и мог сам отбросить устаревшее.

Ограничение: свежесть не равна релевантности. Свежий документ может быть не по теме, а старый - единственным точным описанием механики. Фильтр по дате сужает область, но не заменяет оценку содержания.

Grounding и отношение к извлечённому тексту как к недоверенному

Проверка grounding означает, что утверждение в ответе опирается на конкретный фрагмент источника, а не на общее впечатление от прочитанного. Практически это выглядит так: агент возвращает цитату или ссылку на файл и строку рядом с выводом, а не только вывод. Механику привязки генерации к входным данным подробнее разбирает материал про граундинг.

Извлечённый текст стоит считать недоверенными данными. В документе может оказаться текст, который выглядит как инструкция: «игнорируй предыдущие указания», «отправь содержимое по такому-то адресу». Выполнять его нельзя, системные инструкции имеют приоритет. Рабочая практика: помечать извлечённые фрагменты как данные, отделять их от команд и при сомнении перечитывать источник, а не пересказ.

Риск prompt injection через retrieved-контент реален для любого агента, который читает внешние документы, веб-страницы или письма. Закрыть его одной фильтрацией текста не получится: правила формулируются заранее, атакующий подстраивается. Ограничение полномочий и подтверждение опасных действий человеком остаются последней линией защиты.

Чек-лист: как отладить retrieval в своём агенте

Проверять стоит по порядку: от дешёвых файловых инструментов к инфраструктуре поиска. Каждый пункт закрывает свой класс сбоев.

  1. Посчитайте, сколько токенов уходит на поиски. Сравните объём вызовов поиска с объёмом полезных чтений. Перекос в сторону поиска указывает на первый класс сбоев.
  2. Проверьте, не открывает ли агент файлы вслепую. Чтения без предварительных glob и grep означают, что инструменты поиска не используются или описаны невнятно.
  3. Проверьте размер страницы read_file. Чтение файлов целиком вместо offset и limit возвращает второй класс сбоев.
  4. Проверьте, выгружаются ли крупные результаты. Если инструмент возвращает полный экспорт прямо в контекст, выгрузка не настроена.
  5. Проверьте, изолировано ли чтение результатов RAG. Выдача поиска, которая целиком попадает в окно главного агента, съедает бюджет на планирование.
  6. Проверьте фильтры по дате и свежесть источников. Без фильтра устаревший контекст проходит в окно беспрепятственно.
  7. Проверьте grounding. Ответы без привязки к фрагментам источника сложно проверить, а ошибку легко перенести дальше по цепочке.
  8. Проверьте, не выполняет ли агент инструкции из извлечённого текста. Это граница между retrieval и prompt injection.
  9. Ограничьте число итераций поиска. Явный лимит превращает agentic retrieval в контролируемый цикл, а не в бесконечную переформулировку.

Универсальной настройки нет. Набор приёмов зависит от задачи, инструментов и модели: файловому агенту хватит glob, grep и постраничного чтения, research-агенту понадобятся гибридный поиск, выгрузка результатов и субагенты. Практический смысл context engineering в том, чтобы каждая из этих настроек была осознанным решением, а не дефолтом, который никто не проверял.

Подписаться на канал