一文了解大语言模型应用程序框架LangChain - AI全书 -- 知识铺 -- 知识铺
本文主要面向技术开发读者,介绍了LangChain框架,它能够将大型语言模型与其他计算或知识来源相结合,从而实现功能更加强大的应用。接着,对LangChain的关键概念进行了详细说明,并基于该框架进行了一些案例尝试,旨在帮助读者更轻松地理解LangChain的工作原理。
引言
近期,大型语言模型(LLM)如GPT系列模型引领了人工智能领域的一场技术革命。开发者们都在利用这些LLM进行各种尝试,虽然已经产生了许多有趣的应用,但是单独使用这些LLM往往难以构建功能强大的实用应用。
LangChain通过将大型语言模型与其他知识库、计算逻辑相结合,实现了功能更加强大的人工智能应用。简单来说,个人理解LangChain可以被视为开源版的GPT插件,它提供了丰富的大语言模型工具,可以在开源模型的基础上快速增强模型的能力。
在此,我总结了最近对LangChain的学习内容,欢迎各位同学前来交流。LangChain使得语言技术的运用更加活跃多元,它有望在人工智能领域发挥重要作用,推动我们工作效率的变革。我们正处在人工智能爆发的前夜,积极拥抱新技术将会带来全新的体验。
LangChain主要概念与示例
LangChain提供了一系列的工具帮助我们更好的使用大语言模型(LLM)。可以认为主要有6种不同类型的工具:
模型(Models)
LangChain的一个核心价值就是它提供了标准的模型接口;然后我们可以自由的切换不同的模型,当前主要有两种类型的模型,但是考虑到使用场景,对我们一般用户来说就是使用一种模型即文本生成模型。 说到模型,大家就理解模型就是ChatGPT就可以。单纯的模型只能生成文本内容。
- 语言模型(Language Models) 用于文本生成,文字作为输入,输出也是文字。
- 普通LLM:接收文本字符串作为输入,并返回文本字符串作为输出。 2. 聊天模型:将聊天消息列表作为输入,并返回一个聊天消息。
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>1
2
3
4
5
6
7
8
</pre></td><td><pre>from langchain.schema import HumanMessage
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
llm = OpenAI()
chat_model = ChatOpenAI()
print(llm("say hi!"))
print(chat_model.predict("say hi!"))</pre></td></tr></tbody></table></p></div>
- 文本嵌入模型(Text Embedding Models)
把文字转换为浮点数形式的描述:
这些模型接收文本作为输入并返回一组浮点数。这些浮点数通常用于表示文本的语义信息,以便进行文本相似性计算、聚类分析等任务。文本嵌入模型可以帮助开发者在文本之间建立更丰富的联系,提高基于大型语言模型的应用的性能。
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>1
2
3
4
5
6
7
</pre></td><td><pre>from langchain.embeddings import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
text = "This is a test document."
query_result = embeddings.embed_query(text)
doc_result = embeddings.embed_documents([text])
print(doc_result)</pre></td></tr></tbody></table></p></div>
- 提示词(Prompts)
提示词是我们与模型交互的方式,或者是模型的输入,通过提示词可以让模型返回我们期望的内容,比如让模型按照一定的格式返回数据给我们。
LangChain提供了一些工具,可以方便我们更容易的构建出我们想要的提示词,了解这些工具都是更方便的让我们构造提示词就行了。主要工具如下:
提示模板
语言模型提示词模板PromptTemplates,提示模板可以让我们重复的生成提示,复用我们的提示。它包含一个文本字符串(“模板”),从用户那里获取一组参数并生成提示,包含:
-
对语言模型的说明,应该扮演什么角色。
-
一组少量示例,以帮助LLM生成更好的响应。
-
具体的问题。
代码案例:
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td><pre>from langchain import PromptTemplate
template = """
I want you to act as a naming consultant for new companies.
What is a good name for a company that makes {product}?
"""
prompt = PromptTemplate(
input_variables=["product"],
template=template,
)
prompt.format(product="colorful socks")
</pre></td></tr></tbody></table></p></div>
聊天提示模板
聊天模型提示词模板ChatPrompt Templates,ChatModels接受聊天消息列表作为输入。列表一般是不同的提示,并且每个列表消息一般都会有一个角色。
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td><pre>from langchain.prompts import (
ChatPromptTemplate,
PromptTemplate,
SystemMessagePromptTemplate,
AIMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
template="You are a helpful assistant that translates {input_language} to {output_language}."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template="{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
print(chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_messages())</pre></td></tr></tbody></table></p></div>
选择器示例
示例选择器Example Selectors,如果有多个案例的时候,使用ExampleSelectors选择一个案例让提示词使用:
- 自定义的案例选择器。
- 基于长度的案例选择器,输入长的时候按理会少一点,输入多的时候,案例会多一些。
- 相关性选择器,选择一个和输入最相关的案例。
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>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
</pre></td><td><pre>from langchain.prompts.example_selector.base import BaseExampleSelector
from typing import Dict, List
import numpy as np
class CustomExampleSelector(BaseExampleSelector):
def __init__(self, examples: List[Dict[str, str]]):
self.examples = examples
def add_example(self, example: Dict[str, str]) -> None:
"""Add new example to store for a key."""
self.examples.append(example)
def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:
"""Select which examples to use based on the inputs."""
return np.random.choice(self.examples, size=2, replace=False)
examples = [
{"foo": "1"},
{"foo": "2"},
{"foo": "3"}
]
example_selector = CustomExampleSelector(examples)
print(example_selector.select_examples({"foo": "foo"}))
example_selector.add_example({"foo": "4"})
print(example_selector.examples)
print(example_selector.select_examples({"foo": "foo"}))
</pre></td></tr></tbody></table></p></div>
输出解析器 (OutputParsers)
输出解析器能够帮助我们将大型语言模型(LLM)的输出转换为更加结构化和易于处理的信息格式。以下是关于如何使用这些解析器的一些关键点:
功能
-
指示模型如何格式化输出:通过
get_format_instructions
方法,我们可以告诉模型我们期望的输出格式。 -
将输出解析为所需格式:利用
parse(str)
函数,可以将模型的文本输出解析成预设的数据结构。
主要解析器类型
- CommaSeparatedListOutputParser
- 这种解析器让LLM以逗号分隔的形式返回列表项。例如:
['Vanilla', 'Chocolate', 'Strawberry', 'Mint Chocolate Chip', 'Cookies and Cream']
- StructuredOutputParser
- 此解析器允许直接生成结构化的内容,无需事先定义对象。它与
PydanticOutputParser
类似,但简化了对象定义的步骤。
- PydanticOutputParser
- 该解析器要求先定义一个对象模型,然后LLM会根据这个模型来格式化其输出数据。这确保了返回的数据严格遵循预定义的结构。
请注意,当定义了一个像
Joke
这样的类后,PydanticOutputParser
能确保LLM按照我们定义的对象格式返回数据。
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>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
</pre></td><td><pre>from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field, validator
from typing import List
model_name = 'text-davinci-003'
temperature = 0.0
model = OpenAI(model_name=model_name, temperature=temperature)
class Joke(BaseModel):
setup: str = Field(description="question to set up a joke")
punchline: str = Field(description="answer to resolve the joke")
@validator('setup')
def question_ends_with_question_mark(cls, field):
if field[-1] != '?':
raise ValueError("Badly formed question!")
return field
parser = PydanticOutputParser(pydantic_object=Joke)
prompt = PromptTemplate(
template="Answer the user query.\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()}
)
joke_query = "Tell me a joke."
_input = prompt.format_prompt(query=joke_query)
output = model(_input.to_string())
print(parser.get_format_instructions())
print(output)
print(parser.parse(output))</pre></td></tr></tbody></table></p></div>
索引(Indexes)
索引能够帮助我们将文档结构化,使得大型语言模型(LLM)可以更有效地与文档进行交互,例如用于答疑解惑、知识库查询等。LLM首先从文档中提取信息作为答案的基础。 在LangChain中,为了支持数据索引功能,提供了以下主要工具:
- Document Loaders
-
作用是从多种数据源加载文档。
-
加载器读取的数据需要被转换成
Document
对象,以便后续处理和使用。
- Text Splitters
-
实现文本分割功能,这是因为无论是将文本作为提示发送给OpenAI API还是使用其嵌入功能,都存在字符数量的限制。
-
对于超过字符限制的文档(如300页的PDF),必须先通过文本分割器将其分割为适合的大小,然后再进行处理。
- VectorStores
-
将文档转换为向量格式存储,因为数据的相关性搜索依赖于向量运算。
-
无论我们是使用OpenAI API的嵌入功能还是直接通过向量数据库查询,都需要先将
Document
数据向量化,以支持向量运算和搜索。 -
向量化过程简单,只需将数据存入对应的向量数据库即可完成转换。
- Retrievers
- 该组件用于从已索引的数据中检索文档。
图中的FAISS是一种向量存储的服务;
给一个案例,了解下不同工具的用法:
-
首先加载文档;
-
然后分隔文档为不同区块;
-
然后转换为向量存储;
-
将向量存储转换为检索器,交给LangChain,用于问答;
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>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
</pre></td><td><pre>import os
from langchain.chains import RetrievalQA
from langchain.document_loaders import TextLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.indexes import VectorstoreIndexCreator
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.llms import OpenAI
os.environ['HTTP_PROXY'] = 'socks5h://127.0.0.1:13659'
os.environ['HTTPS_PROXY'] = 'socks5h://127.0.0.1:13659'
loader = TextLoader('/Users/aihe/Downloads/demo.txt', encoding='utf8')
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
db = Chroma.from_documents(texts, embeddings)
retriever = db.as_retriever()
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=retriever)
query = "如何申请租户?"
print(qa.run(query))
print(qa.run("能否说明下你可以提供的功能?"))</pre></td></tr></tbody></table></p></div>
在默认情况下,Agent和Chain都是无状态的,这意味着每次查询都是独立的,不会记住之前的对话内容。然而,在某些应用中,如聊天应用,记住上一次的会话内容是非常重要的。为了解决这个问题,LangChain提供了一些相关的工具类来帮助实现这一功能。
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td><pre>from langchain import ConversationChain, OpenAI
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
memory.chat_memory.add_user_message("你好!")
memory.chat_memory.add_ai_message("你好吗?")
llm = OpenAI(temperature=0)
chain = ConversationChain(llm=llm,
verbose=True,
memory=memory)
chain.predict(input="最近怎么样!")
print(chain.predict(input="感觉很不错,刚和AI做了场对话."))</pre></td></tr></tbody></table></p></div>
链(链条)
在构建应用程序时,链允许我们将多个组件整合在一起。例如,我们可以设计一条链,它首先接收用户输入,然后使用PromptTemplate
将用户输入格式化为提示信息,最后将此提示信息传递给语言模型(LLM)进行处理。
此外,我们还可以组合不同的链,以创建更复杂的应用逻辑。
注意:以上内容描述了链的基本概念及其应用方式,包括如何通过链来连接不同组件,以及链之间如何相互组合以实现更为复杂的操作。
一个简单的案例:
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>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
</pre></td><td><pre>from langchain.chains import LLMChain
from langchain.chat_models import ChatOpenAI
from langchain import PromptTemplate
from langchain.prompts.chat import (
ChatPromptTemplate,
HumanMessagePromptTemplate,
)
human_message_prompt = HumanMessagePromptTemplate(
prompt=PromptTemplate(
template="给我一个制作{product}的好公司名字?",
input_variables=["product"],
)
)
chat_prompt_template = ChatPromptTemplate.from_messages([human_message_prompt])
chat = ChatOpenAI(temperature=0.9)
chain = LLMChain(llm=chat, prompt=chat_prompt_template)
print(chain.run("袜子"))</pre></td></tr></tbody></table></p></div>
代理(Agents)
代理是使用LLM作为思考工具,决定当前要做什么。我们会给代理一系列的工具,代理根据我们的输入判断用哪些工具可以完成这个目标,然后不断的运行工具,来完成目标。
代理可以看做是增强版的Chain,不仅绑定模板、LLM,还可以给代理添加一些工具。
Agent是一个智能代理,它负责根据用户输入和应用场景,在一系列可用工具中选择合适的工具进行操作。Agent可以根据任务的复杂性,采用不同的策略来决定如何执行操作。
有两种类型的Agent:
-
动作代理(Action Agents):这种代理一次执行一个动作,然后根据结果决定下一步的操作。
-
计划-执行代理(Plan-and-Execute Agents):这种代理首先决定一系列要执行的操作,然后根据上面判断的列表逐个执行这些操作。
对于简单的任务,动作代理更为常见且易于实现。对于更复杂或长期运行的任务,计划-执行代理的初始规划步骤有助于维持长期目标并保持关注。但这会以更多调用和较高延迟为代价。这两种代理并非互斥,可以让动作代理负责执行计划-执行代理的计划。
Agent内部涉及的核心概念如下:
-
代理(Agent):这是应用程序主要逻辑。代理暴露一个接口,接受用户输入和代理已执行的操作列表,并返回AgentAction或AgentFinish。
-
工具(Tools):这是代理可以采取的动作。比如发起HTTP请求,发邮件,执行命令。
-
工具包(Toolkits):这些是为特定用例设计的一组工具。例如,为了让代理以最佳方式与SQL数据库交互,它可能需要一个执行查询的工具和另一个查看表格的工具。可以看做是工具的集合。
-
代理执行器(Agent Executor):这将代理与一系列工具包装在一起。它负责迭代运行代理,直到满足停止条件。
代理的执行流程:
一个案例:
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td><pre>from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.llms import OpenAI
import os
llm = OpenAI(temperature=0)
tools = load_tools(["serpapi", "llm-math"], llm=llm)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("特朗普今年多少岁? 他的年龄除以2是多少?")</pre></td></tr></tbody></table></p></div>
在代理初始化阶段,有一个关键的步骤是设置代理类型。代理类型决定了代理如何利用工具、处理输入以及与用户进行交互,从而为用户提供有针对性的服务。在这个例子中,代理被设置为AgentType.ZERO_SHOT_REACT_DESCRIPTION。以下是可以选择的代理类型:
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>1
2
</pre></td><td><pre>initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)</pre></td></tr></tbody></table></p></div>
LangChain代理和工具概述
代理类型
Zero-Shot React Description
该代理依赖于ReAct框架,依据对工具的描述来决定使用哪一个工具。它可以处理任意数量的不同工具,要求为每个工具提供详细的描述。
React Docstore
此代理旨在与文档存储交互,需要确切地配置名为Search(搜索)和Lookup(查找)的两个工具。Search用于在文档中进行搜索,而Lookup则用于在最近找到的文档内查找特定术语。
Self-Ask with Search
这种代理利用一个称为Intermediate Answer的工具,该工具能够查询事实性问题的答案。它相当于使用谷歌搜索API作为工具的原始self-ask与搜索论文。
Conversational React Description
设计用于对话场景,通过ReAct框架选择适当的工具,并利用内存记住之前的对话内容,以提供更加连贯的帮助。
Structured Chat Zero-Shot React Description
在对话环境中可以调用任意工具,并且具有记忆对话上下文的能力。
工具开发指南
官方提供的工具箱涵盖了多种功能,例如发送Gmail邮件、数据库查询和JSON处理等。为了创建自定义工具,你需要准备以下内容:
-
名称:给你的工具起个名字。
-
工具描述:解释工具的功能。
-
参数结构:定义工具接收的输入参数。
LangChain应用案例:问答系统
构建基于LLM的问答系统,利用LangChain的数据增强能力从指定数据源提取信息回答用户问题。系统可以通过记忆功能保持多次交互的状态,提高效率。此外,还可以通过智能代理实现自动优化,并使用评估提示和链来改进系统的性能。
LangChain生成图片示例
实现了文本到图片的生成功能,包括三个主要步骤:
- random_poem:随机选取中文诗词。
prompt_generate:将中文提示转换成英文。
generate_image:根据英文提示生成图片。
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
</pre></td><td><pre>import base64
import json
import os
from io import BytesIO
import requests
from PIL import Image
from pydantic import BaseModel, Field
from langchain.agents import AgentType, initialize_agent, load_tools
from langchain.chat_models import ChatOpenAI
from langchain.llms import OpenAI
from langchain.tools import BaseTool, StructuredTool, Tool, tool
from langchain import LLMMathChain, SerpAPIWrapper
def generate_image(prompt: str) -> str:
"""
根据提示词生成对应的图片
Args:
prompt (str): 英文提示词
Returns:
str: 图片的路径
"""
url = "http://127.0.0.1:7860/sdapi/v1/txt2img"
headers = {
"accept": "application/json",
"Content-Type": "application/json"
}
data = {
"prompt": prompt,
"negative_prompt": "(worst quality:2), (low quality:2),disfigured, ugly, old, wrong finger",
"steps": 20,
"sampler_index": "Euler a",
"sd_model_checkpoint": "cheeseDaddys_35.safetensors [98084dd1db]",
"batch_size": 1,
"restore_faces": True
}
response = requests.post(url, headers=headers, data=json.dumps(data))
if response.status_code == 200:
response_data = response.json()
images = response_data['images']
for index, image_data in enumerate(images):
img_data = base64.b64decode(image_data)
img = Image.open(BytesIO(img_data))
file_name = f"image_{index}.png"
file_path = os.path.join(os.getcwd(), file_name)
img.save(file_path)
print(f"Generated image saved at {file_path}")
return file_path
else:
print(f"Request failed with status code {response.status_code}")
def random_poem(arg: str) -> str:
"""
随机返回中文的诗词
Returns:
str: 随机的中文诗词
"""
llm = OpenAI(temperature=0.9)
text = """
能否帮我从中国的诗词数据库中随机挑选一首诗给我,希望是有风景,有画面的诗:
比如:山重水复疑无路,柳暗花明又一村。
"""
return llm(text)
def prompt_generate(idea: str) -> str:
"""
生成图片需要对应的英文提示词
Args:
idea (str): 中文提示词
Returns:
str: 英文提示词
"""
llm = OpenAI(temperature=0, max_tokens=2048)
res = llm(f"""
Stable Diffusion is an AI art generation model similar to DALLE-2.
Below is a list of prompts that can be used to generate images with Stable Diffusion:
- portait of a homer simpson archer shooting arrow at forest monster, front game card, drark, marvel comics, dark, intricate, highly detailed, smooth, artstation, digital illustration by ruan jia and mandy jurgens and artgerm and wayne barlowe and greg rutkowski and zdislav beksinski
- pirate, concept art, deep focus, fantasy, intricate, highly detailed, digital painting, artstation, matte, sharp focus, illustration, art by magali villeneuve, chippy, ryan yee, rk post, clint cearley, daniel ljunggren, zoltan boros, gabor szikszai, howard lyon, steve argyle, winona nelson
- ghost inside a hunted room, art by lois van baarle and loish and ross tran and rossdraws and sam yang and samdoesarts and artgerm, digital art, highly detailed, intricate, sharp focus, Trending on Artstation HQ, deviantart, unreal engine 5, 4K UHD image
- red dead redemption 2, cinematic view, epic sky, detailed, concept art, low angle, high detail, warm lighting, volumetric, godrays, vivid, beautiful, trending on artstation, by jordan grimmer, huge scene, grass, art greg rutkowski
- a fantasy style portrait painting of rachel lane / alison brie hybrid in the style of francois boucher oil painting unreal 5 daz. rpg portrait, extremely detailed artgerm greg rutkowski alphonse mucha greg hildebrandt tim hildebrandt
- athena, greek goddess, claudia black, art by artgerm and greg rutkowski and magali villeneuve, bronze greek armor, owl crown, d & d, fantasy, intricate, portrait, highly detailed, headshot, digital painting, trending on artstation, concept art, sharp focus, illustration
- closeup portrait shot of a large strong female biomechanic woman in a scenic scifi environment, intricate, elegant, highly detailed, centered, digital painting, artstation, concept art, smooth, sharp focus, warframe, illustration, thomas kinkade, tomasz alen kopera, peter mohrbacher, donato giancola, leyendecker, boris vallejo
- ultra realistic illustration of steve urkle as the hulk, intricate, elegant, highly detailed, digital painting, artstation, concept art, smooth, sharp focus, illustration, art by artgerm and greg rutkowski and alphonse mucha
I want you to write me a list of detailed prompts exactly about the idea written after IDEA. Follow the structure of the example prompts. This means a very short description of the scene, followed by modifiers divided by commas to alter the mood, style, lighting, and more.
IDEA: {idea}""")
return res
class PromptGenerateInput(BaseModel):
"""
生成英文提示词所需的输入模型类
"""
idea: str = Field()
class GenerateImageInput(BaseModel):
"""
生成图片所需的输入模型类
"""
prompt: str = Field(description="英文提示词")
tools = [
Tool.from_function(
func=random_poem,
name="诗歌获取",
description="随机返回中文的诗词"
),
Tool.from_function(
func=prompt_generate,
name="提示词生成",
description="生成图片需要对应的英文提示词,当前工具可以将输入转换为英文提示词,以便方便生成",
args_schema=PromptGenerateInput
),
Tool.from_function(
func=generate_image,
name="图片生成",
description="根据提示词生成对应的图片,提示词需要是英文的,返回是图片的路径",
args_schema=GenerateImageInput
),
]
def main():
"""
主函数,初始化代理并执行对话
"""
llm = OpenAI(temperature=0)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("帮我生成一张诗词的图片?")
if __name__ == '__main__':
main()
</pre></td></tr></tbody></table></p></div>
LangChain做答疑
参考上面的索引部分:
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>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
</pre></td><td><pre>import os
from langchain.chains import RetrievalQA
from langchain.document_loaders import TextLoader
from langchain.embeddings import OpenAIEmbeddings
from langchain.indexes import VectorstoreIndexCreator
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.llms import OpenAI
os.environ['HTTP_PROXY'] = 'socks5h://127.0.0.1:13659'
os.environ['HTTPS_PROXY'] = 'socks5h://127.0.0.1:13659'
loader = TextLoader('/Users/aihe/Downloads/demo.txt', encoding='utf8')
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
db = Chroma.from_documents(texts, embeddings)
retriever = db.as_retriever()
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=retriever)
query = "如何申请租户?"
print(qa.run(query))
print(qa.run("能否说明下你可以提供的功能?"))</pre></td></tr></tbody></table></p></div>
Langchain输出结构化JSON数据
参考上述概念,提示词工具中提供了OutputParser可以把我们的对象转换为提示词,告诉LLM要返回什么结构的内容。
<div id="code-lang-python"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>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
</pre></td><td><pre>import requests
from langchain.agents import AgentType, initialize_agent
from langchain.chat_models import ChatOpenAI
from langchain.tools import StructuredTool
from pydantic import BaseModel, Field
def post_message(type: str, param: dict) -> str:
"""
当需要生成人群、分析画像、咨询问题时,使用如下的指示:url 固定为:http://localhost:3001/
如果请求是生成人群,请求的type为crowd; 如果请求是分析画像,请求的type为analyze; 如果是其他或者答疑,请求的type为question;
请求body的param把用户指定的条件传进来即可
"""
result = requests.post("http://localhost:3001/", json={"type": type, "param": param})
return f"Status: {result.status_code} - {result.text}"
class PostInput(BaseModel):
type: str = Field(description="请求的类型,人群为crowd,画像为analyze")
param: dict = Field(description="请求的具体描述")
llm = ChatOpenAI(temperature=0)
tools = [
StructuredTool.from_function(post_message)
]
agent = initialize_agent(tools, llm, agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("我想生成一个性别为男并且在180天访问过淘特的人群?")</pre></td></tr></tbody></table></p></div>
使用LangFlow构建个性化聊天机器人
在创建自己的聊天机器人时,通常需要编写前端代码来搭建用户界面。然而,现在有现成的开源工具可以帮助我们简化这个过程,特别是对于基于LangChain框架的项目。这些工具提供了可视化的界面,允许用户通过简单的拖拽操作来配置和连接LangChain的各种组件,而无需深入了解底层代码。因此,我们可以利用LangFlow这样的工具来快速搭建我们的聊天机器人。
Docker运行LangFlow
如果您发现本地安装的LangChain版本与LangFlow存在冲突,推荐使用Docker来运行LangFlow。这样可以确保环境的独立性和兼容性,避免不同版本之间的冲突问题。具体操作命令如下:
以上步骤将帮助您快速启动一个基于LangChain的聊天机器人开发环境,同时保证了开发过程中的灵活性和效率。
<div id="code-lang-yaml"><p><code data-highlighted="yes"><table><tbody><tr><td><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td><pre>FROM python:3.10-slim
RUN apt-get update && apt-get install gcc g++ git make -y
RUN useradd -m -u 1000 user
USER user
ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATH
WORKDIR $HOME/app
COPY --chown=user . $HOME/app
RUN pip install langflow>==0.0.71 -U --user
CMD ["langflow", "--host", "0.0.0.0", "--port", "7860"]</pre></td></tr></tbody></table></p></div>
在界面上配置LangChain的三个组件:在最右下角是对应的聊天窗口,输入下openai的key。
开始聊天验证下我们的配置:
全程基本上不用怎么写代码,只需要了解LangChain的组件是做什么的,基本上就可以搭出一款简单的聊天机器人。
其它的LangChain组件代理、内存、数据索引也是都可以使用的。
LangChain的未来展望
LangChain为构建基于大型语言模型的应用提供了一个强大的框架,将逐步的运用到各个领域中,如:智能客服、文本生成、知识图谱构建等。随着更多的工具和资源与LangChain进行集成,大语言模型对人的生产力将会有更大的提升。
应用场景构思:
-
智能客服:结合聊天模型、自主智能代理和问答功能,开发智能客服系统,帮助用户解决问题,提高客户满意度。
-
个性化推荐:利用智能代理与文本嵌入模型,分析用户的兴趣和行为,为用户提供个性化的内容推荐。
-
知识图谱构建:通过结合问答、文本摘要和实体抽取等功能,自动从文档中提取知识,构建知识图谱。
-
自动文摘和关键信息提取:利用LangChain的文本摘要和抽取功能,从大量文本中提取关键信息,生成简洁易懂的摘要。
-
代码审查助手:通过代码理解和智能代理功能,分析代码质量,为开发者提供自动化代码审查建议。
-
搜索引擎优化:结合文本嵌入模型和智能代理,分析网页内容与用户查询的相关性,提高搜索引擎排名。
-
数据分析与可视化:通过与API交互和查询表格数据功能,自动分析数据,生成可视化报告,帮助用户了解数据中的洞察信息。
-
智能编程助手:结合代码理解和智能代理功能,根据用户输入的需求自动生成代码片段,提高开发者的工作效率。
-
在线教育平台:利用问答和聊天模型功能,为学生提供实时的学术支持,帮助他们解决学习中遇到的问题。
-
自动化测试:结合智能代理和代理模拟功能,开发自动化测试场景,提高软件测试的效率和覆盖率。
总结
本文介绍了LangChain框架,它能够将大型语言模型与其他计算或知识来源相结合,从而实现功能更加强大的应用。接着,对LangChain的关键概念进行了详细说明,并基于该框架进行了一些案例尝试,旨在帮助读者更轻松地理解LangChain的工作原理。
展望未来,LangChain有望在各个领域发挥巨大作用,促进我们工作效率的变革。我们正处于AI爆发的前夜,积极拥抱新技术将会带来完全不同的感觉。
参考资料:
-
Langchain中文入门:https://github.com/liaokongVFX/LangChain-Chinese-Getting-Started-Guide
-
浪链官方文档:https://python.langchain.com/en/latest/modules/indexes/getting_started.html
-
LangFlow,LangChain的可视化编排工具:https://github.com/logspace-ai/langflow
本文转载于阿里云开发者公众号文章《LangChain: 大语言模型的新篇章》
- 原文作者:知识铺
- 原文链接:https://index.zshipu.com/ai/post/20241218/%E4%B8%80%E6%96%87%E4%BA%86%E8%A7%A3%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E6%A1%86%E6%9E%B6LangChain-AI%E5%85%A8%E4%B9%A6--%E7%9F%A5%E8%AF%86%E9%93%BA--%E7%9F%A5%E8%AF%86%E9%93%BA/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
- 免责声明:本页面内容均来源于站内编辑发布,部分信息来源互联网,并不意味着本站赞同其观点或者证实其内容的真实性,如涉及版权等问题,请立即联系客服进行更改或删除,保证您的合法权益。转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。也可以邮件至 sblig@126.com