TL;DR
IterChat — метод работы с длинными диалогами, где нужно отслеживать меняющуюся информацию. Суть: вместо обработки всей истории диалога каждый раз, разбей на два блока: суммарное состояние из прошлого + последний обмен репликами.
При обработке многоходового диалога модель "забывает" ранние предпочтения или путается в последовательности изменений. Чем длиннее контекст, тем больше накапливается ошибок — модель теряет нить того, что пользователь хотел в начале, когда добавляются новые требования. Аннотаторам ещё хуже: отследить все изменения через 10-15 ходов — катастрофа, 28% времени тратится впустую на повторные проверки.
Метод работает в три шага: (1) суммируй текущее состояние из предыдущих ходов, (2) извлеки новую информацию только из последнего обмена, (3) объедини старое состояние с новым для получения обновлённого состояния. Так модель всегда работает с компактным входом, а не с растущим контекстом.
Схема метода
ШАГ 1: Суммируй предыдущие n ходов → Компактное состояние Yt
ШАГ 2: Извлеки инфо из последнего хода (At, Qt+1) с учётом Yt → Новая информация Gt+1
ШАГ 3: Объедини Yt + Gt+1 → Обновлённое состояние Yt+1
(Все 3 шага можно выполнить в одном промпте или разбить на отдельные запросы)
Пример применения
Задача: Ты помогаешь клиенту подобрать квартиру в Москве. Он в процессе диалога меняет критерии — район, бюджет, этаж. Нужно не потерять актуальные требования через 10-15 ходов переписки.
Промпт:
Ты — ассистент по подбору квартир.
**Текущие критерии клиента:**
- Район: Арбат или Пресня
- Бюджет: до 15 млн
- Этаж: не первый, не последний
- Метро: до 10 минут пешком
**Последний обмен с клиентом:**
Я: Показал 3 варианта в указанном районе и бюджете.
Клиент: Знаешь, смотрел отзывы про Пресню — шумновато. Давай лучше Чистые пруды или Цветной. И бюджет можно до 17, если квартира того стоит.
**Твоя задача:**
1. Извлеки изменения из последнего обмена
2. Обнови список критериев с учётом изменений
3. Выдай финальные критерии в структурированном виде
Результат: Модель выдаст три блока: (1) что изменилось (район: было Арбат/Пресня → стало Чистые пруды/Цветной; бюджет: было 15 → стало 17), (2) что осталось прежним (этаж, метро), (3) финальный список критериев для следующего поиска. Формат может быть JSON, список или таблица — в зависимости от твоей задачи.
Почему это работает
LLM плохо держит в голове длинные диалоги — ранние детали затираются новыми, особенно когда контекст растёт за 4-5 тысяч токенов. Чем больше информации в истории, тем выше шанс что модель "забудет" важный нюанс из начала разговора или запутается в последовательности изменений.
LLM хорошо работает с компактными структурами — если дать краткую суммарную справку вместо полной истории, модель лучше держит фокус. Извлечение изменений из короткого фрагмента (последний обмен) — простая задача, с которой модель справляется точнее чем с обработкой 15-ходового диалога целиком.
Метод играет на сильных сторонах: вместо многоходовой обработки — серия одноходовых операций. Каждый раз модель работает с небольшим входом (состояние + один ход), а не тащит весь диалог. Это как работать с diff'ами в git, а не перезаписывать весь файл каждый раз — меньше шума, больше точности.
Рычаги управления промптом:
- Частота обновления состояния — обновляй после каждого хода или раз в N ходов. Чем чаще — точнее, но больше запросов.
- Уровень детализации состояния — храни ли только финальные значения или историю изменений. Для сложных задач можно добавить "почему изменилось".
- Формат структуры — используй JSON, маркированные списки или таблицы. Для автоматизации — JSON, для человека — список.
Шаблон промпта
Ты — ассистент, который отслеживает {тип_информации} в диалоге.
**Текущее состояние:**
{компактная_суммарная_справка}
**Последний обмен:**
Я: {твой_последний_ответ}
Пользователь: {новый_запрос_пользователя}
**Твоя задача:**
1. Извлеки изменения или дополнения из последнего обмена
2. Обнови текущее состояние с учётом изменений
3. Выдай финальное состояние в структурированном виде
**Правила обновления:**
- Новое явно перекрывает старое ("вместо X давай Y")
- Дополнения добавляются к старому ("ещё и Z")
- Отказы удаляют старое ("забудь про X")
Пояснение к плейсхолдерам:
{тип_информации}— что отслеживаешь: критерии поиска, требования к задаче, параметры проекта{компактная_суммарная_справка}— краткое резюме прошлого в 3-7 пунктах{твой_последний_ответ}— что сказал ассистент в прошлый раз (даёт контекст){новый_запрос_пользователя}— последняя реплика пользователя
Ограничения
⚠️ Потеря контекста: Если изменение неявное (пользователь ссылается на "то, о чём говорили вчера"), метод может не уловить связь — в состоянии нет полной истории.
⚠️ Короткие диалоги: Для диалога в 2-3 хода метод избыточен — проще обработать весь контекст сразу, чем городить трёхшаговую схему.
⚠️ Противоречия: Если пользователь противоречит сам себе ("хочу тихий район" → "хочу рядом с метро и барами"), модель может не уловить конфликт без полного контекста.
Как исследовали
Команда взяла датасет MultiWOZ (диалоги про отели, рестораны) и создала новый формат данных — вместо многоходовых диалогов разбили на History State + Current Dialogue. Сравнили аннотацию: людям давали либо многоходовой диалог целиком, либо новый формат.
Оказалось, что в новом формате аннотаторы работают на 28.4% быстрее и точность выше на 11.95% (EM metric). Почему? Потому что аннотатору не нужно держать в голове всю цепочку изменений — он видит краткую справку и только последний ход. Это как diff в git: легче понять что изменилось, чем читать весь файл каждый раз.
Потом обучили несколько LLM (Llama-2-7B, Llama-2-13B) на обоих форматах данных. При fine-tuning на IterChat формате модели показали значительно лучшие результаты — например, Llama-2-13B достигла 81.8% EM на отелях против 47% на обычных многоходовых диалогах. Удивительно, что при few-shot промптинге (2 примера) разница не такая драматичная, а вот при обучении — огромная.
Инсайт для практики: модели проще учиться на коротких инкрементальных обновлениях, чем на длинных последовательностях с накапливающимися ошибками. Короткий вход = меньше шума для обучения. Модель не путается в длинной истории и фокусируется на паттерне "старое состояние + изменение = новое состояние".
Адаптации и экстраполяции
💡 Адаптация для управления проектом:
Вместо отслеживания предпочтений пользователя, отслеживай статус задач в проекте.
**Текущий статус проекта:**
- Дизайн: готов, отправлен клиенту
- Бэкенд: в работе, ждём API от подрядчика
- Фронтенд: старт отложен до готовности дизайна
**Последнее обновление:**
Менеджер: Клиент утвердил дизайн с правками. Подрядчик прислал API.
Я: Отлично. Запускаем фронтенд?
**Обнови статус проекта с учётом последнего обновления:**
[модель обновит: Дизайн → утверждён с правками, Бэкенд → API получен можно интегрировать, Фронтенд → готов к запуску]
Ресурсы
Enhancing the Preference Extractor in Multi-turn Dialogues: From Annotating Disasters to Accurate Preference Extraction
Авторы: Cheng Wang, Ziru Liu, Pengcheng Tang, Mingyu Zhang, Quanyu Dai, Yue Zhu
Организации: Huawei Technologies Co., Ltd., Huawei Noah's Ark Lab
