Николай Пискунов, руководитель направления Big Data в Beeline Cloud, опубликовал продолжение цикла о клиенте для Ollama — облачного сервиса для запуска языковых моделей. В новой части он описывает три изменения: смену базы данных, оптимизацию фронтенда и новую функцию анализа кода.

В первой версии проекта история диалогов хранилась в PostgreSQL: таблица chat_history, каждое сообщение — отдельная строка, связанная с сессией через session_id. Схема работала, но обнаружила слабое место при длинных ответах языковых моделей. PostgreSQL использует механизм TOAST (The Oversized-Attribute Storage Technique): когда текст превышает примерно 2 КБ, база автоматически сжимает его и перемещает в отдельные служебные таблицы, оставляя в основной лишь указатель. При чтении истории сервер вынужден собирать диалог по кускам из нескольких таблиц — это создаёт нагрузку на процессор и дисковую систему, а производительность падает по мере роста объёма текста.

ПараметрPostgreSQLMongoDB
Механизм хранения больших текстовTOAST: сжатие и перенос в служебные таблицы при >2 КБBSON-документ целиком, без вспомогательных таблиц
Чтение истории диалогаСборка по строкам через JOIN / ORDER BYОдин запрос — готовый объект со всей историей
Лимит на записьДо 1 ГБ на колонкуДо 16 МБ на документ
Эффективность хранения JSONБазоваяВ 6 раз эффективнее по дисковому пространству (по данным автора)
Обновление записиПерезапись всего объектаОбновление части документа без перезаписи целиком

MongoDB решает эту задачу иначе. Данные хранятся в бинарном формате BSON как самодостаточные документы: весь диалог — один объект в коллекции chat_sessions, внутри которого массив messages с вложенными документами (role, content, timestamp). Чтение сессии — одна операция ввода-вывода. Лимит на документ составляет 16 МБ, чего, по оценке автора, достаточно для подавляющего большинства диалогов с LLM: для сравнения, все тексты Шекспира в текстовом формате занимают около 5,5 МБ. Автор также указывает, что MongoDB в шесть раз эффективнее использует дисковое пространство при работе с JSON по сравнению с PostgreSQL, а нагрузка на процессор снижается за счёт отсутствия постоянного сжатия и распаковки.

MongoDB хранит весь диалог как один BSON-документ: одна операция ввода-вывода вместо сборки по кускам, лимит — 16 МБ на документ.

Смена базы данных повлекла и изменение модели данных. Вместо SQL-запроса, собирающего строки по session_id, сервис теперь получает готовый объект ChatHistory со всей историей диалога за один запрос. Методы addUserMessage и addAssistantMessage инкапсулируют логику добавления сообщений и обновления временных меток — код сервиса стал компактнее. Автор оговаривается, что NoSQL не универсальное решение, но для документоориентированного сценария чата подход оказался органичным.

Вторая проблема проявилась при тестировании с длинными промтами: фронтенд на React начинал подтормаживать и зависать на несколько секунд. Причина — каждый новый чанк от LLM вызывал обновление состояния messages, что приводило к полному перерендеру всего дерева компонентов, включая MessageList и все дочерние элементы. При тысячах чанков в длинном ответе React не успевал перерисовывать интерфейс с частотой 60 кадров в секунду. Решением стала мемоизация через React.memo и useCallback — стандартные инструменты React, которые предотвращают лишние перерендеры компонентов, не получивших новых данных.

Третье изменение — функция «Анализ проекта», позволяющая загрузить код для ревью с фильтрацией через.gitignore. Это удобно при работе с реальными репозиториями: ненужные файлы (зависимости, артефакты сборки) автоматически исключаются, и модели передаётся только релевантный код.

Проект развивается как практический инструмент для работы с локально развёрнутыми языковыми моделями через Ollama. Подобные клиенты востребованы в сценариях, где данные не должны покидать инфраструктуру компании — например, при ревью внутреннего кода или работе с конфиденциальными документами.