AI大模型RAG与智能体开发03LangChain组件
一.StrOutputParser字符串输出解析器
1.StrOutputParser是LangChain内置的简单字符串解析器
- 可以将AIMessage解析为简单的字符串,符合了模型invoke方法要求(可传入字符串,不接收AIMessage类型)
- 是Runnable接口的子类(可以加入链)
parser = StrOutputParser()
chain = prompt | model | parser | model
2.Runnable接口

二.JsonOutputParser&多模型执行链
chain = prompt | model | parser | model | parser
在前面我们完成了这样的需求去构建多模型链,不过这种做法并不标准,因为:
上一个模型的输出,没有被处理就输入下一个模型。
正常情况下我们应该有如下处理逻辑:
invoke|stream 初始输入 提示词模板 模型 数据处理 提示词模板 模型 解析器 结果
即: 上一个模型的输出结果,应该作为提示词模版的输入,构建下一个提示词,用来二次调用模型。
- 模型的输出为:AIMessage类对象
- 提示词模板要求输入:dict类对象
所以,我们需要完成: 将模型输出的AIMessage 转为字典 注入第二个提示词模板中,形成新的提示词(PromptValue对象)

- 模型输入:PromptValue或字符串或序列(BaseMessage、list、tuple、str、dict)。
- 模型输出:AIMessage
- 提示词模板输入:要求是字典
- 提示词模板输出:PromptValue对象
- StrOutputParser:AIMessage输入、str输出
- JsonOutputParser:AIMessage输入、dict输出
三.RunnableLambda&函数加入链
除了JsonOutputParser这类固定功能的解析器之外 我们也可以自己编写Lambda匿名函数来完成自定义逻辑的数据转换,想怎么转换就怎么转换,更自由。 想要完成这个功能,可以基于RunnableLambda类实现。
RunnableLambda类是LangChain内置的,将普通函数等转换为Runnable接口实例,方便自定义函数加入chain。
语法: RunnableLambda(函数对象或lambda匿名函数)

跳过RunnableLambda类,直接让函数加入链也是可以的。
chain = first_prompt | model | (lambda ai_msg: {"name": ai_msg.content}) | second_prompt | model | str_parser
四.Memory
4.1临时会话记忆 InMemoryChatMessageHistory
LangChain提供了History功能,帮助模型在有历史记忆的情况下回答。
- 基于RunnableWithMessageHistory在原有链的基础上创建带有历史记录功能的新链(新Runnable实例)
- 基于InMemoryChatMessageHistory为历史记录提供内存存储(临时用)

4.2长期会话记忆 FileChatMessageHistory
使用InMemoryChatMessageHistory仅可以在内存中临时存储会话记忆,一旦程序退出,则记忆丢失。 InMemoryChatMessageHistory 类继承自 BaseChatMessageHistory
FileChatMessageHistory类实现,核心思路:
- 基于文件存储会话记录,以session_id为文件名,不同session_id有不同文件存储消息
- 继承BaseChatMessageHistory实现如下3个方法:
- add_messages:同步模式,添加消息
- messages:同步模式,获取消息
- clear:同步模式,清除消息

五.Document loaders文档加载器
文档加载器提供了一套标准接口,用于将不同来源(如 CSV、PDF 或 JSON等)的数据读取为 LangChain 的文档格式。这确保了无论数据来源如何,都能对其进行一致性处理。 文档加载器(内置或自行实现)需实现BaseLoader接口。
Class Document,是LangChain内文档的统一载体,所有文档加载器最终返回此类的实例。 一个基础的Document类实例,基于如下代码创建:
from langchain_core.documents import Document
document = Document(
page_content="Hello, world!", metadata={"source": "https://example.com"}
)
可以看到,Document类其核心记录了:
- page_content:文档内容
- metadata:文档元数据(字典)
不同的文档加载器可能定义了不同的参数,但是其都实现了统一的接口(方法)。
- load():一次性加载全部文档
- lazy_load():延迟流式传输文档,对大型数据集很有用,避免内存溢出。
5.1CSVLoader
from langchain_community.document_loaders.csv_loader import CSVLoader
loader = CSVLoader(file_path="./xxx.csv")
data = loader.load()
print(data)
自定义CSV文件的解析和加载:
loader = CSVLoader(
file_path=“./xxx.csv”,
csv_args={
“delimiter”: ",", # 指定分隔符
“quotechar”: '"' # 指定字符串的引号包裹
"fieldnames": ["name", "age", "gender"], # 字段列表(无表头使用,有表头勿用会读取首行做为数据)
},
)
data = loader.load()
print(data)
5.2JSONLoader
JSONLoader用于将JSON数据加载为Document类型对象。
使用JSONLoader需要额外安装: pip install jq

from langchain_community.document_loaders import JSONLoader
loader = JSONLoader(
file_path="xxx.json", # 文件路径
jq_schema=".", # jq schema语法
text_content=False, # 抽取的是否是字符串,默认True
json_lines=True, # 是否是JsonLines文件(每一行都是JSON的文件)
)
5.3PyPDFLoader
from langchain_community.document_loaders import PyPDFLoader
loader = PyPDFLoader(
file_path="", # 文件路径必填
mode='page', # 读取模式,可选page(按页面划分不同Document)和single(单个Document)
password='password', # 文件密码
)
5.4TextLoader和文档分割器
作用:读取文本文件(如.txt),将全部内容放入一个Document对象中。
from langchain_community.document_loaders import TextLoader
loader = TextLoader(
"xxx.txt",
encoding="utf-8",
)
docs = loader.load()
print(docs)
print(len(docs)) # 结果为1
如果文档很大 加载到一个Document对象中是否不太合适?
RecursiveCharacterTextSplitter,递归字符文本分割器,主要用于按自然段落分割大文档。 是LangChain官方推荐的默认字符分割器。

六.Vector stores 向量存储

如图,这是一个典型的向量存储应用,也即是典型的RAG流程。
这部分开发主要涉及到:
- 如何文本转向量(前文已经学习)
- 创建向量存储,基于向量存储完成:
- 存入向量 add_documents
- 删除向量 delete
- 向量检索 similarity_search
内置向量存储的使用:

外部(Chroma)向量存储的使用:

6.2检索向量并构建提示词
向量存储的实例,通过add_texts(list[str])方法可以快速添加到向量存储中。
vector_store.add_texts(["减肥就是要少吃多练","在减脂期吃东西很重要,清单少有控制卡路里","跑步是很好的运动"])
流程:
- 先通过向量存储检索匹配信息
- 将用户提问和匹配信息一同封装到提示词模板中提问模型
6.3RunnablePassthrough的使用

更多推荐



所有评论(0)