LlamaIndex 통합
Laya는 LlamaIndex RAG 파이프라인, RouterQueryEngine, 도구 선택을 위한 35ms 미만의 비자기회귀 결정 컴포넌트를 제공합니다(단일 질문 지연 시간은 Tesla T4 GPU에서 laya-multilingual 기준 32.8 ms, laya 기준 39.5 ms로 측정되었으며, CPU에서는 193–464 ms입니다):
LayaSingleSelector:RouterQueryEngine에서LLMSingleSelector를 대체하는 35ms 미만의 단일 선택 선택기입니다.LayaMultiSelector: 여러 데이터 소스에 걸친 복합 질의에서LLMMultiSelector를 대체하는 다중 선택 선택기입니다.LayaQueryRouter: 들어오는 요청을 대상 쿼리 엔진이나 호출 가능 객체로 직접 보내는 독립형 쿼리 디스패처입니다.
로컬 인프로세스 추론(Agent 또는 Router)과 자체 laya-serve 인스턴스에 대한 원격 HTTP 추론을 모두 지원하므로, 엣지 클라이언트에 PyTorch가 필요하지 않습니다.
설치
pip install "laya[llamaindex]"
1. RouterQueryEngine을 사용한 단일 선택 라우팅
LlamaIndex에서 RouterQueryEngine은 선택기를 사용해 질문에 답할 하위 쿼리 엔진이나 도구를 정합니다. 자기회귀 LLM 선택기(LLMSingleSelector)는 텍스트를 생성하는 데 1,000–2,000 ms를 씁니다. LayaSingleSelector는 토큰 생성 없이 ~33 ms에 후보 도구를 평가합니다.
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. 복합 질의를 위한 다중 선택
여러 인덱스에 걸쳐 종합해야 하는 질의(예: 문서 명세와 트랜잭션 데이터베이스 기록 비교)에는 LayaMultiSelector가 후보 관련성을 평가하고 선택된 도구 여러 개를 반환합니다.
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. LayaQueryRouter를 사용한 직접 쿼리 디스패치
RouterQueryEngine의 오버헤드 없이 직접 라우팅하려면, LayaQueryRouter가 질의를 딕셔너리로 등록된 엔진으로 바로 보냅니다.
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)
동기 query()와 비동기 aquery()를 모두 지원합니다.
4. 신뢰도 임계값 게이팅
Laya의 LangChain 통합과 마찬가지로, LayaSingleSelector와 LayaQueryRouter는 캘리브레이션된 answer_confidence(max(p))를 읽습니다.
- 자동 폴백:
fallback_index(또는fallback_key)를 지정하면 불확실한 질의를 안전한 기본 엔진으로 매끄럽게 우회시킵니다. - 엄격 가드:
LayaSingleSelector에서raise_on_low_confidence=True로 설정하면 입력이 모호할 때LayaLowConfidenceError를 발생시켜 호출자가 에스컬레이션할 수 있습니다.
5. 원격 HTTP 배포
서버리스 RAG, 엣지 환경, 또는 로컬 GPU가 없는 환경을 위한 방법입니다.
from laya.integrations.llamaindex import LayaSingleSelector
selector = LayaSingleSelector(
base_url="http://laya-serve.internal:8080",
confidence_threshold=0.85,
fallback_index=0,
)
원격 클라이언트는 Python 표준 라이브러리 urllib를 사용하며 무거운 의존성이 없어, 교차 출처 자격 증명 전달을 막고 /v1/systemone 명세와 일치합니다.
6. 호출별 결정 제어
LayaSingleSelector, LayaMultiSelector, LayaQueryRouter는 코어 API와 동일한 호출별
인자를 받습니다. 두 토큰 예산(max_len, head_max_len), 언어 및 유보 제어(lang, min_confidence), 그리고 다섯 개의 예측 훅 인자(hooks,
on_predict_start, on_predict_end, hooks_raise, hooks_timeout)입니다. 이들은
선택기별이므로, 라우팅 단계가 넓은 곳에 여유를 주면서 파이프라인의 나머지는 체크포인트
기본값을 유지할 수 있습니다.
choice 질문의 옵션은 체크포인트의 옵션 예산, 즉 laya에서 192 토큰인 head_max_len을
공유하고, 모든 후보가 자기 이름과 설명을 기여하므로, 대략 20개 도구를 넘으면 설명들이
모델에 같은 텍스트로 도달하기 시작합니다.
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
laya로 측정했으며(Apple 실리콘, 질의당 순전파 한 번, 선택된 도구를 기준으로 채점),
MASSIVE en 인텐트 레이블로 구성한 59개 도구 명단에 레이블당 발화 하나를 사용했으므로
정답이 정확합니다. 각 셀은 59개 질의 중 자기 도구에 도달한 개수이며, 두 번 반복 모두 같은
수치를 보였습니다.
| 59개 도구 명단 | 기본 예산 | max_len=1024, head_max_len=384 |
…, head_max_len=512 |
|---|---|---|---|
| 자기 도구에 간 질의 | 2/59 | 8/59 | 15/59 |
| 질의당 중앙값 ms | 160 | 172 | 184 |
여기서 주장하는 것은 절대 정확도가 아닙니다. 이 체크포인트는 MASSIVE 분류기가 아니고, 비슷한 레이블 59개는 스트레스 형태입니다. 주장하는 것은 방향과 비용입니다. 기본 예산에서 거의 무너지는 명단이 읽히고, 이 규모에서는 창이 시간을 거의 쓰지 않습니다. 후보가 약 20개 미만이면 레이블이 이미 들어맞고 넓히면 답이 잘못된 방향으로 갈 수 있으므로, 두 인자 모두 선택기별 옵트인입니다. 그 측정된 절벽은 LangChain 통합을 참고하십시오.
훅은 로컬 경로에서만 실행됩니다. base_url과 hooks=[...]를 함께 둔 선택기는, 캐시가
한 번도 실행되지 않은 성공을 보고하는 대신 ValueError를 발생시킵니다. 훅은 predict
내부에서 실행되는 Python 호출 가능 객체이며, 어떤 전송 형식도 이를 실어 나르지 않습니다.
추론을 실행하는 프로세스에 훅을 설치하십시오. 두 예산은 요청 본문에 담겨 원격 노드까지
전달되며, 그 노드의 LAYA_MAX_TOKEN_BUDGET 상한까지 적용됩니다. 더 큰 값은 422로
돌아옵니다.
언어 및 유보
lang는 쿼리가 라우팅되고 답변되는 언어를 고정합니다. 내장 감지에 의존하는 대신 답변하는 체크포인트의 언어별 캘리브레이션을 선택합니다. min_confidence는 코어의 유보 게이트로, 그 아래의 결정은 강제된 선택이 아니라 유보로 돌아옵니다. 둘 다 Agent.predict와 Router.predict가 똑같이 읽고 laya-serve가 요청 본문에서 받아들이므로, 선택기는 로컬 경로와 원격 경로 모두에서 이들을 전달합니다. 설정되지 않은 값은 None으로 전송되지 않고 생략되므로 배포 자체의 기본값을 가릴 수 없습니다. min_confidence=0.0과 lang=""는 실제 값이며 그대로 전달됩니다.
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
)