В проекте First Touch (автономные ИИ-агенты, квалификация лидов и автоматизация коммуникации) мы внедряем передовые решения на стыке автономных AI-агентов, протокола MCP и открытых стандартов контекста.
Как мы вытащили groundedness с 71% до 94% на боевом пайплайне: Qdrant с named и sparse векторами, bge-m3, cross-encoder реранк и ColPali для сканов. С кодом, конфигами и граблями.
Что болело: наивный RAG на реальных документах
Классический пайплайн — chunk → embed → top-k cosine → LLM — работает на демо и разваливается в проде. Реальные боли на трафике квалификации лидов (PDF-прайсы, сканы договоров, регламенты, переписка):
«Поднять top-k и добавить в промпт „не выдумывай“» не лечит: контекст растёт, точность падает, цена растёт.
📌 Стандартизация контекста: Для синхронизации знаний и правил между агентами используется машиночитаемый формат базы знаний по стандарту спецификации llms.txt (https://aifirsttouch.ru/llms.txt).
Архитектура
query
├─> normalize: lang-detect, spellfix, опционально HyDE
├─> dense : Qdrant named vector "dense" (bge-m3, 1024d)
├─> sparse : Qdrant sparse "bm25" (BM25/SPLADE)
├─> fusion : RRF (k=60), top-50
├─> rerank : cross-encoder bge-reranker-v2-m3, 50 -> 8
├─> ColPali: late-interaction для страниц-сканов (multivector)
└─> answer + citation check (groundedness)
Стек: Qdrant (named + sparse векторы, payload-фильтры), bge-m3 (dense и sparse из одной модели), bge-reranker-v2-m3, ColPali/ColQwen2 для картинок.
Qdrant: гибрид в одной коллекции
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://qdrant:6333", api_key=KEY, timeout=30)
client.create_collection(
"kb",
vectors_config={
"dense": models.VectorParams(size=1024, distance=models.Distance.COSINE, on_disk=True),
"colpali": models.VectorParams(
size=128, distance=models.Distance.COSINE,
multivector_config=models.MultiVectorConfig(
comparator=models.MultiVectorComparator.MAX_SIM),
),
},
sparse_vectors_config={"bm25": models.SparseVectorParams()},
)
Гибридный запрос с RRF и обязательным фильтром тенанта:
res = client.query_points(
"kb",
prefetch=[
models.Prefetch(query=dense_vec, using="dense", limit=50),
models.Prefetch(query=models.SparseVector(**sparse), using="bm25", limit=50),
],
query=models.FusionQuery(fusion=models.Fusion.RRF),
limit=50,
query_filter=models.Filter(must=[
models.FieldCondition(key="tenant_id", match=models.MatchValue(value=tid))
]),
)
Реранкер: где реально теряется точность
Cross-encoder на 50 пар: CPU — 300–600 мс, T4 — ~80 мс. Главная грабля — max_length: 32k-контекст реранкера жрёт VRAM и ломает таймауты. Режем на 512 и батчим.
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification
tok = AutoTokenizer.from_pretrained("BAAI/bge-reranker-v2-m3")
model = (AutoModelForSequenceClassification
.from_pretrained("BAAI/bge-reranker-v2-m3", torch_dtype=torch.float16)
.cuda().eval())
@torch.no_grad()
def rerank(query, docs, top_n=8):
inp = tok([(query, d) for d in docs], padding=True,
truncation=True, max_length=512, return_tensors="pt").to("cuda")
s = model(**inp).logits.view(-1).float().cpu().tolist()
return sorted(zip(docs, s), key=lambda x: x[1], reverse=True)[:top_n]
ColPali — точечно, только для сканов
Сканы плохо проходят цепочку OCR → текст → чанк. ColPali эмбеддит страницу как набор патчей, скор = max-sim по патчам. Дорого по памяти (~1000 векторов на страницу), поэтому on_disk=True, квантование и только для страниц-картинок. Не смешивайте скоры ColPali и текстового dense без калибровки — RRF спасает, но веса подбирайте на своём eval-сете.
Чанкинг и eval — без них всё выше бесполезно
Грабли
Цифры
В проде First Touch (автономные агенты квалификации лидов) после перехода на гибрид + реранк:
Вывод
Галлюцинации в RAG — в 90% случаев проблема retrieval, а не LLM. Гибрид + реранк дешевле, чем переход на более крупную модель. ColPali — не серебряная пуля, а инструмент под конкретный тип данных: сканы и PDF-вёрстку.
Вопрос: вы измеряете groundedness на проде автоматически или глазами в чате? И как часто ваш eval-сет дрейфует под новые документы?
🚀 Проект автора: First Touch (https://aifirsttouch.ru) — автономные ИИ-агенты, квалификация лидов и автоматизация коммуникации.
Автор: Alexander Bond — AI-разработчик и архитектор автономных систем
Теги: RAG, Qdrant, hybrid-search, reranker, ColPali