什么是LangChain?
源起:LangChain产生源于Harrison与领域内的一些人交谈,这些人正在构建复杂的LLM应用,他在开发方式
上看到了一些可以抽象的部分。一个应用可能需要多次提示LLM并解析其输出,因此需要编写大量的复制粘贴。
LangChain使这个开发过程更加简单。一经推出后,在社区被广泛采纳,不仅有众多用户,还有许多贡献者参
与开源工作。
还有大模型本身的问题,无法感知实时数据,无法和当前世界进行交互。
LangChain是一个用于开发大语言模型的框架。
主要特性:
\1. 数据感知:能够将语⾔模型与其他数据源进⾏连接。
\2. 代理性:允许语⾔模型与其环境进⾏交互。可以通过写⼯具的⽅式做各种事情,数据的写⼊更新。
主要价值:
1、组件化了需要开发LLM所需要的功能,提供了很多工具,方便使用。
2、有一些现成的可以完整特定功能的链,也可以理解为提高了工具方便使用。
LangChain 为以下模块提供了标准、可扩展的接口和外部集成,按照复杂程度从低到高列出:
与语言模型进行接口交互
与特定于应用程序的数据进行接口交互
构造调用序列
根据高级指令让链式组装选择要使用的工具
在链式组装的多次运行之间持久化应用程序状态
记录和流式传输任何链式组装的中间步骤
Model I/O = (Model + Prompt + Output Parsers)
Model:各种LLM,ChatGPT,ChatGLM,Claude,通义千问,vicuna
Prompts:模型输⼊的模板,可以动态替换内容,以及⼀些其他的⼯具模板
Output parsers:从模型输出中提取信息
prompt template
提示模板是指一种可复制的生成提示的方式。它包含一个文本字符串(“模板”),可以从最终用户那里接收一组参数并生成提示。
提示模板可以包含:
- 向语言模型提供指令,
- 一组少样本示例,以帮助语言模型生成更好的回复,
- 向语言模型提出问题。
from langchain import PromptTemplate
template = """\
你是一个新公司的命名咨询顾问.
为制作 {product} 的公司起一个好的名字?
"""
prompt = PromptTemplate.from_template(template)
prompt.format(product="五颜六色的袜子")
'你是一个新公司的命名咨询顾问.
为制作 五颜六色的袜子 的公司起一个好的名字?'
Example selectors
如果你有一些示例,可以需要去使用一些示例加到Prompt中。
from langchain.prompts import PromptTemplate
from langchain.prompts import FewShotPromptTemplate
from langchain.prompts.example_selector import LengthBasedExampleSelector
# 这里有很多关于创建反义词的示例。
examples = [
{"input": "happy", "output": "sad"},
{"input": "tall", "output": "short"},
{"input": "energetic", "output": "lethargic"},
{"input": "sunny", "output": "gloomy"},
{"input": "windy", "output": "calm"},
]
example_prompt = PromptTemplate(
input_variables=["input", "output"],
template="输入: {input}\n输出: {output}",
)
example_selector = LengthBasedExampleSelector(
# 这些是它可以选择的示例。
examples=examples,
# 这是用来格式化示例的PromptTemplate。
example_prompt=example_prompt,
# 这是格式化的示例应该的最大长度。
# 长度是通过下面的get_text_length函数来测量的。
max_length=25,
# 这是用来获取字符串长度的函数,用于确定要包含哪些示例。
# 它被注释掉了,因为如果没有指定,它会作为默认值提供。
# get_text_length: Callable[[str], int] = lambda x: len(re.split("\n| ", x))
)
dynamic_prompt = FewShotPromptTemplate(
# 我们提供一个ExampleSelector,而不是示例。
example_selector=example_selector,
example_prompt=example_prompt,
prefix="给出每个输入的反义词",
suffix="输入: {adjective}\n输出:",
input_variables=["adjective"],
)
print(dynamic_prompt.format(adjective="big"))
# 由于max_length设置了25.所以只有一个示例.
long_string = "big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else"
print(dynamic_prompt.format(adjective=long_string))
给出每个输入的反义词
输入: happy
输出: sad
输入: tall
输出: short
输入: energetic
输出: lethargic
输入: sunny
输出: gloomy
输入: windy
输出: calm
输入: big
输出:
给出每个输入的反义词
输入: happy
输出: sad
输入: big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else
输出:
输入为文本字符串,输出为文本字符串的模型
from langchain.llms import OpenAI
llm = OpenAI()
# 输入为字符串,输出也为字符串
output = llm("给我讲个笑话")
print(output)
两个病人在医院病房里,一个说:“你知道为什么医院的灯都是绿色的吗?”另一个病人答道:“不知道,为什么?”第一个病人说:“因为绿色是医生的最爱!”
由语言模型支持,输入为聊天消息列表,输出为聊天消息的模型
from langchain.chat_models import ChatOpenAI
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
chat = ChatOpenAI()
chat([HumanMessage(content="把下面的英文翻译为中文: I love programming.")])
AIMessage(content='我喜欢编程。', additional_kwargs={}, example=False)
语言模型输出文本。但很多时候,您可能希望获得比仅文本更结构化的信息。这就是输出解析器的作用。
输出解析器是帮助结构化语言模型响应的类。一个输出解析器必须实现两个主要方法:
然后再加一个可选的方法:
示例:列表解析器 comma_separated
当您想返回一个逗号分隔项的列表时,可以使用此输出解析器。
from gpt_server import ChatGLMService
llm_model_path = "/mnt/code/LLM_Service/model/chatglm2-6b-32k/"
chatLLM = ChatGLMService()
chatLLM.load_model(model_name_or_path=llm_model_path)
from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
output_parser = CommaSeparatedListOutputParser()
format_instructions = output_parser.get_format_instructions()
prompt = PromptTemplate(
template="List five {subject}.\n{format_instructions}",
input_variables=["subject"],
partial_variables={"format_instructions": format_instructions}
)
_input = prompt.format(subject="ice cream flavors")
output = chatLLM(_input)
print(output)
冰淇淋口味有很多种,这里列举五种常见的口味: 1. 巧克力味 2. 草莓味 3. 香草味 4. 芒果味 5. 巧克力、草莓和香草混合味
output_parser.parse(output)
[‘冰淇淋口味有很多种,这里列举五种常见的口味:\n\n1. 巧克力味\n2. 草莓味\n3. 香草味\n4. 芒果味\n5. 巧克力、草莓和香草混合味’]