Метаданные: контекст вокруг чанка
Чанк — это не только текст и вектор, но и паспорт: откуда он, когда и из какого раздела.
Метаданные чанка — структурированные поля рядом с текстом и вектором: источник, дата, автор, раздел, теги, права доступа.
Зачем они нужны
- Цитирование: ответ может сослаться на конкретный файл и страницу.
- Фильтрация: искать только в свежих документах или только в нужном разделе.
- Права доступа: не отдавать пользователю чанки, которые ему не положены.
- Отладка: видно, откуда пришёл плохой фрагмент.
Чанк как запись
В векторной БД одна запись — это вектор плюс полезная нагрузка (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 | права доступа, мультиарендность |
Итог
- Метаданные хранятся рядом с вектором и текстом чанка.
- Они дают цитирование, фильтрацию по свежести/разделу и контроль доступа.
- Фильтр по метаданным + векторный поиск = точнее и безопаснее выдача.