AI菜鸟向前飞 — LangChain系列之六 - 深入浅出

简介

LCEL是 LangChain Expression Language的缩写


先来做个程序书写的对比,观察一下、使用了Expression Language语法之后更加短小精悍(缩短了一倍长度,更加高级的用法缩短会更多)而且代码看起来更加简单易读。
  • 使用EL
1
2
3
4
5
javascript复制代码from langchain_community.chat_models import ChatOllama
from langchain.schema import HumanMessage
from langchain_core.output_parsers import StrOutputParser

(ChatOllama(model="llama3", temperature=0) | StrOutputParser()).invoke([HumanMessage(content="你好啊, AI小助手")])
  • 未使用EL
1
2
3
4
5
6
7
8
9
10
11
ini复制代码from langchain_community.chat_models import ChatOllama
from langchain.schema import HumanMessage
from langchain_core.output_parsers import StrOutputParser

chat = ChatOllama(model="llama3", temperature=0)

output_parser = StrOutputParser()

response = chat.invoke([HumanMessage(content="你好啊, AI小助手")])

output_parser.invoke(response)
Expression Language是一种将 **Runnable** 组成链 **(Runnables into chains)** 的声明性方式,以这种方式构建的任何链都将自动具有同步、异步、批处理、流支持等等,包含RunnableSequence 和 RunnableParallel两大部分内容。


    关于RunnableParallel内容,放到后面再介绍

RunnableSequence:按顺序调用一系列可运行对象,一个可运行对象的输出充当下一个可运行对象的输入,使用管道符号(即“|”)来分割两个对象。

1
2
3
arduino复制代码chain = prompt | model | output_parser

chain.invoke({"text": "你好啊, AI小助手"})

用一张图简单描绘这流式传输吧:

图片

把上图的组成统一成一个Chain(就是LangChain的“Chain”)

按步骤解析每个可运行对象的处理的过程和内容:

image.png

首先, 让我们看一下代码的完整执行过程

程序

1
2
3
4
5
6
7
8
9
10
11
12
13
ini复制代码from langchain_community.chat_models import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_template("{text}")
model = ChatOllama(model="llama3", temperature=0)
output_parser = StrOutputParser()

chain = prompt | model | output_parser

response = chain.invoke({"text": "你好啊, AI小助手"})

print(response)

输出结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
ruby复制代码[chain/start] [1:chain:RunnableSequence] Entering Chain run with input:
{
"text": "你好啊, AI小助手"
}
[chain/start] [1:chain:RunnableSequence > 2:prompt:ChatPromptTemplate] Entering Prompt run with input:
{
"text": "你好啊, AI小助手"
}
[chain/end] [1:chain:RunnableSequence > 2:prompt:ChatPromptTemplate] [0ms] Exiting Prompt run with output:
[outputs]
[llm/start] [1:chain:RunnableSequence > 3:llm:ChatOllama] Entering LLM run with input:
{
"prompts": [
"Human: 你好啊, AI小助手"
]
}
[llm/end] [1:chain:RunnableSequence > 3:llm:ChatOllama] [5.28s] Exiting LLM run with output:
{
"generations": [
[
{
"text": "😊 你好啊!我是你的AI小助手,欢迎你来到这里!有什么问题或需求,请随时问我,我会尽力帮助你。😊",
"generation_info": {
"model": "llama3",
"created_at": "2024-04-23T17:37:18.840986487Z",
"message": {
"role": "assistant",
"content": ""
},
"done": true,
"total_duration": 5271991298,
"load_duration": 1043179188,
"prompt_eval_count": 18,
"prompt_eval_duration": 1174320000,
"eval_count": 40,
"eval_duration": 2919644000
},
"type": "ChatGeneration",
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain",
"schema",
"messages",
"AIMessage"
],
"kwargs": {
"content": "😊 你好啊!我是你的AI小助手,欢迎你来到这里!有什么问题或需求,请随时问我,我会尽力帮助你。😊",
"tool_calls": [],
"invalid_tool_calls": []
}
}
}
]
],
"llm_output": null,
"run": null
}
[chain/start] [1:chain:RunnableSequence > 4:parser:StrOutputParser] Entering Parser run with input:
[inputs]
[chain/end] [1:chain:RunnableSequence > 4:parser:StrOutputParser] [0ms] Exiting Parser run with output:
{
"output": "😊 你好啊!我是你的AI小助手,欢迎你来到这里!有什么问题或需求,请随时问我,我会尽力帮助你。😊"
}
[chain/end] [1:chain:RunnableSequence] [5.28s] Exiting Chain run with output:
{
"output": "😊 你好啊!我是你的AI小助手,欢迎你来到这里!有什么问题或需求,请随时问我,我会尽力帮助你。😊"
}
😊 你好啊!我是你的AI小助手,欢迎你来到这里!有什么问题或需求,请随时问我,我会尽力帮助你。😊

上一个的输出就是下一个的输入

再分析, 整个Pipeline中每一个可运行的对象,其底层的jsonschema逻辑是什么?(绘制了四张思维导图来说明)

Pasted image 20240424014436.png

Pasted image 20240424014514.png

Pasted image 20240424014538.png

Pasted image 20240424014602.png

还剩余“前后”两个,即:

  • 整体Pipeline Chain输入的Schema(即:prompt的输入的json schema)
1
2
3
4
5
6
7
json复制代码{"title": "PromptInput",
"type": "object",
"properties": {
"text":
{"title": "Text", "type": "string"}
}
}
  • 整体Pipeline Chain输出的Schema(即:output_parser的输出的json schema)
1
json复制代码{"title": "StrOutputParserOutput", "type": "string"}

To be continue…

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%