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
refinecusimilarity_top_kmare 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.responsela unStreamingResponseînainte să consumi generatorul.