openclaw20260213 уже набрал 188k звёзд, но всё ещё слишком сырой: слишком много проблем, даже с компрессией контекста не разобрались — запись о тяжёлой отладке

openclaw20260213 уже набрал 188k звёзд, но всё ещё слишком новый: проблем слишком много, и даже сжатие контекста не доделано — тяжёлый разбор одной отладки

Автор:三局两胜
Время:2026-02-13

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

  • «Пустой ответ» — это не значит, что модель недоступна, и это не точечная поломка QQ-плагина
  • Корневая причина — неконтролируемое раздувание контекста диалога, из‑за чего срабатывает silent overflow(output=0
  • В текущей версии OpenClaw в этом сценарии действительно есть проблема «без подсказки, без авто-восстановления»(у официальных уже есть issue/PR)。

一、Симптомы сбоя(реальная ситуация, с которой я столкнулся)

У меня проявлялось так:

  1. В QQ‑группе бот внезапно начал отвечать «пусто»(выглядит как будто не ответил, или записался только assistant turn, но контент пустой)。
  2. В TG в тот же период всё выглядело нормально, из‑за чего возникала иллюзия «может, сломался QQ‑плагин».
  3. В WebUI видно, что сессия продолжает писать логи, но со стороны пользователя нет валидного текста.

Поначалу отладка была очень хаотичной, потому что в тот же период ещё вперемешку были:

  • проблемы в цепочке отправки файлов(NapCat rich media)
  • триггеры в группе/логика упоминания @
  • конфигурации админов и чёрного списка

Эти проблемы мешают наблюдениям и делают корень «пустого ответа» неочевидным с первого взгляда.


二、Путь диагностики(в хронологическом порядке)

1) Сначала убедиться, что API не «легло» целиком

  • Я сначала проверил, что апстрим‑API(newapi/cpa)доступен в других клиентах。
  • Затем посмотрел локальные логи сессии OpenClaw и обнаружил: это не падение запроса, а типичные записи:
    • usage.input очень большой(уровня 200k~300k)
    • usage.output = 0
    • content = []

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

2) Сравнить объём сессий QQ и TG

Я вытащил и посмотрел ключевые файлы сессий:

  • Сессия QQ‑группы:cb77ecdc-6d64-489f-8aa1-d63a92d67ce7.jsonl
  • Сессия TG‑лички:9c1c29b4-b309-4b71-a1bd-5a7fd8541679.jsonl

Результат очень наглядный:

  • История QQ‑сессии огромная, и много раз встречается input≈260k~282k
  • В TG в тот же период примерно input≈36k~38k, ответы нормальные。

3) Точно найти, «в какой момент вдруг раздулось»

В QQ‑групповой сессии точка перегиба совпала с одной «задачей поиска»:

  • подряд записалось много сверхдлинных toolResult(SearchResults)
  • длина одной записи — десятки KB(например 48k / 38k / 24k)
  • после этого input‑tokens мгновенно прыгнули до 282k, и пошли подряд пустые ответы

То есть контекст «взорвала» не какая‑то обычная реплика пользователя, а то, что результаты инструмента целиком записались в сессию, и протолкнули и так уже большую сессию за критическую границу.

4) Проверить, «а в TG поиск попадает в контекст?»

Я специально сделал контрольное сравнение:

  • В TG тоже записывается toolResult(так же попадает в контекст)
  • Но базовый объём TG‑сессии меньше, поэтому она не взорвалась сразу

Этот шаг ломает распространённое заблуждение:

  • не так, что «в TG не попадает в контекст, а в QQ попадает»
  • а так, что «в обоих попадает — кто раньше достигнет лимита, тот раньше и сломается»

5) Провести жёсткий эксперимент(доказать, что это не иллюзия)

Я сделал два раунда экспериментов:

  • сначала поменял привязку сессии(TG указывал на QQ‑сессию)
  • затем сделал эксперимент с файловой подменой(скопировал содержимое огромной QQ‑сессии в файл TG‑сессии)

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


三、Итоговая корневая причина

Корень можно свести к трём фразам:

  1. История сессии слишком большая(особенно из‑за большого количества toolResult/raw‑контента поиска)。
  2. Когда запрос достигает/превышает эффективное окно контекста модели, возвращается stopReason=length + output=0
  3. В текущем OpenClaw стратегия восстановления на ветке «silent overflow» недостаточна, и со стороны пользователя это выглядит как «бот умер и отвечает пусто».

四、Почему по ощущениям это так плохо

Потому что есть три «контринтуитивные» особенности:

  • Это не ошибка:часто не выбрасывается явная ошибка, а выглядит как «успешно завершилось, но без контента».
  • Не воспроизводится сразу:обычно срабатывает внезапно после накопления длинной сессии。
  • Не привязано к одной платформе:и QQ, и TG могут попасть, просто зависит от того, где сессия раньше раздуется до лимита。

五、Мой временный план «остановки кровотечения»(практически применимо)

  1. Если видите пустой ответ — сначала /newsession или переключение на новую сессию, не пытайтесь «пробить» уже раздутую сессию.
  2. Сократить запись больших исходных текстов инструментов в историю, особенно результаты поиска и длинные веб‑страницы.
  3. Сделать предупреждение «контекст слишком тяжёлый» на уровне плагина(например, при превышении порога input — предлагать открыть новую сессию)。
  4. Для группового сценария рекомендую держать «тестовую маленькую группу(группа на двоих)」для наблюдения за эксплуатацией — так проще быстро проверять состояние бота.

六、Официальный статус:Issue/PR уже есть, но фиксы ещё в процессе

1) Официальные issue(похожие проблемы)

2) Соответствующий PR‑фикс(ключевая идея)

Ключевая идея этого PR:

  • распознавать ветку «silent overflow»
  • включать её в overflow recovery(триггерить compaction/retry),а не считать нормальным завершением

Я считаю, что идея правильная — по крайней мере, это гораздо надёжнее, чем «пользователь вручную удаляет файл сессии».


七、Дополнительные доработки, которые я сделал у себя(на стороне плагина)

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

  • Исправил изоляцию ключей сессии между QQ‑личкой/группой, чтобы не было «перепутывания» между каналами.
  • Привёл /newsession из «команды для вида» к «реальному очищению сессии».
  • Добавил подсказку‑заглушку на случай пустого ответа, чтобы пользователь не воспринимал это как полную потерю связи.
  • Исправил повторное наслоение суффикса занятости(чтобы не было ник(вводит)(вводит))。

Но важно подчеркнуть: это улучшает UX, а настоящий «silent overflow из‑за сверхбольшого контекста» всё равно требует решения на уровне ядра


八、Советы тем, кто столкнётся потом

Если у вас тоже «логи вроде бегут, но ответ пустой»:

  1. Сначала проверьте usage.input/output у соответствующей session.
  2. Если видите output=0 и огромный input — в первую очередь подозревайте переполнение контекста.
  3. Сразу откройте новую сессию для проверки, не гоняйте попытки в старой.
  4. Проверьте, не записываете ли вы большие toolResult(поиск/веб)в сессию без обрезки.
  5. Следите за прогрессом мержа #14064 / #14157.

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

— 三局两胜