- BrainTools - https://www.braintools.ru -
Я разрабатываю приложение KeyRay [1] – кроссплатформенный аналог Punto Switcher, имеющий на порядок лучшую стабильность переключения раскладки. При разработке активно использую нейросети для отладки багов. И столкнулся с неприятной проблемой: при копировании логов в чат огромная часть контекстного окна уходит впустую. Работа с логами во время разработки в паре с ИИ занимает львиную долю времени и контекста чата.
Типичная картина: заметил баг, копирую 1000 строк логов и вставляю в чат. Нейросеть начинает разбирать текст, но из этих 1000 строк реально уникальных — максимум 300. Остальные — это один и тот же шаблон, повторенный сотни раз:
2026-04-18T11:54:02.746 [WinFocusMonitor] computeIsSecureField: queryMsaaProtected == 0
2026-04-18T11:54:02.747 [WinFocusMonitor] workerMain: hwnd=00000000016000FE idObject=-4 idChild=0 -> secure=0
2026-04-18T11:54:02.765 [WinFocusMonitor] computeIsSecureField: queryMsaaProtected == 0
2026-04-18T11:54:02.765 [WinFocusMonitor] workerMain: hwnd=00000000003B0640 idObject=-4 idChild=-45107 -> secure=0
2026-04-18T11:54:04.787 [MemDiag] periodic t+9s WorkingSet=352.257812MB Peak=368.761719MB
2026-04-18T11:54:04.788 [MemDiag] WordIndex en_US READY at t+9s
2026-04-18T11:54:04.788 [MemDiag] after WordIndex en_US READY WorkingSet=352.320312MB Peak=368.761719MB
В логах видны одни и те же компоненты ([WinFocusMonitor], [MemDiag]), одни и те же ключи (WorkingSet=, hwnd=), одни и те же фразы.
Идея состояла в том, чтобы скопировать логи в буфер обмена стандартными способами, затем с помощью сочетания клавиш Ctrl+Alt+V вставить оптимизированный вариант. В результате, с помощью такой простой фоновой утилиты, удалось добиться сжатия логов до 80% в зависимости от объема и количества повторений.
Первая мысль была простой: если что-то повторяется — вынесу это в “легенду” (словарь) и заменю коротким тегом. Попросил нейронку написать скрипт на PowerShell, который анализирует логи и выносит повторяющиеся элементы в теги вида #1#, #2# .
Вот как выглядят те же логи после первой версии скрипта:
--- LEGEND ---
#T# = 2026-04-18T11:54:
#0# = [WinFocusMonitor]
#1# = [MemDiag]
#2# = hwnd=
#3# = idObject=
#4# = idChild=
#5# = secure=
#6# = WorkingSet=
#7# = Peak=
#8# = ' computeIsSecureField: queryMsaaProtected == 0'
#9# = ' WordIndex '
--- LOGS ---
#T#02.746 #0##8#
#T#02.747 #0# workerMain: #00000000016000FE #3#-4 #4#0 -> #5#0
#T#02.765 #0#8
#T#02.765 #0# workerMain: #00000000003B0640 #3#-4 #4#-45107 -> #5#0
#T#04.787 #1# periodic t+9s #6352.257812MB #7#368.761719MB
#T#04.788 #1# #9#en_US READY at t+9s
#T#04.788 #1# after #9#en_US READY #6#352.320312MB #7#368.761719MB
Все базовые повторяющиеся элементы вынесены в легенду наверху.
Результат первого этапа: 4072 символов → 2625 символов. Экономия~35%.
Когда переменных становится много, теги начинают выглядеть как #123, #456 — это уже 4-5 символов на тег.
Это можно оптимизировать возможностью добавления в теги строчных и заглавных букв. В этой системе первые 62 переменные можно записать всего двумя символами:
#0, #1, #2… #9 (10 штук)
#a, #b, #c… #z (26 штук)
#A, #B, #C… #Z (26 штук)
Итого 62 переменные в двух символах. Дальше идут #10, #11 и так далее, но в три символа.
--- LEGEND ---
#T# = 2026-04-18T11:54:
#0# = [WinFocusMonitor]
#1# = [MemDiag]
#2# = hwnd=
#3# = idObject=
#4# = idChild=
#5# = secure=
#6# = WorkingSet=
#7# = Peak=
#8# = ' computeIsSecureField: queryMsaaProtected == 0'
#9# = ' WordIndex '
--- LOGS ---
#T#02.746 #0##8#
#T#02.747 #0# workerMain: #2#16000FE #3#-4 #4#0 -> #5#0
На больших масштабах это может давать дополнительные 3-5% компрессии.
Ещё одна мелочь, которая режет глаз в C++ логах — hex-указатели с фиксированной шириной. Windows API возвращает HWND как 00000000016000FE — восемь ведущих нулей, которые не несут никакой смысловой нагрузки.
Оптимизировал это обрезанием ведущих нулей. Было 00000000016000FE — стало 16000FE.
--- LOGS ---
#T#02.746 #0##8#
#T#02.747 #0# workerMain: #2#16000FE #3#-4 #4#0 -> #5#0
#T#02.765 #0#8
#T#02.765 #0# workerMain: #2#3B0640 #3#-4 #4#-45107 -> #5#0
На 45 КБ логов это дало экономию примерно в 300 символов. Немного, но тем не менее.
Работа с большими логами выявили дубликаты из самих тегов:
#T#19.557 #0##C##8##81# #90#
#T#19.557 #0##K##8##81# #90#
#T#19.601 #0##U##8##81# #90#
#T#19.601 #0##C##8##32# #91#
#T#19.601 #0##w##8##32# #91#
#T#19.601 #0##x##8##32# #91#
Префикс #T#19.557 #0# повторяется несколько раз подряд. Теперь нужно искать повторяющиеся последовательности тегов и выносить их в новые переменные.
Я добавил дополнительный цикл обработки, который работает поверх обычного. Новые переменные стал помечать (!) вместо (#), для разделения:
--- LEGEND ---
#T# = 2026-04-18T11:54:
#0# = [TTDiag]
#8# = vk=
#32# = 881
#81# = 890
#C# = ' > shouldBlockAllFeatures '
#K# = ' > drainPendingReset '
#U# = ' > entry '
#w# = ' > executePendingReplacementIfAny '
#x# = ' > hotkeyManager.processKeyEvent '
!1! = #T#19.557 #0##C##8#
!2! = #T#19.601 #0#
!3! = #8##32# #91#
--- LOGS ---
!1!#81# #90#
!1!#K##81# #90#
!2!#U##81# #90#
!2!#C#!3!
!2!#w#!3!
!2!#x#!3!
Теперь обычные теги складываются в мета-теги.
Результат четвертого этапа: 45 839 символов → 13 398 символа. Сжатие 70.8% от оригинала.
Дальнейшая работа показала следующие паттерны:
!26!#o#!3!
!26!#E#!3!
!26!#K#!3!
!26!#D#!3!
!26!#w#!3!
!26!#z#!3!
!26!#x#!3!
Здесь меняется только один средний элемент! Префикс !26 и суффикс !3 одинаковые во всех строках. Данную конструкцию мы можем вынести в следующий паттерн !26!#@#!3!, где @ – указатель на место подстановки, а само значение в итоговом макросе будем передавать после : , например &1:o
--- LEGEND ---
#o# = ' > shouldExecute '
#E# = ' > hotkeyDefs->snapshot '
#K# = ' > drainPendingReset '
#D# = ' > handleCaseSwitchHotkey '
#w# = ' > executePendingReplacementIfAny '
#z# = ' > handleTranslationHotkey '
#x# = ' > hotkeyManager.processKeyEvent '
!26! = #T##1d#0
!3! = #8#81 #90#
&1 = !26!#@#!3!
--- LOGS ---
&1:o
&1:E
&1:K
&1:D
&1:w
&1:z
&1:x
Теперь логи превратились в чистый перечень указателей. Каждая строка &1:o читается так: “Возьми шаблон &1 (который раскрывается в !26!#@#!3!), подставь вместо @ значение o, и получишь исходную строку лога”.
Результат пятого этапа: 45 839 символа → 10 192 символов. Финальное сжатие 78.4%!
PowerShell — хорошо подходит для быстрой автоматизации на коленке, но он медленно работает с циклами по массивам строк и вложенными итерациями. Это приводило к долгой задержке вставки, которая могла доходить до 20 секунд. В итоге ИИ переписал мне все на Rust и теперь вставка происходит мгновенно.
Возникает вопрос: “А поймут ли нейросети такой формат? Не запутается ли модель в этих тегах?”
Ответ — не только поймут, но работают с ним даже лучше, чем с сырыми логами.
Современные нейросети тренируются на коде, JSON, YAML, markdown. Когда модель видит блок --- LEGEND --- с парами “ключ = значение”, она автоматически понимает: это словарь, нужно держать его в контексте. Ей не нужно объяснять как работать с этим форматом — она сама “разворачивает” теги в уме.
Это самое важное. Когда вы вставляете в чат 1000 строк с одинаковым текстом [WinFocusMonitor] workerMain: hwnd=..., внимание [2] модели (attention mechanism) “размазывается” по повторяющемуся мусору.
В сжатом формате модель видит:
&24:o
&24:E
&24:K
&24:D
Для нейросети это идеальный сигнал: “Ага, структура строки идентична, меняется только один параметр. Давай-ка посмотрю в легенде, что означают o, E, K, D, и сфокусируюсь на отличиях”.
Ошибки [3] и аномалии в таком формате буквально светятся. Если вдруг среди десяти &24:K появится &24:X или вообще &25:K — модель мгновенно увидит нарушение паттерна.
Даже у самых продвинутых моделей есть проблема: чем больше контекст, тем больше “забывчивость”.
Сэкономив до 80% символов на логах, вы оставляете модели больше “оперативной памяти” для:
Удержания архитектуры вашего проекта
Истории текущего чата
Написания качественного кода в ответе
Модель не “забудет” контекст задачи из-за раздутого лога.
Ключевое отличие данного подхода от “попросить ИИ сократить лог” — мы сжимаем математически [4], а не через пересказ. Все миллисекунды, hex-адреса, коды ошибок остаются на своих местах. Алгоритм BPE гарантирует нулевую потерю данных.
Приложение доступно пока только для windows. Работает следующим образом:
Копируете сырые логи из терминала/файла (Ctrl+C)
Переключаетесь в любой чат
Нажимаете Ctrl+Alt+V вместо обычного Ctrl+V
Вставляются сжатые логи
Бонус: исходные логи автоматически восстанавливаются в буфере обмена (на случай, если нужно вставить оригинал куда-то ещё)
Исходный код проекта доступен на GitHub. Вы можете за пару минут портировать этот алгоритм под свою платформу, а также доработать под свои нужды.
Ссылка на GitHub [5]
Автор: sergeivsk
Источник [7]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/29129
URLs in this post:
[1] KeyRay: https://www.keyray.ru/
[2] внимание: http://www.braintools.ru/article/7595
[3] Ошибки: http://www.braintools.ru/article/4192
[4] математически: http://www.braintools.ru/article/7620
[5] Ссылка на GitHub: https://github.com/sergeivaskov/logs-tokenizer
[6] Скачать для Windows: https://github.com/sergeivaskov/logs-tokenizer/releases/latest/download/Logs.Tokenizer.exe
[7] Источник: https://habr.com/ru/articles/1026040/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1026040
Нажмите здесь для печати.