1. 数据库搭建
搭建向量数据库就是将你的知识库内容包括视频,各种文档等知识信息通过embedding的方式转换为向量进行存储。
1.1 数据库的输入
各类知识的读取
本次训练营教程中给了我们三种案例,分别是PDF文档,Markdown文档和Mp4视频的处理方法:
-
PDF文档:
使用LangChain中的PyMuPDFLoader进行加载 -
Markdown文档:
使用LangChain中的UnstructuredMarkdownLoader进行加载 -
Mp4视频:
LangChain中提供了对Youtube视频进行爬取并转写的处理接口,但如果是本地视频,则需要自行转写,这里教程中给了使用whisper来进行转写的方法,然后将txt使用跟markdown相同的加载方法即可课后我又了解了以下whisper相关的项目:insanely-fast-whisper,whisper.cpp,faster-whisper,其中:
- insanely-fast-whisper可以作为独立应用进行使用安装问题少并且性能强悍,十分推荐
- whisper.cpp对whisper的部署较为友好,也非常不错
- faster-whisper相比之下只是降低了显存占用,好,但不多
知识的前处理
为了将各种文档分批,我们需要进行文档分割,这样知识之间才能有所区分
其中最需要了解的两个关键参数:
我们将文档分割成了不同的块
- chunk_size:指的是每个
块
的大小,即包含的字符或token(word, sentence)的数量,也就是知识的细分程度 - chunk_overlap:两个
块
之间共享(重叠)的字符数,为了保留上下文信息用的
LangChain中提供了多种分割方式,各有区别,详见教程C5.1.3
知识的转换(文档词向量化)
通过openai或者zhipuai提供的embedding模型(或者我们本地部署合适的模型),我们可以将文档进行词嵌入,从而转换为向量,也就是模型所认为的“知识”,
生成后,对于每个向量,通过相似度对比,能够判断不同的向量之间的相关性,从而表示不同的词/文章之间的相关性。
文章中介绍了向量点积
及余弦相似度
两种计算相关性的方法。其中点积方法计算简单快速,但是丢失了方向信息,也就是知识的“类别”是否相同。
1.2 数据库的建立、功能与使用
向量数据库专门由于存储和检索向量数据,主要关注向量数据的特性和相似性。在这里,数据被表示为向量形式,每个向量代表一个数据项,可以是数字,文本,图像等等。向量数据库使用高校的索引和查询算法来加速数据的存储和检索过程。
这个项目使用chroma是因为它轻量级且数据存储在内存中,这样它启动和使用都非常简单。
1.3 数据库的建立
vectordb = Chroma.from_documents(
documents=split_docs, # 将分割好的文本作为列表输入
embedding=embedding, # 选择你使用的嵌入模型来对数据进行向量化
persist_directory=persist_directory # 允许我们将persist_directory目录保存到磁盘上
)
构建chroma完成后,为了让我们的向量化数据库持久化以便在未来使用,我们需要运行vectordb.persist()
数据库的检索功能
数据库提供了多种检索功能,教程中介绍了两种:相似度检索和MMR检索(最大边际相关性)
相似度搜索
通过相似度搜索,我们可以检索相关性较强的内容,不过单一指标的搜索往往不够智能,比如可能内容会非常单一之类的
MMR检索
如果只考虑内容相关性会丢失重要信息,MMR可以帮助我们保持相关性同时增加内容丰富度
核心思想:选择了一个相关性高的文档后,在选择一个与已选文档相关性较低但信息丰富的文档,这样可以保持相关性同时增加内容多样性
数据库的使用
现在我们可以通过检索找到数据库里最相关内容了,接下来可以通过LLM来用这些相关内容来回答我们的问题。
现在可以直接提问或者通过结合Prompt的方式进行提问。在通用场景中,我们可能直接提问即可,但是在问答助手的场景中,为了提高助手回答的清晰程度等方面,我们需要通过Prompt对提问作出模板化的要求。
1.4 遇到的问题
UnstructuredMarkdownLoader加载markdown文档时,nltk.download卡住,设置系统代理后可以继续
2. 问答链的完善:清晰回复和历史对话
2.1 Prompt设计原则和技巧
希望之后我在做了一些项目之后还能回过头总结一些相关的经验
原则:
- 指令清晰、具体
- 使用分割符表示输入的不同部分:清晰、安全(防止提示词注入)
- 寻求结构化输出:JSON,HTML等格式的输出
- 设置满足条件并要求模型进行检查:如果不满足,则走另一条路线,比如提示不满足条件等
- 给模型举例:结合上一条,可以举满足上述条件的例子,使得模型对条件有一个初步认知
- 拆解问题
- 分布
- 曲线救国,从另一个方向确定是否成立,有时候绕远路反而使问题更简单(大模型的幻觉问题,这需要我们仔细解决)
2.2 构建问答助手场景的Prompt
通过基于模板的检索链,我们可以设置模板来对模型的输出进行次要方向上的调整,比如对回答进行字数,风格等方面的要求。
在此基础上,我们可以对比直接提问和结合prompt的提问后的效果,从而调整prompt
2.3 添加历史对话的记忆功能
通过Memory,我们可以让对话检索连拥有连续对话的记忆,从而使得助手从只出不进的回答到有进有出的对话。
具体实现都不难,详见教程文档。