使用Langchain构建RAG应用 - II

使用 PDF 文档作为 RAG(检索增强生成)系统的知识源来构建专业知识问答系统是一个非常常见且有效的方案。这种方法在多个领域广泛应用,特别是在需要处理大量结构化文档的专业领域。

实现步骤: a. PDF 文本提取:使用工具如 PyPDF2 或 pdfminer 提取文本。 b. 文本处理:清理和格式化提取的文本。 c. 分块:将长文本分割成适合嵌入的小块。 d. 嵌入生成:使用嵌入模型(如 OpenAI 或 Hugging Face 模型)生成向量表示。 e. 向量存储:使用 FAISS、Pinecone 等存储向量。 f. 检索系统:实现相似性搜索来检索相关信息。 g. 问答生成:结合检索结果和 LLM 生成答案。

实验

本节我们将使用LangChain + FAISS + PDF来构建知识问答系统。

下载pdf到本地目录:

wget https://pingfan.s3.amazonaws.com/files/rag-books.pdf

python代码如下:

from langchain_aws import BedrockLLM as Bedrock
from langchain_aws import BedrockEmbeddings
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
import boto3

AWS_REGION = "us-west-2"

bedrock = boto3.client(service_name="bedrock-runtime", region_name=AWS_REGION)

model = Bedrock(model_id="amazon.titan-text-express-v1", client=bedrock)

bedrock_embeddings = BedrockEmbeddings(
    model_id="amazon.titan-embed-text-v1", client=bedrock
)

question = "What themes does Gone with the Wind explore?"

# data ingestion
loader = PyPDFLoader("rag-books.pdf")
splitter = RecursiveCharacterTextSplitter(separators=[". \n"], chunk_size=200)
docs = loader.load()
splitted_docs = splitter.split_documents(docs)
print(splitted_docs)

# create vector store
vector_store = FAISS.from_documents(splitted_docs, bedrock_embeddings)

# create retriever
retriever = vector_store.as_retriever(
    search_kwargs={"k": 2}
)
results = retriever.invoke(question)


results_string = []
for result in results:
    results_string.append(result.page_content)

print(results_string)

# build template:
template = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "Answer the users question based on the following context: {context}",
        ),
        ("user", "{input}"),
    ]
)

chain = template.pipe(model)

response = chain.invoke({"input": question, "context": results_string})
print(response)

运行结果:

image-20241202091208995