RouterQueryEngine și QueryEngineTool în LlamaIndex & Data RAG

Un query engine care folosește un LLM ca selector: citește descrierile motoarelor disponibile și trimite întrebarea la unul sau la mai multe dintre ele.

Sintaxă & invocare Python
from llama_index.core.query_engine import RouterQueryEngine
from llama_index.core.selectors import PydanticSingleSelector
from llama_index.core.tools import QueryEngineTool

tool_rezumat = QueryEngineTool.from_defaults(
    query_engine=summary_qe, description="Pentru rezumate ale întregului document.")
tool_detalii = QueryEngineTool.from_defaults(
    query_engine=vector_qe, description="Pentru întrebări punctuale și cifre exacte.")

router = RouterQueryEngine(
    selector=PydanticSingleSelector.from_defaults(),
    query_engine_tools=[tool_rezumat, tool_detalii],
)

Routerele primesc o întrebare și o listă de opțiuni descrise prin metadate și aleg una sau mai multe. Cazuri tipice din documentație: alegerea sursei de date potrivite, alegerea între rezumare (un SummaryIndex) și căutare semantică (un VectorStoreIndex), sau încercarea mai multor opțiuni cu combinarea rezultatelor. Fiecare motor se împachetează într-un QueryEngineTool cu o descriere; selectorul decide doar pe baza descrierilor.

Selectoarele vin în două forme: LLMSingleSelector / LLMMultiSelector pun opțiunile ca text în prompt și parsează răspunsul, iar PydanticSingleSelector / PydanticMultiSelector trimit opțiunile ca scheme la un API de function calling. Cu un selector multiplu, răspunsurile motoarelor alese sunt combinate de un sumarizator (implicit TreeSummarize). Rezultatul selecției se citește din raspuns.metadata["selector_result"].

Același mecanism există pentru retriever-i (RouterRetriever cu RetrieverTool), iar selectoarele se pot folosi și separat, cu selector.select(choices, query=...). Pentru întrebări care cer date din mai multe surse în același timp vezi SubQuestionQueryEngine; pentru decizii în mai mulți pași, cu unelte, vezi agenții.

Concepte cheie și caracteristici

Concept / Parametru Descriere practică
selector LLMSingleSelector, LLMMultiSelector, PydanticSingleSelector sau PydanticMultiSelector (din llama_index.core.selectors).
query_engine_tools Lista de QueryEngineTool.
QueryEngineTool.from_defaults(query_engine, name=, description=) Împachetează un motor; descrierea este textul pe care îl citește selectorul.
summarizer Cum se combină răspunsurile când sunt alese mai multe motoare. Implicit TreeSummarize.
llm LLM-ul pentru sumarizator; selectorul primește LLM-ul în from_defaults(llm=...).
verbose Afișează ce motor a fost ales.

Exemple practice și scenarii reale

Exemplul 1: Rutare între rezumat și detalii peste aceleași documente

from llama_index.core import SummaryIndex, VectorStoreIndex

summary_qe = SummaryIndex(nodes).as_query_engine(response_mode="tree_summarize")
vector_qe = VectorStoreIndex(nodes).as_query_engine()
# ... tool_rezumat, tool_detalii, router ca în sintaxă
raspuns = router.query("Despre ce este contractul?")
print(raspuns.metadata["selector_result"])

Exemplul 2: Selector folosit separat

from llama_index.core.selectors import LLMSingleSelector
from llama_index.core.tools import ToolMetadata

alegeri = [
    ToolMetadata(name="hr", description="Manualul angajatului"),
    ToolMetadata(name="it", description="Proceduri tehnice"),
]
rezultat = LLMSingleSelector.from_defaults().select(alegeri, query="Cum resetez parola VPN?")
print(rezultat.selections)

Greșeli frecvente și capcane

  • Descrieri care se suprapun („documente despre firmă” la două unelte). Selectorul nu vede conținutul motoarelor, doar descrierile.
  • Selector Pydantic cu un LLM fără function calling. Folosește atunci LLMSingleSelector.
  • Selector multiplu pentru întrebări simple. Fiecare motor ales face propriul apel LLM, plus sumarizarea finală.

Noțiuni și module înrudite