LangChain学习笔记—RAG(检索增强生成)

news2024/12/28 20:15:26

LangChain

LangChain是一个软件开发框架,可以更轻松地使用大型语言模型(LLM)创建应用程序。它是一个具有 Python 和 JavaScript 代码库的开源工具。LangChain 允许开发人员将 GPT-4 等 LLM 与外部数据相结合,为聊天机器人、代码理解、摘要等各种应用程序开辟了可能性。

LangChain模块

LangChain将其功能分组到以下模块中:

  • 模型
  • 提示
  • 代理
  • 记忆
  • 文档加载程序和索引
提示

        提示是指模型输入。在前面的部分中,您将提示硬编码为 LLM 和聊天模型。此技术不适用,因为在生产环境中不会收到硬编码的完整文本提示。相反,您将收到来自用户的简洁输入,您将希望将其转换为提示。

模型

LangChain支持三种类型的模型:

  • 大型语言模型
  • 聊天模型
  • 文本嵌入模型

链允许您同时运行多个LangChain模块。例如,使用链,您可以同时运行提示符和 LLM,从而避免了首先格式化 LLM 模型的提示,然后使用模型在单独的步骤中执行它。

LangChain支持三种主要类型的链:

  • 简单的 LLM 链
  • 顺序链
  • 定制链
代理

LangChain代理涉及LLM来执行以下步骤:

  1. 根据用户输入或其先前的输出确定要执行的操作。
  2. 执行操作。
  3. 观察输出。
  4. 重复前三个步骤,直到它尽其所能完成用户输入中定义的任务。

RAG Architecture

典型的 RAG 应用程序有两个主要组件:

  • 索引(Indexing)

用于从源获取数据并为其建立索引的管道。这通常发生在离线状态。

  • 提取和生成(Retriever and generation)

实际的 RAG 链,它在运行时接受用户查询并从索引中检索相关数据,然后将其传递给模型。

索引(Indexing)

  • Load

首先需要加载数据,通过DocumentLoaders完成

  • Split

Text splitters将large Documents分成更小的chunks。这对于索引数据和将其传递到模型都很有用,因为大块更难搜索并且不适合模型的有限上下文窗口。

  • Store

存储和索引我们的分割,这通常是使用 VectorStore 和 Embeddings 模型来完成的。

 

矢量数据库

Chroma 是一个用于构建具有嵌入的 AI 应用程序的数据库。

        数据量庞大的知识、新闻、文献、语料等先通过嵌入(embedding)算法转变为向量数据,然后存储在Chroma等向量数据库中。当用户在大模型输入问题后,将问题本身也embedding,转化为向量,在向量数据库中查找与之最匹配的相关知识,组成大模型的上下文,将其输入给大模型,最终返回大模型处理后的文本给用户,这种方式不仅降低大模型的计算量,提高响应速度,也降低成本,并避免了大模型的tokens限制,是一种简单高效的处理手段。 

主流的向量数据库对比如下所示:

向量数据库URLGitHub StarLanguage
chromahttps://github.com/chroma-core/chroma7.4KPython
milvushttps://github.com/milvus-io/milvus21.5KGo/Python/C++
pineconehttps://www.pinecone.io/
qdranthttps://github.com/qdrant/qdrant11.8KRust
typesensehttps://github.com/typesense/typesense12.9KC++
weaviatehttps://github.com/weaviate/weaviate6.9KGo

在这里我们使用chroma

提取和生成(Retrieval and generation)

  1. Retrieve:给定用户输入,使用检索器从存储中检索相关分割。
  2. GenerateChatModel / LLM 使用包含问题和检索到的数据的提示生成答案

 实例

import os
import bs4
from langchain import hub
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import Chroma
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import PyPDFLoader
# Load, chunk and index the contents of the blog.
print("Starting..........")
os.environ['OPENAI_API_KEY'] ="sk-xxxxxxxx"
os.environ['OPENAI_BASE_URL'] ="https://api.chatanywhere.tech/v1"
print("Loading.....")
#loader = WebBaseLoader(
#    web_paths=("https://lilianweng.github.io/posts/2023-06-23-agent/",),
#    bs_kwargs=dict(
#        parse_only=bs4.SoupStrainer(
#            class_=("post-content", "post-title", "post-header")
#        )
#    ),
#)
loader = PyPDFLoader("example_data/计算机信息模型导论2024.pdf")
docs = loader.load()
print("Loadded....")
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings(),persist_directory="./vector_store")

# Retrieve and generate using the relevant snippets of the blog.
retriever = vectorstore.as_retriever()
prompt = hub.pull("rlm/rag-prompt")
print("RAG....")
llm = ChatOpenAI(model_name="gpt-3.5-turbo",base_url="https://api.chatanywhere.tech/v1", temperature=0)


def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)


rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)
print(rag_chain.invoke("what is OPCUA 变量类型? 请中文回答"))
# cleanup
#vectorstore.delete_collection()

        计算机信息模型导论2024.pdf是我正在写的一本书。介绍计算机信息模型,其中包含了OPCUA 的基本知识。        

Chroma 矢量数据库默认是存储在内存中的。如果设置了永久存储目录的位置persist_directory,它会存放在指定的目录中。一旦文档的矢量数据存储在文件中,提问可以不需要每次读pdf文件,程序简化为:

import os
from langchain import hub

from langchain_community.vectorstores import Chroma
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI,OpenAIEmbeddings

# Load, chunk and index the contents of the blog.

os.environ['OPENAI_API_KEY'] ="sk-xxxxxxxxx"
os.environ['OPENAI_BASE_URL'] ="https://api.chatanywhere.tech/v1"
embedding = OpenAIEmbeddings(openai_api_key=os.environ['OPENAI_API_KEY'] )
vectorstore = Chroma(persist_directory="./vector_store",embedding_function=embedding)

# Retrieve and generate using the relevant snippets of the blog.
retriever = vectorstore.as_retriever()
prompt = hub.pull("rlm/rag-prompt")
print("RAG....")
llm = ChatOpenAI(model_name="gpt-3.5-turbo",base_url="https://api.chatanywhere.tech/v1", temperature=0)


def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)


rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)
print(rag_chain.invoke("what is OPCUA 变量类型? 请中文回答"))

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

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

相关文章

代理IP在爬虫中的连接复用与开销减少

目录 一、引言 二、代理IP的基本概念 三、代理IP在爬虫中的使用 四、代理IP的连接复用 五、减少开销的策略 六、代码示例与注释 七、总结 一、引言 在爬虫开发中,代理IP的使用是常见的做法,尤其在目标网站设置了反爬虫机制时。代理IP能够帮助爬虫…

【鸿蒙 HarmonyOS】获取设备的地理位置

一、背景 获取移动设备的地理位置,包含:经度、维度、具体地理位置等,地理位置信息能在许多业务场景中被应用,如导航、地图服务、位置服务、社交媒体等。 下面以一个Demo例子,来实现获取设备地理位置的功能 官方文档…

27.WEB渗透测试-数据传输与加解密(上)

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于: 易锦网校会员专享课 上一个内容:26.WEB渗透测试-BurpSuite(五) BP抓包网站网址:http:…

经济学 赋税

赋税: 1.为政府服务提供金钱来源 2. 用于保护环境 3.帮助国家使用财政和货币政策,推动经济增长 4.再分配社会财富的一种方式,平衡富人和穷人的贫富差距 5.帮助我们支付市场自身可能无法实现的服务,比如公共安全,国…

Day105:代码审计-PHP原生开发篇SQL注入数据库监控正则搜索文件定位静态分析

目录 代码审计-学前须知 Bluecms-CNVD-1Day-常规注入审计分析 emlog-CNVD-1Day-常规注入审计分析 emlog-CNVD-1Day-2次注入审计分析 知识点: 1、PHP审计-原生态开发-SQL注入&语句监控 2、PHP审计-原生态开发-SQL注入&正则搜索 3、PHP审计-原生态开发-SQ…

全力推进Copilot,微软抽调Teams团队精英

据 Business Insider 网站报道,他们获得的一份俺们微软内部备忘录显示,说俺们微软正在建立一个专门团队,负责俺们家的 Copilot 及其相关产品的后续开发工作。 该备忘录由俺们微软人工智能业务副总裁贾里德・斯帕塔罗(Jared Spata…

【201】Java8读取JSON树形结构并插入到MySQL数据库表中

我写了一个 maven 项目的 Demo,用来演示 JAVA8 如何读取 JSON 文件树形结构,并将这种树形结构保存到 MySQL 中。 json文件 city.json {"name": "山东省","sub": [{"name": "青岛市","sub"…

【蓝桥杯嵌入式】RTC——实时时钟

一、RTC简介 RTC RTC—real time clock,实时时钟,主要包含日历、闹钟和自动唤醒这三部分的功能,其中的日历功能我们使用的最多。日历包含两个32bit的时间寄存器,可直接输出时分秒,星期、月、日、年。 从Cubemx里的配置…

【OpenCV】图像算术操作

1 前言 介绍图像算术操作,以及其可以实现的图像亮度、对比度调整效果。相关API: add() subtract() multiply() divide() addWeighted() 2 代码及内容 #include "iostream" #include "opencv2/opencv.hpp"using namespace std…

成都源聚达:抖音小店押金收费标准

在数字浪潮中,抖音小店如星辰般熠熠生辉,吸引了无数商家和创业者。然而,想要在这片星海中畅游,首先得了解其押金的收费标准。正如古人言:“无规矩不成方圆”,明确规则是成功的关键一步。 抖音小店的押金制度…

java爬虫入门程序

<!--爬虫仅支持1.8版本的jdk--> <!-- 爬虫需要的依赖--> <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.2</version> </dependency><!-- 爬虫需…

vue2+element-ui 实现OSS分片上传+取消上传

遇到问题&#xff1a;项目中需要上传500MB以上的视频。一开始使用上传组件el-upload&#xff0c;调用后台接口&#xff0c;但是出现了onprogress显示百分百后接口一直pending&#xff0c;过了很多秒后接口才通&#xff0c;如果遇到大文件的话&#xff0c;接口就会报超时。 解决…

批量复制空白文件夹,轻松管理文件,高效办公新选择

在繁忙的办公环境中&#xff0c;文件管理是提升工作效率的关键。想象一下&#xff0c;你需要为每一个新项目、新任务或新客户创建一个新的文件夹来整理和存储相关文件。手动一个一个地创建文件夹不仅耗时&#xff0c;而且容易出错。现在&#xff0c;我们为你带来一个全新的解决…

R语言中的常用数据结构

目录 R对象的基本类型 R对象的属性 R的数据结构 向量 矩阵 数组 列表 因子 缺失值NA 数据框 R的数据结构总结 R语言可以进行探索性数据分析&#xff0c;统计推断&#xff0c;回归分析&#xff0c;机器学习&#xff0c;数据产品开发 R对象的基本类型 R语言对象有五…

[leetcode] 25. K 个一组翻转链表

给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。 你不能只是单纯的改变节点内部的值…

老板们注意了,AI可能在悄悄威胁你的工作

前天,科技新闻大佬The Register发了一篇文章,说的是AI在科研领域的管理角色越来越大,可能会让管理岗位变得过时,听起来是不是有点儿疯狂? ESMT Berlin的研究小伙伴们发现,AI能够以更大的规模和效率来管理研究项目,比如审查科学文献和预测创新化合物等等,而不是取代人类…

【Frida】【Android】 工具篇:ProxyPin抓包详解

&#x1f6eb; 系列文章导航 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446【Frida】【Android】03_RPC https://bl…

【JVM】JVM简介

文章目录 &#x1f334;简介&#x1f332;JVM发展史&#x1f338;Sun Classic VM&#x1f338;Exact VM&#x1f338;HotSpot VM&#x1f338;JRockit&#x1f338;J9 JVMTaobao JVM&#xff08;国产研发&#xff09; &#x1f333;JVM 运行流程⭕总结 &#x1f334;简介 JVM …

【项目启动执行指定代码】⭐️通过案例测试下常用的实现方式

目录 前言 1、监听 ApplicationContext事件 2、实现CommandLineRunner接口 3、实现ApplicationRunner接口 4、使用PostConstruct注解 章末 前言 为了保证程序在启动后的稳定性&#xff0c;需要执行初始化操作&#xff0c;像加载配置&#xff0c;建立数据库连接可以在项目启…

(2024)Ubuntu源码安装多个版本的opencv并切换使用

本人工作会用到x86_64的opencv和aarch64的opencv&#xff0c;所以写下来备忘自用 一、源码编译安装 依赖库安装&#xff1a; sudo apt-get install build-essential libgtk2.0-dev libgtk-3-dev libavcodec-dev libavformat-dev libjpeg-dev libswscale-dev libtiff5-dev o…