随着人工智能技术的发展,结合检索增强生成(Retrieval-Augmented Generation, RAG)的问答系统在文档处理领域展现出强大的潜力。本系统基于‌LangChain框架‌与‌FaISS向量数据库‌,专注于实现对PDF文件的高效语义理解与智能问答,适用于企业文档管理、学术研究、法律咨询等场景。

核心组件与技术

  1. LangChain框架

    • 提供PDF解析、文本分块、嵌入生成与大模型交互的全流程支持,简化复杂任务编排。
    • 支持与多种大语言模型(如GPT、Llama等)无缝集成,用于答案生成与推理。
  2. FaISS向量数据库

    • 通过高效的相似性搜索,快速匹配用户问题与PDF文本片段。
    • 支持大规模嵌入向量的实时检索,保障系统响应速度。
  3. RAG架构

    • 检索(Retrieval)‌:利用FaISS检索与问题相关的PDF文本片段。
    • 生成(Generation)‌:基于检索结果,由大模型生成精准、上下文相关的答案。

系统流程

  1. 文档预处理‌:解析PDF文本,按语义分块并生成嵌入向量。
  2. 向量索引构建‌:将文本嵌入存储于FaISS,建立高效检索索引。

代码实现

导入包
import os

from dotenv import load_dotenv

from PyPDF2 import PdfReader

from langchain_community.embeddings import DashScopeEmbeddings

from langchain_community.vectorstores import FAISS

from langchain.text_splitter import RecursiveCharacterTextSplitter

from langchain_openai import ChatOpenAI

from langchain.chains.question_answering import load_qa_chain
一、读取pdf
# 读取pdf文件
pdf = PdfReader("C:/wwqqq.pdf")

# 解析pdf 获取文本和页码
def split_pdf(pdf) -> str:
    text = ""
    for page in pdf.pages:
        extract_text = page.extract_text()
        if extract_text:
            text += extract_text
    return text

text = split_pdf(pdf)
二、分词创建向量库
# 创建向量数据库
def create_vector_store(text: str,embedding=None) -> FAISS:
    print("开始创建向量数据库......................")
    # 进行分词
    text_splitter = RecursiveCharacterTextSplitter(
        separators=["\n\n", "\n", ".", " ", ""],
        chunk_size=1000, 
        chunk_overlap=200
    )
    # 创建embedding模型
    # embedding = OpenAIEmbeddings()
    if embedding is None:
        embedding = DashScopeEmbeddings(
            model = 'text-embedding-v1',
            dashscope_api_key = os.getenv('DASHSCOPE_API_KEY')
        )
    
    chunks = text_splitter.split_text(text)


    # 创建向量数据库
    vector_store = FAISS.from_texts(chunks, embedding)
    # 保存向量数据库
    vector_store.save_local("faiss_db")
    return vector_store
三、判断向量库
embedding = DashScopeEmbeddings(
    model = 'text-embedding-v1',
    dashscope_api_key = os.getenv('DASHSCOPE_API_KEY')
)

db_dir = "./faiss_db"

# 方法一
def is_db_exist(db_dir) -> FAISS:
    vector_store = None
    is_db_exist = os.path.exists(db_dir)
    if is_db_exist:
        vector_store = FAISS.load_local(
            db_dir, 
            embedding,
            allow_dangerous_deserialization=True
        )
    else:
        vector_store = create_vector_store(text,embedding)
    return vector_store
# 方法二
def is_db_exist_1(db_dir) -> FAISS:
    try:
        vector_store = FAISS.load_local(
            db_dir, 
            embedding,
            allow_dangerous_deserialization=True
        )
    except Exception as e:
        vector_store = create_vector_store(text,embedding)
    return vector_store

vector_store = is_db_exist_1(db_dir)
四、问题回答
def answer_question(query):
    if query:
        # 向量数据库检索文档
        docs = vector_store.similarity_search(query)

        # 创建模型
        llm = ChatOpenAI(
            model = 'gpt-3.5-turbo',
            api_key = os.getenv('OPENAI_API_KEY'),
            base_url = 'https://openai.itit.cc/v1'
        )

        # 创建chain
        chain = load_qa_chain(llm, chain_type="stuff")
        
        input = {"input_documents": docs, "question": query}

        # 执行问答链
        response = chain.invoke(input=input)
        print(response["output_text"])

answer_question("尼恩Java高并发三部曲是什么?列出对应的书籍名目")
五、运行结果

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐