第四、五章
前言
【在线阅读地址】https://datawhalechina.github.io/llm-universe/
【项目仓库地址】https://github.com/datawhalechina/llm-universe
【用户反馈地址】https://emoumcwvfx.feishu.cn/share/base/form/shrcnWBh2a9gl3HhW5ww736B64f
【小程序使用手册】
https://mp.weixin.qq.com/s/iPmzb72Yk0mhIA2NYezXDg
第四章 数据库搭建
一、知识库文档处理
1、文档加载
pdf文档:使用 PyMuPDFLoader 来读取
markdown文档:使用 UnstructuredMarkdownLoader读取
MP4 视频:先使用 Whisper 实现视频的转写,转换成txt文件,再使用UnstructuredFileLoader加载txt文件
2、文档分割
Langchain 中文本分割器都根据 chunk_size (块大小)和 chunk_overlap (块与块之间的重叠大小)进行分割。
3、文档向量化
在机器学习和自然语言处理(NLP)中,Embeddings(嵌入)是一种将类别数据,如单词、句子或者整个文档,转化为实数向量的技术。这些实数向量可以被计算机更好地理解和处理。嵌入背后的主要想法是,相似或相关的对象在嵌入空间中的距离应该很近。
度量两个向量之间的相关性:计算两个向量之间的内积、计算两个向量之间的余弦相似度
二、向量数据库的介绍及使用
1、向量数据库是一种专门用于存储和检索向量数据(embedding)的数据库系统。
2、Chroma向量数据库:轻量级且数据存储在内存中
3、向量数据库检索
(1)相似度检索
(2)MMR 检索
最大边际相关性 (MMR, Maximum marginal relevance) 可以帮助我们在保持相关性的同时,增加内容的丰富度。
核心思想是在已经选择了一个相关性高的文档之后,再选择一个与已选文档相关性较低但是信息丰富的文档。这样可以在保持相关性的同时,增加内容的多样性,避免过于单一的结果。
4、构造检索性问答链
(1)直接询问LLM
构造一个使用 LLM 进行问答的检索式问答链。传入一个语言模型和一个向量数据库来创建检索器,用问题作为查询调用检索器。
(2)结合 prompt 提问
定义一个提示模板:
from langchain.prompts import PromptTemplate
# Build prompt
template = """使用以下上下文片段来回答最后的问题。如果你不知道答案,只需说不知道,不要试图编造答案。答案最多使用三个句子。尽量简明扼要地回答。在回答的最后一定要说"感谢您的提问!"
{context}
问题:{question}
有用的回答:"""
QA_CHAIN_PROMPT = PromptTemplate.from_template(template)
第五章 Prompt设计
一、Prompt设计的原则和技巧
prompt(提示) 就是用户与大模型交互输入的代称。即我们给大模型的输入称为 Prompt,而大模型返回的输出一般称为 Completion。
1、原则一:编写清晰、具体的指令
记住用清晰、详尽的语言表达 Prompt,就像在给外星人讲解人类世界一样,“Adding more context helps the model understand you better.”。
(1)使用分隔符清晰地表示输入的不同部分
(2)寻求结构化的输出
prompt = f"""
请生成包括书名、作者和类别的三本虚构的、非真实存在的中文书籍清单,\
并以 JSON 格式提供,其中包含以下键:book_id、title、author、genre。
"""
response = get_completion(prompt)
print(response)
(3)要求模型检查是否满足条件
# 满足条件的输入(text中提供了步骤)
text_1 = f"""
泡一杯茶很容易。首先,需要把水烧开。\
在等待期间,拿一个杯子并把茶包放进去。\
一旦水足够热,就把它倒在茶包上。\
等待一会儿,让茶叶浸泡。几分钟后,取出茶包。\
如果您愿意,可以加一些糖或牛奶调味。\
就这样,您可以享受一杯美味的茶了。
"""
prompt = f"""
您将获得由三个引号括起来的文本。\
如果它包含一系列的指令,则需要按照以下格式重新编写这些指令:
第一步 - ...
第二步 - …
…
第N步 - …
如果文本中不包含一系列的指令,则直接写“未提供步骤”。"
\"\"\"{text_1}\"\"\"
"""
response = get_completion(prompt)
print("Text 1 的总结:")
print(response)
(4) 提供少量示例
prompt = f"""
您的任务是以一致的风格回答问题(注意:文言文和白话的区别)。
<学生>: 请教我何为耐心。
<圣贤>: 天生我材必有用,千金散尽还复来。
<学生>: 请教我何为坚持。
<圣贤>: 故不积跬步,无以至千里;不积小流,无以成江海。骑骥一跃,不能十步;驽马十驾,功在不舍。
<学生>: 请教我何为孝顺。
"""
response = get_completion(prompt)
print(response)
2、给模型时间去思考
(1)指定完成任务所需的步骤
(2)指导模型在下结论之前找出一个自己的解法
(3)要求模型检查是否满足条件
二、基于问答助手的Prompt构建
1、加载向量数据库
2、创建一个LLM
3、构建prompt
三、添加历史对话的记忆功能
在与语言模型交互时,它们并不记得你之前的交流内容。可以使用LangChain 中的储存模块ConversationBufferMemory,它保存聊天消息历史记录的列表,这些历史记录将在回答问题时与问题一起传递给聊天机器人,从而将它们添加到上下文中。
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(
memory_key="chat_history", # 与 prompt 的输入变量保持一致。
return_messages=True # 将以消息列表的形式返回聊天记录,而不是单个字符串
)
对话检索链(ConversationalRetrievalChain)在检索 QA 链的基础上,增加了处理对话历史的能力。
它的工作流程是:
- 将之前的对话与新问题合并生成一个完整的查询语句。
- 在向量数据库中搜索该查询的相关文档。
- 获取结果后,存储所有答案到对话记忆区。
- 用户可在 UI 中查看完整的对话流程。