Проблема

Я разрабатываю приложение KeyRay - кроссплатформенный аналог 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% в зависимости от объема и количества повторений.

Этап 1: Базовая идея — словарь повторений

Первая мысль была простой: если что-то повторяется — вынесу это в “легенду” (словарь) и заменю коротким тегом. Попросил нейронку написать скрипт на 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%.

Этап 2: Оптимизация тегов через Base62

Когда переменных становится много, теги начинают выглядеть как #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% компрессии.

Этап 3: Удаление ведущих нулей

Ещё одна мелочь, которая режет глаз в 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 символов. Немного, но тем не менее.

Этап 4: Meta-BPE — теги из тегов

Работа с большими логами выявили дубликаты из самих тегов:

#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% от оригинала.

Этап 5: Макросы с подстановкой

Дальнейшая работа показала следующие паттерны:

!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 и теперь вставка происходит мгновенно.

Как это работает с нейросетями?

Возникает вопрос: “А поймут ли нейросети такой формат? Не запутается ли модель в этих тегах?”

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

1. LLM обучены на структурированных данных

Современные нейросети тренируются на коде, JSON, YAML, markdown. Когда модель видит блок --- LEGEND --- с парами “ключ = значение”, она автоматически понимает: это словарь, нужно держать его в контексте. Ей не нужно объяснять как работать с этим форматом — она сама “разворачивает” теги в уме.

2. Фокус на аномалиях

Это самое важное. Когда вы вставляете в чат 1000 строк с одинаковым текстом [WinFocusMonitor] workerMain: hwnd=..., внимание модели (attention mechanism) “размазывается” по повторяющемуся мусору.

В сжатом формате модель видит:

&24:o
&24:E
&24:K
&24:D

Для нейросети это идеальный сигнал: “Ага, структура строки идентична, меняется только один параметр. Давай-ка посмотрю в легенде, что означают o, E, K, D, и сфокусируюсь на отличиях”.

Ошибки и аномалии в таком формате буквально светятся. Если вдруг среди десяти &24:K появится &24:X или вообще &25:K — модель мгновенно увидит нарушение паттерна.

3. Экономия контекстного окна

Даже у самых продвинутых моделей есть проблема: чем больше контекст, тем больше “забывчивость”.

Сэкономив до 80% символов на логах, вы оставляете модели больше “оперативной памяти” для:

  • Удержания архитектуры вашего проекта

  • Истории текущего чата

  • Написания качественного кода в ответе

Модель не “забудет” контекст задачи из-за раздутого лога.

4. Нет галлюцинаций

Ключевое отличие данного подхода от “попросить ИИ сократить лог” — мы сжимаем математически, а не через пересказ. Все миллисекунды, hex-адреса, коды ошибок остаются на своих местах. Алгоритм BPE гарантирует нулевую потерю данных.

Как использовать?

Приложение доступно пока только для windows. Работает следующим образом:

  1. Копируете сырые логи из терминала/файла (Ctrl+C)

  2. Переключаетесь в любой чат

  3. Нажимаете Ctrl+Alt+V вместо обычного Ctrl+V

  4. Вставляются сжатые логи

  5. Бонус: исходные логи автоматически восстанавливаются в буфере обмена (на случай, если нужно вставить оригинал куда-то ещё)

Исходный код проекта доступен на GitHub. Вы можете за пару минут портировать этот алгоритм под свою платформу, а также доработать под свои нужды.

Ссылка на KeyRay

Комментарии (5)


  1. Shaman_RSHU
    21.04.2026 11:02

    В SIEM "сырые" события перед обработкой тоже проходят санитайзинг, агрегацию и корреляцию. Только после этого вступают в работу обработчики правил срабатывания.


  1. difhel
    21.04.2026 11:02

    А у вас есть какие-то бенчмарки эффективности работы с логами, какая методика исследования? Например, можно 100 раз прогнать один и тот же лог в одном формате, посмотреть процент корректно распознанных проблем, и сравнить с таким же процентом, если просто давать сырые логи. Это было бы интересно глянуть, учитывая, что у современных LLM достаточно большой контекст (сотни тысяч-миллионы токенов), и они и так должны были бы неплохо справляться с такими задачами.


    1. sergeivsk Автор
      21.04.2026 11:02

      Бэнчмарки самые примитивные и простые. Скопировал логи – вставил логи. В системном уведомлении отобразилось сколько символов было и сколько стало, а также процент компрессии. На моем типе логов она плавает в среднем в районе 76-78%. Чем больше логов, тем больше степень сжатия.

      LLM достаточно большой контекст (сотни тысяч-миллионы токенов), и они и так должны были бы неплохо справляться с такими задачами.

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


      1. difhel
        21.04.2026 11:02

        Я имею в виду бенчмаркинг эффективности анализа логов (насколько с вашим подходом модель чаще/реже корректно определяет проблему по логам, чем если бы ей просто скормить логи). Компрессия input токенов понятна, да.


  1. Amareis
    21.04.2026 11:02

    Индустрия понемногу переизобретает компрессию данных для более дешевой их обработки...)