Метаданные: контекст вокруг чанка

Чанк — это не только текст и вектор, но и паспорт: откуда он, когда и из какого раздела.

Метаданные чанка — структурированные поля рядом с текстом и вектором: источник, дата, автор, раздел, теги, права доступа.

Зачем они нужны

  • Цитирование: ответ может сослаться на конкретный файл и страницу.
  • Фильтрация: искать только в свежих документах или только в нужном разделе.
  • Права доступа: не отдавать пользователю чанки, которые ему не положены.
  • Отладка: видно, откуда пришёл плохой фрагмент.

Чанк как запись

В векторной БД одна запись — это вектор плюс полезная нагрузка (payload). Текст и метаданные хранятся рядом с эмбеддингом.

chunk = {
    "id": "doc42-3",
    "text": "Возврат товара возможен в течение 14 дней.",
    "vector": [0.01, -0.2, 0.7],  # в реальности сотни чисел
    "metadata": {
        "source": "policy.pdf",
        "page": 4,
        "section": "Возврат",
        "date": "2024-11-01",
    },
}
print("Чанк", chunk["id"], "из", chunk["metadata"]["source"],
      "стр.", chunk["metadata"]["page"])

Вывод:

Чанк doc42-3 из policy.pdf стр. 4

Фильтрация по метаданным руками

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

chunks = [
    {"text": "Старый регламент возврата", "date": "2021-01-01"},
    {"text": "Новый регламент возврата",  "date": "2024-11-01"},
    {"text": "Архивная инструкция",       "date": "2019-05-01"},
]

def only_recent(items, after="2023-01-01"):
    return [c for c in items if c["date"] > after]

for c in only_recent(chunks):
    print(c["date"], c["text"])

Вывод:

2024-11-01 Новый регламент возврата

Так можно гарантировать, что модель не процитирует устаревший документ. Реальные векторные БД (Qdrant, Pinecone) делают такую фильтрацию прямо в запросе поиска, не вытаскивая всё в память.

Тонкость: pre-filter и post-filter

Есть два способа совмещать фильтр и векторный поиск, и разница важна. Post-filter: сначала найти top-k по вектору, потом выкинуть неподходящие по метаданным. Беда в том, что после отсева может остаться слишком мало результатов — иногда вообще ноль, если все ближайшие не прошли фильтр. Pre-filter: сначала отобрать кандидатов по метаданным, и только среди них искать ближайших. Это надёжнее по полноте, но требует от базы поддержки фильтруемого индекса. Хорошие векторные БД делают pre-filter эффективно; если вы фильтруете руками после поиска, держите k с запасом, чтобы было из чего выбирать.

Что класть в метаданные

ПолеПольза
source / urlцитирование, доверие
dateфильтр по свежести
section / titleнавигация, контекст
access / tenantправа доступа, мультиарендность

Итог

  • Метаданные хранятся рядом с вектором и текстом чанка.
  • Они дают цитирование, фильтрацию по свежести/разделу и контроль доступа.
  • Фильтр по метаданным + векторный поиск = точнее и безопаснее выдача.
Проверьте себя
1. Что относится к метаданным чанка?
AТолько сам вектор
BИсточник, дата, раздел, права доступа рядом с текстом
CРазмер модели эмбеддингов
DСкорость поиска
2. Какую возможность напрямую дают метаданные о дате?
AУскоряют эмбеддинг
BПозволяют фильтровать выдачу и не цитировать устаревшие документы
CУменьшают размерность
DШифруют чанк
3. Зачем в метаданные кладут поле source/url?
AДля красоты
BЧтобы ответ мог сослаться на конкретный источник (цитирование)
CЧтобы ускорить ANN
DЧтобы увеличить размер вектора
Поддержать проект