llamaindex 集成查询引擎指南

集成查询引擎指南

概述

在构建检索增强生成(RAG)应用程序时,通常需要尝试不同的查询管道(例如,top-k 检索、关键词搜索、知识图谱)。如果我们能够同时尝试多种策略,并让语言模型(LLM)评估每个查询的相关性并综合结果,那将会非常有用。

本指南展示了如何在《了不起的盖茨比》上进行集成检索。我们通过不同的分块大小和不同的索引进行集成检索。

安装依赖

首先,我们需要安装必要的库:

%pip install llama-index-llms-openai
!pip install llama-index
设置

在 Jupyter Notebook 中,我们需要应用 nest_asyncio 以允许嵌套的异步查询:

import nest_asyncio
nest_asyncio.apply()
下载数据

下载《了不起的盖茨比》的全文:

!wget 'https://raw.githubusercontent.com/jerryjliu/llama_index/main/examples/gatsby/gatsby_full.txt' -O 'gatsby_full.txt'
加载数据

我们将文档转换为节点,并插入到文档存储中:

from llama_index.core import SimpleDirectoryReader

documents = SimpleDirectoryReader(
    input_files=["./gatsby_full.txt"]
).load_data()
定义查询引擎

初始化设置(设置分块大小):

from llama_index.llms.openai import OpenAI
from llama_index.core import Settings

Settings.llm = OpenAI(model="gpt-3.5-turbo")
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 SimpleKeywordTableIndex, VectorStoreIndex

keyword_index = SimpleKeywordTableIndex(
    nodes,
    storage_context=storage_context,
    show_progress=True,
)
vector_index = VectorStoreIndex(
    nodes,
    storage_context=storage_context,
    show_progress=True,
)

定义查询模板:

from llama_index.core import PromptTemplate

QA_PROMPT_TMPL = (
    "Context information is below.\n"
    "---------------------\n"
    "{context_str}\n"
    "---------------------\n"
    "Given the context information and not prior knowledge, "
    "answer the question. If the answer is not in the context, inform "
    "the user that you can't answer the question - DO NOT MAKE UP AN ANSWER.\n"
    "In addition to returning the answer, also return a relevance score as to "
    "how relevant the answer is to the question. "
    "Question: {query_str}\n"
    "Answer (including relevance score): "
)
QA_PROMPT = PromptTemplate(QA_PROMPT_TMPL)

初始化关键词查询引擎和向量查询引擎:

keyword_query_engine = keyword_index.as_query_engine(
    text_qa_template=QA_PROMPT
)
vector_query_engine = vector_index.as_query_engine(text_qa_template=QA_PROMPT)

测试查询引擎:

response = vector_query_engine.query(
    "Describe and summarize the interactions between Gatsby and Daisy"
)
print(response)

response = keyword_query_engine.query(
    "Describe and summarize the interactions between Gatsby and Daisy"
)
print(response)
定义路由器查询引擎

初始化查询引擎工具:

from llama_index.core.tools import QueryEngineTool

keyword_tool = QueryEngineTool.from_defaults(
    query_engine=keyword_query_engine,
    description="Useful for answering questions about this essay",
)
vector_tool = QueryEngineTool.from_defaults(
    query_engine=vector_query_engine,
    description="Useful for answering questions about this essay",
)

初始化路由器查询引擎:

from llama_index.core.query_engine import RouterQueryEngine
from llama_index.core.selectors import LLMSingleSelector, LLMMultiSelector
from llama_index.core.selectors import (
    PydanticMultiSelector,
    PydanticSingleSelector,
)
from llama_index.core.response_synthesizers import TreeSummarize

TREE_SUMMARIZE_PROMPT_TMPL = (
    "Context information from multiple sources is below. Each source may or"
    " may not have \na relevance score attached to"
    " it.\n---------------------\n{context_str}\n---------------------\nGiven"
    " the information from multiple sources and their associated relevance"
    " scores (if provided) and not prior knowledge, answer the question. If"
    " the answer is not in the context, inform the user that you can't answer"
    " the question.\nQuestion: {query_str}\nAnswer: "
)

tree_summarize = TreeSummarize(
    summary_template=PromptTemplate(TREE_SUMMARIZE_PROMPT_TMPL)
)

query_engine = RouterQueryEngine(
    selector=LLMMultiSelector.from_defaults(),
    query_engine_tools=[
        keyword_tool,
        vector_tool,
    ],
    summarizer=tree_summarize,
)
实验查询

使用异步查询进行实验:

response = await query_engine.aquery(
    "Describe and summarize the interactions between Gatsby and Daisy"
)
print(response)

response = await query_engine.aquery(
    "What part of his past is Gatsby trying to recapture?"
)
print(response)
拓展内容

集成查询引擎的优势:

  1. 多样性:通过集成多种查询策略,可以提高检索结果的多样性和全面性。
  2. 鲁棒性:不同的查询策略可能在不同的场景下表现更好,集成查询引擎可以提高系统的鲁棒性。
  3. 自动化评估:通过 LLM 自动评估查询结果的相关性,可以减少人工干预,提高效率。

实际应用场景:

  1. 问答系统:在问答系统中,集成查询引擎可以提供更准确和全面的答案。
  2. 信息检索:在信息检索系统中,集成查询引擎可以提高检索结果的质量。
  3. 知识图谱:在知识图谱中,集成查询引擎可以提供更丰富的知识关联和推理。

通过这些详细的讲解和示例,学生们可以更好地理解和掌握集成查询引擎的定义与实现方法,从而在实际项目中高效地应用。

<think>我们正在回答用户的问题:如何使用LlamaIndex查询MySQL数据库,并给出具体示例。 根据引用[2]和引用[4],我们知道LlamaIndex提供了DatabaseReader来读取数据库数据,并且可以结合MySQL数据库实现RAG系统。 步骤: 1. 安装必要的库:llama-index,mysql-connector-python,sqlalchemy 2. 创建数据库连接 3. 使用DatabaseReader读取数据库表 4. 构建索引 5. 查询引擎进行查询 注意:引用[1]和引用[3]提到了路由查询引擎和SQLAutoVectorQueryEngine,但用户当前问题只需要查询MySQL数据库(即结构化数据),所以我们先给出基本的结构化数据查询示例。 示例代码:</think>### LlamaIndex 查询 MySQL 数据库完整指南 LlamaIndex 通过 **SQLDatabase 工具** 和 **DatabaseReader 模块** 实现 MySQL 数据库的查询,以下是详细实现步骤: --- #### 1. 环境准备 ```python # 安装核心依赖 !pip install llama-index sqlalchemy pymysql # 导入关键模块 from llama_index.core import SQLDatabase, VectorStoreIndex from llama_index.core.query_engine import NLSQLTableQueryEngine from sqlalchemy import create_engine ``` --- #### 2. 建立 MySQL 连接 ```python # 创建数据库引擎(替换实际参数) db_engine = create_engine( "mysql+pymysql://<user>:<password>@<host>:<port>/<database>" ) # 初始化SQLDatabase对象 sql_database = SQLDatabase( db_engine, include_tables=["products", "customers"] # 指定查询的表 ) ``` --- #### 3. 基础 SQL 查询 ```python # 创建自然语言转SQL的查询引擎 query_engine = NLSQLTableQueryEngine( sql_database=sql_database, tables=["products"] # 指定查询表 ) # 执行自然语言查询 response = query_engine.query( "2023年销售额超过10万元的产品有哪些?" ) print(response.metadata["sql_query"]) # 查看生成的SQL语句 print(response) # 查看查询结果 ``` **输出示例**: ``` 生成的SQL: SELECT * FROM products WHERE sales > 100000 AND year = 2023 结果: [{'product_id': 'P1001', 'name': '高端路由器', 'sales': 125000}, {'product_id': 'P1005', 'name': '智能手表', 'sales': 142000}] ``` --- #### 4. 高级混合查询(SQL + 向量) 结合结构化数据和非结构化文档(引用[3][4]): ```python from llama_index.core.query_engine import SQLAutoVectorQueryEngine # 创建混合查询引擎 hybrid_engine = SQLAutoVectorQueryEngine( sql_database=sql_database, vector_store=vector_index, # 已构建的向量索引 table_context={ "products": "包含产品ID、名称、销售额等字段", "manual": "产品技术手册文档" } ) # 执行跨模态查询 response = hybrid_engine.query( "找出销售额最高的产品,并列出其技术手册中的关键参数" ) ``` 该引擎自动执行流程: 1. 用 SQL 查询 `products` 表获取产品ID 2. 用向量检索在 `manual` 文档中匹配技术参数 3. 组合结果生成最终回复 --- #### 5. 网页集成示例(引用[5]) 结合 Chainlit 构建交互界面: ```python import chainlit as cl from llama_index.core import SQLDatabase @cl.on_message async def main(message: str): # 初始化数据库连接 sql_db = SQLDatabase.from_uri("mysql://user:pass@localhost/db") # 执行查询 query_engine = NLSQLTableQueryEngine(sql_db) response = query_engine.query(message) # 返回结果 await cl.Message( content=f"SQL: {response.metadata['sql_query']}\n结果: {response}" ).send() ``` --- ### 关键技术解析 | 功能 | 实现方式 | 适用场景 | |--------------------|----------------------------|-------------------------| | **基础查询** | `NLSQLTableQueryEngine` | 纯结构化数据查询 | | **混合查询** | `SQLAutoVectorQueryEngine` | SQL+文档联合查询[^3] | | **元数据过滤** | `include_tables`参数 | 限制可访问的表 | | **查询优化** | `table_context`字典 | 提升NL2SQL准确率 | | **结果后处理** | `response.metadata` | 获取生成的SQL语句 | > 注:实际部署时建议通过环境变量管理数据库凭证[^5] --- ### 常见问题解决方案 1. **中文查询异常** 在连接字符串中添加:`?charset=utf8mb4` ```python "mysql+pymysql://.../db?charset=utf8mb4" ``` 2. **权限控制** 通过 `include_tables` 限制可见表: ```python SQLDatabase(..., include_tables=["public_table"]) ``` 3. **复杂查询优化** 添加表描述提升NL2SQL准确性: ```python table_context = {"sales": "包含日期、产品ID、销售额等字段"} ``` --- ### 相关问题 1. 如何防止自然语言查询生成危险的 `DELETE` 或 `DROP` 语句? 2. 当表结构变更时,如何避免 LlamaIndex 的 SQL 查询引擎失效? 3. 在混合查询中,如何平衡 SQL 结果和向量检索结果的权重? 4. 如何处理需要多表 JOIN 的复杂自然语言查询? 5. 如何监控和优化 LlamaIndex 对 MySQL 的查询性能?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

需要重新演唱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值