Проблема
Я разрабатываю приложение 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. Работает следующим образом:
Копируете сырые логи из терминала/файла (
Ctrl+C)Переключаетесь в любой чат
Нажимаете
Ctrl+Alt+Vвместо обычногоCtrl+VВставляются сжатые логи
Бонус: исходные логи автоматически восстанавливаются в буфере обмена (на случай, если нужно вставить оригинал куда-то ещё)
Исходный код проекта доступен на GitHub. Вы можете за пару минут портировать этот алгоритм под свою платформу, а также доработать под свои нужды.
Комментарии (4)

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

sergeivsk Автор
21.04.2026 11:02Бэнчмарки самые примитивные и простые. Скопировал логи – вставил логи. В системном уведомлении отобразилось сколько символов было и сколько стало, а также процент компрессии. На моем типе логов она плавает в среднем в районе 76-78%. Чем больше логов, тем больше степень сжатия.
LLM достаточно большой контекст (сотни тысяч-миллионы токенов), и они и так должны были бы неплохо справляться с такими задачами.
Справляются-то они хорошо с большим количеством логов, но в случае когда их просто нужно вставить в чат обычным копипастом, то нерйонка все равно расходует на это токены и как следствие лимиты и ваши деньги. Данное приложение призвано сократить расход в таких ситуациях.

difhel
21.04.2026 11:02Я имею в виду бенчмаркинг эффективности анализа логов (насколько с вашим подходом модель чаще/реже корректно определяет проблему по логам, чем если бы ей просто скормить логи). Компрессия input токенов понятна, да.
Shaman_RSHU
В SIEM "сырые" события перед обработкой тоже проходят санитайзинг, агрегацию и корреляцию. Только после этого вступают в работу обработчики правил срабатывания.