Filtrare pe metadate și auto-retrieval (VectorIndexAutoRetriever) în LlamaIndex & Data RAG

Restrângerea căutării vectoriale după metadate: manual, cu MetadataFilters, sau automat, cu VectorIndexAutoRetriever, unde un LLM deduce din întrebare textul de căutare și filtrele.

Sintaxă & invocare Python
from llama_index.core.retrievers import VectorIndexAutoRetriever
from llama_index.core.vector_stores import MetadataInfo, VectorStoreInfo

info = VectorStoreInfo(
    content_info="Rapoarte financiare și contracte de achiziții",
    metadata_info=[
        MetadataInfo(name="an", type="integer", description="Anul fiscal, de exemplu 2025"),
        MetadataInfo(name="departament", type="str", description="Unul dintre: IT, Marketing, Legal"),
    ],
)
retriever = VectorIndexAutoRetriever(index, vector_store_info=info)
noduri = retriever.retrieve("Cât s-a cheltuit pe licențe IT în 2025?")

O căutare vectorială simplă poate întoarce fragmente din alt an sau alt departament, pentru că textul lor seamănă cu întrebarea. Filtrele pe metadate restrâng căutarea la nodurile care respectă condițiile. Manual, le dai ca MetadataFilters: o listă de MetadataFilter(key=..., value=..., operator=...) combinată cu FilterCondition.AND, OR sau NOT, transmisă prin index.as_retriever(filters=...) sau as_query_engine(filters=...).

VectorIndexAutoRetriever face pasul automat: primește un VectorStoreInfo cu descrierea conținutului (content_info) și a fiecărei chei de metadate (MetadataInfo cu nume, tip și descriere), iar LLM-ul transformă întrebarea într-un text de căutare, filtre și, opțional, un top_k (limitat de max_top_k, implicit 10). Descrierile bune, cu valorile permise enumerate, sunt cele care ghidează modelul.

Operatorii disponibili (FilterOperator) sunt ==, !=, >, <, >=, <=, in, nin, any, all, text_match, contains, is_empty și alții, dar nu toate bazele vectoriale îi suportă pe toți: tabelul de integrări din documentație arată care bază are filtrare pe metadate. Filtrele se aplică în baza vectorială, deci tipul valorilor din metadate trebuie să corespundă (un an salvat ca text nu se compară cu >).

Concepte cheie și caracteristici

Concept / Parametru Descriere practică
MetadataFilters(filters=[...], condition=...) Filtrele și modul de combinare (and implicit, or, not).
MetadataFilter(key, value, operator) O condiție; operatorul implicit este ==.
VectorStoreInfo(content_info, metadata_info) Descrierea pentru LLM a conținutului și a cheilor de metadate.
MetadataInfo(name, type, description) O cheie de metadate; descrierea poate enumera valorile permise.
max_top_k Limita pentru top_k dedus de LLM. Implicit 10.
extra_filters Filtre fixe adăugate mereu peste cele deduse (de exemplu clientul curent).
llm / verbose LLM-ul care deduce filtrele; verbose=True afișează interogarea generată.

Exemple practice și scenarii reale

Exemplul 1: Filtre manuale

from llama_index.core.vector_stores import (
    FilterCondition, FilterOperator, MetadataFilter, MetadataFilters,
)

filtre = MetadataFilters(
    filters=[
        MetadataFilter(key="departament", value="IT"),
        MetadataFilter(key="an", value=2025, operator=FilterOperator.GTE),
    ],
    condition=FilterCondition.AND,
)
qe = index.as_query_engine(filters=filtre, similarity_top_k=5)

Exemplul 2: Auto-retrieval cu un filtru fix de securitate

retriever = VectorIndexAutoRetriever(
    index,
    vector_store_info=info,
    extra_filters=MetadataFilters(filters=[MetadataFilter(key="client_id", value="c-42")]),
    verbose=True,
)
noduri = retriever.retrieve("Contractele de marketing din 2025")

Greșeli frecvente și capcane

  • Descrieri vagi în MetadataInfo („departamentul”). Fără valorile permise și formatul lor, LLM-ul generează filtre care nu se potrivesc cu datele.
  • Să lași separarea pe clienți în seama auto-retrieval-ului. LLM-ul poate omite un filtru; restricțiile de acces se pun în extra_filters sau în filtre manuale.
  • Operatori nesuportați de baza vectorială aleasă. Verifică în tabelul de integrări și în documentația bazei.

Noțiuni și module înrudite