Перейти к содержимому
AUTHORВЫПУСК №008 → АВТОМАТИЗАЦИЯ АГЕНТАМИ: 90% НЕ ПРОМПТ / имейте совесть, когда будете делиться или копировать
>AISTUDY_

Модуль md.2 · Урок 2

Индексация медицинских PDF: FAISS и embeddings

45 мин
Практика
md.2 / Урок 2 из 3

Чему вы научитесь

  • Разбивать медицинские PDF на осмысленные фрагменты (чанки)
  • Превращать фрагменты в эмбеддинги и складывать их в FAISS
  • Делать семантический поиск похожих случаев
  • Обезличивать данные до индексации — это обязательный шаг

Зачем индексировать, а не «скармливать» PDF целиком

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

flowchart LR
    PDF["PDF-кейсы"] --> CL["Обезличивание"]
    CL --> CH["Чанкинг\n(фрагменты)"]
    CH --> EM["Эмбеддинги"]
    EM --> FA["FAISS-индекс"]
    Q["Вопрос"] --> EM2["Эмбеддинг вопроса"]
    EM2 --> FA
    FA --> R["Top-k фрагментов"]
    style CL fill:#fee2e2,stroke:#DC2626
    style FA fill:#eef2ff,stroke:#4400FF
    style R fill:#ecfdf5,stroke:#059669

Обезличивание идёт первым

Это не последний шаг и не «когда-нибудь потом». До любой индексации из текста убираются идентифицирующие данные: имена, даты рождения, номера полисов, адреса, телефоны.


Чанкинг: размер имеет значение

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

ПараметрТипичное значениеЗачем
Размер чанка500–1000 символовБаланс смысла и точности поиска
Перекрытие10–20%Чтобы не терять контекст на границе
Метаданныеисточник, страницаДля цитат в отчёте

Метаданные важны не меньше текста: без указания источника и страницы цитата в отчёте будет непроверяемой.


Сборка индекса на Python

Учебный пример: разбиваем, считаем эмбеддинги, кладём в FAISS. Конкретная модель эмбеддингов и LLM выбирается под доступность; в открытом MedicalAgentX в демо использовались эмбеддинги OpenAI.

import faiss
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("intfloat/multilingual-e5-base")  # локально, без отправки данных

chunks = chunk_documents(deidentified_pdfs, size=800, overlap=120)
texts = [c.text for c in chunks]

vectors = model.encode(texts, normalize_embeddings=True)
index = faiss.IndexFlatIP(vectors.shape[1])  # косинусная близость
index.add(vectors)


def search(question: str, k: int = 5):
    qv = model.encode([question], normalize_embeddings=True)
    scores, ids = index.search(qv, k)
    return [chunks[i] for i in ids[0]]  # фрагменты с метаданными для цитат

Проверка качества поиска

  1. Соберите тестовые вопросы. Несколько вопросов, на которые вы точно знаете ответ из проиндексированных документов.

  2. Прогоните поиск. Убедитесь, что в top-k попадают именно релевантные фрагменты.

  3. Проверьте метаданные. У каждого фрагмента должны быть источник и страница для цитирования.


Что дальше

База готова. Следующий урок — как подключить реальный медицинский тул-сервер через MCP: md.2/03.

Скачать урок

Есть идея или нашли ошибку?

// Обсуждение

Можно писать анонимно. Укажите email, чтобы получать уведомления об ответах.