Усі уроки · 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-каналу — залюбки обговоримо проєктування контексту й поділимося прикладами.