Langchain教程 | langchain+OpenAI+PostgreSQL(PGVector) 实现全链路教程,简单易懂入门

前提:

        在阅读本文前,建议要有一定的langchain基础,以及langchain中document loader和text spliter有相关的认知,不然会比较难理解文本内容。

        如果是没有任何基础的同学建议看下这个专栏:人工智能 | 大模型 | 实战与教程

        本文主要展示如何结合langchain使用Postgres矢量数据库,其他相关的基础内容,可以看专栏了解,都已经拆分好了,一步步食用即可,推荐线路:langchain基础、document loader加载器、text spliter文档拆分器等按顺序学习。

PGVector是一个开源向量相似性搜索Postgres

它支持:- 精确和近似最近邻搜索- L2距离,内积和余弦距离 

基础库准备:

# Pip install necessary package
%pip install --upgrade --quiet  pgvector
%pip install --upgrade --quiet  psycopg2-binary
%pip install --upgrade --quiet  tiktoken
%pip install --upgrade --quiet  openai
from langchain.docstore.document import Document
from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores.pgvector import PGVector
from langchain_community.embeddings.openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter

我们想使用OpenAIEmbeddings所以我们必须获得OpenAI API密钥。

提示:因为国内政策原因,建议采购代理key,至于哪家好用,这里就不推荐了。

em.py 设置环境变量

import getpass
import osos.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")

 加载环境变量,openai库会自动读取该参数OPEN_API_KEY

## Loading Environment Variables
from dotenv import load_dotenvload_dotenv()

 这里使用的文本内容是: 人民财评:花香阵阵游人醉,“春日经济”热力足

将链接中的文本内容保存到 :state_of_the_union.txt

拆分中文文档需要用到递归型的字符拆分器 RecursiveCharacterTextSplitter,同时要使用中文分隔符:句号。逗号,顿号、感叹号!等。

loader = TextLoader("../../modules/state_of_the_union.txt")
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)embeddings = OpenAIEmbeddings()

连接Postgre矢量存储库

# PGVector needs the connection string to the database.
CONNECTION_STRING = "postgresql+psycopg2://harrisonchase@localhost:5432/test3"# # Alternatively, you can create it from environment variables.
# import os

类还内置了一个更直观的方法:connection_string_from_db_params()

CONNECTION_STRING = PGVector.connection_string_from_db_params(driver=os.environ.get("PGVECTOR_DRIVER", "psycopg2"),host=os.environ.get("PGVECTOR_HOST", "localhost"),port=int(os.environ.get("PGVECTOR_PORT", "5432")),database=os.environ.get("PGVECTOR_DATABASE", "postgres"),user=os.environ.get("PGVECTOR_USER", "postgres"),password=os.environ.get("PGVECTOR_PASSWORD", "postgres"),
)

使用欧氏距离进行相似性搜索(默认)

# The PGVector Module will try to create a table with the name of the collection.
# So, make sure that the collection name is unique and the user has the permission to create a table.COLLECTION_NAME = "state_of_the_union_test"db = PGVector.from_documents(embedding=embeddings,documents=docs,collection_name=COLLECTION_NAME,connection_string=CONNECTION_STRING,
)
query = "今年长三角铁路春游运输共历时多少天?"
docs_with_score = db.similarity_search_with_score(query)
for doc, score in docs_with_score:print("-" * 80)print("Score: ", score)print(doc.page_content)print("-" * 80)

输出结果:

最大边际相关性搜索

最大边际相关性优化了查询的相似性和所选文档的多样性。 

docs_with_score = db.max_marginal_relevance_search_with_score(query)
for doc, score in docs_with_score:print("-" * 80)print("Score: ", score)print(doc.page_content)print("-" * 80)

打印结果:

使用vectorstore 

        上面,我们从头开始创建了一个vectorstore。但是,我们经常希望使用现有的vectorstore。为了做到这一点,我们可以直接初始化它。

store = PGVector(collection_name=COLLECTION_NAME,connection_string=CONNECTION_STRING,embedding_function=embeddings,
)

添加文档

我们可以向现有的vectorstore添加文档。

store.add_documents([Document(page_content="今年春游创收客观,实际增长30%。")])
docs_with_score = db.similarity_search_with_score("春游增长多少")
print(docs_with_score[0])
print(docs_with_score[1])

覆盖向量存储

        如果您有一个现有的集合,您可以通过执行以下操作来覆盖它from_documents和设置pre_delete_collection=真

db = PGVector.from_documents(documents=docs,embedding=embeddings,collection_name=COLLECTION_NAME,connection_string=CONNECTION_STRING,pre_delete_collection=True,
)

将VectorStore用作检索器

retriever = store.as_retriever()

与OpenAI结合使用完整代码

里面包含了详细的步骤和注释,直接复制就可运行。

import os
from langchain_community.document_loaders import TextLoader
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores.pgvector import PGVector
from langchain_text_splitters import RecursiveCharacterTextSplitter
from dotenv import load_dotenv# 加载环境变量或者加载.env文件
load_dotenv()
# 导入文本文件
loader = TextLoader("./demo_static/splitters_test.txt")
# 生成文档加载器
documents = loader.load()
# 文档拆分,每块最大限制20,覆盖量10
text_splitter = RecursiveCharacterTextSplitter(separators=["\n\n", "\n", "。", "?", ";"],chunk_size=100,chunk_overlap=20,
)
# 开始拆分文档
docs = text_splitter.split_documents(documents)
# print(len(docs))
# print(docs)# 初始化嵌入式OpenAI大语言模型,手动指定key和代理地址
embeddings = OpenAIEmbeddings(openai_api_key=os.getenv("OEPNAPI_API_KEY"),openai_api_base=os.getenv("OPENAI_API_BASE"))
# 连接矢量存储库,链接换成自己专属的*
CONNECTION_STRING = "postgresql+psycopg2://postgres:password@localhost:5432/postgres"
# 矢量存储名
COLLECTION_NAME = "state_of_the_union_test"
# 建立索引库
vector = PGVector.from_documents(embedding=embeddings,documents=docs,collection_name=COLLECTION_NAME,connection_string=CONNECTION_STRING,use_jsonb=True,pre_delete_collection=True,
)
# 生成检索器
retriever = vector.as_retriever()
# 一个对话模板,内含2个变量context和question
template = """Answer the question based only on the following context:
{context}
Question: {question}
"""
# 基于模板生成提示
prompt = ChatPromptTemplate.from_template(template)
# 基于对话openai生成模型
model = ChatOpenAI(openai_api_key=os.getenv("OEPNAPI_API_KEY"),openai_api_base=os.getenv("OPENAI_API_BASE"))
# 生成输出解析器
output_parser = StrOutputParser()
# 将检索索引器和输入内容(问题)生成检索
setup_and_retrieval = RunnableParallel({"context": retriever, "question": RunnablePassthrough()}
)
# 建立增强链
chain = setup_and_retrieval | prompt | model | output_parser
# 问题
question = "今年长三角铁路春游运输共历时多少天?"
# 发起请求
res = chain.invoke(question)
# 打印结果
print(res)

打印结果:

    32天

 创作不易,来个三连(点赞、收藏、关注),同学们的满意是我(H-大叔)的动力。

 代码运行有问题或其他建议,请在留言区评论,看到就会回复,不用私聊。

专栏人工智能 | 大模型 | 实战与教程里面还有其他人工智能|大数据方面的文章,可继续食用,持续更新。

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

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

相关文章

4.1网安学习第四阶段第一周回顾(个人学习记录使用)

本周重点 ①Nmap的使用 ②MSF的使用 ③XRAY / Dirb / AWVS / FSCAN 的使用 ④Nessus的使用 ⑤MsfVenom木马制作 ⑥反弹shell的各种实现方式 本周主要内容 DAY1 一、课程介绍 第一阶段 :网络 和 协议 以及 等保 ,主要是对于网络整个安全的架构设…

8.java openCV4.x 入门-Mat之多维元组(Tuple)

专栏简介 💒个人主页 📰专栏目录 点击上方查看更多内容 📖心灵鸡汤📖我们唯一拥有的就是今天,唯一能把握的也是今天建议把本文当作笔记来看,据说专栏目录里面有相应视频🤫 🧭文…

Python基于深度学习的屋内烟雾检测系统的研究与实现,附源码

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

51单片机实验03-定时器T0来实现流水灯从左到右再从右到左

目录 一、实验目的 二、实验说明 1、51单片机有两个16位内部计数器/定时器(C/T, Counter/Timer)。 2、模式寄存器TMOD 1) M1M0工作模式控制位; 2) C/T定时器或计数器选择位: 3)GATE定时器/计数器运行…

分类预测 | Matlab实现GWO-LSSVM灰狼算法优化最小二乘支持向量机数据分类预测

分类预测 | Matlab实现GWO-LSSVM灰狼算法优化最小二乘支持向量机数据分类预测 目录 分类预测 | Matlab实现GWO-LSSVM灰狼算法优化最小二乘支持向量机数据分类预测分类效果基本介绍程序设计参考资料 分类效果 基本介绍 1.Matlab实现GWO-LSSVM灰狼算法优化最小二乘支持向量机数据…

Mysql底层原理十一:Mvcc

为什么要mvcc? 提高并发度,如果读和写都是通过加锁的方式,并发肯定上不来,通过mvcc来实现写通过加锁,读通过mvcc readView机制 3.9.1 Undo版本链 再重复一遍,页面中的记录存放在用户表空间的数据页中&a…

RuoYi-Vue若依框架-在框架内用颜色选择器,页面显示色块

在用若依框架进行二次开发的时候写到自己的一个模块,其中涉及到颜色,我就想着是手动输入还是采用颜色选择器呢,考虑到后续涉及到另一个字段编码于时就采用了颜色选择器,选择完的颜色显示的是十六进制的颜色选择器,这时…

【Java网络编程】计算机网络基础概念

就目前而言,多数网络编程的系列的文章都在围绕着计算机网络体系进行阐述,但其中太多理论概念,对于大部分开发者而言,用途甚微。因此,在本系列中则会以实际开发者的工作为核心,从Java程序员的角度出发&#…

蓝桥-回文日期

目录 题目链接 ​编辑 ​编辑 什么是回文数?​编辑 代码 100%过 90%暴力 优化写的暴力代码 题目链接 2.回文日期 - 蓝桥云课 (lanqiao.cn) 什么是回文数? 代码 100%过 把那个90%的代码的循环限制条件去掉就行了,题目只是限制了N…

Peter算法小课堂—线性dp

今天,你读完这篇文章,普及组的动态规划已经可以秒了。 最长公共子序列 求两个数列的最长公共子序列(Longest Common Subsequence,LCS)的长度。 数列 X 和 Y 的最长公共子序列 Z,是指 Z 既是 X 的子序列&…

cutlass之基础类型

Coord Coord是一个基础数据类型&#xff0c;在cutlass用的很多&#xff0c;有必要掌握清楚&#xff0c;该类型主要使用场景如下&#xff1a; 顾名思义就是坐标保存。using stridecoord<2>使用方式, 保存一个tensor不同维度之间的步长&#xff0c;这样讲不太好理解步长&…

【JavaEE】_Spring MVC项目获取Cookie

目录 1. Cookie与Session基础知识 1.1 Cookie与Session的区别 2. 使用servlet原生方法获取Cookie 2.2 关于λ表达式遍历法的空指针问题 2.3 Cookie的伪造 3. 使用Spring注解获取Cookie 3.1 获取单个Cookie 3.2 获取多个Cookie 1. Cookie与Session基础知识 在本专栏HTT…