基于langchain的简单RAG的实现

news2025/6/9 0:37:16

闲来无事,想研究一下RAG的实现流程,看网上用langchain的比较多,我自己在下面也跑了跑,代码很简单,以次博客记录一下,方便回顾

langchain

LangChain 是一个基于大型语言模型(LLM)开发应用程序的框架。LangChain 简化了LLM应用程序生命周期的每个阶段。

比如,在下面的实现中,LangChain可以将LLM提示词模板检索器组合在一起快速的完成检索增强整个流程,而不需要你去关心底层具体是怎么实现的。

代码demo

实现思路:

  1. 加载文档,并对文档进行切分
  2. 将切分后的文档转化为向量,存储到向量库中
  3. 根据用户query去向量库中检索,找到最相关的回复,并拼接到prompt中
  4. 根据最新的prompt调用大模型产生增强回复

加载文档 -> 切分文档 -> 创建向量数据库 -> 执行相似度搜索 -> 构建并增强 prompt -> 使用模型生成回答

import os
from openai import OpenAI
import requests
from langchain.text_splitter import CharacterTextSplitter
from weaviate.embedded import EmbeddedOptions
from langchain.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnablePassthrough
from langchain.schema.output_parser import StrOutputParser

from langchain_community.document_loaders import TextLoader
from langchain_community.chat_models import ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.schema import Document
from langchain_core.messages import HumanMessage, SystemMessage


"""
实现一
"""
def method_one(vectorstore,llm,query):

    # 根据用户query进行检索,并将检索结果拼接到prompt中
    def augment_prompt(query: str):

        # 获取top2的文本片段
        results = vectorstore.similarity_search(query, k=1)
        source_knowledge = "\n\n".join([x.page_content for x in results])

        # 构建prompt
        augmented_prompt = f"""你叫david,你需要解答xxx问题

        ###参考样例###
        {source_knowledge}
        """
        return augmented_prompt

    prompt=augment_prompt(query)
    print(prompt)

    # 封装输入
    messages = [
        SystemMessage(content=prompt),
        HumanMessage(content=query),
    ]

    # 生成检索增强回复
    res = llm.invoke(messages)

    return res.content


"""
实现二
"""
def method_two(vectorstore,llm,query):
    
    # 将 vectorstore 转换为一个检索器
    retriever = vectorstore.as_retriever()

    # 定义提示模板
    template = """你叫david,你需要解答xxx问题

    ###参考样例###
    {context}

    ###用户问题###
    {question}
    """

    prompt = ChatPromptTemplate.from_template(template)

    print(prompt)

    # LangChain 提供了一个高度模块化和可组合的框架就是链,使得你可以根据任务的特性自定义每个组件,并将它们按需组合成执行流程
    # 定义一个执行流程链,包含如下组件
    # {"context": retriever,  "question": RunnablePassthrough()}:用来将上下文(通过检索器获得)和用户问题传递给后续组件
    # prompt里面的占位符与上述定义的context和question是要保持一致的
    # StrOutputParser():该组件用于解析模型的输出,将其转换为字符串格式
    rag_chain = (
        {"context": retriever,  "question": RunnablePassthrough()}
        | prompt
        | llm
        | StrOutputParser()
    )

    response = rag_chain.invoke(query)

    return response



if __name__=="__main__":

    # 加载单个文档,这里只需要匹配单个文档里面的片段
    path="../rag/faq.txt"
    loader = TextLoader(path)
    documents = loader.load()

    # 如果需要加载多个文档,将上述path改为跟路径即可,然后通过下述两行代码对多个文档进行切分
    # text_splitter = CharacterTextSplitter()
    # doc = text_splitter.split_documents(documents)

    # 切分文档,给定的文档内容主要是通过换行符分隔的
    text = documents[0].page_content
    chunks = [Document(page_content=chunk) for chunk in text.split("\n\n\n") if chunk.strip()]

    #  将文档片段转化为向量,并存储到 
    # Chroma 是一个 开源的向量数据库,用于存储和检索向量嵌入
    model_name = "../model/bge-base-zh-v1.5"
    embedding = HuggingFaceEmbeddings(model_name=model_name)
    vectorstore_hf = Chroma.from_documents(documents=chunks, embedding=embedding , collection_name="huggingface_embed")
    vectorstore = Chroma.from_documents(chunks, embedding)

    # 初始化对话模型
    llm = ChatOpenAI(
        openai_api_key="",
        openai_api_base="",
        model='qwen-max'
    )
    
    # 用户query
    query = "今天天气如何?"

    # 检索增强之后的回答
    enhanced_result=method_one(vectorstore,llm,query)
    # enhanced_result=method_two(vectorstore,llm,query)

    print(enhanced_result)

思考

  • 在尝试中发现,文档的嵌入模型选择对匹配结果也影响很大
  • 文档越规范越好切(不同的切分规则对检索和增强都有影响)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VmWare Ubuntu22.04 搭建DPDK 20.11.1

一、开发环境 Ubuntu 版本 二、增加虚拟机的网卡 给虚拟机增加1个网卡,加上原来的网卡,一共2个 网络适配器作为 ssh 连接的网卡,网络适配器2作为 DPDK 运行的网卡。 三、NAT模式简介 这里待补充,网上都是那一张图,看不懂 四、使网卡名称从0开始命名 进入管理员权限 s…

selenium-自动更新谷歌浏览器驱动

1、简介 selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题,因为有些网页数据是通过JavaScript动态加载的。selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如输入…

Docker容器部署elasticsearch8.*与Kibana8.*版本使用filebeat采集日志

第 1 步:使用 Docker Compose 部署 Elasticsearch 和 Kibana 首先,我们需要创建一个 docker-compose.yml 文件来定义和运行 Elasticsearch 和 Kibana 服务。这种方式可以轻松管理两个容器的配置和网络。 创建 docker-compose.yml 文件 在一个新的文件夹…

OpenCV CUDA模块图像处理------双边滤波的GPU版本函数bilateralFilter()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 该函数在 GPU 上执行双边滤波操作,是一种非线性平滑滤波器,能够在 保留边缘的同时去除噪声。 函数原型 void cv::cuda:…

华为手机开机卡在Huawei界面不动怎么办?

遇到华为手机卡在启动界面(如HUAWEI Logo界面)的情况,可依次尝试以下解决方案,按操作复杂度和风险由低到高排序: 🔧 一、强制重启(优先尝试) 1.通用方法‌ 长按 ‌电源键 音量下键‌…

go语言map扩容

map是什么? ​在Go语言中,map是一种内置的无序key/value键值对的集合,可以根据key在O(1)的时间复杂度内取到value,有点类似于数组或者切片结构,可以把数组看作是一种特殊的map,数组的key为数组的下标&…

5.3 Spring Boot整合JPA

本文详细介绍了如何在Spring Boot项目中整合Spring JPA,实现对数据库的高效操作。首先,创建Spring Boot项目并添加必要的依赖,如Druid数据源。接着,配置数据源属性,创建实体类Comment和Article,并使用JPA注…

腾讯开源视频生成工具 HunyuanVideo-Avatar,上传一张图+一段音频,就能让图中的人物、动物甚至虚拟角色“活”过来,开口说话、唱歌、演相声!

腾讯混元团队提出的 HunyuanVideo-Avatar 是一个基于多模态扩散变换器(MM-DiT)的模型,能够生成动态、情绪可控和多角色对话视频。支持仅 10GB VRAM 的单 GPU运行,支持多种下游任务和应用。例如生成会说话的虚拟形象视频&#xff0…

[文献阅读] Emo-VITS - An Emotion Speech Synthesis Method Based on VITS

[文献阅读]:An Emotion Speech Synthesis Method Based on VITS 在VITS基础上通过参考音频机制,获取情感信息,从而实现的情感TTS方式。 摘要 VITS是一种基于变分自编码器(VAE)和对抗神经网络(GAN&#xf…

OpenCV-Python Tutorial : A Candy from Official Main Page(持续更新)

OpenCV-Python 是计算机视觉领域最流行的开源库之一,它结合了 OpenCV (Open Source Computer Vision Library) 的 C 高性能实现和 Python 的简洁易用特性,为开发者提供了强大的图像和视频处理能力。具有以下优势: 典型应用领域: …

【Vue】指令补充+样式绑定+计算属性+侦听器

【指令补充】 【指令修饰符】 指令修饰符可以让指令的 功能更强大,书写更便捷 分类: 1.按键修饰符(侦测当前点击的是哪个按键) 2.事件修饰符(简化程序对于阻止冒泡, 一些标签的默认默认行为的操作&…

LLM 笔记:Speculative Decoding 投机采样

1 基本介绍 投机采样(Speculative Sampling)是一种并行预测多个可能输出,然后快速验证并采纳正确部分的加速策略 在不牺牲输出质量的前提下,减少语言模型生成 token 所需的时间 传统的语言模型生成是 串行 的 必须生成一个&…

当SAP系统内计划订单转换为生产订单时发生了什么?

【SAP系统研究】 #SAP #计划订单 #生产订单 #采购申请 一、关于计划订单的一点疑惑 曾经对SAP为什么会有计划订单,是感到很疑惑的。 这个界面简单,配置点也不多,能被随意“摆布”,一旦要变形就消失得无影无踪的计划订单,why? 但是,再次重新审视过之后,才发现它其实…

PDF转PPT转换方法总结

你是否遇到过这些场景? 收到客户发来的产品手册PDF,明天就要用它做演示; 公司历史资料只有PDF版,领导突然要求更新为幻灯片。 这时PDF转PPT工具就成了救命稻草。接下来,介绍三种PDF转PPT工具。 1. iLoveOFD在线转换…

3D Web轻量化引擎HOOPS Communicator的定制化能力全面解析

HOOPS Communicator 是Tech Soft 3D推出的高性能Web工程图形引擎。它通过功能丰富的JavaScript API,帮助开发团队在浏览器中快速添加2D/3D CAD模型的查看与交互功能。该引擎专为工程应用优化,支持大规模模型的流畅浏览、复杂装配的智能导航、流式加载和服…

【力扣链表篇】19.删除链表的倒数第N个节点

题目: 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5]示例 2: 输入:head [1], n 1 输出:[]…

如何使用Jmeter进行压力测试?

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、什么是压力测试 软件测试中:压力测试(Stress Test),也称为强度测试、负载测试。压力测试是模拟实际应用的软硬…

Grafana-ECharts应用讲解(玫瑰图示例)

工具: MySQL 数据库 MySQL Workbench 数据库管理工具(方便编辑数据) Grafana v11.5.2 Business Charts 6.6(原 Echarts插件) 安装 安装 MySQL社区版安装 MySQL Workbench安装 Grafana在 Grafana 插件中搜索 Business Charts 进行安装以上安装步骤网上教程很多,自行搜…

前端vue3 上传/导入文件 调用接口

点击按钮导入&#xff1a; <el-uploadaction"https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15":auto-upload"false":on-change"handleFileChange":show-file-list"false"><el-button type"warning"…

Python训练营-Day22-Titanic - Machine Learning from Disaster

Description linkkeyboard_arrow_up &#x1f44b;&#x1f6f3;️ Ahoy, welcome to Kaggle! You’re in the right place. This is the legendary Titanic ML competition – the best, first challenge for you to dive into ML competitions and familiarize yourself w…