Integração com LlamaIndex
O Laya fornece componentes de decisão abaixo de 35 ms e não autorregressivos para pipelines RAG do
LlamaIndex, o RouterQueryEngine e a seleção de ferramentas (latência de pergunta única medida
em 32.8 ms com laya-multilingual e 39.5 ms com laya numa GPU Tesla T4; 193–464 ms em
CPU):
LayaSingleSelector: Seletor de escolha única abaixo de 35 ms que substitui oLLMSingleSelectorpara oRouterQueryEngine.LayaMultiSelector: Seletor de escolha múltipla que substitui oLLMMultiSelectorpara consultas compostas que abrangem várias fontes de dados.LayaQueryRouter: Despachante de consultas autónomo que encaminha os pedidos recebidos diretamente para os motores de consulta ou invocáveis alvo.
Suporta tanto inferência local em processo (Agent ou Router) como inferência HTTP remota
contra a tua própria instância laya-serve, sem exigir PyTorch em clientes de periferia.
Instalação
pip install "laya[llamaindex]"
1. Encaminhamento de escolha única com o RouterQueryEngine
No LlamaIndex, o RouterQueryEngine usa um seletor para decidir que motor de consulta ou ferramenta
subjacente deve responder a uma pergunta. Os seletores LLM autorregressivos (LLMSingleSelector)
levam 1,000–2,000 ms a gerar texto. O LayaSingleSelector avalia as ferramentas candidatas em
~33 ms sem geração de tokens:
from llama_index.core.query_engine import RouterQueryEngine
from llama_index.core.tools import QueryEngineTool, ToolMetadata
from laya.integrations.llamaindex import LayaSingleSelector
# Define query engine tools
docs_tool = QueryEngineTool(
query_engine=vector_index.as_query_engine(),
metadata=ToolMetadata(
name="vector_documentation",
description="Semantic search over technical user documentation and API guides.",
),
)
sql_tool = QueryEngineTool(
query_engine=sql_index.as_query_engine(),
metadata=ToolMetadata(
name="sql_database",
description="Structured SQL database containing customer accounts, billing, and orders.",
),
)
# Initialize Laya sub-35ms selector with confidence fallback
selector = LayaSingleSelector(
confidence_threshold=0.80, # If confidence < 0.80, fall back to index 0
fallback_index=0,
)
router_engine = RouterQueryEngine(
selector=selector,
query_engine_tools=[docs_tool, sql_tool],
)
response = router_engine.query("What is the shipping address for order #4912?")
print(response)
2. Seleção de escolha múltipla para consultas compostas
Para consultas que exigem síntese entre vários índices (por exemplo, comparar especificações de
documentação com registos de bases de dados transacionais), o LayaMultiSelector avalia a
relevância dos candidatos e devolve várias ferramentas selecionadas:
from laya.integrations.llamaindex import LayaMultiSelector
multi_selector = LayaMultiSelector(
probability_threshold=0.25, # Select all tools with probability >= 0.25
max_outputs=2,
)
tools = [docs_tool.metadata, sql_tool.metadata, summary_tool.metadata]
result = multi_selector.select(
tools,
"How does the database security policy compare with our published compliance guide?"
)
for sel in result.selections:
print(f"Tool: {tools[sel.index].name} | {sel.reason}")
3. Despacho direto de consultas com o LayaQueryRouter
Para encaminhamento direto sem a sobrecarga do RouterQueryEngine, o LayaQueryRouter encaminha as
consultas diretamente para motores registados num dicionário:
from laya.integrations.llamaindex import LayaQueryRouter
router = LayaQueryRouter(
query_engines={
"vector": vector_query_engine,
"sql": sql_query_engine,
"summary": summary_query_engine,
},
descriptions={
"vector": "Semantic search over product documentation and guides",
"sql": "Structured SQL queries for user accounts and transactions",
"summary": "Quarterly reports and high-level business summaries",
},
confidence_threshold=0.75,
fallback_key="vector",
)
# Route and execute in one call:
response = router.query("How many active subscriptions were renewed in Q3?")
print(response)
Ambos são suportados: o query() síncrono e o aquery() assíncrono.
4. Gating por limiar de confiança
Tal como a integração do Laya com o LangChain, o LayaSingleSelector e o LayaQueryRouter leem a
answer_confidence calibrada (max(p)):
- Fallback automático: Especifica
fallback_index(oufallback_key) para desviar sem falhas as consultas incertas para um motor predefinido seguro. - Guarda estrita: Define
raise_on_low_confidence=TruenoLayaSingleSelectorpara levantarLayaLowConfidenceErrorquando a entrada é ambígua, permitindo o escalonamento pelo autor da chamada.
5. Implementações HTTP remotas
Para RAG serverless, ambientes de periferia, ou ambientes sem GPUs locais:
from laya.integrations.llamaindex import LayaSingleSelector
selector = LayaSingleSelector(
base_url="http://laya-serve.internal:8080",
confidence_threshold=0.85,
fallback_index=0,
)
O cliente remoto usa a biblioteca padrão do Python urllib com zero dependências pesadas, evitando
o encaminhamento de credenciais entre origens e correspondendo à especificação /v1/systemone.
6. Controlos de decisão por chamada
LayaSingleSelector, LayaMultiSelector e LayaQueryRouter aceitam os mesmos argumentos por
chamada que a API core: os dois orçamentos de tokens (max_len, head_max_len), os controlos de idioma e abstenção (lang, min_confidence), e os cinco
argumentos de hook de predição (hooks, on_predict_start, on_predict_end, hooks_raise,
hooks_timeout). São por seletor, por isso um passo de encaminhamento largo pode receber espaço
enquanto o resto do pipeline mantém as predefinições do checkpoint.
As opções de uma pergunta choice partilham o orçamento de opções do checkpoint – head_max_len,
192 tokens no laya – e cada candidato contribui com o seu nome e descrição, por isso a partir de
cerca de 20 ferramentas as descrições começam a chegar ao modelo como o mesmo texto.
selector = LayaSingleSelector(
instructions="Which tool or query engine is best suited to answer this query?",
max_len=1024, # total window
head_max_len=512, # tokens shared by the option prompt
)
result = selector.select(tools, query) # tools: 59 descriptions
Medido no laya (Apple silicon, uma passagem direta por consulta, pontuado na ferramenta escolhida)
com um roster de 59 ferramentas construído a partir das etiquetas de intenção MASSIVE en e uma
utterance por etiqueta, para que a verdade de referência seja exata. Cada célula é quantas das 59
consultas chegaram à sua própria ferramenta; ambas as repetições deram a mesma contagem.
| Roster de 59 ferramentas | Orçamento predefinido | max_len=1024, head_max_len=384 |
…, head_max_len=512 |
|---|---|---|---|
| Consultas na sua própria ferramenta | 2/59 | 8/59 | 15/59 |
| Mediana de ms por consulta | 160 | 172 | 184 |
A precisão absoluta não é a alegação aqui: o checkpoint não é um classificador MASSIVE, e 59 etiquetas semelhantes são uma forma de stress. A alegação é a direção e o preço – um roster que o orçamento predefinido colapsa para quase nada é legível, e com este tamanho a janela custa pouco tempo. Com menos de cerca de 20 opções as etiquetas já cabem e alargar pode mover respostas na direção errada, e é por isso que ambos os argumentos são opt-in por seletor. Vê a integração com LangChain para esse precipício medido.
Os hooks correm apenas no caminho local. Um seletor com um base_url e hooks=[...] levanta
ValueError em vez de reportar um sucesso cuja cache nunca correu – um hook é um invocável Python
que corre dentro de predict, e nenhum formato wire o transporta. Instala os hooks no processo que
corre a inferência. Os dois orçamentos viajam até um nó remoto, no corpo do pedido, até ao seu teto
LAYA_MAX_TOKEN_BUDGET; um valor maior volta como um 422.
Idioma e abstenção
lang fixa o idioma em que a consulta é encaminhada e respondida – seleciona a calibração por idioma do checkpoint que responde em vez de depender da deteção integrada – e min_confidence é o gate de abstenção do core: uma decisão abaixo dele volta como uma abstenção em vez de uma seleção forçada. Ambos são lidos de igual forma por Agent.predict e Router.predict e aceites pelo laya-serve no corpo do pedido, por isso um seletor reencaminha-os tanto no caminho local como no remoto. O que não estiver definido é omitido, não enviado como None, para que não possa ofuscar a predefinição da própria implementação; min_confidence=0.0 e lang="" são valores reais e são reencaminhados tal como estão.
selector = LayaSingleSelector(
instructions="Which tool or query engine is best suited to answer this query?",
lang="de", # answer German queries in German
min_confidence=0.3, # abstain when no tool clears a 0.3 confidence
)