ToB企服应用市场:ToB评测及商务社交产业平台

标题: RAG实战教程:利用Langchain和Milvus向量数据库打造个性化本地知识库 [打印本页]

作者: 滴水恩情    时间: 2024-9-1 05:35
标题: RAG实战教程:利用Langchain和Milvus向量数据库打造个性化本地知识库
RAG实操教程: langchain+Milvus向量数据库创建你的本地知识库

本篇文章是 Milvus 向量数据库学习的总结篇,打造自己的知识库系统。
RAG是什么

RAG 是retrieval-augmented-generation的缩写,翻译为中文的意思就检索增强,以基于最新,最准确的数据建立LLM的语料知识库。
LLM 有哪些痛点

我们知道 LLM的知识库是通过现有的网络公开的数据作为数据源来训练的,现在公开的许多模型他们基于的训练数据会比我们现在网络上公开的数据早许多,那自然就会产生一种题目,网络上最新的数据和知识 LLM是不知道。还有一种环境就是许多企业他们对自己的数据的安全做的很好,也就是私有化数据(这些数据是有代价的,也是企业的驻足之本)。这些数据网络上肯定是不存在,那自然 LLM也是不知道的。
我们在提问LLM 对于一些不知道的知识时间,LLM 许多时间是不知道怎样答复题目的。甚至会对我们的题目进行胡诌随机答复,也就是瞎说。
为什么要用 RAG

如果使用预训练好的 LLM 模型,应用在某些景象下势必会有些词不达意的题目,比方问 LLM 你个人的信息,那么它会无法答复;这种环境在企业内部也是一样,比方使用 LLM 来答复企业内部的规章条款等。
这种时间主要有三种方式来让 LLM 变得更符合你的需求:

现在的研究已经表明,RAG 在优化 LLM 方面,相较于其他方法具有明显的优势。
主要的优势可以体现在以下几点:
不过固然RAG有许多优势在,但这3种方法并不是互斥的,反而是相辅相成的。 联合 RAG 和 Fine tuning ,甚至 Promt Enginerring 可以让模型本领的条理性得增强。 这种协同作用特别在特定情境下显得重要,可以或许将模型的效能推至最佳。 整体过程大概必要经过多次迭代和调整,才华达到最佳的成效。 这种迭代过程涵盖了对模型的持续评估和改进,以满意特定的应用需求。

怎样解决上面的题目

那怎样让 LLM 知道这些最新/私有的数据的知识呢❓
那就是 RAG。通过将模型建立在外部知识来源的基础上来增补答复。从而提高 LLM生成答复的质量。
在基于 LLM实现的问答系统中使用 RAG 有三方面的好处:

现在所有基础模型使用的是 transformer 的 AI 架构。它将大量原始数据转换为其基本布局的压缩表示形式。这种原始的表示基础模型可以适应各种任务,并对标志的、特定于范畴的知识进行一些额外的微调。
不过仅靠微调很少能为模型提供在不断变化的环境中答复高度具体题目所需的全部知识,而且微调的时间周期还比较长。所以科学家们提出了 RAG,让 LLM 可以或许访问训练数据之外的信息。RAG 答应 LLM 建立在专门的知识体系之上,以更准确的答复题目,减低幻觉的产生。
下面我将 langchain+Milvus 向量数据库创建你的本地知识库
安装 langchain

使用下面的命令可以快速安装 langchain 相干的依赖
  1. pip install langchain
  2. pip install langchain-community # 默认安装
  3. pip install langchain-core # 默认安装
  4. pip install langchain-cli # LangChain 命令行界面
  5. pip install --upgrade --quiet pypdf # 安装pdf 加载器的依赖
复制代码
文档加载器 pdf

在这篇文章中我们使用pdf作为我们的知识库文档。
加载文档的过程一般必要下面的步调:

这些步调 langchain 已经给联合自己的工具连做好了封装,所以我们直接使用 langchain 来构建RAG。
  1. from langchain_text_splitters import CharacterTextSplitter
  2. from langchain_community.document_loaders import PyPDFLoader
  3. file_path = 'CodeGeeX 模型API.pdf'
  4. # 初始化pdf 文档加载器
  5. loader = PyPDFLoader(file_path=file_path)
  6. # 将pdf中的文档解析为 langchain 的document对象
  7. documents = loader.load()
  8. # 将文档拆分为合适的大小
  9. text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
  10. docs = text_splitter.split_documents(documents)
复制代码
上面有两个参数必要注意下:
chunk_size=1000
表示拆分的文档的大小,也就是上面所说的要设置为多少符合取决于所使用LLM 的窗口大小。

chunk_overlap=100
这个参数表示每个拆分好的文档重复多少个字符串。

Miluvs 向量数据库

关于 Milvui 可以参考我的前两篇文章
下面我们安装 pymilvus 库
  1. pip install --upgrade --quiet  pymilvus
复制代码
如果你使用的不是 Miluvs 数据库,那也没关系,langchain 已经给我们分装了几十种向量数据库,你选择你必要的数据库即可。本文中我们是系列教程中一篇,所以我们使用 Miluvs 向量库。
Embedding model


这里必要明确的两个功能是:

我这里使用 AzureOpenAIEmbeddings 是个收费的模型。有开源的 embedding Model可以部署在本地使用,如果你的呆板性能足够好。如果要本地部署可以参考 docker 部署 llama2 模型 。
这里我使用 AzureOpenAIEmbeddings, 相干设置我放到了 .env 文件中,并使用 dotenv 加载。
  1. # AZURE config
  2. AZURE_OPENAI_ENDPOINT=''
  3. AZURE_OPENAI_API_KEY=''
  4. OPENAI_API_VERSION=2024-03-01-preview
  5. AZURE_DEPLOYMENT_NAME_GPT35 = "gpt-35-turbo"
  6. AZURE_DEPLOYMENT_NAME_GPT4 = "gpt-4"
  7. AZURE_EMBEDDING_TEXT_MODEL = "text-embedding-ada-002"
复制代码
这里各位可以依据自己的环境设定即可。
向量化+存储

上面已经分析了向量库以及embedding model的关系。我们直接使用 langchain 提供的工具连完成 embedding 和store。
  1. # 初始化 embedding model
  2. from langchain_openai import AzureOpenAIEmbeddings
  3. embeddings = AzureOpenAIEmbeddings()
复制代码
  1. from langchain_community.vectorstores import Milvus
  2. vector = Milvus.from_documents(
  3.      documents=documents, # 设置保存的文档
  4.      embedding=embeddings, # 设置 embedding model
  5.      collection_name="book", # 设置 集合名称
  6.      drop_old=True,
  7.      connection_args={"host": "127.0.0.1", "port": "19530"},# Milvus连接配置
  8. )
复制代码
执行完成上面的代码,我们就将pdf中文档内容生存到 vector_db 中。

字段 vector 就是生存的多维向量。

Milvus search

固然现在我们还没有使用 LLM 的任何本领,但是我们已经可以使用 vector 的搜索功能了。
  1. query = "CodeGeeX模型API参数有那些?"
  2. docs = vector.similarity_search(query)
  3. print(docs)
复制代码
  1. # 带score搜索
  2. query = "CodeGeeX模型API参数有那些?"
  3. docs = vector.similarity_search_with_score(query, k=2)
  4. print(docs)
复制代码
similarity_search 与 similarity_search_with_score 的区别就是 similarity_search_with_score 搜索出来会带有一个 score 分值的字段,某些环境下这个 score 很有用。
langchain 不但仅提供了基础的搜索本领,还有其他的搜索方法,感兴趣的可以去研究下。
RAG Chat

准备工作我们已经停当,接下来我们使用langchain 构建我们的chat。
既然是聊天也就是我们跟模型的一问一答的形式来体现。这两年LLM的出现,关于 LLM 的知识内里我们估计最熟悉就是脚色设定了。

   在大型语言模型(LLM)中,脚色设定指的是为AI助手创建一个特定的人格或身份。这个设定包括AI助手的语言风格、知识范畴、代价观、举动方式等各个方面。通过这些设定,AI助手可以扮演差别的脚色,比如专业的客服、风趣幽默的聊天对象,或是特定范畴的专家顾问。
  脚色设定可以让AI助手的答复更加符合特定的场景和用户的盼望。比如一个扮演医生的AI助手,会用专业术语表明病情,给出严谨的建议;而一个扮演朋侪的AI助手,会用轻松的语气聊天,给出生存化的提示。
  别的,脚色设定还可以资助限定AI助手的举动界限,避免其做出不恰当或有害的回应。设定明确的脚色定位,有助于AI助手更好地理解自己的身份和职责,从而提供更加符合和有资助的答复。
  总的来说,脚色设定让AI助手的对话更加自然和人性化,让用户获得更好的使用体验。同时它也是引导AI助手举动、确保其安全可控的重要本领。
  在 chat中我们同样也必要以及简朴的 prompt:
  1. template = """You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know.
  2. Question: {question}
  3. Context: {context}
  4. Answer:
  5. """
复制代码
这个prompt中很明显我们设定了两个变量 question, context。
question: 这个会在后面被更换为用户的输入,也就是用户的题目。
context: 这个变量我们在后面会更换为向量检索出来的内容。
   请思索下: 我们最后提供给LLm的内容只是用户的题目呢照旧题目连带内容一起给到LLM?
  chat chain

基于上面的内容我们基本的工作已经完成,下面就是我们基于 langchain构建chat。
  1. import os
  2. from langchain_core.prompts import ChatPromptTemplate
  3. prompt = ChatPromptTemplate.from_template(template)
  4. print(prompt)
  5. # 加载chat model
  6. from langchain_openai import AzureChatOpenAI
  7. from langchain_core.runnables import RunnableParallel,RunnablePassthrough
  8. from langchain_core.output_parsers import StrOutputParser
  9. llm = AzureChatOpenAI(
  10.      azure_deployment=os.environ.get('AZURE_DEPLOYMENT_NAME_GPT35')
  11. )
  12. retriever = vector.as_retriever()
  13. chain = (
  14.      RunnableParallel({"context": retriever, "question": RunnablePassthrough()})
  15.      | prompt
  16.      | llm
  17.      | StrOutputParser()
  18. )
复制代码
对于初学者大概有个题目就是:为什么这里有个 AzureChatOpenAI() 的实例 llm 。
这是个好题目,对于初学者会被各种 LLM 搞晕




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4