路由查询引擎
概述
在本教程中,我们定义了一个自定义路由查询引擎,该引擎从多个候选查询引擎中选择一个来执行查询。
安装依赖
首先,我们需要安装 LlamaIndex:
%pip install llama-index-embeddings-openai
%pip install llama-index-llms-openai
!pip install llama-index
在 Jupyter Notebook 中,我们需要应用 nest_asyncio
以允许嵌套的异步查询:
import nest_asyncio
nest_asyncio.apply()
设置全局模型:
import os
os.environ["OPENAI_API_KEY"] = "sk-..."
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core import Settings
Settings.llm = OpenAI(model="gpt-3.5-turbo-1106", temperature=0.2)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
加载数据
将文档转换为节点,并插入到文档存储中:
from llama_index.core import SimpleDirectoryReader
# 加载文档
documents = SimpleDirectoryReader("../data/paul_graham").load_data()
from llama_index.core import Settings
# 初始化设置(设置分块大小)
Settings.chunk_size = 1024
nodes = Settings.node_parser.get_nodes_from_documents(documents)
from llama_index.core import StorageContext
# 初始化存储上下文(默认是内存中的)
storage_context = StorageContext.from_defaults()
storage_context.docstore.add_documents(nodes)
定义摘要索引和向量索引
在相同的文档存储上构建摘要索引和向量索引:
from llama_index.core import SummaryIndex
from llama_index.core import VectorStoreIndex
summary_index = SummaryIndex(nodes, storage_context=storage_context)
vector_index = VectorStoreIndex(nodes, storage_context=storage_context)
定义查询引擎和设置元数据
我们为每个索引定义一个查询引擎。然后使用 QueryEngineTool
包装这些查询引擎。
from llama_index.core.tools import QueryEngineTool
list_query_engine = summary_index.as_query_engine(
response_mode="tree_summarize",
use_async=True,
)
vector_query_engine = vector_index.as_query_engine()
list_tool = QueryEngineTool.from_defaults(
query_engine=list_query_engine,
description=(
"Useful for summarization questions related to Paul Graham eassy on"
" What I Worked On."
),
)
vector_tool = QueryEngineTool.from_defaults(
query_engine=vector_query_engine,
description=(
"Useful for retrieving specific context from Paul Graham essay on What"
" I Worked On."
),
)
定义路由查询引擎
有几种选择器可用,每种都有一些独特的属性。
LLM 选择器使用 LLM 输出一个解析的 JSON,并查询相应的索引。
Pydantic 选择器(目前仅支持 gpt-4-0613 和 gpt-3.5-turbo-0613(默认))使用 OpenAI 函数调用 API 生成/解析 pydantic 选择对象,而不是解析原始 JSON。
对于每种类型的选择器,还可以选择路由到一个索引或多个索引。
PydanticSingleSelector
使用 OpenAI 函数 API 生成/解析 pydantic 对象作为路由选择器。
from llama_index.core.query_engine import RouterQueryEngine
from llama_index.core.selectors import LLMSingleSelector, LLMMultiSelector
from llama_index.core.selectors import (
PydanticMultiSelector,
PydanticSingleSelector,
)
query_engine = RouterQueryEngine(
selector=PydanticSingleSelector.from_defaults(),
query_engine_tools=[
list_tool,
vector_tool,
],
)
response = query_engine.query("What is the summary of the document?")
print(str(response))
response = query_engine.query("What did Paul Graham do after RICS?")
print(str(response))
LLMSingleSelector
使用 OpenAI(或其他 LLM)解析生成的 JSON 以选择子索引进行路由。
query_engine = RouterQueryEngine(
selector=LLMSingleSelector.from_defaults(),
query_engine_tools=[
list_tool,
vector_tool,
],
)
response = query_engine.query("What is the summary of the document?")
print(str(response))
response = query_engine.query("What did Paul Graham do after RICS?")
print(str(response))
# [可选] 查看选择结果
print(str(response.metadata["selector_result"]))
PydanticMultiSelector
如果你期望查询路由到多个索引,应使用多选择器。多选择器将查询发送到多个子索引,然后使用摘要索引聚合所有响应以形成完整答案。
from llama_index.core import SimpleKeywordTableIndex
keyword_index = SimpleKeywordTableIndex(nodes, storage_context=storage_context)
keyword_tool = QueryEngineTool.from_defaults(
query_engine=vector_query_engine,
description=(
"Useful for retrieving specific context using keywords from Paul"
" Graham essay on What I Worked On."
),
)
query_engine = RouterQueryEngine(
selector=PydanticMultiSelector.from_defaults(),
query_engine_tools=[
list_tool,
vector_tool,
keyword_tool,
],
)
response = query_engine.query(
"What were noteable events and people from the authors time at Interleaf"
" and YC?"
)
print(str(response))
# [可选] 查看选择结果
print(str(response.metadata["selector_result"]))
拓展内容
路由查询引擎的优势:
- 灵活性:可以根据查询内容动态选择合适的查询引擎,提高查询效率和准确性。
- 扩展性:可以轻松添加新的查询引擎和工具,而无需修改现有代码。
- 性能优化:通过选择最合适的查询引擎,可以减少不必要的计算和资源消耗。
实际应用场景:
- 问答系统:在问答系统中,可以根据问题的类型选择不同的查询引擎,提高回答的准确性。
- 信息检索:在信息检索系统中,可以根据用户的查询内容选择合适的检索策略,提高检索结果的质量。
- 知识图谱:在知识图谱中,可以根据查询的复杂度选择不同的查询引擎,提高查询效率。
通过这些详细的讲解和示例,学生们可以更好地理解和掌握路由查询引擎的定义与实现方法,从而在实际项目中高效地应用。