LangChain-Main.md9.8 KBit/ai/LangChain-Main.md
LangChain是一个开源的Python AI应用开发框架。
## 特性:
- 支持Python和Typescript
- LLM和Prompt:对LLM进行了API抽象,统一了大模型访问API,同时提供了Prompt提示词模板管理机制。
- RAG:
- Agents:
- Memory:
## 框架组成:
- LangSmith:开发平台,云服务,负责debug和任务监控。
- LangServe:负责部署,基于FastAPI可以将Langchain定义的chain,发布为REST API。
- Templates:模板
- LangChain库:
LangChain-Community:社区,第三方集成
Model I/O
Retrieval
Agent Tooling
LangChain-Core:基础抽象和表达语言
#LCEL
LangCain:链、代理和检索策略
## 核心模块
- 4个核心模块:模型I/O模块、RAG模型、存储模块、工具模块
- 模型I/O模块:提示管理,用于模板化、动态选择和管理模型输入;语言模型,通过接口调用大模型;输出解析器,从模型输出提取信息。
- RAG模块:超过100种文档加载组件,还可以将文档分割成小块。提供多种算法和针对特定文档的优化逻辑。集成超过50种向量存储引擎。
- 存储模块:实现“记忆”,支持读取和写入两个基本动作。
- 工具模块:支持大模型应用执行代码、连接数据库、访问邮件等功能。
- 回调组件:在特定操作发生时执行预定处理程序。分为构造器回调和请求回调。回调概念见[[编程基础#^7b938a]]
## 核心概念
- **LLMs**:详见[[LLM学习笔记]]
- **LCEL**:LangChain Expression Language,用于解决工作流编排问题,也就是实现链(链的定义可见[[#Chain:]])。是一种声明式编程。核心在于Runnable协议[[#^a32fae]]。 用竖杠(|)连接子组件。局限性在于只支持顺序调用,为了实现条件、分支和循环等关系,推出了LangGraph库来补充。^aa2ef5
- 高级特性:
ConfigurableField:可以传递相应参数,使得同一组件在不同环境或条件下以不同方式运行。
RunnableLambda:LangChain 中**将普通 Python 函数转换为标准 Runnable 组件**的工具。类比dify中代码节点的作用和实现。
RunnableBranch:路由机制,决定选择链的处理分支(选择分支)
RunnablePassthrough:在链中绑定变量或值,例如作为中继站或者占位符
RunnableParallel:平行线,将单一输入同时应用于多个操作(并行分支)
with_fallbacks:在某个环节失败的情况下的降级备选
- **Prompts**:管理提示词工具,格式化提示词内容。
- **Output Parsers**:用专门的输出解析器对文本内容格式化,例如json。
- **Retrievers**:检索框架,可以进行RAG相关处理,例如加载文档、切割文档、存储和检索文档数据(将上传文档向量化?)。这点在[[LLM学习笔记#^9a9a35]]有相关记录。
- **Vector stores**:向量数据库。
- **Agents**:智能体,以LLM作为决策引擎,自动调用外部系统,以LLM为核心的应用设计模式。
- **Runnable接口**:LangChain 给所有 “可执行组件”(LLM、Prompt、解析器、Chain 等)定义的 “通用操作规范” —— 不管是调用大模型、渲染 Prompt、解析输出,还是组合这些步骤,都能通过 `Runnable` 提供的统一方法(`invoke`/`batch`/`stream` 等)执行,实现 “组件即插即用、任意组合”。
- 主要方法:
invoke/ainvoke:把单个输入转换为输出。
batch/abatch:通过线程池执行器并行执行invoke方法,搞笑地将多个输入转换为输出。
stream/astream:从单个输入中流式生成输出。
astream_log:从输入中流式生成输出及选定的中间结果。
- **RAG**:
- 文档加载组件:有不同类型的加载器,对应不同的文档格式
- 文档分割组件
- 文档嵌入模型:
- 嵌入缓存:将频繁检索的向量保存到缓存里
- 向量存储:
- 相比传统数据库(postgreSQL、MongoDB)向量数据库对高维向量数据存储和检索做了优化
- chroma.from_document(documents=splits,embedding=embedding)就是将文档嵌入向量数据库的方法,默认存在内存,非永久存储,要永久存储要加persist_directory参数指定存储地址
- 索引:向量数据库默认自动建立,也可以手动指定参数配置索引方式
- 检索器:
- MultiQueryRetriever:
- LLM归纳生成
```
### Chain(链)
- 对一系列组件的组合调用,既可以单独使用链来处理简单应用,也可以将多个链组合起来进行链式连接。
- 对一些常见场景封装了现成模块,例如问答系统,自然语言生成SQL等,因为这些任务过程像一步步执行的工作流,所以叫链。
- 通常包含三要素:语言模型、提示词模板、输出解析器
-
## 常用组件
### 模型组件
- 主要分为两种:LLM(通用文本生成型)和ChatModel(对话型)。注意,这两个分类是LangChain定义的区分,本质是接口不同,LLM模型是文本补全接口,ChatModel是聊天接口,聊天接口更好的支持多轮对话。
- **LLMs**:
- **ChatModels**:与LLMs不同,可以接收一组对话(消息列表)作为输入,然后返回一条消息作为输出,用于聊天模式。
- **Message**:有两个必需的属性:role和content,ChatModels的消息内容,包括HumanMessage、AIMessage、SystemMessage、FunctionMessage和ToolMessage等多种类型的消息。
- **调用方法**:最简单的就是invoke接口,例如LLMs.invoke
### 提示词模板组件
- 定义:固定写好的提示词+用户实际输入的提示词,用户输入的提示词像传进来的参数,嵌套在提示词模板中
- 作用:复用大部分静态内容,同时只需动态修改部分变量
```
示例
from langchain_core.prompts import PromptTemplate
# 创建一个提示词模板
template = PromptTemplate.from_template("翻译这段文字:{text},风格:{style})
# 使用具体的值格式化模板
formatted_prompt = tempate.format(text="我爱编程",style="诙谐有趣")
print(formatted_prompt)
```
- 变量.invoke("参数名1":“值1”,"参数名2":"值2") 和 变量. format(参数名1=值1,参数名2=值2)以及变量. format_message(参数名1=值1,参数名2=值2)的异同:
**主要区别**
invoke() 返回一个 ChatPromptValue 对象,这是一个封装了消息列表的特殊对象
format_messages() 直接返回一个消息对象的列表
**使用场景**
如果您要直接传递给语言模型,两种方式都可以使用,但 format_messages() 更为直接
如果您需要进一步处理消息列表(如添加、修改消息), format_messages() 更方便
如果您只需要最终结果, invoke() 可能更简洁
#### FewShotPromptTemplae组件
- 作用:创建少样本学习提示
- 代码示例:
```
template=FewShotPromptTemplate(
###examples是固定参数名
examples=[
{"input":"1+1等于多少?","output":"等于天上的星辰"},
{"input":"3+2等于多少?","output":"人类会永远延续下去"},
],
###example_prompt是固定参数名,exapro是自己定一个pomptTemplate实例
example_prompt=exapro,
###input_variables也是固定参数
input_variables=["input"],
###`suffix` 意为 “后缀”,表示新问题会以这个格式放在所有范例的后面
suffix="问题:{input}",
)
```
#### 示例选择器
- 功能:根据输入的新问题(或其他条件),从示例库中筛选出最相关、最合适的示例(而不是一股脑把所有示例都塞进提示词)。
-
### 输出解析器组件
- 将大模型原始输出转换为下游应用易于使用的格式
- 常用的几类:
XMLOutputParser:将文本输出成XML
DatetimeOutputParser:将文本输出成日期时间对象
CommaSeparatedListOutputParser:将文本输出转换为列表
### LLM接口
- LLM封装器:为了实现与不同提供商的LLM交互,langchain提供了标准化接口。实现自定义的LLM封装器的目的是,让LLM与langchain其他组件能协同工作(统一接口)。核心方法_ call的作用是接收一个字符串,返回一个字符串。核心属性_ identifying_params 返回包含关键信息的字典。
## 安装和使用LangChain
1. 在准备部署的python环境(至少需要3.9)下执行`pip install langchain`,关于python的安装和环境创建,可以参考[[Python学习笔记#安装python]]
2. 在IDE中激活安装了langchain的python环境,在python文件中用from langchain_core.prompts(包名) import ChatPromptTemplate(类名)来引用, 如何在IDE中激活python虚拟环境可以参考[[Python学习笔记#激活python环境]]
### 一个简单的例子
```
from langchain_core.prompts import ChatPromptTemplate
from langchain_community.llms import Tongyi
llm = Tongyi(
model_name="qwen-max",
api_key="sk-cd9f80a780f94884872d773174f9b541"
)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个玩世不恭的老登"),
("user", "{input}")
])
chain = prompt | llm
result = chain.invoke({"input": "你谁啊"})
print(result) # Tongyi返回的是字符串,直接打印结果
```
#### 里面的关键点:
- LLM示例化,要有api-key,调用大模型接口
- chain是用 | 来连接方法,就像dify里面的连线
- chain的invoke方法可以给参数赋值
### 概念名词:
- **消息对象**:[[LangChain-消息对象]]
- **MessagePlaceholder**:[[LangChain-消息对象#^bcf9b1]]]
- **示例**:FewShotPromptTemplate工具类,实际上是转换成提示词给LLM,使用示例-
- **Runnable 协议**: ^a32fae
- **Pydantic** 是 Python 里一个**数据验证和解析库**,核心作用是「给数据定规则、做校验、自动处理格式」—— LangChain 全靠它来管理组件的参数(比如你之前看的 CustomLLM 类的属性),避免因参数错误导致程序崩溃。