首页 > 教程攻略 > ai资讯 >LangChain和qwen实现RAG增强检索

LangChain和qwen实现RAG增强检索

来源:互联网 时间:2026-08-01 14:12:08

LangChain和qwen实现RAG增强检索

先说说选型理由。这套教程的技术栈是 LangChain + 通义千问(Qwen),用的是通义千问提供的 API。为什么不选本地部署的开源模型?坦白讲,目前还处在探索 RAG 项目应用的阶段,本地电脑配置有限,跑小模型效果又不好。好在通义千问的 API 目前有免费额度,开箱即用,对于起步阶段来说,是个相当务实的选择。

在动手之前,我们先花几分钟搞清楚——RAG 到底是什么?

RAG,全称检索增强生成,是一种用外部数据来增强大语言模型能力的技术。它的核心思路是:当用户提出问题时,系统先从一个大型语料库中检索出相关信息,再把这些信息连同问题一起交给模型去生成答案。说白了,就是让模型“先查资料,再回答问题”。这样一来,回答的准确性和全面性都明显提升了一个台阶。

RAG 的工作流程,可以拆成下面这几个关键步骤:

1. 数据获取

:加载各种类型的数据,比如文本文件、PDF、网站数据、数据库,甚至接口 API 都行。

2. 数据预处理和清理

:不同格式的数据混杂在一起,必须先做清理,去掉那些无关紧要的部分。

3. 分块

:把大块的数据切成更小的片段。道理很简单,数据块太大,搜索起来又慢又不精准,而且大模型处理上下文的能力也有限,小块数据更合适。

4. 词嵌入

:分完块之后,要把文本转换成模型能理解的数字形式,也就是向量嵌入。

5. 向量数据库

:把这些向量数据存起来,方便后续进行大规模的相似性检索。

6. 检索相关内容

:根据用户提出的问题,先从向量数据库中找到最相似的内容片段。

7. LLM 生成

:把检索到的相关内容,连同用户的问题一起喂给大语言模型,让它生成更准确、更有针对性的回答。

准备工作

通义千问 API-KEY(必须):申请过程很简单,注册账号后完成认证就能开通,几分钟就能搞定。

LangChain 的安装

# pip安装
pip install langchain
# 如果你用的是Conda,也可以通过以下命令
# conda install langchain -c conda-forge

# pdf文档的读取和ocr识别
pip install pypdf rapidocr-onnxruntime

pip install --upgrade --quiet  dashscope

引入相关包

from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import DashScopeEmbeddings

from langchain_community.llms import Tongyi
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
import os

数据的准备

第一步,自然是先把 PDF 数据读出来,然后拆成小块。这里有几个关键参数需要注意:

chunk_size 设为 1000,意思每个片段长度控制在 1000 个字符左右。

chunk_overlap 设为 200,让前后片段之间有 200 个字符的重叠,可以保证上下文不丢得太厉害。

add_start_index 设置为 True,会在每个片段开头加上起始索引,方便定位。

pdf_loader = PyPDFLoader('test.pdf', extract_images=True)
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000, chunk_overlap=200, add_start_index=True
)
pages = pdf_loader.load_and_split()

词嵌入并保存到向量数据库

接下来,利用阿里灵积模型服务的文本嵌入模型,把刚才切好的小块数据向量化。做完这一步,可以先做一个简单的查询测试,返回两个最相似的数据块,确认一下效果。最后再把索引保存到向量数据库里,方便后续复用。

embeddings = DashScopeEmbeddings(
    model="text-embedding-v1", dashscope_api_key="你申请的千问API-KEY"
)

faiss_index = FAISS.from_documents(all_splits, embeddings)
# 搜索我们的文档数据,返回两个最相似的

docs = faiss_index.similarity_search("本季度排名第一的电视剧是啥?", k=2)

# 打印输入
for doc in docs:
    print(str(doc.metadata["page"]) + ":", doc.page_content[:300])

# 保存到向量数据库中
faiss_index.sa ve_local('testpdf.faiss')

调用大语言模型生成结果

数据库建好了,接下来把它加载回来,转换成 Retriever 类,方便后面用。然后配置好通义千问的大语言模型服务。

faiss_index = FAISS.load_local('testpdf.faiss', embeddings, allow_dangerous_deserialization=True)

retriever = faiss_index.as_retriever(search_kwargs={"k": 6})

os.environ["DASHSCOPE_API_KEY"] = "你申请的千问API-KEY"

llm = Tongyi()

开始构建模板

模板设计的核心思路是:把检索到的上下文和用户的问题拼在一起,交给模型。如果上下文里没有相关信息,就明确让它说“不知道”,不要瞎编。

template = """利用以下上下文回答最后的问题。如果不知道答案,就说不知道,不要试图编造答案。

{context}

Question: {question}

Helpful Answer:"""
custom_rag_prompt = PromptTemplate.from_template(template)

rag_chain = (
  {"context": retriever, "question": RunnablePassthrough()}
    | custom_rag_prompt
    | llm
    | StrOutputParser()
)

进行提问

rag_chain.invoke("本季度排名第一的电视剧是啥?")