Все уроки · 44
Приёмы контекстной инженерии: сжатие, изоляция, RAG и не только
Пять основных приёмов контекстной инженерии — сжатие, изоляция, RAG с динамическими фильтрами, обработка длинного контекста и управление состоянием — и когда какой применять.
Пять приёмов, одна цель
Помните про стол: окно контекста — единственная поверхность, которую видит модель. Этот урок — об уборке на этом столе: что оставить, что сократить до краткого пересказа, что передать кому-то другому и что вообще не пускать на стол.
У контекстной инженерии одна цель: модель должна видеть всё, что ей нужно, и ничего лишнего. Каждый из приёмов ниже — это способ нажимать на один и тот же рычаг с разных сторон. В реальных проектах вы будете их сочетать, а умение состоит в том, чтобы понимать, какой из них решает вашу текущую проблему.
Вот весь урок по одной строке на приём — прежде чем мы углубимся:
- Сжатие — запишите краткие заметки о разговоре, а саму стенограмму выбросьте.
- Изоляция — отправьте коллегу читать сорок документов; он вернётся с одним абзацем.
- RAG с фильтрами — обратитесь к библиотекарю, который перед чтением проверяет раздел и год.
- Обработка длинного контекста — один раз вывалите весь архив на стол, когда работа огромная.
- Состояние — ведите блокнот и берите его на каждую встречу.
Сжатие: пересказываем прошлое
Сжатие (compaction) — это переписывание старых частей контекста в более короткую форму. Представьте протокол совещания: от первого часа в нём остаются три принятых решения. После двадцати реплик разговора не обязательно отправлять заново все двадцать дословно: модель пересказывает первые пятнадцать одним абзацем, и дальше уходит этот абзац. Агенты, которые работают часами, делают это постоянно: когда окно заполняется, старые выводы инструментов сжимаются в заметку «пока что мы сделали X и Y».
У сжатия есть цена: пересказ теряет подробности. Оставляйте главное (системный промпт, текущую задачу, ключевые решения), а болтовню отпускайте.
Изоляция: дайте субагентам собственные окна
Изоляция контекста — это разделение работы между несколькими вызовами модели, у каждого из которых свой чистый контекст. Агент-исследователь, которому нужно прочитать сорок документов, запускает субагента: тот читает их и возвращает краткое содержание, а основной контекст хранит только его. Это как поручить исследование коллеге: гора книг остаётся у него, а вам он приносит одну страницу.
Этот приём вам уже знаком по функциям в коде: запутанное внутреннее состояние субагента спрятано за небольшим возвращаемым значением. Изоляция сохраняет основное окно небольшим и сфокусированным, но ценой потери нюансов на границе.
RAG и динамические фильтры
RAG подтягивает только документы, относящиеся к текущему вопросу. Но именно на шаге поиска решается качество контекста, и наивного «5 самых похожих фрагментов» редко достаточно. Динамические фильтры ужесточают поиск во время работы: до ранжирования фильтруйте по языку, дате, типу документа, правам пользователя или линейке продуктов. Библиотекарь проверяет раздел, год и ваш пропуск, прежде чем снять что-либо с полки. Пять отфильтрованных фрагментов лучше пятидесяти необработанных — и по токенам, и по полезному сигналу.
Приходит живой вопрос.
сколько стоит печать на холсте 30x40
Вот всё это в виде кода. Читайте сверху вниз — комментарии называют приём, который использует каждая строка:
1def build_context(query, history):2 # Эта функция выполняется при КАЖДОМ запросе. То, что она возвращает, —3 # буквально всё, что увидит модель.4 context = []5 6 # 1. Постоянные инструкции — всегда первыми: правила,7 # которые должны пережить всё остальное.8 context.append(SYSTEM_PROMPT)9 10 # 2. СЖАТИЕ: 40 старых реплик превращаются в один абзац.11 # Дешевле, чем вся история, и отбрасывает тупиковые ветки.12 context.append(summarize(history))13 14 # 3. RAG + ДИНАМИЧЕСКИЕ ФИЛЬТРЫ: ищем в базе знаний, но15 # только среди фрагментов на нужном языке, за последние16 # 12 месяцев, которые этому пользователю разрешено видеть.17 docs = retriever.search(18 query,19 top_k=3,20 filters={#98c379">"lang": user_lang,21 #98c379">"date": "last_12_months",22 #98c379">"acl": user_permissions})23 context.extend(docs)24 25 # 4. Живой вопрос идёт последним — туда, где модель26 # уделяет больше всего внимания.27 context.append(query)28 29 return contextПростыми словами: сначала правила, затем краткая версия прошлого, потом только документы, пережившие фильтры, и в самом конце — сам вопрос. Так выглядит хорошо собранный запрос.
Обработка длинного контекста: иногда проще вставить всё
Современные модели справляются со 128K токенов и больше, а это открывает другую стратегию: обработку длинного контекста — вывалить весь набор документов в окно и позволить модели самой найти нужное. Для разового глубокого анализа кодовой базы или длинного договора это разумный способ, и он выигрывает у построения пайплайна поиска.
Цена такая: задержка растёт вместе с окном, стоимость растёт ещё быстрее, а качество внимания падает в середине длинных контекстов — середину огромной стопки модель читает не так внимательно, как края. Длинный контекст — инструмент для редких тяжёлых задач, а не вариант по умолчанию для каждого вопроса пользователя.
Состояние и исторический контекст
Наконец, часть информации должна сохраняться между сессиями: предпочтения пользователя, решения по проекту, прошлые ошибки. Это состояние (state): тщательно отобранные данные, которые загружаются в контекст в начале каждой сессии, — как блокнот, который вы берёте на каждую встречу. Здесь всё решает отбор: память, которая растёт без границ, превращается в ящик со всякой всячиной, который отравляет каждый будущий запрос. Храните решения и предпочтения; устаревшие факты удаляйте.
Когда какой приём применять
| Симптом | Приём |
|---|---|
| Разговор не помещается в окно | Сжатие |
| Одна задача тонет в шуме подзадач | Изоляция (субагенты) |
| Модели не хватает ваших закрытых знаний | RAG с динамическими фильтрами |
| Разовый глубокий анализ большого документа | Обработка длинного контекста |
| Модель забывает всё между сессиями | Состояние и исторический контекст |
Посмотрите, как происходит сжатие. Переключите флажок — и увидите, какие части длинной сессии уцелеют и сколько бюджета это освободит:
Начинайте со скучного
Сначала берите сжатие, потом изоляцию, и только потом экзотические архитектуры. Самая частая ошибка — городить многоагентный цирк, когда окно спасла бы одна строка с кратким пересказом.
В длинной сессии заканчивается место. За что браться в первую очередь?
Зачем фильтровать результаты RAG по языку, дате и правам доступа до ранжирования?
Какой блок нельзя убирать при сжатии ни в коем случае?
Итог
Каждый приём — это ещё и новый способ сломаться: плохой пересказ, шумный поиск, устаревшая память. Чтобы всё это заработало на практике, нужно знать, как ломается контекст и как поймать поломку раньше пользователей.
Есть вопросы?
Присоединяйтесь к Telegram-каналу — с радостью обсудим проектирование контекста и поделимся примерами.