4. Retrieval
许多LLM需要使用特定用户的外部数据,这些数据不属于模型训练集的一部分。实现这一目标的主要方法是通过检索增强生成(RAG)。在此过程中,将检索外部数据,然后在执行生成步骤时将其传递给 LLM 。这包含几个关键模块:
4.1 Document loaders
Document loaders
加载来自许多不同来source的文档。LangChain 提供 100 多种不同的文档加载器,并与该领域的其他主要提供商(例如 AirByte 和 Unstructed)集成。LangChain 提供了从所有类型的位置(私有 S3 存储桶、公共网站)加载所有类型文档(HTML、PDF、代码)的集成。收录了海量的第三方Document loaders。例如,有用于加载简单.txt文件的,用于加载相对结构化的markdown文件的,用于加载任何网页文本内容,甚至用于加载解析YouTube视频的脚本。(旧版本在langchain.document_loaders
,新版本在langchain_community.document_loaders
)
使用Document loaders
可以将源中的数据加载为Document
。Document由一段文本
和相关的元数据
组成。
TextLoader可以将任意文本文件加载为纯文本字符串和元数据metadata,其中元数据包含source路径信息metadata={'source': '/home/pgao/yue/test.py'}
from langchain_community.document_loaders import TextLoader
loader = TextLoader(file_path)
print(loader.load())
# Document(page_content="xxx", metadata="xx")
JSONLoader指定的jq 架构
来解析 JSON 文件(JSON Lines
是一种文件格式.jsonl
,其中每一行都是有效的 JSON 对象)。jq_schema
可以选择加载的字段,jq_schema=‘.’
加载整个json文件。加载.jsonl
文件时需要设置json_lines=True
from langchain_community.document_loaders import JSONLoader
from pprint import pprint
loader = JSONLoader(
file_path='/home/pgao/yue/StyleDiff-Agent/results/dance_long/sd_prompts.json',
jq_schema='.content',
text_content=False)
data = loader.load()
pprint(data)
loader = JSONLoader(
file_path='./example_data/facebook_chat_messages.jsonl',
jq_schema='.content',
text_content=False,
json_lines=True)
data = loader.load()
4.2 Text Splitter
当我们加载Document
到内存后,我们通常还会希望将他们尽可能的结构化 / 分块,以进行更加灵活的操作
最简单的例子是,我们很多时候都需要将一个长文档拆分成更小的块,以便放入模型的上下文窗口中;LangChain有许多内置的Document transformers
(大部分都是Text Spliter
,旧版本在langchain.document_loaders
中,新版本在langchain.text_splitter
中),可以轻松地拆分、合并、筛选和以其他方式操作文档,一些常用的Document transformers如下:
对于一般文本,默认推荐使用RecursiveCharacterTextSplitter
文本分割器。它由字符列表参数化。它尝试按顺序分割它们,直到块足够小。默认列表是 ["\n\n", "\n", " ", ""]
. 这样做的效果是尝试将所有段落(然后是句子,然后是单词)尽可能长时间地放在一起,因为这些通常看起来是语义相关性最强的文本片段,得到的text
是分割好的str的list
。
# This is a long document we can split up.
with open("/home/pgao/yue/loveu-tgve-2023/README.md") as f:
state_of_the_union = f.read()
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
# Set a really small chunk size, just to show.
chunk_size=