Перейти к содержанию
Публикация AiManual

OncoAgent: open-source мультиагентная система для онкологии на LangGraph и QLoRA

Обзор OncoAgent — мультиагентной системы на LangGraph и QLoRA для анализа рака. Приватное развертывание на AMD MI300X. Сравнение с Med-PaLM, примеры.

Коротко

Что будет в материале

  1. 01

    Когда врачам нужен AI, который не сливает данные в облако

  2. 02

    Двухуровневая архитектура: супервизор и армия специалистов

  3. 03

    RAG, который не галлюцинирует

  4. 04

    Сравнение с альтернативами: Google Med-PaLM vs OncoAgent

Когда врачам нужен AI, который не сливает данные в облако

Представьте: онкологический центр с сотнями историй болезни, снимков, результатов биопсий. Им нужен AI-ассистент, который не отправит данные в Google Cloud, не подчиняется HIPAA через юридические танцы с бубном. Закрытые системы вроде Google Med-PaLM 2 работают хорошо, но вы не контролируете модель, не знаете, на каких данных она дообучена, а главное — ваши пациенты летят на сервера корпорации. IBM Watson for Oncology? Устарел морально и архитектурно. OncoAgent — это open-source ответ: мультиагентный оркестратор на LangGraph, с RAG-пайплайном и дообучением через QLoRA, который вы разворачиваете у себя на AMD MI300X. Если вам нужен приватный медицинский AI без компромиссов — вы на правильном пути.

Двухуровневая архитектура: супервизор и армия специалистов

OncoAgent построен по принципу dual-tier: сверху — supervisor-агент, снизу — пул специализированных агентов (радиолог, патолог, онколог, генетик). Supervisor пишется на LangGraph — фреймворке для построения графов из LLM-шагов. Он получает запрос, парсит его, раскладывает на подзадачи и отправляет нужному агенту.

Звучит логично? На практике графы LangGraph — та ещё боль. В статье AI-агент для код-ревью: как мы строили на LangGraph и что пошло не так авторы честно признаются, где споткнулись. OncoAgent использует похожий граф, но с жёсткой типизацией состояний: supervisor ждёт ответы от всех агентов, потом собирает единый отчёт.

Ключевая фишка: каждый специализированный агент — это отдельная LLM, дообученная на узком домене (например, радиолог — на радиологических заключениях). Supervisor не лезет в предметную область, он только координатор.

Как это выглядит в коде? Ниже — упрощённый пример графа на LangGraph (не пытайтесь скопировать один в один, тут опущены хитрости с очередями).

from langgraph.graph import StateGraph, END

class OncologyState(dict):
    query: str
    images: list[bytes]
    lab_results: dict
    radiologist_output: str = None
    pathologist_output: str = None
    oncologist_output: str = None
    final_report: str = None

def radiologist_agent(state: OncologyState):
    # Анализ снимков, возвращает текст
    return {"radiologist_output": analyze_scan(state["images"])}

def pathologist_agent(state: OncologyState):
    return {"pathologist_output": analyze_biopsy(state["lab_results"])}

def oncologist_agent(state: OncologyState):
    return {"oncologist_output": recommend_treatment(state)}

def supervisor_decide(state):
    if state.get("radiologist_output") and state.get("pathologist_output"):
        return "oncologist"
    return "wait"

builder = StateGraph(OncologyState)
builder.add_node("radiologist", radiologist_agent)
builder.add_node("pathologist", pathologist_agent)
builder.add_node("oncologist", oncologist_agent)
builder.set_conditional_edge_source("router", supervisor_decide, {"oncologist": "oncologist", "wait": END})
builder.set_entry_point("radiologist")
builder.add_edge("radiologist", "router")
# ... и так далее

Не советую использовать приведённый код для продакшна без обработки таймаутов и отказов. Supervisor должен уметь запрашивать уточнения, если агент вернул мусор.

RAG, который не галлюцинирует

Каждый агент имеет доступ к векторному хранилищу (FAISS или Chroma) с медицинскими документами: PubMed, клинические рекомендации NCCN, ESMO, FDA approvals. RAG-pipeline собирает релевантные фрагменты, чтобы модель не выдумывала стадии и протоколы.

Но базовая LLM (в текущей версии — Llama 3.3 70B) должна быть дообучена на медицинских текстах. Полный fine-tune на 70B — дорого (16 H100, 2 недели). OncoAgent использует QLoRA: 4-битное квантование + LoRA-адаптеры. Всё влезает на одну AMD MI300X с 192 ГБ HBM3. Скорость инференса — ~40 токенов/с для 70B модели в 4-bit.

Метод Потребление памяти Время обучения (на MI300X) Качество (F1 на MedQA)
Полный fine-tune (16-bit) ~280 GB ~14 дней 82.1
QLoRA (4-bit + LoRA rank=64) ~48 GB ~3 дня 80.7

Потеря 1.4% F1 — допустимая плата за возможность развернуть всё на одном ускорителе, который к тому же стоит дешевле H100. Кстати, о настройке стека локальных LLM-агентов и выборе квантований читайте в материале Как настроить стек локальных LLM-агентов для программирования — подходы те же, только модель медицинская.

Сравнение с альтернативами: Google Med-PaLM vs OncoAgent

Рынок медицинских AI-систем — минное поле. Закрытые решения доминируют, но OncoAgent пробивает окно.

Критерий OncoAgent Google Med-PaLM 2 IBM Watson Health
Лицензия Apache 2.0 Закрытая (API) Закрытая (EOL)
Приватность данных Полная (локально) Данные покидают клинику –
Мультиагентная архитектура Да (LangGraph) Нет (одна модель) Модульный, но не мультиагентный
Дообучение QLoRA на своих данных Недоступно Только через IBM
Аппаратное обеспечение AMD MI300X или NVIDIA A100/H100 TPU Google Любое (legacy)

Med-PaLM 2 показывает высокую точность (на MedQA ~78%), но вы не сможете его адаптировать под специфику вашей клиники. OncoAgent проигрывает в эталонной точности (80.7% на том же бенчмарке после QLoRA), но выигрывает в гибкости.

Пример из жизни: анализ рентгенограммы с историей болезни

Допустим, пациент с подозрением на рак лёгкого. В систему загружают: КТ-снимки, предыдущие биопсии (текст), уровень онкомаркеров.

  1. Radiologist-агент использует дообученную модель для сегментации опухоли (на базе SAM-CLIP) и генерирует описание: размер, инвазия в лимфоузлы.
  2. Pathologist-агент анализирует текст биопсии, извлекает гистологический тип (аденокарцинома, EGFR-мутация?).
  3. Oncologist-агент консультируется с RAG (PubMed, NCCN) и выдает рекомендацию: "Таргетная терапия озимертинибом, рассмотреть иммунотерапию пембролизумабом".
  4. Supervisor собирает всё в PDF-отчёт на русском/английском.

Весь цикл занимает ~15 секунд на одном MI300X. При этом ни один байт не покидает сервер больницы.

💡
Визуализировать, что происходит в головах агентов, помогает OpenCode — утилита, которая показывает граф вызовов и промежуточные результаты в реальном времени. Для отладки supervisor-графа вещь незаменимая.

Кому это реально нужно

OncoAgent — инструмент для тех, кто устал от чёрных ящиков:

  • Исследовательские группы, которые хотят ставить эксперименты с мультиагентными архитектурами. Сравните с подходом, описанным в Как выбрать архитектуру мульти-агента — OncoAgent использует гибрид: supervisor с кондициональными рёбрами, а не полный mesh.
  • Онкологические центры с собственным IT-отделом, которым нужна полная приватность.
  • Разработчики медицинского AI, которые хотят форкнуть код и адаптировать под конкретный вид рака. Кстати, профессор биологии недавно собрал похожий multi-agent оркестратор для локальных LLM — его опыт подсказывает, что не стоит завязывать всю логику на одном supervisor, лучше сделать супервизора второго уровня для сложных запросов.

Закончу советом, который звучит банально, но игнорировать его — ошибка: не пытайтесь покрыть все 200+ видов рака сразу. Выберите один — рак лёгкого или молочной железы — соберите качественный датасет, отладьте граф и RAG, а потом масштабируйте. Иначе через месяц вы проклинаете день, когда решили, что мультиагент = универсальный солдат.

Подписаться на канал