当前位置:   article > 正文

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

langchain pgvector

前提:

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

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

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

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

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

基础库准备:

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

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

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

em.py 设置环境变量

  1. import getpass
  2. import os
  3. os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")

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

  1. ## Loading Environment Variables
  2. from dotenv import load_dotenv
  3. load_dotenv()

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

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

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

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

连接Postgre矢量存储库

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

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

  1. CONNECTION_STRING = PGVector.connection_string_from_db_params(
  2. driver=os.environ.get("PGVECTOR_DRIVER", "psycopg2"),
  3. host=os.environ.get("PGVECTOR_HOST", "localhost"),
  4. port=int(os.environ.get("PGVECTOR_PORT", "5432")),
  5. database=os.environ.get("PGVECTOR_DATABASE", "postgres"),
  6. user=os.environ.get("PGVECTOR_USER", "postgres"),
  7. password=os.environ.get("PGVECTOR_PASSWORD", "postgres"),
  8. )

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

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

输出结果:

最大边际相关性搜索

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

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

打印结果:

使用vectorstore 

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

  1. store = PGVector(
  2. collection_name=COLLECTION_NAME,
  3. connection_string=CONNECTION_STRING,
  4. embedding_function=embeddings,
  5. )

添加文档

我们可以向现有的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=真

  1. db = PGVector.from_documents(
  2. documents=docs,
  3. embedding=embeddings,
  4. collection_name=COLLECTION_NAME,
  5. connection_string=CONNECTION_STRING,
  6. pre_delete_collection=True,
  7. )

将VectorStore用作检索器

retriever = store.as_retriever()

与OpenAI结合使用完整代码

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

  1. import os
  2. from langchain_community.document_loaders import TextLoader
  3. from langchain_core.output_parsers import StrOutputParser
  4. from langchain_core.prompts import ChatPromptTemplate
  5. from langchain_core.runnables import RunnableParallel, RunnablePassthrough
  6. from langchain_openai import OpenAIEmbeddings, ChatOpenAI
  7. from langchain_community.vectorstores.pgvector import PGVector
  8. from langchain_text_splitters import RecursiveCharacterTextSplitter
  9. from dotenv import load_dotenv
  10. # 加载环境变量或者加载.env文件
  11. load_dotenv()
  12. # 导入文本文件
  13. loader = TextLoader("./demo_static/splitters_test.txt")
  14. # 生成文档加载器
  15. documents = loader.load()
  16. # 文档拆分,每块最大限制20,覆盖量10
  17. text_splitter = RecursiveCharacterTextSplitter(
  18. separators=["\n\n", "\n", "。", "?", ";"],
  19. chunk_size=100,
  20. chunk_overlap=20,
  21. )
  22. # 开始拆分文档
  23. docs = text_splitter.split_documents(documents)
  24. # print(len(docs))
  25. # print(docs)
  26. # 初始化嵌入式OpenAI大语言模型,手动指定key和代理地址
  27. embeddings = OpenAIEmbeddings(openai_api_key=os.getenv("OEPNAPI_API_KEY"),
  28. openai_api_base=os.getenv("OPENAI_API_BASE"))
  29. # 连接矢量存储库,链接换成自己专属的*
  30. CONNECTION_STRING = "postgresql+psycopg2://postgres:password@localhost:5432/postgres"
  31. # 矢量存储名
  32. COLLECTION_NAME = "state_of_the_union_test"
  33. # 建立索引库
  34. vector = PGVector.from_documents(
  35. embedding=embeddings,
  36. documents=docs,
  37. collection_name=COLLECTION_NAME,
  38. connection_string=CONNECTION_STRING,
  39. use_jsonb=True,
  40. pre_delete_collection=True,
  41. )
  42. # 生成检索器
  43. retriever = vector.as_retriever()
  44. # 一个对话模板,内含2个变量context和question
  45. template = """Answer the question based only on the following context:
  46. {context}
  47. Question: {question}
  48. """
  49. # 基于模板生成提示
  50. prompt = ChatPromptTemplate.from_template(template)
  51. # 基于对话openai生成模型
  52. model = ChatOpenAI(openai_api_key=os.getenv("OEPNAPI_API_KEY"),
  53. openai_api_base=os.getenv("OPENAI_API_BASE"))
  54. # 生成输出解析器
  55. output_parser = StrOutputParser()
  56. # 将检索索引器和输入内容(问题)生成检索
  57. setup_and_retrieval = RunnableParallel(
  58. {"context": retriever, "question": RunnablePassthrough()}
  59. )
  60. # 建立增强链
  61. chain = setup_and_retrieval | prompt | model | output_parser
  62. # 问题
  63. question = "今年长三角铁路春游运输共历时多少天?"
  64. # 发起请求
  65. res = chain.invoke(question)
  66. # 打印结果
  67. print(res)

打印结果:

    32

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/851652
推荐阅读
相关标签
  

闽ICP备14008679号