Загрузка 0
ПОДЕЛИТЬСЯ

Мой блог

Листай вниз

Долгосрочная память для медицинского AI-ассистента: архитектура LTM

Долгосрочная память для медицинского AI-ассистента: архитектура LTM

При разработке персонального цифрового ассистента здоровья «Я Здоров» я столкнулся с необходимостью внедрения надежной долгосрочной памяти — долгосрочная память LTM. Мобильное приложение собирает медицинские данные пользователей, оцифровывает документы, отслеживает анализы и ведет дневники здоровья, позволяя общаться с искусственным интеллектом в чате.

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

Архитектурный компонент системы ассистента здоровья
Техническая схема элемента обработки данных
Схема обработки запросов в системе LTM
Схема маршрутизации запросов внутри ассистента
Модуль валидации структурированных данных
Проверка типов и значений перед записью в память
Фильтрация статусов при выборочном извлечении
Фильтрация записей по их актуальному статусу
Тестирование уровней архитектуры памяти
Проверка каждого компонента системы по отдельности
Масштабирование долгосрочной памяти AI-ассистента
Проблема накопления фактов при долгосрочном использовании
Итоговая схема архитектуры памяти health-ассистента
Финальная архитектурная концепция LTM

Первая версия LTM: все данные из диалогов в одном JSON

На старте проекта я использовал простую архитектуру. Все факты, извлеченные из бесед с пользователем, аккумулировались в едином громоздком JSON-объекте. Этот файл постоянно дополнялся новыми записями, а при генерации каждого нового ответа передавался в модель целиком.

Реклама

Однако по мере накопления информации этот подход продемонстрировал серьезные ограничения. Трудность заключалась не в самом формате данных, а в том, что память обрабатывалась как единый монолитный массив. Это привело к трем ключевым проблемам.

Проблемы монолитной архитектуры памяти

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

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

Архитектура памяти: синхронное чтение и асинхронная запись
Разделение процессов на синхронное чтение и фоновую асинхронную запись

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

Реклама

Версия 2: разделили память, чтение и запись

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

Логика работы также претерпела изменения и была разделена на два независимых контура: синхронное чтение (read-path) и асинхронную запись (write-path). Read-path отвечает за оперативное формирование ответа, выбирая из памяти только релевантные блоки для текущего запроса.

Асинхронная запись вынесена в фон намеренно, чтобы процесс извлечения и обновления фактов не увеличивал время ожидания ответа для пользователя. Такой подход позволяет анализировать связные фрагменты диалога целиком, а не пытаться обновлять базу после каждого отправленного сообщения.

LLM понимает смысл. Состоянием памяти управляет код

Разберем контур записи подробнее на примере сообщения пользователя об аллергии на арахис. Сначала классификатор на базе языковой модели определяет затронутый раздел — в данном случае allergies. Затем специальный экстрактор применяет правила выбранного раздела и формирует структурированное событие.

Процесс попадания нового факта в систему LTM
Последовательность шагов при добавлении новой информации в базу знаний

На этом этапе зона ответственности нейросети завершается. Полученная структура проходит строгую программную валидацию типов полей и допустимых значений. Если проверка успешна, код сопоставляет событие с существующими фактами, определяя сценарий: первое упоминание, подтверждение, изменение или отрицание.

Таким образом, языковая модель отвечает исключительно за семантику и понимание естественного языка. Технические идентификаторы, временные метки и типы изменений вычисляются программным кодом, что исключает ситуативные ошибки модели при изменении критических данных.

Реклама

Один факт — это текущее состояние плюс история

Для каждого факта, например приема лекарственного препарата, я разделил текущее состояние и историю событий. Сущности хранят исходную формулировку (name_raw) и нормализованное наименование (name_normalized), а также дозировку, частоту приема, статус и медицинские показания.

Текущее состояние отражает актуальную информацию, доступную системе в данный момент. История фиксирует все эволюционные изменения: первичное назначение, начало приема, смену дозировки или прекращение курса. Благодаря этому для обычных запросов не нужно передавать модели всю хронологию, но при необходимости прошлые события можно легко восстановить.

Текущее состояние факта и его исторические изменения
Разделение актуального среза информации и полной истории ее изменений

Не каждый сохраненный факт нужен модели прямо сейчас

Чтобы избежать перегрузки контекста, процесс извлечения данных (retrieval) начинается с классификации запроса. Система заранее знает, какие именно разделы памяти требуются для обработки конкретной темы, и объединяет их без дублирования.

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

Пользователь говорит одно, медицинские документы — другое. Что попадет в контекст?

Важно разграничивать данные из чатов (self-reported) и официальную медицинскую документацию, включая результаты анализов и врачебные заключения. Эти источники хранятся раздельно и передаются модели в виде маркированных блоков с указанием происхождения (provenance).

Если в чате и документах обнаруживаются расхождения, специального программного арбитра для поиска «абсолютной истины» в архитектуре не предусмотрено. Модель получает оба факта и в случае клинической значимости расхождений должна учитывать неопределенность, рекомендуя пользователю уточнить информацию у специалиста.

А если LLM просто пропустила важный факт?

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

Жизненный цикл фармацевтического факта в памяти
Жизненный цикл факта о приеме лекарственного препарата

Проверяем не только ответ, а всю цепочку

Для обеспечения надежности я тестирую каждый уровень архитектуры изолированно:

  • Классификатор проверяется на корректность определения тематических разделов.
  • Экстрактор тестируется на полноту извлечения сущностей и отсутствие галлюцинаций.
  • Детерминированная логика проверяется на корректность переходов состояний и учет отрицаний.
  • Модуль retrieval проверяется на точность фильтрации данных под конкретные запросы.
  • End-to-end тесты охватывают полный цикл от реплики пользователя до формирования итогового ответа.

Вместо погони за абстрактными метриками точности я фокусируюсь на стабильности архитектурных свойств: изоляции разделов, чистоте валидации и разделении текущих данных и истории.

Что произойдет, когда фактов станет слишком много

Постоянный рост долгосрочной памяти создает новые вызовы. Выборочное извлечение снижает нагрузку на контекст на уровне разделов, но со временем объем данных будет увеличиваться и внутри них.

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

LTM и Медицинская карта как два независимых источника
Интеграция данных из долгосрочной памяти и официальных медицинских документов

Вместо вывода

Опыт проектирования показал, что долгосрочная память AI-ассистента выходит далеко за рамки простого хранилища фактов. Главные архитектурные вызовы возникают после этапа записи: необходимо точно определять актуальное состояние, сохранять историю изменений, грамотно фильтровать контекст и разграничивать зоны ответственности языковой модели и детерминированного кода.

01.