环境:OpenEuler、Windows 11、WSL 2、Python 3.12.3 langchain 0.3
背景:前期忙碌的开发阶段结束,需要沉淀自己的应用知识,过一遍LangChain
时间:20250212
说明:技术梳理
提示模板将用户输入和参数转换为语言模型的指令,以此来实现模型的响应,帮助它理解上下文并生成相关且连贯的基于语言的输出。其接受一个字典作为输入,其中每个键代表提示模板中要填充的一个变量。它会输出一个PromptValue,这个参数值可以传递给LLM或ChatModel,也可以转换为字符串或消息列表,存在此值的原因是为了便于在字符串和消息之间切换。
用于格式化单个字符串,通常用于更简单的输入,该模板由字符串模板组成。它接受用户提供的参数集,可用于生成语言模型的提示。模板可以使用f-strings(默认)、jinja2或mustache语法进行格式化,建议使用f-string方式(安全方面考虑)
from langchain_core.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template("Tell me a joke about {topic}")
prompt_template.invoke({"topic": "cats"})
为大型语言模型提供少量这样的示例称为少量示例提示,这是引导生成的一种简单而强大的方法,在某些情况下可以显著提高模型性能。少量示例提示模板可以从一组示例构建,也可以从负责从定义的集合中选择子集的示例选择器类构建。
此处有详细介绍:langchain系列 - FewShotPromptTemplate 少量示例-CSDN博客
用于格式化消息列表。这些“模板”由模板本身的列表组成
from langchain_core.prompts import ChatPromptTemplate
prompt_template = ChatPromptTemplate([
("system", "You are a helpful assistant"),
("user", "Tell me a joke about {topic}")
])
prompt_template.invoke({"topic": "cats"})
在上面的例子中,这个ChatListTemplate在被调用时将构造两条消息。第一个是系统消息,它没有要格式化的变量。第二个是HumanMessage,它将由用户传入的topic
变量格式化。
用于在特定位置添加消息列表
在上面的聊天模板中,我们看到了如何格式化两条消息,每条消息都是一个字符串。但是,如果我们希望用户传递一个消息列表,并将其插入特定的位置,这时需要使用MessagesPlaceholder的方式
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage
prompt_template = ChatPromptTemplate([
("system", "You are a helpful assistant"),
MessagesPlaceholder("msgs")
])
prompt_template.invoke({"msgs": [HumanMessage(content="hi!")]})
这将产生两条消息的列表,第一条是系统消息,第二条是我们传入的HumanMessage。如果我们传入了5条消息,那么它总共会产生6条消息(系统消息加上传入的5条消息)。这对于将消息列表插入特定位置非常有用
上述示例为显式使用,下面为隐式使用
prompt_template = ChatPromptTemplate([
("system", "You are a helpful assistant"),
("placeholder", "{msgs}") # <-- This is the changed part
])
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
# 调用一个大模型,qwen的开源,可以自己获取
translate_llm = ChatOpenAI(base_url="https://llm.xxx.xxxx.com/v1/",openai_api_key="sk-xxxxxxxxxx",model_name="qwen2.5-instruct")
# 创建一个提示词模板,变量即为用户输入的英文
translate_prompt = PromptTemplate.from_template("请将英文翻译为中文, 问题:{input}")
print("translate_prompt:", translate_prompt)
# 构造链,最终以字符串格式输出
model = translate_prompt | translate_llm | StrOutputParser()
# 调用链
response = model.invoke({"input":"hello"})
print("response:", response)
# 输出打印内容
(venv) jack@desktop-legion-7000k:~/lang_test$ python translate_tt.py
translate_prompt: input_variables=['input'] input_types={} partial_variables={} template='请将英文翻译为中文, 问题:{input}'
response: 翻译:你好
以上示例可以成功执行,由此可以看出:translate_prompt是一个对象,其属性template为自定义的字符串
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
# 调用一个大模型,qwen的开源,可以自己获取
translate_llm = ChatOpenAI(base_url="https://llm.xxxxxx.com/v1/",openai_api_key="sk-xxxxxxxx",model_name="qwen2.5-instruct")
# 创建一个提示词模板,变量即为用户输入的英文
translate_prompt = PromptTemplate.from_template("请将英文翻译为中文, 问题:{input}")
# 调用链
response = translate_prompt.invoke({"input":"hello"})
print("response:", response)
# 输出内容
response: text='请将英文翻译为中文, 问题:hello'
此处没有使用模型以及chain,输出内容为替换后的字符串
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# 调用一个大模型,qwen的开源,可以自己获取
translate_llm = ChatOpenAI(base_url="https://llm.xxxxxx.com/v1/",openai_api_key="sk-xxxxxxxx",model_name="qwen2.5-instruct")
# 创建一个提示词模板,变量即为用户输入的英文
translate_prompt = ChatPromptTemplate.from_messages(
[("system", "你是一个专业的翻译助手,将用户输入的英文翻译为中文"), ("human", "{input}")]
)
print("translate_prompt:", type(translate_prompt))
print("translate_prompt:", translate_prompt)
# 构造链,最终以字符串格式输出
model = translate_prompt | translate_llm | StrOutputParser()
# 调用链
response = model.invoke({"input":"hello"})
print("response:", response)
# 输出内容
translate_prompt:
translate_prompt: input_variables=['input'] input_types={} partial_variables={} messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], input_types={}, partial_variables={}, template='你是一个专业的翻译助手,将用户输入的英文翻译为中文'), additional_kwargs={}), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], input_types={}, partial_variables={}, template='{input}'), additional_kwargs={})]
response: 你好
从上述打印的translate_prompt中的
[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], input_types={}, partial_variables={}, template='你是一个专业的翻译助手,将用户输入的英文翻译为中文'), additional_kwargs={}), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input']
可以看出:属性messages是一个模板列表,分别是系统和用户模板
其中,system也可以使用如下方式实现
from langchain_core.messages import SystemMessage
translate_prompt = ChatPromptTemplate.from_messages(
[SystemMessage(content="你是一个专业的翻译专家,将用户输入的内容翻译为中文"),
("human", "{input}")
]
)
content的内容推测是无法实现格式化的,测试未通过。如下:
translate_prompt = ChatPromptTemplate.from_messages(
[
SystemMessage(content="你是一个专业的翻译专家,将用户输入的内容翻译为中文"),
HumanMessage(content="{input}")
]
)
文中演示的为systemmessage,还有 AIMessage, HumanMessage, ChatMessage, FunctionMessage, ToolMessage五个,大家可以自己测试,下面也会说一下
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.output_parsers import StrOutputParser
from langchain_core.messages import HumanMessage
# 调用一个大模型,qwen的开源,可以自己获取
translate_llm = ChatOpenAI(base_url="https://llm.xxxxxx.com/v1/",openai_api_key="sk-xxxxxxxx",model_name="qwen2.5-instruct")
# 创建一个提示词模板,变量即为用户输入的英文
translate_prompt = ChatPromptTemplate.from_messages(
[("system", "你是一个专业的翻译助手,将用户输入的英文翻译为中文"), MessagesPlaceholder("input")]
)
print("translate_prompt:", type(translate_prompt))
print("translate_prompt:", translate_prompt)
# 构造链,最终以字符串格式输出
model = translate_prompt | translate_llm | StrOutputParser()
# 调用链
response = model.invoke({"input":[HumanMessage(content="hi!")]})
print("response:", response)
# 输出内容
translate_prompt:
translate_prompt: input_variables=['input'] input_types={'input': list[typing.Annotated[typing.Union[typing.Annotated[langchain_core.messages.ai.AIMessage, Tag(tag='ai')], typing.Annotated[langchain_core.messages.human.HumanMessage, Tag(tag='human')], typing.Annotated[langchain_core.messages.chat.ChatMessage, Tag(tag='chat')], typing.Annotated[langchain_core.messages.system.SystemMessage, Tag(tag='system')], typing.Annotated[langchain_core.messages.function.FunctionMessage, Tag(tag='function')], typing.Annotated[langchain_core.messages.tool.ToolMessage, Tag(tag='tool')], typing.Annotated[langchain_core.messages.ai.AIMessageChunk, Tag(tag='AIMessageChunk')], typing.Annotated[langchain_core.messages.human.HumanMessageChunk, Tag(tag='HumanMessageChunk')], typing.Annotated[langchain_core.messages.chat.ChatMessageChunk, Tag(tag='ChatMessageChunk')], typing.Annotated[langchain_core.messages.system.SystemMessageChunk, Tag(tag='SystemMessageChunk')], typing.Annotated[langchain_core.messages.function.FunctionMessageChunk, Tag(tag='FunctionMessageChunk')], typing.Annotated[langchain_core.messages.tool.ToolMessageChunk, Tag(tag='ToolMessageChunk')]], FieldInfo(annotation=NoneType, required=True, discriminator=Discriminator(discriminator=, custom_error_type=None, custom_error_message=None, custom_error_context=None))]]} partial_variables={} messages=[SystemMessagePromptTemplate(prompt=PromptTemplate(input_variables=[], input_types={}, partial_variables={}, template='你是一个专业的翻译助手,将用户输入的英文翻译为中文'), additional_kwargs={}), MessagesPlaceholder(variable_name='input')]
response: 你好!
与之前相比:属性messages是一个模板列表,分别是系统和信息占位符模板
注:此处均为源码扒下来并翻译为中文
所有提示模板的基类,返回提示。
提示模板 用于将多个提示模板组合在一起。当您想要重用部分提示时,这可能很有用。
PipelinePrompt 由两个主要部分组成:
- final_prompt:这是返回的最终提示
- pipeline_prompts:这是一个元组列表,包括
字符串 ('name') 和提示模板。
每个 PromptTemplate 都将被格式化,然后传递
将 future prompt 模板作为变量替换为
与 'name' 同名
聊天提示模板的基类
聊天模型的提示模板,用于为聊天模型创建灵活的模板化提示
公开 format 方法的 String prompt,返回一个 prompt
语言模型的提示模板,提示模板由字符串模板组成。它接受一组参数,来自可用于为语言模型生成提示的用户,可以使用 f-strings (默认) 或 jinja2 语法对模板进行格式化
包含少量示例的提示模板
包含少量示例的提示模板
多模态模型的图像提示模板
-----------------------------------------------------------------
消息提示模板的基类
假定 variable 的提示模板已经是消息列表,一个占位符,可用于传入消息列表。
使用字符串提示模板的消息提示模板的基类
聊天消息提示模板
人工消息提示模板。这是用户发送的消息(源码中注释确实相同)
人工消息提示模板。这是用户发送的消息
AI 消息提示模板。这是从 AI 发送的消息
系统消息提示模板,这是一条不发送给用户的消息。
LangChain中的message指的是功能角色间的信息传递所需的文本内容,如:
用户输入的是HumanMessage,其最终传输时封装为类似HumanMessage(content="hello")
其他如system等也是类似的
所有消息都有 role、content 和 response_metadata 属性。
描述了谁在说这条消息。标准角色是 'user'、'assistant'、'system' 和 'tool'。
LangChain 为不同角色提供了不同的消息类。
描述了消息的内容,可以是字符串或是字典列表
可选,用于区分具有相同角色的多个发言者
包含有关响应的附加元数据。
这里的数据通常是特定于每个大模型供应商的。 这里可能存储诸如日志概率和令牌使用等信息。
用于引导AI行为的消息,定义AI的角色、功能信息,是作为一系列输入消息中的第一条传递的。
来自AI的消息,是由聊天模型作为对提示的响应返回的,此消息代表模型的输出,包括模型返回的原始输出以及LangChain框架添加的标准字段(例如,工具调用,使用情况元数据)。
从人类传递到模型的消息
可分配任意说话人的消息
用于将执行工具的结果传递回模型的消息。
FunctionMessage 是 ToolMessage 架构的旧版本,而不包含 tool_call_id 字段。
tool_call_id 字段用于将工具调用请求与工具调用响应。这在聊天模型能够以并行请求多个工具调用。
用于将执行工具的结果传递回模型的消息。
ToolMessage 包含工具调用的结果。通常,结果在 'content' 字段。
未完待续。。。根据后续的blog添加示例吧