LangChain的核心组件
模型I/O
- 提示 prompts: 将模型输入模板化、动态选择和管理
- 语言模型 models: 通过常见接口调用语言模型
- 输出解析器 output_parsers: 从模型输出中提取信息
语言模型
- LLMs: 输入一个文本字符串并返回一个文本字符串的模型
- 聊天模型: 由语言模型支持的模型,接受一个聊天消息列表作为输入并返回一个聊天消息
LMs和聊天模型在细微但重要的方面有所不同。
LangChain中的LLMs是指纯文本完成模型。它们包装的API接受一个字符串提示作为输入,并输出一个字符串完成。OpenAI的GPT-3是作为LLM实现的。
聊天模型通常由LLMs支持,但专门调整用于进行对话。关键是,它们的提供者API使用与纯文本完成模型不同的接口。它们不是接受单个字符串作为输入,而是接受一个聊天消息列表作为输入。通常,这些消息带有发言者标签(通常是“系统”,“AI”和“人类”之一)。它们返回一个AI聊天消息作为输出。GPT-4和Anthropic的Claude都是作为聊天模型实现的。
- 文本嵌入模型(Embedding Model): 这些模型将文本作为输入并返回浮点数列表,也就是Embedding。文本嵌入模型负责把文档存入向量数据库。
提示模板
直接创建PromptTemplate类
from langchain import PromptTemplate
# an example prompt with multiple input variables
multiple_input_prompt = PromptTemplate(
input_variables = ["adjective", "content"],
template = "Tell me a {adjective} joke about {content}."
)
multiple_input_prompt.format(adjective="funny", content="chickens")
# -> "Tell me a funny joke about chickens."
使用 from_template 类方法创建 PromptTemplate
template = "Tell me a {adjective} joke about {content}."
prompt_template = PromptTemplate.from_template(template)
prompt_template.input_variables
# -> ['adjective', 'content']
prompt_template.format(adjective="funny", content="chickens")
# -> Tell me a funny joke about chickens.
聊天提示模板
聊天模型以聊天消息列表作为输入,这个列表通常称为
prompt。 这些聊天消息与原始字符串不同(您会将其传递给 LLM 模型),因为每个消息都与一个role相关联。 LangChain 提供了几个提示模板,以便更轻松地构建和处理提示。
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])
其他提示模板
提示工程相关概念
Chain of Thought (CoT)
CoT 主要通过将推理过程链式化来增强模型的推理能力。其核心思想是让模型逐步地表达每个推理步骤,从而提高推理的透明度和正确性。
-
Few-Shot CoT:这种方法通过提供一些链式思考的示例,让模型学习如何按顺序进行推理。示例的作用是帮助模型理解如何逐步拆解问题,做出合理的推理。
- 示例:例如,对于一个数学问题,模型可以首先展示如何通过逐步运算得出答案。在 Few-Shot CoT 中,通常会给模型几个类似的推理示例,然后让模型在类似情境下按示例思考。
-
Zero-Shot CoT:与 Few-Shot CoT 不同,Zero-Shot CoT 直接告诉模型如何按步骤推理,而无需提供示例。模型在接到问题后,直接开始逐步推理并给出结论。
- 示例:如果问题是“如何选择适合的鲜花”,Zero-Shot CoT 会要求模型列出选择花卉时应考虑的各个因素,并按照顺序推理出一个合理的选择步骤。
Tree of Thought (ToT)
ToT 是对 CoT 思想的进一步扩展,它通过引入“思维树”这一结构,使推理过程更具层次性和多样性。与 CoT 依赖线性推理不同,ToT 通过在推理过程中进行搜索,探索多个可能的推理路径,从而更加全面地解决复杂问题。
-
核心思想:ToT 通过构建一个由连贯语言序列组成的“思维树”,来表示不同的推理路径和决策。这种树状结构允许模型在多个可能的推理路径之间进行搜索,从而找到最优的解决方案。
-
应用实例:以“鲜花选择”的问题为例,ToT 可以引导模型通过树状结构逐步探索不同的选项:
- 第一层:列出所有可选的鲜花种类(如玫瑰、百合、康乃馨等)。
- 第二层:根据不同的选择标准(如颜色、香气、价格等)对每种花卉进行分类和筛选。
- 第三层:进一步评估各花卉在不同场景中的适用性(如婚礼、生日等)。
最终,模型根据这些推理路径确定最合适的鲜花类型。
输出解析器
输出解析器是帮助结构化语言模型响应的类。一个输出解析器必须实现两个主要方法:
- "获取格式化指令": 一个返回包含语言模型输出应如何格式化的字符串的方法。
- "解析": 一个接受字符串(假设为语言模型的响应)并将其解析为某种结构的方法。
使用例:
# 导入结构化输出解析器和ResponseSchema
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
# 定义我们想要接收的响应模式
response_schemas = [ ResponseSchema(name="description", description="鲜花的描述文案"), ResponseSchema(name="reason", description="问什么要这样写这个文案") ]
# 创建输出解析器
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
# 获取格式指示
format_instructions = output_parser.get_format_instructions()
# 根据原始模板创建提示,同时在提示中加入输出解析器的说明
prompt = PromptTemplate.from_template(prompt_template, partial_variables={"format_instructions": format_instructions})
# 获取模型的输出
output = model.invoke(input)
# 解析模型的输出(这是一个字典结构)
parsed_output = output_parser.parse(output)