Motorul de interogare: index.as_query_engine() în LlamaIndex & Data RAG

Interogare & RAG Avansat Nivel: începător

Interfața de întrebare-răspuns peste un index: regăsește nodurile relevante, le trece prin postprocesoare și le dă unui response synthesizer care redactează răspunsul cu LLM-ul.

Sintaxă & invocare Python
query_engine = index.as_query_engine(
    similarity_top_k=5,
    response_mode="compact",
    streaming=True,
)
raspuns = query_engine.query("Cum se configurează autentificarea?")
raspuns.print_response_stream()

Un query engine primește o întrebare în limbaj natural și întoarce un Response. Intern, RetrieverQueryEngine face trei pași: retriever-ul aduce similarity_top_k noduri (implicit 2), node_postprocessors le filtrează sau reordonează (vezi reranking), iar response synthesizer-ul construiește răspunsul. index.as_query_engine(...) este API-ul de nivel înalt; pentru control complet compui manual VectorIndexRetriever, get_response_synthesizer() și RetrieverQueryEngine.

response_mode stabilește cum se combină fragmentele. compact (implicit) lipește cât mai multe fragmente într-un prompt și face mai puține apeluri decât refine. refine trece prin fiecare fragment și face câte un apel LLM pentru fiecare. tree_summarize rezumă recursiv, potrivit pentru rezumate. Mai există simple_summarize (trunchiază totul într-un singur prompt), accumulate, compact_accumulate și no_text (doar regăsire, fără apel la LLM).

Cu streaming=True, query() întoarce un StreamingResponse imediat ce pornește apelul LLM; tokenii se citesc din response_gen sau se afișează cu print_response_stream(). Când motorul face mai multe apeluri LLM, doar ultimul este transmis în streaming. Un query engine nu ține istoric; pentru conversații folosești chat engine-ul.

Concepte cheie și caracteristici

Concept / Parametru Descriere practică
similarity_top_k Câte noduri aduce retriever-ul. Implicit 2.
response_mode compact (implicit), refine, tree_summarize, simple_summarize, accumulate, compact_accumulate, no_text.
streaming Întoarce un StreamingResponse.
node_postprocessors Listă de postprocesoare aplicate între regăsire și sinteză.
llm LLM local în locul lui Settings.llm.
filters Filtre pe metadate (MetadataFilters), vezi filtrarea pe metadate.
text_qa_template / refine_template Prompturile folosite la sinteză.

Exemple practice și scenarii reale

Exemplul 1: Rezumat peste mai multe fragmente

qe = index.as_query_engine(similarity_top_k=10, response_mode="tree_summarize")
raspuns = qe.query("Rezumă principalele obligații ale furnizorului.")
print(raspuns.response)

Exemplul 2: Doar regăsire, fără apel la LLM

retriever = index.as_retriever(similarity_top_k=5)
for nod in retriever.retrieve("termen de livrare"):
    print(round(nod.score, 3), nod.node.get_content()[:80])

Exemplul 3: Compunere manuală (API de nivel jos)

După exemplul „Low-Level Composition API” din documentație.

from llama_index.core import get_response_synthesizer
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.retrievers import VectorIndexRetriever

retriever = VectorIndexRetriever(index=index, similarity_top_k=4)
synth = get_response_synthesizer(response_mode="refine")
qe = RetrieverQueryEngine(retriever=retriever, response_synthesizer=synth)

Greșeli frecvente și capcane

  • Să folosești refine cu similarity_top_k mare fără să numeri apelurile: face câte un apel LLM pentru fiecare fragment.
  • Să aștepți un istoric al conversației de la query(). Fiecare întrebare este independentă.
  • Să citești raspuns.response la un StreamingResponse înainte să consumi generatorul.

Noțiuni și module înrudite