урок 5 из 16

Контекст: что кладут в окно

Собирать окно осознанно: понимать, из чего оно состоит и за что в нём платят, класть важное в начало и в конец, различать «положить заранее» и «дать искать», и заранее решать, что делать, когда история перестанет помещаться.

17 мин чтения · 4 главы ·4 задания ·домашняя работа

Из чего состоит окно

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

Системное сообщение: кто вы, что за проект, чего нельзяОписания инструментовПоручение человекаШаг 1: просьба и результатШаги 2–7: просьбы и результаты, среди них длинныепоручение — это обычно два процента окна, а решает оно всё остальное
Поручение занимает в нём малую часть. Всё остальное положила туда обвязка — и за всё это платится при каждом следующем вызове.

На первом шаге в окне лежит немного: системное сообщение, описания инструментов и поручение. К восьмому шагу картина другая — большую часть места занимает история работы, и среди неё бывают очень длинные куски.

Разберём части по очереди.

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

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

Поручение — то, ради чего всё затевалось. Показательно, что это обычно самая маленькая часть окна: сто-двести знаков против десятков тысяч. И при этом именно оно определяет, будет ли работа сделана. Это не парадокс, а обычное дело: инструкция к станку длиннее, чем чертёж детали.

История — просьбы модели и результаты инструментов. Она растёт сама и требует управления; ей посвящена последняя глава этого урока.

И сразу — про самое частое заблуждение. Кажется, что положить в окно побольше безопаснее: пусть будет, вдруг пригодится. Это неверно сразу по двум причинам. Во-первых, за объём платят — каждый шаг, а не один раз. Во-вторых, и это важнее: лишнее в окне не нейтрально. Оно конкурирует за внимание с нужным. Модель, которой дали пять файлов вместо одного нужного, будет искать ответ во всех пяти — и иногда найдёт его не там.

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

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

Где в окне читается лучше

Теперь про свойство, которое стоит знать всем, кто строит обвязку: внимание распределено по окну неравномерно. Начало и конец работают надёжнее середины.

началосерединаконецправила, роль,запретыдлинные выводы,старые шагитекущая задача,что делать сейчасВажное кладут в начало или в конец, а не в серединуесли что-то обязано быть учтено — повторите это в конце
Начало и конец окна работают надёжнее середины. Это свойство, а не поломка, и на него опираются, а не борются с ним.

Это не поломка конкретной модели и не временное явление. Оно проявляется у всех и в разной степени, и относиться к нему стоит как к свойству материала — как столяр относится к тому, что дерево колется вдоль волокон. С этим не борются, на это опираются.

Практические следствия простые.

Правила и запреты — в начало. Системное сообщение стоит первым не случайно: это самое надёжное место окна.

Текущая задача — в конец. Если после сорока тысяч знаков истории вы хотите, чтобы модель помнила, что именно сейчас требуется, — напомните об этом в последнем сообщении. Это называют «повторить задачу в конце», и приём стоит одной строки.

Длинные выводы — в середину. Не потому, что они неважны, а потому, что середина всё равно самое слабое место, и класть туда стоит то, что модель будет искать целенаправленно, а не то, что она должна учесть непременно.

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

Отсюда привычка: всё, что кладётся в окно, подписывается. Не просто содержимое файла, а «файл src/cart.js, строки 1–80». Не просто вывод команды, а «вывод npm test, код завершения 1». Подпись стоит двадцать знаков и снимает целый класс путаницы — особенно когда файлов несколько.

И третье, менее очевидное: порядок внутри окна должен быть осмысленным. Если вы кладёте три файла, положите сначала тот, который правится, а потом те, которые нужны для справки. Модель читает подряд, и первый файл получает больше внимания. Порядок «по алфавиту» здесь — это порядок «случайно», и он работает хуже.

Положить заранее или дать искать

Следующий вопрос — что класть в окно заранее, а что оставить агенту искать самому. Это выбор между двумя способами, у каждого своя цена.

Положить заранееДать искать
стоимостьплатим всегда, даже если не пригодилосьплатим шагами, только когда нужно
скоростьмгновеннодва-три оборота круга
рисклишнее отвлекаетможет не найти или найти не то
когда лучшенужно почти всегда и невеликонужно изредка или объёмно

Правило, которое из этого выводится: кладите заранее то, что нужно почти всегда и невелико; остальное дайте искать.

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

Что во вторую: содержимое конкретных файлов, история изменений, документация, данные из внешних систем. Это объёмно, нужно выборочно, и заранее вы не знаете, что именно понадобится.

Симметричный признак: вы положили слишком много, если в окне регулярно лежит то, к чему агент ни разу не обратился. Понять это сложнее, потому что напрямую не видно, но косвенный признак есть: окно большое, а шагов мало. Значит, работа простая, а платите вы за объём.

Теперь про поиск. Если агент ищет сам, качество поиска становится частью качества системы — и это часто недооценивают. Плохой поиск даёт три беды сразу: агент не находит нужного и работает по неполным данным; находит слишком много и забивает окно; тратит лишние шаги на уточнение запроса.

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

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

И последнее про подачу — про то, что кладётся не в окно, а рядом. Есть материалы, которые нужны редко, но когда нужны, нужны целиком: подробная документация, справочник кодов ошибок, длинный регламент. Класть их заранее нельзя (объём), давать искать по ним сложно (поиск по тексту регламента работает плохо). Разумный приём — дать оглавление в окно, а содержимое по разделам через инструмент. Оглавление короткое, агент видит, что такой раздел существует, и запрашивает его целиком, когда доходит до дела.

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

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

Когда история не помещается

Рано или поздно история перестаёт помещаться в окно. Это не исключительная ситуация: на длинной задаче она наступает обязательно, и решение должно быть принято заранее.

Выбросить старое: дёшево, но агент забывает начало работыСжать в итог: одна лишняя просьба к модели, зато помнит сутьВынести в файл: помнит всё, но должен догадаться перечитатьНе предусмотреть ничего: падение на середине задачипервые три — решения, четвёртое — то, что получается самоесли про переполнение не подумали заранее
Три способа, и у каждого своя цена. Худший — четвёртый: сделать вид, что этого не бывает, и падать на середине задачи.

Выбросить старое. Самый простой способ: держим системное сообщение, поручение и последние N сообщений, всё, что между, выбрасываем. Дёшево и работает, пока задача не требует помнить начало. Беда в том, что именно в начале обычно лежит то, что было решено и почему.

Сжать в итог. Когда история подбирается к пределу, обвязка делает лишний вызов модели: «перескажи коротко, что уже сделано, что выяснилось и что осталось». Итог заменяет собой выброшенные сообщения. Стоит одного вызова и заметно лучше держит длинную работу.

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

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

И более общее правило, которое сильно упрощает жизнь: лучший способ справиться с переполнением — не доводить до него. Задача, которая укладывается в десять шагов, не переполнит окно почти никогда. Переполнение — это, как правило, симптом того, что задача слишком крупная или что в окно кладётся слишком много. Прежде чем строить сжатие, стоит посмотреть, нельзя ли разделить работу.

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

Задания урока

Каждое проверяется сразу: ответ сверяется с эталоном, и на неверный вариант приходит разбор.

  1. Положить в окно побольше — безопасный выбор: вдруг пригодится.средне
  2. Разложите по местам в окне.средне
  3. Что стоит класть в окно заранее, а не давать искать?средне
  4. При сжатии истории достаточно попросить модель пересказать, что сделано.средне

Практика и материалы по теме курса

Пройти урок с проверкой заданий Курс «ИИ-Инжиниринг» открыт и бесплатен, прогресс сохраняется.
Открыть курс