langchain实现simple RAG

news/2025/3/22 23:17:59/文章来源:https://www.cnblogs.com/idazhi/p/18787304

RAG

前提准备:

  • 配置ollama环境并下载模型

知识点总结:

  • 解析PDF并提取文本,然后可以查询该存储的关键信息。

安装环境依赖

pypdf
faiss-gpu # GPU 环境下可以安装 faiss-cpu-1.10.0
langchain
langchain_community
tiktoken
langchain-openai
langchainhub

导入库

import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.getcwd(), '..'))) 
# Add the parent directory to the path since we work with notebooks
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

PDF文本去噪

def replace_t_with_space(list_of_documents):for doc in list_of_documents:doc.page_content = doc.page_content.replace('\t', ' ') # Replace tabs with spacesreturn list_of_documents

embedding

from enum import Enum
# Enum class representing different embedding providers
class EmbeddingProvider(Enum):OPENAI = "openai"COHERE = "cohere"AMAZON_BEDROCK = "bedrock"OLLAMA = "ollama"
def get_langchain_embedding_provider(provider: EmbeddingProvider, model_id: str = None):if provider == EmbeddingProvider.OPENAI:from langchain_openai import OpenAIEmbeddingsreturn OpenAIEmbeddings()elif provider == EmbeddingProvider.COHERE:from langchain_cohere import CohereEmbeddingsreturn CohereEmbeddings()elif provider == EmbeddingProvider.OLLAMA:from langchain_community.embeddings import OllamaEmbeddingsreturn OllamaEmbeddings(base_url="http://127.0.0.1:11434", model="smartwang/bge-large-zh-v1.5-f32.gguf")elif provider == EmbeddingProvider.AMAZON_BEDROCK:from langchain_community.embeddings import BedrockEmbeddingsreturn BedrockEmbeddings(model_id=model_id) if model_id else BedrockEmbeddings(model_id="amazon.titan-embed-text-v2:0")else:raise ValueError(f"Unsupported embedding provider: {provider}")

PDF解析并构建知识库

from langchain_community.vectorstores import FAISS
def encode_pdf(path, chunk_size=1000, chunk_overlap=200):# Load PDF documentsloader = PyPDFLoader(path)documents = loader.load()# Split documents into chunkstext_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap, length_function=len)texts = text_splitter.split_documents(documents)cleaned_texts = replace_t_with_space(texts)# Create embeddings (Tested with OLLAMA、OpenAI and Amazon Bedrock)embeddings = get_langchain_embedding_provider(EmbeddingProvider.OLLAMA)#embeddings = get_langchain_embedding_provider(EmbeddingProvider.OPENAI)#embeddings = get_langchain_embedding_provider(EmbeddingProvider.AMAZON_BEDROCK)# Create vector storevectorstore = FAISS.from_documents(cleaned_texts, embeddings)return vectorstore
path = "data/rag.pdf"
chunks_vector_store = encode_pdf(path, chunk_size=1000, chunk_overlap=200)

Retriever构建

chunks_query_retriever = chunks_vector_store.as_retriever(search_kwargs={"k":2})

知识库检索

def retrieve_context_per_question(question, chunks_query_retriever):docs = chunks_query_retriever.get_relevant_documents(question)# Concatenate document content# context = " ".join(doc.page_content for doc in docs)context = [doc.page_content for doc in docs]return context
调用
test_query = "介绍一下OpenAI"
context = retrieve_context_per_question(test_query, chunks_query_retriever)
# 展示检索结果
def show_context(context):for i, c in enumerate(context):print(f"Context {i + 1}:")print(c)print("\n")
show_context(context)

LLMsProvider定义

from enum import Enum
# Enum class representing different LLMs providers
class LLMsProvider(Enum):OPENAI = "openai"OLLAMA = "ollama"
def get_langchain_llms_provider(provider: LLMsProvider, model_id: str = None):if provider == LLMsProvider.OPENAI:from langchain_openai import ChatOpenAIimport osfrom dotenv import load_dotenv# Load environment variables from a .env fileload_dotenv()# Set the OpenAI API key environment variable (comment out if not using OpenAI)if not os.getenv('OPENAI_API_KEY'):os.environ["OPENAI_API_KEY"] = input("Please enter your OpenAI API key: ")else:os.environ["OPENAI_API_KEY"] = os.getenv('OPENAI_API_KEY')return ChatOpenAI(temperature=0, model_name="gpt-4-turbo-preview")elif provider == LLMsProvider.OLLAMA:from langchain_openai import ChatOpenAIreturn ChatOpenAI(api_key="token",base_url="http://127.0.0.1:11434/v1",model="qwen2.5:1.5b")else:raise ValueError(f"Unsupported LLMs provider: {provider}")

LLMs回复

from langchain_core.pydantic_v1 import BaseModel, Field
class QuestionAnswerFromContext(BaseModel):answer_based_on_content:str = Field(description="Generates an answer to a query based on a given context.")
def create_question_answer_from_context_chain(llm):# Initialize the ChatOpenAI model with specific parametersquestion_answer_from_context_llm = llm# Define the prompt template for chain-of-thought reasoningquestion_answer_prompt_template = """For the question below, provide a concise but suffice answer based ONLY on the provided context:{context}Question{question}"""# Create a PromptTemplate object with the specified template and input variablesquestion_answer_from_context_prompt = PromptTemplate(template=question_answer_prompt_template,input_variables=["context", "question"],)# Create a chain by combining the prompt template and the language modelquestion_answer_from_context_cot_chain = question_answer_from_context_prompt | question_answer_from_context_llm.with_structured_output(QuestionAnswerFromContext)return question_answer_from_context_cot_chain
# 大模型回复函数定义
from langchain_core.prompts import PromptTemplate
def answer_question_from_context(question, context, question_answer_from_context_chain):input_data = {"question": question,"context": context}print("Answering the question from the retrieved context...")output = question_answer_from_context_chain.invoke(input_data)answer = output.answer_based_on_contentreturn {"answer": answer, "context": context, "question": question}
大模型回复
# Initialize LLM
llm = get_langchain_llms_provider(LLMsProvider.OLLAMA)
question_answer_from_context_chain = create_question_answer_from_context_chain(llm)
#Note - this currently works with OPENAI only
print(answer_question_from_context(test_query, context, question_answer_from_context_chain))

问题一:

未能正确配置ollama

总结:

​ RAG通过检索外部知识源(如文档、数据库)并结合生成模型(如Transformer)来生成答案

​ RAG通过结合检索增强生成模块,显著提升了模型在知识密集型任务中的表现。

参考连接:https://articles.zsxq.com/id_xjev7q5fszae.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/903678.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

昆明理工大学最新《现代材料测试技术》复试真题及答案

-材料测试 昆工材料物理与化学、材料学、材料表征与分析、材料工程、F001现代材料测试技术、864材料科学基础、昆明理工大学材料调剂

RTT 全志D1s跑tina linux

刚毕业那会抽奖抽了一块RTT的D1S开发板,看了一下打印log就放下吃灰了。跑RT-thread的感觉折腾起来太麻烦了就让他吃灰了。最近手头有一块屏幕和一个2欧的小喇叭打算驱动一下。 正好这块板子也出来好多年了。玩一玩。首先我找到了百问网的哪吒开发板他也是D1S的,直接把他的SDK…

COMSOL 基础学习笔记

设置网格 软件通过计算网格顶点的数值,推算其他位置的数值。 行函数:移动的波。 二次行函数(除网格顶点外还计算两定点连线中心的值):网格最大长度 \(≤\frac{λ}{6}\) 一次行函数:网格最大长度 \(≤\frac{λ}{12}\) 修改方式:

NSSCTF ROUND#28 Ciallo~(∠・ω )⌒☆ WriteUp

WriteUp 题目信息 来源:NSSCTF 名称:ROUND#28 Ciallo~(∠・ω )⌒☆ 分类:Reverse 描述:无题目链接: https://www.nssctf.cn/contest/732/解题思路 首先使用DIE对文件进行查壳,发现这是一个无壳的64位exe文件。于是使用64位IDA对文件进行反汇编,得到伪代码如下:先一步步…

day35 nfs共享服务器的学习

day35 nfs共享服务器的学习 1.企业集群为什么要共享服务器 没有共享服务器先看一下没有共享服务器的问题 A用户上传啦图片到web01的服务器,然后B用户访问但是负载均衡服务器把请求分发到了web02的服务器上,导致B用户查看不了图片。配置啦共享服务器无论是用户把图片发送给web…

Nature Communications | 全基因组沉默子图谱揭示人类细胞基因调控新机制

摘要总结 这篇文章是2025年1月发表在《Nature Communications》杂志上的一篇研究,标题为“Uncovering the whole genome silencers of human cells via Ss-STARR-seq”。这篇文章通过开发一种名为Ss-STARR-seq的高通量筛选技术,首次在全基因组范围内系统性鉴定了人类细胞中的…

数据结构3

基本数据处理技术概率论与数理统计1-基本概念 概率论与数理统计2-基本数据结构 概率论与数理统计3-基本数据处理技术 基本的数据处理技术 查找 查找的基本概念 在哪里找:查找表是由同一类型的数据元素(或记录)构成的集合,集合中的数据元素之间关系松散。 按什么查找:根据给…

NSSCTF ROUND#28 动态调试 WriteUp

WriteUp 题目信息 来源:NSSCTF 名称:ROUND#28 动态调试 分类:Reverse 描述:无题目链接: https://www.nssctf.cn/contest/732/解题思路 首先使用DIE对文件进行查壳,发现这是一个无壳的32位ELF文件。于是使用32位IDA对文件进行反汇编,得到伪代码如下:为方便阅读伪代码,修…

Video Analysis Assignment

This scene is what the heroine saw from a begin sycarmore at the first time . It was this landscape that awake the heroine of her father’s word: “ A painting is more than the sum of its parts”. This scene is shot from the big sycarmore and it is a estab…

AI一键生成流程图架构图甘特图饼图等可视化图形 原创

AI脑图除了使用文字、语音、图片、文件、网页和视频等一键生成思维导图外,现在也可以支持一键生成流程图、架构图、甘特图等可视化图形了,使用非常简单,告诉AI脑图你想要生成什么图,大概不到两分钟就会制作好并以图片回复给你啦。 支持的可视化图形有: 流程图 例如向AI脑图…

Atcoder ABC398.F - ABCBA 题解 KMP的next函数

题目链接:https://atcoder.jp/contests/abc398/tasks/abc398_f 题目大意: 给你一个字符串 \(s\),要求在字符串 \(s\) 的末尾添加尽可能少的字符使其变成一个回文串。 解题思路: 首先,设输入的字符串为 \(s = s_1 s_2 \ldots s_n\),设字符串 \(s\) 翻转后的字符串为 \(s\)…

方法的定义和调用

//方法的应用 package Base; public class Demon16 { public static void main(String[] args) {// TODO Auto-generated method stubint max=max(10,10);System.out.println(max); } //比大小 public static int max(int num1,int num2) {int result=0;if(num1==num2) {System…