queryEngine介绍

在 LlamaIndex 中,index.as_query_engine () 是连接 “索引(Index)” 与 “用户查询” 的核心方法 —— 它将构建好的索引(如 VectorStoreIndex TreeIndex)转换为 QueryEngine 对象,封装了 “检索相关文档片段→整合信息→调用大模型→生成回答” 的全流程,让开发者无需手动串联检索与生成逻辑,直接通过简单接口实现 “输入查询→输出答案” 的核心功能。

从索引构建查询引擎
首先,你需要构建一个索引。然后,你可以通过以下代码从索引构建一个查询引擎:

query_engine = index.as_query_engine()

在你的数据上提问
构建好查询引擎后,你可以通过以下代码在你的数据上提问:

response = query_engine.query("说了什么?")
 

具体案例

在大模型应用落地过程中,基于私有文档的智能问答是高频场景 —— 企业内部手册、行业报告、个人知识库等非公开文档无法直接被通用大模型检索,而 LlamaIndex(原 GPT Index)作为一站式的大模型应用开发框架,能完美衔接本地文档与大模型,结合阿里云千问系列模型,可快速搭建私有化的 PDF 文档问答系统。

一、核心技术栈解析

本文实现的 PDF 问答系统核心依赖以下技术组件,先理清各组件的定位:

组件 作用
LlamaIndex 核心框架,负责文档加载、切分、向量化、索引构建和查询调度
PyMuPDF (fitz) 高性能 PDF 解析库,精准提取 PDF 文本内容
千问文本嵌入模型(text-embedding-v2) 将文本转化为向量,实现语义层面的相似性检索
千问大模型(qwen-plus) 基于检索到的文档片段生成自然语言回答
python-dotenv 安全管理环境变量(如 API 密钥)

二、实现步骤:从 0 到 1 搭建 PDF 问答系统

2.1 环境准备

首先安装所需依赖包,建议在虚拟环境中执行:

# 核心依赖:LlamaIndex框架及阿里云千问适配插件
pip install llama-index llama-index-embeddings-dashscope llama-index-llms-dashscope
# 辅助依赖:PDF解析、环境变量管理、OpenAI兼容接口
pip install llama-index-llms-openai-like pymupdf python-dotenv

2.2 密钥配置

阿里云千问模型需通过 API 调用,需先在阿里云百炼控制台获取 API Key,创建.env文件存放密钥(避免硬编码):

env

DASHSCOPE_API_KEY=你的阿里云API密钥

2.3 完整代码实现

以下是可直接运行的核心代码,附带详细注释:

import os
from dotenv import load_dotenv
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core.node_parser import TokenTextSplitter
from llama_index.readers.file import PyMuPDFReader
from llama_index.embeddings.dashscope import DashScopeEmbedding
from llama_index.llms.openai_like import OpenAILike

# 1. 加载环境变量(安全读取API密钥)
load_dotenv()
api_key = os.getenv("DASHSCOPE_API_KEY")

# 2. 配置千问文本嵌入模型(文本向量化核心)
embed_model = DashScopeEmbedding(
    model_name="text-embedding-v2",  # 千问轻量嵌入模型,性价比高
    api_key=api_key,
    timeout=30  # 防止网络超时
)

# 3. 配置千问大语言模型(回答生成核心)
llm = OpenAILike(
    model="qwen-plus",  # 千问增强版,兼顾效果和速度
    api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",  # 阿里云兼容OpenAI的接口
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    is_chat_model=True  # 标记为对话型模型
)

# 4. 加载本地PDF文档
# 注意:提前在项目根目录创建data文件夹,放入待解析的PDF文件
documents = SimpleDirectoryReader(
    input_dir="./data",  # 文档存放目录
    required_exts=[".pdf"],  # 仅处理PDF文件
    file_extractor={".pdf": PyMuPDFReader()}  # 指定PDF解析器
).load_data()
print(f"成功加载 {len(documents)} 个PDF文档")

# 5. 文档切分(解决大模型上下文长度限制)
node_parser = TokenTextSplitter(
    chunk_size=300,    # 每个文本块300个token(适配千问上下文)
    chunk_overlap=50   # 块间重叠50个token,保证语义连贯
)
nodes = node_parser.get_nodes_from_documents(documents)
print(f"文档切分为 {len(nodes)} 个文本块")

# 6. 构建向量索引(核心:将文本块转化为向量并存储)
index = VectorStoreIndex(
    nodes,
    embed_model=embed_model,  # 使用千问嵌入模型
    show_progress=True        # 显示索引构建进度
)

# 7. 构建查询引擎(连接索引与大模型)
query_engine = index.as_query_engine(
    llm=llm,                  # 绑定千问大模型
    similarity_top_k=2,       # 返回最相似的2个文本块
    streaming=False           # 非流式输出(如需流式可改为True)
)

# 8. 执行查询(示例:查询文档中的"所获荣誉"相关内容)
query = "所获荣誉"
response = query_engine.query(query)

# 输出结果
print("===== 问答结果 =====")
print(f"问题:{query}")
print(f"回答:{response.response}")

# 输出参考文档片段(可验证回答来源)
print("\n===== 参考文档片段 =====")
for i, node in enumerate(response.source_nodes):
    print(f"【片段{i+1}】相似度:{node.score:.4f}")
    print(f"内容:{node.text[:200]}...")  # 仅展示前200字符

三、关键技术点详解

3.1 文档加载与切分

  • PDF 加载:通过PyMuPDFReader解析 PDF,相比原生解析器,PyMuPDF 支持复杂排版 PDF 的文本提取,且速度更快;
  • 文本切分TokenTextSplitter按 token 数切分而非字符数,更贴合大模型的上下文计算逻辑。chunk_size=300chunk_overlap=50是经验值 —— 过小会导致语义碎片化,过大则可能超出嵌入模型的输入限制,可根据文档类型调整。

3.2 向量索引构建

LlamaIndex 的VectorStoreIndex会将每个文本块通过千问嵌入模型转化为 768 维向量,然后构建向量索引。核心逻辑是:

  1. 接收用户查询→将查询语句向量化;
  2. 在向量库中检索相似度最高的文本块;
  3. 将检索结果作为上下文传给大模型生成回答。

3.3 千问模型适配

通过OpenAILike类适配阿里云千问模型,核心是api_base参数指定阿里云兼容 OpenAI 的接口地址,使得无需修改核心代码即可切换不同大模型(如切换为 GPT-3.5/4 仅需修改modelapi_base)。

四、运行与优化建议

4.1 运行步骤

  1. 在项目根目录创建data文件夹,放入待查询的 PDF 文件;
  2. 配置.env文件中的DASHSCOPE_API_KEY
  3. 运行代码,修改query变量即可查询不同问题。

4.2 优化方向

  1. 性能优化:默认向量索引是内存级的,可替换为FAISS/Milvus等向量数据库,支持海量文档;
  2. 效果优化
    • 调整chunk_size(如长文档可设为 500)和similarity_top_k(如设为 3-5);
    • 更换更强的嵌入模型(如text-embedding-v1)或大模型(如qwen-max);
  3. 功能扩展
    • 增加多格式支持(Word/Excel/Markdown),只需扩展file_extractor
    • 增加对话记忆,通过ChatEngine实现多轮对话;
    • 增加流式输出,将streaming=True并遍历response获取实时结果。

五、应用场景与价值

该方案可快速落地以下场景:

  • 企业知识库问答:员工查询内部制度、产品手册;
  • 学术研究辅助:检索论文 PDF 中的关键数据、结论;
  • 个人知识管理:对电子书、笔记 PDF 进行智能问答;
  • 客服系统:基于产品说明书自动回答用户问题。

总结

本文基于 LlamaIndex 框架结合阿里云千问大模型,实现了本地 PDF 文档的智能问答系统,核心关键点如下:

  1. LlamaIndex 简化了文档处理、向量化、索引构建的全流程,无需从零实现向量检索;
  2. 阿里云千问模型通过 OpenAI 兼容接口快速集成,兼顾私有化部署和模型效果;
  3. 文档切分的参数调优是影响问答效果的关键,需根据文档类型适配chunk_sizechunk_overlap

该方案兼具易用性和扩展性,开发者可基于此框架快速定制专属的文档问答系统,解决通用大模型无法访问私有文档的痛点。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐