第03章:LangChain使用之Model I/O

1、Model I/O介绍

Model I/O 模块是与语言模型(LLMs)进行交互的 核心组件 ,在整个框架中有着很重要的地位。

所谓的Model I/O,包括输入提示(Format)、调用模型(Predict)、输出解析(Parse)。分别对应着Prompt Template , Model 和 Output Parser 。

简单来说,就是输⼊、模型处理、输出这三个步骤。

针对每个环节,LangChain都提供了模板和工具,可以快捷的调用各种语言模型的接口。

2、Model I/O之调用模型1

LangChain作为一个"工具",不提供任何 LLMs,而是依赖于第三方集成各种大模型。比如,将OpenAI、Anthropic、Hugging Face 、LlaMA、阿里Qwen、ChatGLM等平台的模型无缝接入到你的应用。

2.1 模型的不同分类方式

简单来说,就是⽤谁家的API以什么⽅式调⽤哪种类型的⼤模型

角度1:按照模型功能的不同:

非对话模型(LLMs、Text Model)

对话模型(Chat Models)( 推荐 )

嵌入模型(Embedding Models)( 暂不考虑 )

角度2:模型调用时,几个重要参数的书写位置的不同:

硬编码:写在代码文件中

使用环境变量

使用配置文件( 推荐 )

角度3:具体调用的API

OpenAI提供的API

其它大模型自家提供的API

LangChain的统一方式调用API( 推荐 )

背景小知识:

OpenAI的GPT系列模型影响了⼤模型技术发展的开发范式和标准。所以⽆论是Qwen、ChatGLM等模型,它们的使⽤⽅法和函数调⽤逻辑基本 遵循OpenAI定义的规范 ,没有太⼤差异。这就使得⼤部分的开源项⽬能够通过⼀个较为通⽤的接口来接⼊和使⽤不同的模型。

2.2 角度1出发:按照功能不同举例

类型1:LLMs(非对话模型)

LLMs,也叫Text Model、非对话模型,是许多语言模型应用程序的支柱。主要特点如下:

输入:接受 文本字符串 或 PromptValue 对象

输出:总是返回 文本字符串

适用场景:仅需单次文本生成任务(如摘要生成、翻译、代码生成、单次问答)或对接不支持消息结构的旧模型(如部分本地部署模型)( 言外之意,优先推荐ChatModel )

不支持多轮对话上下文。每次调用独立处理输入,无法自动关联历史对话(需手动拼接历史文本)。

局限性:无法处理角色分工或复杂对话逻辑。

举例:

python 复制代码
import os
import dotenv
from langchain_openai import OpenAI
dotenv.load_dotenv(
    dotenv_path=r"C:\Users\fei\Desktop\companyProject\pythonProject\LangChain-tutorial\.env"
)
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
os.environ["OPENAI_BASE_URL"] = os.getenv("OPENAI_BASE_URL")


###########核心代码############
llm = OpenAI()
str = llm.invoke("写一首关于春天的诗")  # 直接输入字符串
print(str)
print(type(str))
txt 复制代码
春风拂过大地  
万物复苏欣欣向荣  
花开满山谷  
鸟儿啁啾歌声飘  
春雨滋润田野  
农夫欢呼收获丰  
春日暖阳温柔  
人们心情也随之舒  
春天来了  
带来新的开始  
带走冬日的寒冷  
带来生机与希望  
春天啊,美丽的季节  
让我们一起欢庆  
迎接春天的到来  
让快乐永远驻留心中。

类型2:Chat Models(对话模型)

ChatModels,也叫聊天模型、对话模型,底层使用LLMs。

大语言模型调用,以 ChatModel 为主!

主要特点如下:

输入:接收消息列表 List[BaseMessage] 或 PromptValue ,每条消息需指定角色(如SystemMessage、HumanMessage、AIMessage)

输出:总是返回带角色的 消息对象 ( BaseMessage 子类),通常是 AIMessage

原生支持多轮对话。通过消息列表维护上下文(例如: [SystemMessage, HumanMessage,AIMessage, ...] ),模型可基于完整对话历史生成回复。

适用场景:对话系统(如客服机器人、长期交互的AI助手)

举例:

python 复制代码
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage
import os
import dotenv
dotenv.load_dotenv()
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
os.environ["OPENAI_BASE_URL"] = os.getenv("OPENAI_BASE_URL")


########核心代码############
chat_model = ChatOpenAI(model="gpt-4o-mini")

messages = [
    SystemMessage(content="我是人工智能助手,我叫小智"),
    HumanMessage(content="你好,我是小明,很高兴认识你")
]

#输入:list[basemessage]
#输出:AIMessage
response = chat_model.invoke(messages)  # 输入消息列表

print(type(response))  # <class 'langchain_core.messages.ai.AIMessage'>
print(response.content)

类型3:Embedding Model(嵌入模型)

Embedding Model:也叫文本嵌入模型,这些模型将 文本 作为输入并返回 浮点数列表 ,也就是Embedding。(后面章节《07-LangChain使用之Retrieval》重点讲)

python 复制代码
import os
import dotenv
from langchain_openai import OpenAIEmbeddings
dotenv.load_dotenv()
os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY")
os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")


#############
embeddings_model = OpenAIEmbeddings(
    model="text-embedding-ada-002"
)

res1 = embeddings_model.embed_query('我是文档中的数据')
print(res1)
16 #打印结果:[-0.004306625574827194, 0.003083756659179926, -0.013916781172156334, ..., ]

2.3 角度2出发:参数位置不同举例

这里以 LangChain 的API为准,使用对话模型,进行测试。

2.3.1模型调用的主要方法及参数

相关方法及属性:

OpenAI(...) / ChatOpenAI(...) :创建一个模型对象(非对话类/对话类)

model.invoke(xxx) :执行调用,将用户输入发送给模型

.content :提取模型返回的实际文本内容

模型调用函数使用时需初始化模型,并设置必要的参数。

1)必须设置的参数:

base_url :大模型 API 服务的根地址

api_key :用于身份验证的密钥,由大模型服务商(如 OpenAI、百度千帆)提供

model/model_name :指定要调用的具体大模型名称(如 gpt-4-turbo 、 ERNIE-3.5-8K 等)

2)其它参数:

temperature :温度,控制生成文本的"随机性",取值范围为0~1。

。 值越低 输出越确定、保守(适合事实回答)

。 值越高 输出越多样、有创意(适合创意写作)

通常,根据需要设置如下:

精确模式(0.5或更低):生成的文本更加安全可靠,但可能缺乏创意和多样性。

平衡模式(通常是0.8):生成的文本通常既有一定的多样性,又能保持较好的连贯性和准确性。

创意模式(通常是1):生成的文本更有创意,但也更容易出现语法错误或不合逻辑的内容。

max_tokens :限制生成文本的最大长度,防止输出过长。

Token是什么?

基本单位 : 大模型处理文本的最小单位是token(相当于自然语言中的词或字),输出时逐个token依次生成。

收费依据 :大语言模型(LLM)通常也是以token的数量作为其计量(或收费)的依据。

1个Token≈1-1.8个汉字,1个Token≈3-4个英文字母

Token与字符转化的可视化工具:

OpenAI提供:https://platform.openai.com/tokenizer

百度智能云提供:https://console.bce.baidu.com/support/#/tokenizer

max_tokens设置建议:

客服短回复:128-256。比如:生成一句客服回复(如"订单已发货,预计明天送达")

∘^ \circ∘ 常规对话、多轮对话:512-1024

长内容生成:1024-4096。比如:生成一篇产品说明书(包含功能、使用方法等结构)

2.3.2 模型调用推荐平台:closeai

考虑到OpenAI等模型在国内访问及充值的不便,大家可以使用CloseAI网站注册和充值, 具体费用自理 。

https://www.closeai-asia.com

2.3.3 方式1:硬编码

直接将 API Key 和模型参数写入代码,仅适用于临时测试,存在密钥泄露风险,在 生产环境不推荐 。

python 复制代码
from langchain_openai import ChatOpenAI
# 调用非对话模型:
# llms = OpenAI(...)


# 调用对话模型:
chat_model = ChatOpenAI(
    #必须要设置的3个参数
    model_name="gpt-4o-mini",   #默认使用的是gpt-3.5-turbo模型
    base_url="https://api.openai-proxy.org/v1",
    api_key="sk-zD4CB2Qe7G2Dp6veCfPRSxeDx9fQPxCUIfOFAk20ETV5B2VA",

)

# 调用模型
response = chat_model.invoke("什么是langchain?")

# 查看响应的文本
# print(response.content)
print(response)

神经⽹络是⼀种模拟⼈脑神经元之间信息传递的数学模型。神经⽹络由多层神经元组成,每个神经元接收来⾃上⼀层神经元的输⼊信号,并通过激活函数将输⼊信号进⾏加权求和并输出⼀个结果。

在神经⽹络中,数据通过输⼊层传递到隐藏层,最终到输出层。在每⼀层中,神经元通过学习算法不断调整连接权重,以使神经⽹络能够准确地对输⼊数据进⾏分类或预测。

神经⽹络的训练过程是通过反向传播算法进⾏的。该算法通过计算神经⽹络输出结果与实际结果之间的误差,然后根据误差调整神经元之间的连接权重,以提⾼神经⽹络的准确性。

总的来说,神经⽹络通过模拟⼈脑神经元之间的信息传递过程,利⽤数学模型来实现对复杂问题的学习和预测。神经⽹络的原理是基于神经元之间的连接权重调整和误差反向传播的机制。

2.3.4 方式2:配置环境变量

通过系统环境变量存储密钥,避免代码明文暴露。

方式1:终端设置环境变量(临时生效):

1 export OPENAI_API_KEY χ="sk{ \bf \chi } = " s kχ="sk -xxxxxxxxxxxxxxxxxxxx" # Linux/Mac

2 set OPENAI_API_KEY Ω=Ω′′Sk\mathbf { \Omega } = { \bf \Omega } ^ { \prime \prime } S kΩ=Ω′′Sk -xxxxxxxxxxxxxxxxxxxx" # Windows

方式2:从PyCharm设置

举例:

python 复制代码
from langchain_openai import ChatOpenAI


# 1、获取对话模型:
chat_model = ChatOpenAI(
    #必须要设置的3个参数
    model_name="gpt-4o-mini",   #默认使用的是gpt-3.5-turbo模型
    base_url=os.environ["OPENAI_BASE_URL"],
    api_key=os.environ["OPENAI_API_KEY"],

)

# 2、调用模型
response = chat_model.invoke("什么是langchain?")

# 3、查看响应的文本
# print(response.content)
print(response)

输出:略

优点:密钥与代码分离,适合单机开发

缺点 :切换终端或文件后,变量失效,需重新设置。

2.3.5 方式3:使用.env配置文件

使用 python-dotenv 加载本地配置文件,支持多环境管理(开发/生产)。

1)安装依赖

txt 复制代码
pip install python-dotenv

 #或者

 conda install python-dotenv

2)创建 .env 文件(项目根目录):

OPENAI_API_KEY="sk-xxxxxxxxx" # 需填写自己的API KEY

OPENAI_BASE_URL ="https://api.openai-proxy.org/v1"

2.4 角度3出发:各平台API的调用举例(了解)

2.4.1 OpenAI 官方API

考虑到OpenAI在国内访问及充值的不便,我们仍然使用CloseAI网站(https://www.closeai-asia.com)注册和充值, 具体费用自理

2.4.2 百度千帆平台

开发参考文档:

https://cloud.baidu.com/doc/qianfan-docs/s/Mm8r1mejk

获取API Key和App ID:

创建API Key:https://console.bce.baidu.com/qianfan/ais/console/apiKey

创建App ID:https://console.bce.baidu.com/qianfan/ais/console/applicationConsole/application/v2

代码举例:

python 复制代码
from openai import OpenAI

client = OpenAI(
    api_key="bce-v3/ALTAK-Ynzfb6RBYeGiyI08yEXuf/21f994aeb874bbc0c55c3c4dc37a6b9b0cccaac1",  # 千帆bearer token
    base_url="https://qianfan.baidubce.com/v2",  # 千帆域名
    default_headers={"appid": "app-y3sQKuT2"}   # 用户在千帆上的appid,非必传
)

completion = client.chat.completions.create(
    model="ernie-4.0-turbo-8k", # 预置服务请查看模型列表,定制服务请填入API地址
    messages=[{'role': 'system', 'content': 'You are a helpful assistant.'},
              {'role': 'user', 'content': 'Hello!'}]
)

print(completion.choices[0].message)

2.4.3 阿里云百炼平台

注册与key的获取:

提前开通百炼平台账号并申请API KEY:https://bailian.console.aliyun.com/#/home

对应的配置文件:

1 DASHSCOPE_API_KEY = "sk-f1a87324#####e6a819a482" #使用自己的api key

2 DASHSCOPE_BASE_URL ="https://dashscope.aliyuncs.com/compatible-mode/v1"

模型的调用:

参考具体模型的代码示例。这里以DeepSeek为例:

模型广场

举例1:通过OpenAI SDK

python 复制代码
import os
from openai import OpenAI

client = OpenAI(
    # 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:api_key="sk-xxx",
    api_key=os.getenv("DASHSCOPE_API_KEY"),  # 如何获取API Key:https://help.aliyun.com/zh/model-studio/developer-reference/get-api-key
    base_url=os.getenv("DASHSCOPE_BASE_URL")
)

completion = client.chat.completions.create(
    model="deepseek-r1",  # 此处以 deepseek-r1 为例,可按需更换模型名称。
    messages=[
        {'role': 'user', 'content': '9.9和9.11谁大'}
    ]
)

# 通过reasoning_content字段打印思考过程
print("思考过程:")
print(completion.choices[0].message.reasoning_content)

# 通过content字段打印最终答案
print("最终答案:")
print(completion.choices[0].message.content)

举例2:通过DashScope SDK

1 pip install dashscope

python 复制代码
import os
import dashscope

messages = [
    {'role': 'user', 'content': '你是谁?'}
]

response = dashscope.Generation.call(
    # 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:api_key="sk-xxx",
    api_key=os.getenv('DASHSCOPE_API_KEY'),
    model="deepseek-r1",  # 此处以 deepseek-r1 为例,可按需更换模型名称。
    messages=messages,
    # result_format参数不可以设置为"text"。
    result_format='message'
)

print("=" * 20 + "思考过程" + "=" * 20)
print(response.output.choices[0].message.reasoning_content)
print("=" * 20 + "最终答案" + "=" * 20)
print(response.output.choices[0].message.content)

2.4.4 智谱的GLM

安装 Python SDK

Python SDK 地址: https://github.com/zhipuai/zhipuai-sdk-python-v4

首先请通过如下方式进行安装SDK包:

举例1:使用OpenAI SDK

python 复制代码
from langchain_openai import ChatOpenAI
from langchain.schema import HumanMessage, SystemMessage

# 创建LLM实例
llm = ChatOpenAI(
    temperature=0.7,
    model="glm-4.5",
    openai_api_key="4806f93a9fa948b3ad0da1ec6f989261.sRf49YGloBNigTox",
    openai_api_base="https://open.bigmodel.cn/api/paas/v4/"
)

# 创建消息
messages = [
    SystemMessage(content="你是一个有用的AI助手"),
    HumanMessage(content="请介绍一下人工智能的发展历程")
]

# 调用模型
response = llm(messages)
print(response.content)

2.4.5 硅基流动平台

官网:https://www.siliconflow.cn/

申请API Key:

参考文档:https://docs.siliconflow.cn/cn/userguide/quickstart

python 复制代码
import requests

url = "https://api.siliconflow.cn/v1/chat/completions"

payload = {
    "model": "Qwen/QwQ-32B",
    "messages": [
        {
            "role": "user",
            "content": "What opportunities and challenges will the Chinese large model industry face in 2025?"
        }
    ]
}
headers = {
    "Authorization": "Bearer sk-auciaxqpzchyauiovpzkwrjhznkzepozralhwleyrdoyjani", #填写自己的api-key
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())

2.5 如何选择合适的大模型

2.5.1 有没有最好的大模型

凡是问「哪个大模型最好?」的,都是不懂的。

不妨反问:「无论做什么,有都表现最好的员工吗?」

划重点:没有最好的大模型,只有最适合的大模型

基础模型选型,合规和安全是首要考量因素!

为什么不要依赖榜单?

榜单已被应试教育污染,还算值得相信的榜单:LMSYS Chatbot Arena Leaderboard

榜单体现的是整体能力,放到一件具体事情上,排名低的可能反倒更好

榜单体现不出成本差异

3、Model I/O之调用模型2

3.1 关于对话模型的Message(消息)

聊天模型,出了将字符串作为输入外,还可以使用 聊天消息 作为输入,并返回 聊天消息 作为输出。

LangChain有一些内置的消息类型:

· SystemMessage :设定AI行为规则或背景信息。比如设定AI的初始状态、行为模式或对话的总体目标。比如"作为一个代码专家",或者"返回json格式"。通常作为输入消息序列中的第一个传递。

· HumanMessage :表示来自用户输入。比如"实现 一个快速排序方法"

· AIMessage :存储AI回复的内容。这可以是文本,也可以是调用工具的请求

· ChatMessage :可以自定义角色的通用消息类型

· FunctionMessage/ToolMessage :函数调用/工具消息,用于函数调用结果的消息类型

注意

FunctionMessage和ToolMessage分别是在函数调⽤和⼯具调⽤场景下才会使⽤的特殊消息类型,HumanMessage、AIMessage和SystemMessage才是最常⽤的消息类型。
举例1:

python 复制代码
from langchain_core.messages import SystemMessage, HumanMessage

system_message = SystemMessage(content="你是一个英语教学方向的专家")
human_message = HumanMessage(content="帮我制定一个英语六级学习的计划")

messages = [system_message, human_message]

print(messages)

SystemMessage(content='你是一个英语教学方向的专家', additional_kwargs={}, response_metadata={}), HumanMessage(content='帮我制定一个英语六级学习的计划', additional_kwargs={}, response_metadata={})

举例2:

txt 复制代码
from langchain_core.messages import SystemMessage, HumanMessage

system_message = SystemMessage(
    content="你是一个英语教学方向的专家",
    additional_kwargs={"tool":"invoke_func1"}
)
human_message = HumanMessage(content="帮我制定一个英语六级学习的计划")

messages = [system_message, human_message]

print(messages)

SystemMessage(content='你是一个英语教学方向的专家', additional_kwargs={'tool': 'invoke_func1'}, response_metadata={}), HumanMessage(content='帮我制定一个英语六级学习的计划', additional_kwargs={}, response_metadata={})

举例3:

python 复制代码
from langchain_core.messages import (
    AIMessage,
    HumanMessage,
    SystemMessage,
    ChatMessage
)

# 创建不同类型的消息
system_message = SystemMessage(content="你是一个专业的数据科学家")
human_message = HumanMessage(content="解释一下随机森林算法")
ai_message = AIMessage(content="随机森林是一种集成学习方法...")
custom_message = ChatMessage(role="analyst", content="补充一点关于超参数调优的信息")

print(system_message.content)
print(human_message.content)
print(ai_message.content)
print(custom_message.content)

你是一个专业的数据科学家

解释一下随机森林算法

随机森林是一种集成学习方法...

补充一点关于超参数调优的信息

举例4:结合大模型使用

python 复制代码
import os
from langchain_core/messages import SystemMessage, HumanMessage
dotenv.load_dotenv()
os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY")
os.environ['OPENAI_BASE_url'] = os.getenv("OPENAI_BASE_url")
chat_model = ChatOpenAI(
    model="gpt-4o-mini",
)
# 组成消息列表
messages = [
SystemMessage(content="你是一个擅长人工智能相关学科的专家"),
HumanMessage(content="请解释一下什么是机器学习?")
]
response = chat_model.invoke/messages)
print(response.content)
print(type(response)) #<class 'langchain_core/messages.ai.AIMessage'>

3.2 关于多轮对话与上下文记忆

前提:获取大模型

python 复制代码
import os
import dotenv
from langchain_openai import ChatOpenAI

dotenv.load_dotenv()

os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")

chat_model = ChatOpenAI(
	model="gpt-4o-mini"
)

测试1:

python 复制代码
from langchain_core.messages import SystemMessage, HumanMessage

# 第1组
sys_message = SystemMessage(
    content="我是一个人工智能的助手,我的名字叫小智",
)
human_message = HumanMessage(content="猫王是一只猫吗?")

messages = [sys_message, human_message]

# 第2组
sys_message1 = SystemMessage(
    content="我可以做很多事情,有需要就找我吧",
)

human_message1 = HumanMessage(content="你叫什么名字?")

messages1 = [sys_message1,human_message1]

#调用大模型,传入messages
response = chat_model.invoke(messages)
# print(response.content)

response = chat_model.invoke(messages1)
print(response.content)

我是一个人工智能助手,没有具体的名字,你可以叫我助手或者AI。如果你有任何问题,随时问我!

3.3 关于模型调用的方法

为了尽可能简化自定义链的创建,我们实现了一个"Runnable"协议。许多LangChain组件实现了Runnable 协议,包括聊天模型、提示词模板、输出解析器、检索器、代理(智能体)等。

Runnable 定义的公共的调用方法如下:

invoke : 处理单条输入,等待LLM完全推理完成后再返回调用结果

stream : 流式响应,逐字输出LLM的响应结果

batch : 处理批量输入

这些也有相应的异步方法,应该与 asyncio 的 await 语法一起使用以实现并发:

astream : 异步流式响应

ainvoke : 异步处理单条输入

abatch : 异步处理批量输入

astream_log : 异步流式返回中间步骤,以及最终响应

astream_events : (测试版)异步流式返回链中发生的事件(在 langchain-core 0.1.14 中引入)

3.3.1 流式输出与非流式输出

在Langchain中,语言模型的输出分为了两种主要的模式:流式输出与非流式输出。

下面是两个场景:

非流式输出:这是Langchain与LLM交互时的 默认行为 ,是最简单、最稳定的语言模型调用方式。当用户发出请求后,系统在后台等待模型 生成完整响应 ,然后 一次性将全部结果返回 。

举例:用户提问,请编写一首诗,系统在静默数秒后 突然弹出 了完整的诗歌。(体验较单调)

在大多数问答、摘要、信息抽取类任务中,非流式输出提供了结构清晰、逻辑完整的结果,适合快速集成和部署。

流式输出:一种 更具交互感 的模型输出方式,用户不再需要等待完整答案,而是能看到模型 逐个token 地实时返回内容。

举例:用户提问,请编写一首诗,当问题刚刚发送,系统就开始 一字一句 (逐个token)进行回复,感觉是一边思考一边输出。

更像是"实时对话",更为贴近人类交互的习惯,更有吸引力。

适合构建强调"实时反馈"的应用,如聊天机器人、写作助手等。

Langchain 中通过设置 stream ∣=| =∣= True 并配合 回调机制 来启用流式输出。

非流式输出:

举例1:

1 import os

2 import dotenv

3 from langchain_core.messages import HumanMessage

from langchain_openai import ChatOpenAI4

dotenv.load_dotenv()6

8 os.environ['OPENAI_API_KEY'] === os.getenv("OPENAI_API_KEY1")

9 os.environ['OPENAI_BASE_URL'] === os.getenv("OPENAI_BASE_URL")

10

txt 复制代码
11 #初始化大模型  
12 chat_model = ChatOpenAI(model = "gpt-4o-mini")  
13  
14 #创建消息  
15 messages = [HumanMessage(content = "你好,请介绍一下自己")]  
16  
17 #非流式调用LLM获取响应  
18 response = chat_model.invoke/messages)  
19  
20 #打印响应内容  
21 print(response)

输出结果如下,是直接全部输出的。

javascript 复制代码
content='你好!我是一个人工智能助手,专门设计来提供信息和解答问题。我可以帮助你解答各种问题,比如学习、科技、文化、生活等方面的内容。如果你有任何具体的问题或者需要了解的主题,欢迎随时问我!'additional_kwarges={'refusal':None} response_metadata={'tokenusage':{'completion_tokens':57,'prompt_tokens':12,'total_tokens':69,'completion_tokens_details':{'accepted_prediction_tokens':0,'audio_tokens':0, 'reasoning_tokens':0,'rejected_prediction_tokens':0}, 'prompt_tokens_details':{'audio_tokens':0,'cached_tokens':0}}, 'model_name':'gpt-4o-mini-2024-07-18', 'system_fingerprint':'fp_efad92c60b', 'id':'chatmpl-BmdJTYMLA9iiUFDIAJLJREFdJN5Us', 'service-tier':None,'finish_reason':stop,'logprobs': None} id='run--2b25b74a-12b0-4162-80fc-7d348b3ed3fb-0' usage_metadata={input_tokens':12,'output_tokens':57,'total_tokens':69,'input_token_details':{'audio':0,'cache_read':0}, 'output_token_details':{'audio':0,'reasoning':0}}

举例2:

python 复制代码
1 import os  
2 import dotenv  
3 from langchain_core/messages import HumanMessage, SystemMessage  
4 from langchain_openai import ChatOpenAI  
5  
6 dotenv.load_dotenv()  
7  
8 os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")  
9 os.environ['OPENAI_BASE_url'] = os.getenv("OPENAI_BASE_url")  
10  
11 #初始化大模型  
12 chat_model = ChatOpenAI(model="gpt-4o-mini")  
13  
14 #支持多个消息作为输入  
15 messages = [  
16 SystemMessage(content="你是一位乐于助人的助手。你叫于老师"),  
17 HumanMessage(content="你是谁?")  
18 ]  
19 response = chat_model.invokemessages)  
20 print(response.content)

我叫于⽼师,是⼀位乐于助⼈的助⼿。在这⾥我可以帮助你解答问题、提供信息或是进⾏交流。有需要帮助的地⽅吗?

举例3:

python 复制代码
1 import os  
2 import dotenv  
3 from langchain_core/messages import HumanMessage, SystemMessage  
4 from langchain_openai import ChatOpenAI  
5  
6 dotenv.load_dotenv()  
7 1  
8 os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")  
9 os.environ['OPENAI_BASE_url'] = os.getenv("OPENAI_BASE_url")  
10  
11 #初始化大模型  
12 chat_model = ChatOpenAI(model="gpt-4o-mini")  
13  
14 #支持多个消息作为输入  
15 messages = [  
16 SystemMessage(content="你是一位乐于助人的助手。你叫于老师"),  
17 HumanMessage(content="你是谁?")  
18 ]  
19 response = chat_model/messages) #特别的写法  
20 print(response.content)

第19行,底层调用 BaseChatModel.call ,内部调用的还是invoke()。后续还会有这种写法出现,了解即可。

流式输出

一种更具交互感的模型输出方式,用户不再需要等待完整答案,而是能看到模型逐个 token 地实时返回内容。适合构建强调"实时反馈"的应用,如聊天机器人、写作助手等。

Langchain 中通过设置 streaming=True 并配合 回调机制 来启用流式输出。

举例:

python 复制代码
1 import os  
2 import dotenv  
3 from langchain_core/messages import HumanMessage  
4 from langchain_openai import ChatOpenAI  
5  
6 dotenv.load_dotenv()  
7  
8 os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY")  
9 os.environ['OPENAI_BASE_url'] = os.getenv("OPENAI_BASE_url")  
10  
11 #初始化大模型  
12 chat_model = ChatOpenAI(model="gpt-4o-mini", streaming=True #启用流式输出  
13)  
14  
15  
16 #创建消息
txt 复制代码
17 messages = [HumanMessage(content = "你好,请介绍一下自己")]  
18  
19 #流式调用LLM获取响应  
20 print("开始流式输出:")  
21 for chunk in chat_model.stream/messages):  
22 #逐个打印内容块  
23 print(chunk(content, end=True, flush=True) #刷新缓冲区(无换行符,缓冲区未刷新,内容可能不会立即显示)  
24  
25 print("\n流式输出结束")

输出结果如下(一段段文字逐个输出)

开始流式输出:1

你好!我是一个人工智能助手,旨在帮助用户回答问题、提供信息和解决问题。我可以处理各种主题,包括科技、历史、文化、语言学习等。无论你有什么问题,尽管问我,我会尽力提供准确和有用的回答!

流式输出结束3

3.3.2 批量调用

举例:

python 复制代码
1 import os  
2 import dotenv  
3 from langchain_core/messages import HumanMessage, SystemMessage  
4 from langchain_openai import ChatOpenAI  
5  
6 dotenv.load_dotenv()  
7  
8 os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY")  
9 os.environ['OPENAI_BASE_url'] = os.getenv("OPENAI_BASE_url")  
10  
11 #初始化大模型  
12 chat_model = ChatOpenAI(model="gpt-4o-mini")  
13  
14 messages1 = [SystemMessage(content="你是一位乐于助人的智能小助手"), HumanMessage(content="请帮我介绍一下什么是机器学习"), ]  
15  
16  
17 messages2 = [SystemMessage(content="你是一位乐于助人的智能小助手"), HumanMessage(content="请帮我介绍一下什么是AIGC"), ]  
18  
19  
20 messages3 = [SystemMessage(content="你是一位乐于助人的智能小助手"), HumanMessage(content="请帮我介绍一下什么是大模型技术"), ]  
21  
22  
23 messages = [messages1, messages2, messages3]  
24  
#调用batch  
25 response = chat_model.batch闭环()  
26 print(response)

AIMessage(content=机器学习是⼈⼯智能(AI)的⼀种分⽀,它使计算机能够通过经验⾃动改进其性能,而不需要明确的编程指令。简而⾔之,机器学习关注的是让计算机从数据中学习,并在此基础上做出决策或预测。\\n\\n机器学习的基本流程通常包括以下⼏个步骤: ∣n∣n∣\\lvert \\boldsymbol { \\mathrm { n } } \\rvert \\boldsymbol { \\mathrm { n } } \\rvert∣n∣n∣ . 数据收集:收集和准备数据,这是机器学习的基础。数据可以是结构化的(如表格)或⾮结构化的(如⽂本、图像)。 μn2\\mu \\mathrm { n } 2μn2 . 数据预处理:对数据进⾏清洗、整理和转换,以适合后续的分析和建模。这可能包括去除噪声、填补缺失值和标准化数据等。 ∣n∣n3\\lvert \\boldsymbol { \\mathrm { n } } \\rvert \\boldsymbol { \\mathrm { n } } 3∣n∣n3 . 选择模型:根据问题的性质选择合适的机器学习算法或模型。例如,线性回归、决策树、⽀持向量机、神经⽹络等。 ⌊n\\n4\\scriptstyle \\lfloor { \\mathrm { n } } \\backslash { \\mathrm { n } } 4⌊n\\n4 . 训练模型:使⽤准备好的数据来训练模型。模型通过调整内部参数来最小化预测与实际结果之间的差距。 ∣n∣n5\\lvert \\boldsymbol { \\mathrm { n } } \\rvert \\boldsymbol { \\mathrm { n } } 5∣n∣n5 . 评估模型:使⽤测试数据集来评估模型的性能,通常通过准确率、召回率、F1值等指标。 ∣n∣n6\\lvert \\boldsymbol { \\mathrm { n } } \\rvert \\boldsymbol { \\mathrm { n } } 6∣n∣n6 . 模型优化:根据评估结果调整模型参数或选择不同的算法,以提⾼模型的表现。 $ { \\mathrm { \\Delta } } { \\mathrm { \\backslash n } } { \\mathrm { \\backslash n } } 7$ . 部署应⽤:将训练好的模型应⽤于实际问题,进⾏实时或批量预测。\\n\\n机器学习通常被分为三⼤类: ∣n∣n∣\\lvert \\boldsymbol { \\mathrm { n } } \\rvert \\boldsymbol { \\mathrm { n } } \\rvert∣n∣n∣ . 监督学习:模型在拥有标记数据的情况下学习,⽬标是预测新的输⼊数据的结果。常⽤例⼦包括分类和回归任务。 $ { \\mathrm { \\backslash n } } { \\mathrm { n } } 2$ . ⽆监督学习:模型在没有标记数据的情况下学习,⽬标是发现数据的结构和模式。常⽤例⼦包括聚类和降维。 μn3.\\mu \\mathrm { n } 3 .μn3. . 强化学习:模型通过与环境交互来学习,⽬标是通过试错过程来优化决策,最⼤化累积奖励。\\n\\n机器学习的应⽤⾮常⼴泛,包括图像识别、语⾔处理、推荐系统、⾦融预测、医疗诊断等领域。随着数据的增加和计算能⼒的提升,机器学习正在快速发展,越来越多地被应⽤于实际问题中。', additional_kwargs={refusal: None}, response_metadata Π‾‾\\underline { { \\underline { { \\mathbf { \\Pi } } } } }Π {token_usage: {completion_tokens: 490, prompt_tokens: 30, total_tokens: 520,completion_tokens_details: {accepted_prediction_tokens: 0, audio_tokens: 0,reasoning_tokens: 0, rejected_prediction_tokens: 0}, prompt_tokens_details:{audio_tokens: 0, cached_tokens: 0}}, model_name: gpt-4o-mini-2024-07-18,system_fingerprint: fp_57db37749c, id: chatcmpl-Bms2AQa5fLnKKMWybQvs0oLm3mc7C, service_tier: None, finish_reason: stop,logprobs: None}, id=run--6ab9c603-e5bc-4cc7-bba4-706bdc6f28d9-0, usage_metadata={input_tokens: 30, output_tokens: 490, total_tokens: 520, input_token_details: {audio:0, cache_read: 0}, output_token_details: {audio: 0, reasoning: 0}}),AIMessage(content=AIGC(⼈⼯智能⽣成内容,Artificial Intelligence GeneratedContent)是指利⽤⼈⼯智能技术⾃动⽣成各种内容的过程。这些内容可以包括⽂本、图像、⾳频、视频等。随着深度学习、⾃然语⾔处理和计算机视觉等技术的发展,AIGC在各个领域展现出巨⼤的潜⼒和应⽤前景。\\n\\n例如: ∣n∣n∣\\lvert \\boldsymbol { \\mathrm { n } } \\rvert \\boldsymbol { \\mathrm { n } } \\rvert∣n∣n∣ . ⽂本⽣成:使⽤语⾔模型,如OpenAI的GPT系列,⽣成⽂章、故事、诗歌等。它可以⽤于内容创作、新闻报道的⾃动撰写等。 μn2\\mu \\mathrm { n } 2μn2 . 图像⽣成:基于⽣成对抗⽹络(GAN)等技术,创建新的图像或艺术作品。例如,DALL-E和Midjourney等⼯具能够根据⽤⼾输⼊的⽂本描述⽣成相应的图⽚。 ∣n∣n3\\lvert \\boldsymbol { \\mathrm { n } } \\rvert \\boldsymbol { \\mathrm { n } } 3∣n∣n3 . ⾳频⽣成:通过AI算法⽣成⾳乐、语⾳或其他⾳频内容,能够⽤于⾳乐创作、虚拟助理中的语⾳输出等。 $ { \\mathrm { \\backslash n } } { \\mathrm { \\Omega } } _ { { \\mathrm { \\Omega } } }$ . 视频⽣成:AI也可以⽣成或编辑视频内容,应⽤于影视制作、⼴告创意等领域。\\n\\nAIGC的优势在于其⾼效性和创新能⼒,它能⼤幅度提⾼内容⽣产的速度,降低成本,同时也可以帮助创作者激发灵感。不过,AIGC也⾯临⼀些挑战,如版权问题、⽣成内容的质量和真实性等。随着技术的不断进步,AIGC的应⽤领域和影响⼒仍在不断扩⼤。', additional_kwargs={refusal: None}, response_metadata={token_usage: {completion_tokens: 318, prompt_tokens: 31, total_tokens: 349,completion_tokens_details: {accepted_prediction_tokens: 0, audio_tokens: 0,reasoning_tokens: 0, rejected_prediction_tokens: 0}, prompt_tokens_details:{audio_tokens: 0, cached_tokens: 0}}, model_name: gpt-4o-mini-2024-07-18,system_fingerprint: fp_efad92c60b, id: chatcmpl-Bms2A0v8agsIGevCNImWTIq7ICZgq,service_tier: None, finish_reason: stop, logprobs: None}, id=run--7aa515e5-37b2-49e7-91be-b29a231537d1-0, usage_metadata={input_tokens: 31, output_tokens: 318,total_tokens: 349, input_token_details: {audio: 0, cache_read: 0},output_token_details: {audio: 0, reasoning: 0}}), AIMessage(content=⼤模型技术是指通过⼤规模的数据集和强⼤的计算能⼒训练出的复杂机器学习模型,特别是深度学习模型。这些模型通常具有数亿甚⾄数万亿个参数,能够在多个领域中执⾏各种任务,如⾃然语⾔处理、计算机视觉、语⾳识别等。\\n\\n以下是⼤模型技术的⼀些关键特点和应⽤: ∣n∣n∣\\lvert \\boldsymbol { \\mathrm { n } } \\rvert \\boldsymbol { \\mathrm { n } } \\rvert∣n∣n∣ . 规模与复杂性:⼤模型通常由多层神经⽹络构成,具备⾼维度和显著的表达能⼒。这使得它们可以捕捉到数据中的复杂模式。 $ { \\mathrm { \\backslash n } } { \\mathrm { n } } 2$ . 预训练与微调:⼤模型通常采⽤预训练和微调的⽅法。模型先在⼤规模通⽤数据集上进⾏预训练,然后再在特定任务的数据集上进⾏微调,以提⾼在特定任务上的性能。 ∣n∣n3\\lvert \\boldsymbol { \\mathrm { n } } \\rvert \\boldsymbol { \\mathrm { n } } 3∣n∣n3 . 迁移学习:⼤模型可以将从⼀个任务中学到的知识迁移到其他相关任务上,从而减少各个任务之间的训练时间和数据需求。 $ { \\mathrm { \\backslash n } } { \\mathrm { \\Omega } } _ { { \\mathrm { \\Omega } } }$ . 多模态学习:⼀些⼤模型技术⽀持多模态输⼊,即可以同时处理⽂本、图像、声⾳等多种数据类型,增强了模型的通⽤性和应⽤范围。 ∣n∣n5\\lvert \\boldsymbol { \\mathrm { n } } \\rvert \\boldsymbol { \\mathrm { n } } 5∣n∣n5 . 应⽤范围⼴泛:⼤模型被⼴泛应⽤于聊天机器⼈、⾃动翻译、图像⽣成、医学影像分析、内容推荐等多个领域。 ∣n∣n6\\lvert \\boldsymbol { \\mathrm { n } } \\rvert \\boldsymbol { \\mathrm { n } } 6∣n∣n6 . 技术挑战:尽管⼤模型技术具有很⾼的性能,但在训练和推理过程中,也带来了计算资源需求⼤、能耗⾼、模型解释性差等挑战。\\n\\n总的来说,⼤模型技术代表了机器学习和⼈⼯智能领域的⼀种趋势和发展⽅向,其强⼤的能⼒使其在许多实际应⽤中表现出⾊。', additional_kwargs={refusal: None},response_metadata={token_usage: {completion_tokens: 383, prompt_tokens: 31,total_tokens: 414, completion_tokens_details: {accepted_prediction_tokens: 0,audio_tokens: 0, reasoning_tokens: 0, rejected_prediction_tokens: 0},prompt_tokens_details: {audio_tokens: 0, cached_tokens: 0}}, model_name: gpt-4o-mini-2024-07-18, system_fingerprint: fp_efad92c60b, id: chatcmpl-Bms2Atgkau6s0fmfThAacknwoZNal, service_tier: None, finish_reason: stop,logprobs: None}, id=run--93b50346-c340-4821-9847-562f80fb8cbc-0, usage_metadata={input_tokens: 31, output_tokens: 383, total_tokens: 414, input_token_details: {audio:0, cache_read: 0}, output_token_details: {audio: 0, reasoning: 0}})

3.3.3 同步调用与异步调用(了解)

同步调用

举例:

1 import time

2

3 def call_model():

4 #模拟同步API调用

5 print("开始调用模型...")

6 time.sleep(5) # 模拟调用等待,单位:秒

7 print("模型调用完成。")

8

9 def perform_other_tasks():

10 # 模拟执行其他任务

11 for i in range(5):

12 print(f"执行其他任务 {i+1}\{i + 1\}{i+1} ")

13 time.sleep(1) # 单位:秒

14

15 def main():

16 start_time = time.time()

17 call_model()

18 perform_other_tasks()

19 end_time = time.time()

20 total_time = end_time - start_time

21 return f"总共耗时:{total_time}秒"

22

23 # 运行同步任务并打印完成时间

24 main_time = main()

25 print(main_time)

txt 复制代码
开始调用模型...  
模型调用完成。  
执行其他任务1  
执行其他任务2  
执行其他任务3  
执行其他任务4  
执行其他任务5  
总共耗时:10.061029434204102秒

之前的 llm.invoke(...) 本质上是一个同步调用。每个操作依次执行,直到当前操作完成后才开始下一个操作,从而导致总的执行时间是各个操作时间的总和。

异步调用

异步调用,允许程序在等待某些操作完成时继续执行其他任务,而不是阻塞等待。这在处理I/O操作(如网络请求、文件读写等)时特别有用,可以显著提高程序的效率和响应性。

举例:

写法1:此写法适合Jupyter Notebook

python 复制代码
1 import asyncio  
2 import time  
3  
4 async def async_call(llm):  
5 await asyncio.sleep(5) # 模拟异步操作  
6 print("异步调用完成")  
7  
8 async def perform_other_tasks():  
9 await asyncio.sleep(5) # 模拟异步操作  
10 print("其他任务完成")  
11  
12 async def run_async_tasks():  
13 start_time = time.time()  
14 await asyncio[gather(  
15 async_call(None), # 示例调用,使用None模拟LLM对象  
16 perform_other_tasks()  
17 )  
18 end_time = time.time()  
19 return f"总共耗时:{end_time - start_time}秒"  
20  
21 # 正确运行异步任务的方式  
22 # if_name == "_main_:  
23 # # 使用asyncio.run()来启动异步程序  
24 # result = asyncio.run(run_async_tasks())  
25 # print(result)  
26  
27  
28 # 在Jupyter单元格中直接调用  
29 result = await run_async_tasks()  
30 print(result)

异步调⽤完成

其他任务完成

总共耗时:5.001038551330566秒

写法2:(此写法不适合Jupyter Notebook)

1 import asyncio

2 import time

3

4 async def async_call(llm):

5 awaitasyncio.sleep(5)#模拟异步操作

6 print("异步调用完成")

7

8 async def perform_other_tasks():

9 awaitasyncio.sleep(5)#模拟异步操作

10 print("其他任务完成")

11

12 async def run_async_tasks():

13 start_time === time.time()

14 awaitasyncio.gather(

15 async_call(None),#示例调用,替换None为模拟的LLM对象

16 perform_other_tasks()

17 )

18 end_time === time.time()

19 returnf"总共耗时:{end_time-start_time}秒"

20

21 #正确运行异步任务的方式

22 if_name ≡=\equiv =≡= "main":

23 #使用asyncio.run()来启动异步程序

24 result === awaitio.runasync Tasks())

25 print(result)

26

使用 asyncio.gather() 并行执行时,理想情况下,因为两个任务几乎同时开始,它们的执行时间将重叠。如果两个任务的执行时间相同(这里都是5秒),那么总执行时间应该接近单个任务的执行时间,而不是两者时间之和。

异步调用之ainvoke

举例1:验证ainvoke是否是异步

txt 复制代码
1 #方式1  
2 import inspect  
3  
4 print("invoke是协程函数:",inspect.iscoroutinefunction chat_model=ainvoke)  
5 print("invoke是协程函数:",inspect.iscoroutinefunction chat_model.invoke))

ainvoke 是协程函数: True

invoke 是协程函数: False

import asyncio

import os

import time

import dotenv

from langchain_core.messages import HumanMessage, SystemMessage

from langchain_openai import ChatOpenAI

dotenv.load_dotenv()

os.environ['OPENAI_API_KEY'] === os.getenv("OPENAI_API_KEY1")

os.environ['OPENAI_BASE_URL'] === os.getenv("OPENAI_BASE_URL")

初始化大模型

chat_model === ChatOpenAI(mode === "gpt-4o-mini")

同步调用(对比组)

def sync_test():

messages1 === [SystemMessage(content === "你是一位乐于助人的智能小助手"),

HumanMessage(conten :=: =:= "请帮我介绍一下什么是机器学习"), ]

start_time === time.time()

response === chat_model.invoke(messages1) # 同步调用

duration === time.time() - start_time

print(f"同步调用耗时:{duration:.2f}秒")

return response, duration

异步调用(实验组)

async def async_test():

messages1 === [SystemMessage(content === "你是一位乐于助人的智能小助手"),

HumanMessage(conten :=: =:= "请帮我介绍一下什么是机器学习"), ]

start_time === time.time()

response === await chat_model.ainvoke(messages1) # 异步调用

duration === time.time() - start_time

print(f"异步调用耗时:{duration:.2f}秒")

return response, duration

运行测试

if name_ == main

运行同步测试

sync_response, sync_duration === sync_test()

print(f"同步响应内容: {sync_response.content[:100]}...\n")

运行异步测试

async_response, async_duration === asyncio.run(async_test())

print(f"异步响应内容: {async_response.content[:100]}...\n")

并发测试 - 修复版本

print( ∣n==\scriptstyle { | n = = { } }∣n== 并发测试 ==− d dt= = - \frac { \ d } { \ d t }==− dt d

start_time === time.time()

53

54 async def run_concurrent/tests():

55 #创建3个异步任务

56 tasks === [async_test() for_in range(3)]

57 #并发执行所有任务

58 return await asyncio.gather(*tasks)

59

60

61 #执行并发测试

62 results === asyncio.run(run_concurrent/tests())

63

64 total_time === time.time()-start_time

65 print(f"\n3个并发异步调用总耗时:{total_time:.2f秒}

66 print(f"平均每个调用耗时:{total_time/3:.2f秒}"

67

同步调用耗时:5.73秒1

同步响应内容: 机器学习是人工智能(AI)的一个子领域,旨在通过让计算机系统从数据中学习和改进其性能,而无需明确的编程。它的核心理念是利用算法和统计模型,分析和识别数据中的模式,从而在新数据出现时做出预测或决策。

56 异

异步响应内容: 机器学习是一种人工智能(AI)技术,它使计算机能够通过经验自我学习和改进,而无需明确编程。换句话说,机器学习使计算机能够从数据中提取模式和规律,并根据这些信息进行预测或决策。

8机器学习的基本过程通常...

10

11

12

13

14

15

16

17 3个并发异步调用总耗时: 7.43秒18 平均每个调用耗时: 2.48秒

4、Model I/O之Prompt Template

Prompt Template,通过模板管理大模型的输入。

4.1 介绍与分类

Prompt Template 是LangChain中的一个概念,接收用户输入,返回一个传递给LLM的信息(即提示词prompt)。

在应用开发中,固定的提示词限制了模型的灵活性和适用范围。所以,prompt template 是一个 模板化的字符串 ,你可以将 变量插入到模板 中,从而创建出不同的提示。调用时:

以 字典 作为输入,其中每个键代表要填充的提示模板中的变量。

输出一个 PromptValue 。这个 PromptValue 可以传递给 LLM 或 ChatModel,并且还可以转换为字符串或消息列表。

有几种不同类型的提示模板:

PromptTemplate :LLM提示模板,用于生成字符串提示。它使用 Python 的字符串来模板提示。

ChatPromptTemplate :聊天提示模板,用于组合各种角色的消息模板,传入聊天模型。

XxxMessagePromptTemplate :消息模板词模板,包括:SystemMessagePromptTemplate、HumanMessagePromptTemplate、AIMessagePromptTemplate、ChatMessagePromptTemplate等

FewShotPromptTemplate :样本提示词模板,通过示例来教模型如何回答

PipelinePrompt :管道提示词模板,用于把几个提示词组合在一起使用。

自定义模板 :允许基于其它模板类来定制自己的提示词模板。

模版导入

python 复制代码
1 from langchain+prompts.prompt import PromptTemplate   
2   
3 from langchain+prompts import ChatPromptTemplate   
4   
5 from langchain+prompts import FewShotPromptTemplate   
6   
7 from langchain+promptspipeline import PipelinePromptTemplate   
8   
9 from langchain+prompts import (   
10 ChatMessagePromptTemplate,   
11 SystemMessagePromptTemplate,   
12 AIMessagePromptTemplate,   
13 HumanMessagePromptTemplate,   
14 ) 

4.2 复习:str.format()

Python的 str.format() 方法是一种字符串格式化的手段,允许在 字符串中插入变量 。使用这种方法,可以创建包含 占位符 的字符串模板,占位符由花括号 {} 标识。

调用format()方法时,可以传入一个或多个参数,这些参数将被顺序替换进占位符中。

str.format()提供了灵活的方式来构造字符串,支持多种格式化选项。

在LangChain的默认设置下, PromptTemplate 使用 Python 的 str.format() 方法进行模板化。这样在模型接收输入前,可以根据需要对数据进行预处理和结构化。

带有位置参数的用法

使用位置参数1

info2 === "Name: {0}, Age: {1}".format("Jerry", 25)

3 print(info)

Name: Jerry, Age: 25

带有关键字参数的用法

使用关键字参数1

info2 === "Name: {name}, Age: {age}".format(name ∗=^ { * = }∗= "Tom", age =25= 2 5=25 )

3 print(info)

Name: Tom, Age: 25

使用字典解包的方式

使用字典解包1

2 person === {"name": "David", "age": 40}

3 info === "Name: {name}, Age: {age}".format(**person)

print(info) 4

Name: David, Age: 40

4.3 具体使用:PromptTemplate

4.3.1 使用说明

PromptTemplate类,用于快速构建 包含变量 的提示词模板,并通过 传入不同的参数值 生成自定义的提示词。

主要参数介绍:

template:定义提示词模板的字符串,其中包含 文本 和 变量占位符(如{name}) ;

input_variables: 列表,指定了模板中使用的变量名称,在调用模板时被替换;

partial_variables:字典,用于定义模板中一些固定的变量名。这些值不需要再每次调用时被替换。

函数介绍:

format():给input_variables变量赋值,并返回提示词。利用format() 进行格式化时就一定要赋值,否则会报错。当在template中未设置input_variables,则会自动忽略。

4.3.2 两种实例化方式

方式1:使用构造方法

举例1:

from langchain.prompts import PromptTemplate1

2

定义模板:描述主题的应用3

template4 === PromptTemplate(template === "请简要描述{topic}的应用。",

5 input_variables === ["topic"])

6

7 print(template)

8

9 # 使用模板生成提示词

10 prompt_1 === template.format(topic === "机器学习")

prompt_211 === template.format(topic === "自然语言处理")

12

13 print("提示词1:", prompt_1)

14 print("提示词2:", prompt_2)

input_variables Π‾‾\underline { { \underline { { \mathbf { \Pi } } } } }Π [topic] input_types Ω={}{ \it \Omega } = \{ \}Ω={} partial_variable ={}= \{ \}={} template : d dt\mathrel { \mathop : } \frac { \ d } { \ d t }: dt d 请简要描述{topic}的应⽤。'

提⽰词1: 请简要描述机器学习的应⽤。

提⽰词2: 请简要描述⾃然语⾔处理的应⽤。

可以直观的看到PromptTemplate可以将template中声明的变量topic准确提取出来,使prompt更清晰。

举例2:定义多变量模板

1 from langchain.prompts import PromptTemplate

2

3 #定义多变量模板

4 template === PromptTemplate( template ≡\equiv≡ "请评价product的优缺点,包括{aspect1}和{aspect2}。" input_variables ≔\coloneqq:= ["product","aspect1","aspect2"]

7

8 #使用模板生成提示词

9 prompt_1 === template.format product ≡\equiv≡ "智能手机", aspect1 === "电池续航", aspect2 === "拍照质量"

10 prompt_2 === template.format product ≡\equiv≡ "笔记本电脑", aspect1 === "处理速度", aspect2 === "便携性"

11

12 print("提示词1:"prompt_1)

13 print("提示词2:"prompt_2)

方式2:调用from_template()

举例1:

python 复制代码
1 from langchain.prompts import PromptTemplate  
2  
3 prompt_template = PromptTemplate.from_template(  
4 "请给我一个关于{topic}的{type}解释。"  
5 )  
6  
7 #传入模板中的变量名  
8 prompt = prompt_template.format(type="详细", topic="量子力学")  
9  
10 print(prompt)

请给我⼀个关于量⼦⼒学的详细解释。

举例2:模板支持任意数量的变量,包括不含变量:

python 复制代码
1 #1.导入相关的包  
2 from langchain_core.prompts import PromptTemplate  
3  
4 #2.定义提示词模版对象  
5 text = ""  
6 Tell me a joke  
7 ""  
8  
9 prompt_template = PromptTemplate.from_template(text)  
10 #3.默认使用f-string进行格式化(返回格式好的字符串)  
11 prompt = prompt_template.format()  
12 print(prompt)
txt 复制代码
Tell me a joke 

4.3.3 两种新的结构形式

形式1:部分提示词模版

在生成prompt前就已经提前初始化部分的提示词,实际进一步导入模版的时候只导入除已初始化的变量即可。

举例1:

方式1:实例化过程中使用partial_variables变量

1 from langchain.prompts import PromptTemplate

2

3 #方式2:

4 template2 = PromptTemplate(

5 template === {"foo}{bar}",

6 input_variables ≔\coloneqq:= ["foo","bar"],

7 partial_variables ≡\equiv≡ {"foo": "hello"}

8 )

9

10 prompt2 === template2.format(bar === "world")

11

12 print(prompt2)

方式2:使用 PromptTemplate.partial() 方法创建部分提示模板

from langchain+prompts import PromptTemplate

template1 === PromptTemplate( template ≡\equiv≡ {"foo}{bar} ", input_variables ≡\equiv≡ ["foo", "bar"]

#方式1:

partial_template1 === template1部分内容(foo ≡\equiv≡ "hello")

prompt1 === partial_template1.format(bar ≡\equiv≡ "world")

print(prompt1)

举例2:

1 from langchain_core.prompts import PromptTemplate

2

3 #完整模板

4 full_template === ""你是一个{role},请用{style}风格回答:

5 问题:{question}

6 答案:""

7

8 #预填充角色和风格

9 partial_template === PromptTemplate.from_template(full_template).partial( role ≡\equiv≡ "资深厨师", style ≡\equiv≡ "专业但幽默"

10

11

12 )

13

14 #只需提供剩余变量

15 print(partial_template.format(question ≡\equiv≡ "如何煎牛排?"))

你是⼀个资深厨师,请⽤专业但幽默⻛格回答:

问题:如何煎⽜排?

答案:

举例3:

python 复制代码
1 prompt_template = PromptTemplate.from_template(
2 template = "请评价{product}的优缺点,包括{aspect1}和{aspect2}。"
3 partial_variables = {"aspect1":"电池","aspect2":"屏幕}
4 )
5
6 prompt = prompt_template.format.product = "笔记本电脑"
7 print(prompt)

请评价笔记本电脑的优缺点,包括电池和屏幕。

举例:

1 from langchain_core.prompts import PromptTemplate

2 template === ( PromptTemplate.from_template("Tell me a joke about {topic}

5 +",make it funny"

6 +"\n\nand in{language}"

7 )

8

9 prompt ≡\equiv≡ template.formattopic ≡\equiv≡ "sports",language ≡\equiv≡ "spanish")

10 print(prompt)

Tell me a joke about sports, make it funny and in spanish

4.3.4 format() 与 invoke()

只要对象是RunnableSerializable接口类型,都可以使用invoke(),替换前面使用format()的调用方式。

format(),返回值为字符串类型;invoke(),返回值为PromptValue类型,接着调用to_string()返回字符串。

举例1:

python 复制代码
1 #1.导入相关的包  
2 from langchain_core.prompts import PromptTemplate  
3  
4 #2.定义提示词模版对象  
5 prompt_template = PromptTemplate.from_template(  
6 "Tell me a {adjective} joke about {content}.")  
7  
8 #3.默认使用f-string进行格式化(返回格式好的字符串)  
9 prompt_template.invoke({"adjective": "funny", "content": "chickens"})

StringPromptValue(tex ⋅=†\cdot = ^ { \dag }⋅=† Tell me a funny joke about chickens.)

举例2:

python 复制代码
1 #1.导入相关的包  
2 from langchain_core.prompts import PromptTemplate  
3  
4 #2.使用初始化器进行实例化  
5 prompt = PromptTemplate(  
6 input_variables=[ "adjective", "content"],  
7 template="Tell me a {adjective} joke about {content}"]  
8  
9 #3. PromptTemplate底层是RunnableSerializable接口所以可以直接使用invoke()调用  
10 prompt.invoke({ "adjective": "funny", "content": "chickens"})

举例3:

1 from langchain_core.prompts import PromptTemplate

2

3 prompt_template === ( PromptTemplate.from_template("Tell me a joke about {topic}")

4 +",make it funny"

5 + "and in{language}"

6

7 )

8

9 prompt === prompt_template.invoke({"topic":"sports","language":"spanish"})

10 print(prompt)

4.3.5 结合LLM调用

Prompt 与大模型结合。

问题:这里的大模型,是哪类呢?非对话大模型?对话大模型?

提供大模型:(非对话大模型)

python 复制代码
1 import os  
2 import dotenv  
3 from langchain_openai import OpenAI  
4  
5 dotenv.load_dotenv()  
6  
7 os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")  
8 os.environ['OPENAI_BASE_url'] = os.getenv("OPENAI_BASE_url")  
9  
10 llm = OpenAI() 

提供大模型:(对话大模型)

python 复制代码
1 import os  
2 import dotenv  
3 from langchain_openai import ChatOpenAI  
4  
5 dotenv.load_dotenv()  
6  
7 os.environ['OPENAI_API_KEY] = os.getenv("OPENAI_API_KEY1")  
8 os.environ['OPENAI_BASE_URL] = os.getenv("OPENAI_BASE_URL")  
9  
10 llm = ChatOpenAI(  
11 model="gpt-4o-mini"  
12 ) 

调用过程:

python 复制代码
1 prompt_template = PromptTemplate.from_template(
    template = "请评价{product}的优缺点,包括{aspect1}和{aspect2}"  
3 )  
4  
5 prompt = prompt_template.format.product = "电脑", aspect1 = "性能", aspect2 = "电池"  
6 # prompt = prompt_template.invoke({
    "product": "电脑", "aspect1": "性能", "aspect2": "电池"
)  
7  
8 print(type(prompt))  
9  
10 # llm.invoke_prompt) #使用非对话模型调用  
11  
12 llm1.invoke_prompt) #使用对话模型调用
twig 复制代码
<class 'str'> 
txt 复制代码
AIMessage(content='电脑的优缺点可以从多个方面进行分析,包括性能和电池等方面。以下是对电脑的一些优缺点的总结:\n\n优点\n\n1. 性能强大:\n - 现代电脑,尤其是高端型号,配备了强大的处理器(如Intel i7/i9、AMD Ryzen系列)、充足的内存(8GB、16GB或更高)以及快速的固态硬盘(SSD),能够高效地处理复杂任务,如视频编辑、3D建模和游戏等。\n\n2. 多功能性:\n - 电脑可以用于多种用途,包括办公、学习、编程、设计、娱乐等,满足不同用户的需求。\n\n3. 扩展性:\n - 许多台式电脑具有良好的扩展性,可以方便地升级硬件(如增加内存、升级显卡或更换硬盘)以提高性能。\n\n4. 大屏幕和高分辨率:\n - 电脑通常配备比手机和笔记本更大的显示屏,能够提供更好的视觉体验,特别适合进行多任务处理和观看视频。\n\n5. 丰富的软件支持:\n - 电脑平台(如Windows、macOS、Linux)支持的软件种类繁多,包括一些专业软件和开发工具,适合各类专业用户。\n\n6. 便携性差:\n - 台式电脑通常体积较大,不适合携带;相比之下,尽管笔记本电脑便携性较好,但通常性能相对较低。\n\n7. 电池续航有限(笔记本电脑):\n - 对于笔记本电脑而言,虽然电池技术在不断进步,但高性能笔记本在高负载情况下电池续航时间可能较短,常需要频繁充电。\n\n8. 散热和噪音问题:\n - 高负载时,电脑可能会产生较高的热量和噪音,尤其是在运行大型应用或游戏时,散热和风扇噪音可能影响使用体验。\n\n9. 更新换代快:\n - 电脑硬件和软件更新换代非常快,用户需要不时购买新设备或升级硬件,以保持性能。\n\n10. 成本:\n - 高性能的电脑往往价格昂贵,尤其是游戏电脑和专业工作站,可能不适合预算有限的用户。\n\n11. 基本:\n - 高性能的电脑往往价格昂贵,尤其是游戏电脑和专业工作站,可能不适合预算有限的用户。\n\n12. 效果:\n - 电脑在性能和多功能性上有显著优势,但在便携性和电池续航等方面存在一定的局限性。用户在选择电脑时,需要根据自己的需求和使用场景进行权衡。\n\n13. 添加功能:\n - 添加功能是通过添加新的功能来实现的。\n\n14. 添加功能的类型:\n\n15. 添加功能的名称:\n\n16. 添加功能的描述:\n\n17. 添加功能的说明:\n\n18. 添加功能的使用场景:\n\n
txt 复制代码
'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details':  
{'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18',  
'system_fingerprint': 'fp_efad92c60b', 'id': 'chatcmpl-BzjJi5AmgpC71coOr6IgrIRRRlsdB',  
'service-tier': None, 'finish_reason': 'stop', 'logprobs': None}, id='run--c1165c77-9944-4d3a-8df7-053000e94f11-0', usage_metadata={'input_tokens': 20, 'output_tokens': 589,  
'total_tokens': 609, 'input_token_details': {'audio': 0, 'cache_read': 0},  
'output_token_details': {'audio': 0, 'reasoning': 0}}) 

4.4 具体使用:ChatPromptTemplate

4.4.1 使用说明

ChatPromptTemplate是创建 聊天消息列表 的提示模板。它比普通 PromptTemplate 更适合处理多角色、多轮次的对话场景。

特点:

支持 System / Human / AI 等不同角色的消息模板

对话历史维护

参数类型:列表参数格式是tuple类型( role :str content :str 组合最常用)

元组的格式为:

txt 复制代码
(role: str | type, content: str | list[dict] | list[object]) 

其中 role 是:字符串(如 "system" 、 "human" 、 "ai" )

4.4.2 两种实例化方式

方式1:使用构造方法

举例:

1 from langchain_core+prompt import ChatPromptTemplate

2

3 #参数类型这里使用的是tuple构成的list

4 prompt_template === ChatPromptTemplate([

5 #字符串role +^++ 字符串content

6 ("system","你是一个AI开发工程师.你的名字是{name}."),

7 ("human","你能开发哪些AI应用?"),

8 ("ai","我能开发很多AI应用,比如聊天机器人,图像识别,自然语言处理等."),

9 ("human","{user_input}")

10 ])

11

12 #调用format()方法,返回字符串

13 prompt === prompt_template.invoke(input={'name":"小谷AI","user_input":"你能帮我做什么?'})

14 print(type(prompt))

15 print(prompt)

javascript 复制代码
<class 'langchain_core.prompt_values.ChatPromptValue'>  
messages=[SystemMessage(content='你是一个AI开发工程师.你的名字是小谷AI.',  
additional_kwarges={}, response_metadata={}), HumanMessage(content='你能开发哪些AI应  
用?', additional_kwarges={}, response_metadata={}), AIMessage(content='我能开发很多AI应
txt 复制代码
用,比如聊天机器人,图像识别,自然语言处理等!,additional_kwarges={},response_metadata=  
}),HumanMessage(content='你能帮我做什么?', additional_kwarges={}, response_metadata=  
})]

方式2:调用from_messages()

举例1:

python 复制代码
1 #导入相关依赖  
2 from langchain_core+prompts import ChatPromptTemplate  
3  
4 #定义聊天提示词模版  
5 chat_template = ChatPromptTemplate.from/messages(  
6 [  
7 ("system", "你是一个有帮助的AI机器人,你的名字是{name}。"),  
8 ("human", "你好,最近怎么样?"),  
9 ("ai", "我很好,谢谢!"),  
10 ("human", {"user_input"}),  
11 ]  
12 )  
13  
14 #格式化聊天提示词模版中的变量  
15 messages = chat_template.invoke(input={'name":"小明","user_input":"你叫什么名字?'})  
16  
17 #打印格式化后的聊天提示词模版内容  
18 print/messages)
javascript 复制代码
messages=[SystemMessage(content='你是一个有帮助的AI机器人,你的名字是小明。','additional_kwargs={'}, response_metadata={'}), HumanMessage(content='你好,最近怎么样?', additional_kwargs={'}, response_metadata={'}), AIMessage(content='我很好,谢谢!','additional_kwargs={'}, response_metadata={'}), HumanMessage(content='你叫什么名字?','additional_kwargs={'}, response_metadata={'})]

举例2:了解

1 #示例1:role为字符串

2 from langchain_core+prompts import ChatPromptTemplate

3

4 prompt === ChatPromptTemplate.from/messages([("system","你是一个{role}."),("human","{user_input}"),

5 ])

6

7

8

9 #示例2:role为消息类不支持

10 from langchain_core/messages import SystemMessage,HumanMessage

11

12 #prompt === ChatPromptTemplate.from/messages([SystemMessage,"你是一个{role}."),#类对象role +^++ 字符串content

13

14 # (HumanMessage,["你好!",{"type":"text}}],#类对象role +^++ list[dict]content

15 #])

16 #修改

17 prompt === ChatPromptTemplate.from/messages([

txt 复制代码
18 ("system", ["你好! ", {"type": "text"}]), # 字符串 role + list[dict] content  
19 ])

4.4.3 模板调用的几种方式

对比: invoke() 、 format() 、 format_messages() 、 format_prompt()

方式1:使用 invoke(),前面已经讲过

txt 复制代码
1 from langchain_core.prompts import ChatPromptTemplate  
2  
3 #参数类型这里使用的是tuple构成的list  
4 prompt_template = ChatPromptTemplate([  
5 #字符串role + 字符串content  
6 ("system", "你是一个AI开发工程师.你的名字是{name}."),  
7 ("human", "你能开发哪些AI应用?"),  
8 ("ai", "我能开发很多AI应用,比如聊天机器人,图像识别,自然语言处理等."),  
9 ("human", {"user_input"})  
10 ])  
11  
12 prompt = prompt_template.invoke({ "name"."小谷AI", "user_input"."你能帮我做什么?"})  
13 print(type(prompt))  
14 print(prompt)  
15 print(len(prompt/messages))
txt 复制代码
<class 'langchain_core.prompt_values.ChatPromptValue'>  
messages=[SystemMessage(content='你是一个AI开发工程师.你的名字是小谷AI.', additional_kwarges={'}, response_metadata={'}}, HumanMessage(content='你能开发哪些AI应用?', additional_kwarges={'}, response_metadata={'}}, AIMessage(content='我能开发很多AI应用,比如聊天机器人,图像识别,自然语言处理等', additional_kwarges={'}, response_metadata={'}}, HumanMessage(content='你能帮我做什么?', additional_kwarges={'}, response_metadata={'}})]  
4

方式2:使用format()

python 复制代码
1 from langchain_core.prompts import ChatPromptTemplate  
2  
3 #参数类型这里使用的是tuple构成的list  
4 prompt_template = ChatPromptTemplate([  
5 #字符串role + 字符串content  
6 ("system", "你是一个AI开发工程师.你的名字是{name}."),  
7 ("human", "你能开发哪些AI应用?"),  
8 ("ai", "我能开发很多AI应用,比如聊天机器人,图像识别,自然语言处理等."),  
9 ("human", {"user_input"})  
10 ])  
11  
12 #方式1:调用format()方法,返回字符串  
13 prompt = prompt_template.format(name="小谷AI", user_input="你能帮我做什么?")  
14 print(type(prompt))  
15 print(prompt)
twig 复制代码
<class 'str'> 

System: 你是⼀个AI开发⼯程师. 你的名字是 小⾕AI.

Human: 你能开发哪些AI应⽤?

AI: 我能开发很多AI应⽤, ⽐如聊天机器⼈, 图像识别, ⾃然语⾔处理等.

Human: 你能帮我做什么?

方式3:使用format_messages()

1 from langchain_core.prompts import ChatPromptTemplate

2

3 prompt_template === ChatPromptTemplate([

4 ("system","你是一个AI开发工程师你的名字是{name}.),

5 ("human","你能开发哪些AI应用?"),

6 ("ai","我能开发很多AI应用,比如聊天机器人,图像识别,自然语言处理等.),

7 ("human","{user_input}")

8 ])

9

10 #调用format_messages()方法,返回消息列表

11 prompt2 === prompt_template.format/messages(name ≡\equiv≡ "小谷AI",user_input ≡\equiv≡ "你能帮我做什么?"

12 print(type(prompt2))

13 print(prompt2)

txt 复制代码
<class 'list'> 
txt 复制代码
[SystemMessage(content='你是一个AI开发工程师.你的名字是小谷AI.', additional_kwargs= {}, response_metadata={'}), HumanMessage(content='你能开发哪些AI应用?', additional_kwargs={'}, response_metadata={'}), AIMessage(content='我能开发很多AI应用,比如聊天机器人,图像识别,自然语言处理等,' additional_kwargs={'}, response_metadata={'}), HumanMessage(content='你能帮我做什么?', additional_kwargs={'}, response_metadata={'})]

结论:给占位符赋值,针对于ChatPromptTemplate,推荐使用 format_messages() 方法,返回消息列表。

方式4:使用format_prompt()

1 from langchain_core.prompts import ChatPromptTemplate

2

3 #参数类型这里使用的是tuple构成的list

4 prompt_template === ChatPromptTemplate([

5 #字符串role +^++ 字符串content

6 ("system","你是一个AI开发工程师.你的名字是{name}."),

7 ("human","你能开发哪些AI应用?"),

8 ("ai","我能开发很多AI应用,比如聊天机器人,图像识别,自然语言处理等."),

9 ("human","{user_input}")

10 ])

11

12 prompt === prompt_template.format_prompt(name ≡\equiv≡ "小谷AI",user_input ≡\equiv≡ "你能帮我做什么?"

13 print(prompt.to/messages())

14 print(type(prompt.to/messages()))

15

r 复制代码
16 #print(prompt.to_string())
17 #print(type(prompt.to_string())) 
txt 复制代码
\[ \text{SystemMessage(content='你是一个AI开发工程师。你的名字是小谷AI', additional_kwargs=} \}, \text{response_metadata=} \} \), HumanMessage(content='你能开发哪些AI应用?', additional_kwargs=} \}, response_metadata=} \}), AIMessage(content='我能开发很多AI应用,比如聊天机器人,图像识别,自然语言处理等,' additional_kwargs=} \}, response_metadata=} \)), HumanMessage(content='你能帮我做什么?', additional_kwargs=} \}, response_metadata=} \)] <class 'list'>

4.4.4 更丰富的实例化参数类型

前面讲了ChatPromptTemplate的两种创建方式。我们看到不管使用构造方法,还是使用from_messages(),参数类型都是 列表类型 。列表中的元素可以是多种类型,前面我们主要测试了元组类型。

源码:

1 def_init_self,

2 messages: Sequence[BaseMessagePromptTemplate | BaseMessage | BaseChatPromptTemplate | tuple[str| type, str| listdict] | listobject] | str| dict[str, Any]],

3 * ,

4 template_format:Literal["f-string","mustache","jinja2"] === "f-string",

5 **kwargs: Any) -> None

源码:

1 @classmethod def frommessages(cls,

2 messages: Sequence[BaseMessagePromptTemplate | BaseMessage |

3 BaseChatPromptTemplate | tuple[str| type, str| listdict] | listobject] | str| dict[str, Any]],

4 template_format:Literal["f-string","mustache","jinja2"] === "f-string")

5 →\rightarrow→ ChatPromptTemplate

结论:参数是列表类型,列表的元素可以是字符串、字典、字符串构成的元组、消息类型、提示词模板类型、消息提示词模板类型等

类型1:str类型

列表参数格式是str类型(不推荐),因为默认角色都是human

python 复制代码
1 #1.导入相关依赖  
2 from langchain_core.prompts import ChatPromptTemplate  
3 from langchain_core/messages import SystemMessage, HumanMessage, AIMessage  
4 #2.定义聊天提示词模版  
5 chat_template = ChatPromptTemplate.from/messages(  
6 [  
7 "Hello, {name}!" # 等价于 ("human", "Hello, {name}!")  
8 ]  
9 )  
10
txt 复制代码
11 #3.1格式化聊天提示词模版中的变量(自己提供的)  
12 messages = chat_template.format/messages(name='小谷A')  
13 #3.2使用invoke执行  
14 #messages = chat_template.invoke(['name':'小谷AI'])  
15  
16 #4.打印格式化后的聊天提示词模版内容  
17 print/messages)

类型2:dict类型

列表参数格式是dict类型

txt 复制代码
1 #示例:字典形式的消息  
2 prompt = ChatPromptTemplate.from/messages([  
3 {"role": "system", "content": "你是一个{role}."}  
4 {"role": "human", "content": ["复杂内容", {"type": "text"}]},  
5 ])  
6  
7 print(prompt.format_messages(role = "教师")

类型3:Message类型

from langchain_core/messages import SystemMessage,HumanMessage

chat_prompt_template === ChatPromptTemplate.from/messages([ SystemMessage(content ≡\equiv≡ "我是一个贴心的智能助手") HumanMessage(content ≡\equiv≡ "我的问题是:人工智能英文怎么说?")

])

messages === chat_prompt_template.format/messages()

print messages)

print(type/messages))

latex 复制代码
[ \text{SystemMessage(content='我是一个贴心的智能助手', additional_kwarges=} \}, ]  
response_metadata=\{}), HumanMessage(content='我的问题是:人工智能英文怎么说?',' additional_kwarges=\{}), response_metadata=\{})]  
<class 'list'>

类型4:BaseChatPromptTemplate类型

使用 BaseChatPromptTemplate,可以理解为ChatPromptTemplate里嵌套了ChatPromptTemplate。

举例1:不带参数

1 from langchain_core.prompts import ChatPromptTemplate

2

3 #使用BaseChatPromptTemplate(嵌套的ChatPromptTemplate)

4 nested_prompt_template =1= 1=1 ChatPromptTemplate.frommessages([("system","我是一个人工智 能助手])

5 nested_prompt_template =2= 2=2 ChatPromptTemplate.frommessages([("human","很高兴认识你"])

6

7 prompt_template === ChatPromptTemplate.frommessages([

8 nested_prompt_template1,nested_prompt_template2

9 ])

10

11 prompt_template.format/messages()

txt 复制代码
[ \text{SystemMessage(content='嵌套提示词之System', additional_kwargs=} \}, ]  
response_metadata=\{}),  
HumanMessage(content='嵌套提示词之Human', additional_kwargs=\{}),  
response_metadata=\{}])

举例2:带参数

1 from langchain_core.prompts import ChatPromptTemplate

2

3 #使用BaseChatPromptTemplate(嵌套的ChatPromptTemplate)

4 nested_prompt_template === ChatPromptTemplate.from/messages([ ("system","我是一个人工智能助手,我的名字叫{name}")

5 )

6

7 nested_prompt_template2 === ChatPromptTemplate.from/messages([ ("human","很高兴认识你我的问题是{question}")

8 )

9 )

10

11 prompt_template === ChatPromptTemplate.from/messages([

12 nested_prompt_template1,nested_prompt_template2

13 )

14

15 prompt_template.format_messages(name ≡\equiv≡ "小智",question ≡\equiv≡ "你为什么这么帅?")

javascript 复制代码
[SystemMessage(content='我是一个人工智能助手,我的名字叫小智', additional_kwargs={'}, response_metadata={'}), HumanMessage(content='很高兴认识你,我的问题是你为什么这么帅?', additional_kwargs={'}, response_metadata={'})]

类型5:BaseMessagePromptTemplate类型

txt 复制代码
LangChain提供不同类型的MessagePromptTemplate。最常用的是SystemMessagePromptTemplate、HumanMessagePromptTemplate和AIMessagePromptTemplate,分别创建系统消息、人工消息和AI消息,它们是ChatMessagePromptTemplate的特定角色子类。

基本概念:

HumanMessagePromptTemplate,专用于生成 用户消息(HumanMessage) 的模板类,是ChatMessagePromptTemplate的特定角色子类。

本质 :预定义了 role === "human" 的 MessagePromptTemplate,且无需无需手动指定角色

模板化 :支持使用变量占位符,可以在运行时填充具体值

格式化 :能够将模板与输入变量结合生成最终的聊天消息

输出类型 :生成 HumanMessage 对象( content +^ ++ role === "human" )

设计目的 :简化用户输入消息的模板化构造,避免重复定义角色

SystemMessagePromptTemplate、AIMessagePromptTemplate:类似于上面,不再赘述

ChatMessagePromptTemplate,用于构建聊天消息的模板。它允许你创建可重用的消息模板,这些模板可以动态地插入变量值来生成最终的聊天消息

角色指定 :可以为每条消息指定角色(如 "system"、"human"、"ai") 等,角色灵活。

模板化 :支持使用变量占位符,可以在运行时填充具体值

格式化 :能够将模板与输入变量结合生成最终的聊天消息

举例1:

txt 复制代码
1 #导入聊天消息类模板  
2 from langchain_core+prompts import ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate  
3  
4 #创建消息模板  
5 system_template = "你是一个专家{role}"  
6 system_message_prompt = SystemMessagePromptTemplate.from_template(system_template)  
7  
8 human_template = "给我解释{concept},用浅显易懂的语言"  
9 human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)  
10  
11 #组合成聊天提示模板  
12 chat_prompt = ChatPromptTemplate.from/messages([system_message_prompt, human_message_prompt])  
13  
14 #格式化提示  
15 formatted_messages = chat_prompt.format/messages(  
16 role="物理学家",  
17 concept="相对论"  
18 )  
19 print(formatted/messages)
ini 复制代码
[SystemMessage(content='你是一个专家物理学家', additional_kwargs=\{} response_metadata=\{\}, HumanMessage(content='给我解释相对论,用浅显易懂的语言', additional_kwargs=\{\}, response_metadata=\{\}]  
[SystemMessage(content='你是一个专家物理学家', additional_kwargs=\{\}, response_metadata=\{\}, HumanMessage(content='给我解释相对论,用浅显易懂的语言', additional_kwargs=\{\}, response_metadata=\{\}]

举例2:ChatMessagePromptTemplate的理解

python 复制代码
1 # 1.导入先关包  
2 from langchain_core.prompts import ChatMessagePromptTemplate  
3
txt 复制代码
4 #2.定义模版  
5 prompt = "今天我们授课的内容是{subject}"  
6  
7 #3.创建自定义角色聊天消息提示词模版  
8 chat_message_prompt = ChatMessagePromptTemplate.from_template( role="teacher", template=prompt  
9)  
10  
11 #4.格式聊天消息提示词  
12 resp = chat_message_prompt.format(subject="我爱北京天安门")  
13 print(type(resp))  
14 print(resp)
javascript 复制代码
<class 'langchain_core/messages chat.ChatMessage'>content='今天我们授课的内容是我爱北京天安门'additional_kwargs={'}response_metadata={'}role='teacher'

举例3:综合使用

python 复制代码
from langchain_core+prompts import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from langchain_core/messages import SystemMessage, HumanMessage
#示例1:使用BaseMessagePromptTemplate
system_prompt = SystemMessagePromptTemplate.from_template("你是一个{role}.")
human_prompt = HumanMessagePromptTemplate.from_template({user_input})
#示例2:使用BaseMessage(已实例化的消息)
system msg = SystemMessage(content="你是一个AI工程师。")
human msg = HumanMessage(content="你好!")
#示例3:使用BaseChatPromptTemplate(嵌套的ChatPromptTemplate)
nested_prompt = ChatPromptTemplate.frommessages([( "system", "嵌套提示词")] )
prompt = ChatPromptTemplate.from/messages(
system_prompt, #MessageLike(BaseMessagePromptTemplate)
human_prompt, #MessageLike(BaseMessagePromptTemplate)
system msg, #MessageLike(BaseMessage)
humanmsg, #MessageLike(BaseMessage)
nested_prompt, #MessageLike(BaseChatPromptTemplate)
))

类似的:

python 复制代码
1 from langchain_core/messages import HumanMessage, AIMessage   
2 from langchain_core.prompts import HumanMessagePromptTemplate, SystemMessagePromptTemplate   
3 from langchain_core.prompts import ChatPromptTemplate 
txt 复制代码
chat_template = ChatPromptTemplate.from/messages( [ SystemMessagePromptTemplate.from_template("你是一个AI开发工程师.你的名字是 {name}."), HumanMessage(content=("你能开发哪些AI应用?"), AIMessage(content=("我能开发很多AI应用,比如聊天机器人,图像识别,自然语言处理等")), HumanMessagePromptTemplate.from_template("input") ]   
12 )   
13 messages = chat_template.format/messages(input="你能帮我做什么?",name="小谷AI")   
14 print/messages)

SystemMessage(content=你是⼀个AI开发⼯程师. 你的名字是 小⾕AI., additional_kwargs={}, response_metadata ={}= \\{ \\}={} ), HumanMessage(content=你能开发哪些AI应⽤?',additional_kwarg Ω={}{ \\it \\Omega } = \\{ \\}Ω={} , response_metadata Ω={},{ \\it \\Omega } = \\{ \\} ,Ω={}, ), AIMessage(content=我能开发很多AI应⽤, ⽐如聊天机器⼈, 图像识别, ⾃然语⾔处理等.', additional_kwargs={}, response_metadata ={}= \\{ \\}={} ),HumanMessage(content=你能帮我做什么?', additional_kwarg ={}:{ \\mathfrak { = } } \\{ \\} _ { \\mathrm { : } }={}: , response_metadata={})

4.4.5 结合LLM

举例1:

1 from langchain+prompts chat import ChatPromptTemplate

2

3 ##1、提供提示词##1

4 chat_prompt === ChatPromptTemplate.from/messages([ ("system","你是一个数学家,你可以计算任何算式"), ("human","我的问题:{question}"),

5 7

8

9

10 #输入提示

11 messages === chat_prompt.format/messages(question ≡\equiv≡ "我今年18岁,我的舅舅今年38岁,我的爷 爷今年72岁,我和舅舅一共多少岁了?")

12 #print/messages)

13

14 ##2、提供大模型###

15 import os

16 import dotenv

17 from langchain_openai import ChatOpenAI

18

19 dotenv.load_dotenv()

20

21 os.environ['OPENAL_API_KEY] === os.getenv("OPENAL_API_KEY1")

22 os.environ['OPENAL_BASE_URL] === os.getenv("OPENAL_BASE_URL")

23

24 chat_model === ChatOpenAI(model ≡\equiv≡ "gpt-4o-mini")

25

26 #得到模型的输出

27

28 #得到模型的输出

29 output === chat_model.invoke闭环

打印输出内容 30

31 print(output.content)

你今年18岁,你的舅舅今年38岁。那么你和舅舅的年龄总和是:

18+38=5618 + 38 = 5618+38=56

所以你和舅舅⼀共56岁。

举例2:

1 from dotenv import load_dotenv

2 from langchain.prompts chat import SystemMessagePromptTemplate,

3 HumanMessagePromptTemplate, AIMessagePromptTemplate

4 from langchain_core.prompts import ChatPromptTemplate

5 from langchain_openai import ChatOpenAI

6 load_dotenv()

7 llm === ChatOpenAI()

8

9 template === ChatPromptTemplate.from/messages(

10 [ SystemMessagePromptTemplate.from_template("你是 product)的客服助手。你的名字叫

11 {name}),

12 HumanMessagePromptTemplate.from_template("hello 你好吗?",

13 AIMessagePromptTemplate.from_template("我很好 谢谢!",

14 HumanMessagePromptTemplate.from_template({query}),

15 ]

16 )

17

18 prompt === template.formatmessages(

19 product === "AGI课堂",

20 name === "Bob",

21 query === "你是谁"

22 )

23

24 #提供聊天模型

25 import os

26 import dotenv

27 from langchain_openai import ChatOpenAI

28

29 dotenv.load_dotenv()

30

31 os.environ['OPENAI_API_KEY] === os.getenv("OPENAI_API_KEY1")

32 os.environ['OPENAI_BASE_URL] === os.getenv("OPENAI_BASE_URL")

33 chat_model ≡\equiv≡ ChatOpenAI(model === "gpt-4o-mini")

35

#调用聊天模型

37 response ≡\equiv≡ chat_model.invoke(prompt)

38 print(response(content)

我是Bob,AGI课堂的客服助⼿。有什么我可以帮助你的吗?

4.4.6 插入消息列表:MessagesPlaceholder

当你不确定消息提示模板使用什么角色,或者希望在格式化过程中 插入消息列表 时,该怎么办? 这就需要使用 MessagesPlaceholder,负责在特定位置添加消息列表。

使用场景:多轮对话系统存储历史消息以及Agent的中间步骤处理此功能非常有用。

举例1:

1 from langchain_core.prompts import ChatPromptTemplate, MessagesplacesHolder

2 from langchain_core/messages import HumanMessage

3

4 prompt_template === ChatPromptTemplate.from/messages([

5 ("system","You are a helpful assistant"),

6 Messagesplacesholder("msgs")

7 ])

8 #prompt_template.invoke((""msgs":[HumanMessage(content ≡\equiv≡ "hi!"]])

9

10 prompt_template.format_messages(msgs ≔\coloneqq:= [HumanMessage(content ≡\equiv≡ "hi!"]))

txt 复制代码
[SystemMessage(content='You are a helpful assistant', additional_kwargs=\{\}, response_metadata=\{\}),]  
HumanMessage(content='hi!', additional_kwargs=\{\}, response_metadata=\{\}) 

这将生成两条消息,第一条是系统消息,第二条是我们传入的 HumanMessage。 如果我们传入了 5 条消息,那么总共会生成 6 条消息(系统消息加上传入的 5 条消息)。 这对于将一系列消息插入到特定位置非常有用。

举例2:存储对话历史内容

1 from langchain_core.prompts import ChatPromptTemplate, Messagesplacesholder

2 from langchain_core/messages import AIMessage

3

4 prompt === ChatPromptTemplate.from/messages(

5 [ ("system","You are a helpful assistant.,"),

6 Messagesplacesholder("history"),

7 ("human","{question}")

8 ]

9 1

10 )

11

12 prompt.format_messages(

13 history=[HumanMessage(content ≔\coloneqq:= "1+23 =?= ?=? ),AIMessage(content ≔\coloneqq:= "1+2 3=7)],

14 question ≔\coloneqq:= "我刚才问题是什么?")

15

16 #prompt.invoke(

17 # {

18 # "history": ["human", "what's 5+25 + 25+2 ", ("ai", "5 + 2 is 7)],

19 # "question": "now multiply that by 4"

txt 复制代码
20 # }   
21 #) 

举例3:

1 #1.导入相关包

2 from langchain_core.prompts import (ChatPromptTemplate, HumanMessagePromptTemplate, MessagesPlaceholder)

3

4 #2.定义消息模板

5 prompt = ChatPromptTemplate.frommessages([SystemMessagePromptTemplate.from_template("你是{role}"),MessagesPlaceholder(variable_name="intermediate_steps"),HumanMessagePromptTemplate.from_template({query})])

10

11 #3.定义消息对象(运行时填充中间步骤的结果)

12 intermediate = [SystemMessage(name="search", content="北京:晴, 25∘C25^{\circ}C25∘C ")

14 ]

15 #4.格式化聊天消息提示词模版

16 prompt.format/messages(

17 role="天气预报员",

18 intermediate_steps=intermediate,

19 query="北京天气怎么样?"

20 )

txt 复制代码
\[ \text{SystemMessage(content='你是天气预报员', additional_kwargs={'}, response_metadata={'}}\),  
\[ \text{SystemMessage(content='北京:晴, 25°C', additional_kwargs={'}, response_metadata={'}}, \]  
\[ \text{name='search'}}\),  
\[ \text{HumanMessage(content='北京天气怎么样?', additional_kwargs={'}, response_metadata={'}}\]

举例4:作为拓展,课下看看即可

txt 复制代码
1 #1.导入相关包  
2 from langchain_core.prompts import (ChatPromptTemplate, HumanMessagePromptTemplate, MessagesReplacement)  
3 from langchain_core/messages import AIMessage, HumanMessage  
4  
5 #2,定义HumanMessage对象  
6 human_message = HumanMessage(content="学习编程的最好方法是什么?")  
7 #3.定义AIMessage对象  
8 ai_message = AIMessage( content=""|  
9 1.选择一门编程语言:选择一门你想学习的编程语言.  
10 2.从基础开始:熟悉基本的编程概念,如变量、数据类型和控制结构.  
11 3.练习,练习,再练习:学习编程的最好方法是通过实践经验|  
12 4.练习,练习,再练习:学习编程的最好方法是通过实践经验|  
13 5.练习,练习,再练习:学习编程的最好方法是通过实践经验|  
14 6

17

18 #4.定义提示词

19 human_prompt === "用{word_count}个词总结我们到目前为止的对话"

20

21 #5.定义提示词模版

22 human_message_template ≡\equiv≡ HumanMessagePromptTemplate.from_template(human_prompt)

23

24 chat_prompt === ChatPromptTemplate.from/messages( [ MessagesPlaceholder(variable_name ≡\equiv≡ "conversation"), human_message_template ]

29 )

30 #6.格式化聊天消息提示词模版

31 messages1 === chat_prompt.format/messages( conversation=[human_message,ai_message],word_count =′′10′′= ^{\prime \prime}10^{\prime \prime}=′′10′′ 33 )

34 printmessages1)

javascript 复制代码
[HumanMessage(content='学习编程的最好方法是什么?', additional_kwargs={'}, response_metadata={'}}, AIMessage(content='1. 选择一门编程语言:选择一门你想学习的编程语言\n\n2.从基础开始:熟悉基本的编程概念,如变量、数据类型和控制结构\n\n3.练习,练习,再练习:学习编程的最好方法是通过实践经验', additional_kwargs={'}, response_metadata={'}}, HumanMessage(content='用10个词总结我们到目前为止的对话', additional_kwargs={'}, response_metadata={'}]

4.5 具体使用:少量样本示例的提示词模板

4.5.1 使用说明

在构建prompt时,可以通过构建一个 少量示例列表 去进一步格式化prompt,这是一种简单但强大的指导生成的方式,在某些情况下可以 显著提高模型性能 。

少量示例提示模板可以由 一组示例 或一个负责从定义的集合中选择 一部分示例 的示例选择器构建。

前者:使用 FewShotPromptTemplate 或 FewShotChatMessagePromptTemplate

后者:使用 Example selectors(示例选择器)

每个示例的结构都是一个 字典 ,其中 键 是输入变量, 值 是输入变量的值。

体会:zeroshot会导致低质量回答

python 复制代码
1   
2 from langchain_openai import ChatOpenAI   
3   
4 import os   
5 import dotenv   
6 from langchain_openai import ChatOpenAI   
7   
8 dotenv.load_dotenv()   
9   
10 os.environ['OPENAL_API_KEY] = os.getenv("OPENAL_API_KEY1") 
python 复制代码
11 os.environ['OPENAL_BASE_URL] = os.getenv("OPENAL_BASE_URL")  
12  
13 chat_model = ChatOpenAI(model="gpt-4o-mini", temperature=0.4)  
14  
15  
16 res = chat_model.invoke("2 9是多少?")  
17 print(res(content)

2 ?? 9 的计算⽅式取决于你所⽤的符号"??"的含义。请提供更多信息或者说明这个符号代表什么运算。

4.5.2 FewShotPromptTemplate的使用

举例1:

1 from langchain.prompts import PromptTemplate

2 from langchain.prompts.few_shot import FewShotPromptTemplate

3

4 #1、创建示例集合

5 examples === [ {"input": "北京天气怎么样", "output": "北京市"}, {"input": "南京下雨吗", "output": "南京市"}, {"input": "武汉热吗", "output": "武汉市"}]

10

11 #2、创建PromptTemplate实例

12 example_prompt = PromptTemplate.from_template( template ≔\coloneqq:= "Input: {input}nOutput: {output}"

14 )

15

16 #3、创建FewShotPromptTemplate实例

17 prompt === FewShotPromptTemplate( examples ≡\equiv≡ examples, example_prompt ≡\equiv≡ example_prompt, suffix ≡\equiv≡ "Input:{input}nOutput:",#要放在示例后面的提示模板字符串。 input_variables ≡\equiv≡ ["input"] #传入的变量

22 )

23

24 #4、调用

25 prompt === prompt.invoke({"input":"长沙多少度"})

26

27 print("*Prompt")

28 print(prompt)

29

30

1 ==== = ==== Prompt ≡==\equiv = =≡== 2 Input:北京天气怎么样

3 Output:北京市

4

5 Input:南京下雨吗

6 Output:南京市

7

8 Input:武汉热吗

9 Output:武汉市

10

11 Input:长沙多少度

12 Output:

结合大模型调用:

python 复制代码
1 import os  
2 import dotenv  
3 from langchain_openai import ChatOpenAI  
4  
5 dotenv.load_dotenv()  
6  
7 os.environ['OPENAI_API_KEY] = os.getenv("OPENAI_API_KEY1")  
8 os.environ['OPENAI_BASE_url] = os.getenv("OPENAI_BASE_url")  
9  
10 #获取大模型  
11 chat_model = ChatOpenAI(model='gpt-4o-mini')  
12  
13 #调用  
14 print("==Response==")  
15 response = chat_model.invoke(response)  
16 print(response.content)

1 ==== = ==== Response ≡==\equiv = =≡== 2 长沙市

举例2:

python 复制代码
1 #1、创建提示模板  
2 from langchain+prompts import PromptTemplate  
3  
4 #创建提示模板,配置一个提示模板,将一个示例格式化为字符串  
5 prompt_template = "你是一个数学专家,算式:{input}值:{output}使用:{description}"  
6  
7 #这是一个提示模板,用于设置每个示例的格式  
8 prompt_sample = PromptTemplate.from_template(prompt_template)  
9  
10 #2、提供示例  
11 examples = [

12 {"input": "2+2", "output": "4", "description": "加法运算",

13 {"input": "5-2", "output": "3", "description": "减法运算",

14 ]

15

16

17 #3、创建一个FewShotPromptTemplate对象

18 from langchain.prompts.few_shot import FewShotPromptTemplate

19

20

21 prompt === FewShotPromptTemplate( examples ≡\equiv≡ examples, example_prompt ≡\equiv≡ prompt_sample, suffix ≡\equiv≡ "你是一个数学专家,算式:{input}值:{output}", input_variables ≡\equiv≡ ["input","output"]

26 print(prompt.invoke({"input":"25","output":"10"}))
28
29 #4、初始化大模型,然后调用
30 import os
31 import dotenv
32 from langchain_openai import ChatOpenAI
33
34 dotenv.load_dotenv()
35
36 os.environ['OPENAI_API_KEY] === os.getenv("OPENAI_API_KEY1")
37 os.environ['OPENAI_BASE_URL] === os.getenv("OPENAI_BASE_URL")
38
39 chat_model === ChatOpenAI(model ≡\equiv≡ "gpt-4o-mini")
40
41 result === chat_model.invoke(prompt.invoke({"input":"2
5","output":"10"}))

42 print(result(content) #使用:乘法运算

你是⼀个数学专家,算式: 2∗52 ^ { \ast } 52∗5 值: 10 使⽤: 乘法运算

如果你还需要其他的数学计算或者有任何问题,请随时告诉我!

4.5.3 FewShotChatMessagePromptTemplate的使用

除了FewShotPromptTemplate之外,FewShotChatMessagePromptTemplate是专门为 聊天对话场景 设计的少样本(few-shot)提示模板,它继承自 FewShotPromptTemplate ,但针对聊天消息的格式进行了优化。

特点:

自动将示例格式化为聊天消息( HumanMessage / AIMessage 等)

输出结构化聊天消息( List[BaseMessage] )

保留对话轮次结构

举例1:基本结构

1 from langchain.prompts import (

FewShotChatMessagePromptTemplate,

ChatPromptTemplate

#1.示例消息格式

examples === [ {"input": "1+1等于几?","output": "1+1等于2", {"input": "法国的首都是?","output": "巴黎"}

]

#2.定义示例的消息格式提示词模版

msg_example_prompt === ChatPromptTemplate.from/messages([ ("human", {"input"}), ("ai", {"output"}),

]}

#3.定义FewShotChatMessagePromptTemplate对象

few_shot_prompt === FewShotChatMessagePromptTemplate( example_prompt=msg_example_prompt, examples=examples

#4.输出格式化后的消息

print(few_shot_prompt.format())

txt 复制代码
1 Human: 1+1等于几?  
2 Al: 1+1等于2  
3 Human: 法国的首都是?  
4 Al: 巴黎

举例2:

使用方式:将原始输入和被选中的示例组一起加入Chat提示词模版中。

txt 复制代码
1 #1.导入相关包  
2 from langchain_core.prompts import (FewShotChatMessagePromptTemplate, ChatPromptTemplate)  
3  
4 #2.定义示例组  
5 examples = [  
6 {input: "2Q2", "output: "4},  
7 {input: "2Q3", "output: "8},  
8 ]  
9  
10 #3.定义示例的消息格式提示词模版  
11 example_prompt = ChatPromptTemplate.from/messages([ 'human', {'input} 是多少?],  
12 ('ai', {'output'})  
13 ])  
14 ]]  
15  
16 #4.定义FewShotChatMessagePromptTemplate对象  
17 few_shot_prompt = FewShotChatMessagePromptTemplate( examples=examples, # 示例组  
18 example_prompt=example_prompt, # 示例提示词词模版

20)

21 #5.输出完整提示词的消息模版

22 final_prompt === ChatPromptTemplate.from/messages(

23 [ ('system',你是一个数学奇才),

25 few_shot_prompt, (human' {input},\{\mathrm{input}\} ,{input}, 26 1

27 ]

28 )

29

30 #6.提供大模型

31 import os

32 import dotenv

33 from langchain_openai import ChatOpenAI

34

35 dotenv.load_dotenv()

36

37 os.environ['OPENAI_API_KEY] === os.getenv("OPENAI_API_KEY1")

38 os.environ['OPENAI_BASE_URL] === os.getenv("OPENAI_BASE_URL")

39

40 chat_model === ChatOpenAI(model === "gpt-4o-mini", temperature=0.4)

41

42

43 chat_model.invoke(final_prompt.invoke(input === "2@4").content

'2??4 等于 16∘1 6 _ { \circ }16∘ 。'

举例3:与前面类似

javascript 复制代码
1 #1.导入相关包  
2 from langchain_core.prompts import (FewShotChatMessagePromptTemplate, ChatPromptTemplate)  
3  
4 #2.定义示例组  
5 examples = [  
6 {input: "2+2", "output: "4},  
7 {input: "2+3", "output: "5},  
8 ]  
9  
10 #3.定义示例的消息格式提示词模版  
11 example_prompt = ChatPromptTemplate.from/messages([('human', 'What is {input}?'), ('ai', {'output'})])  
12  
13 #4.定义FewShotChatMessagePromptTemplate对象  
14 few_shot_prompt = FewShotChatMessagePromptTemplate(  
15 examples=examples, #示例组  
16 example_prompt=example_prompt, #示例提示词词模版  
17 )  
18 #5.输出完整提示词的消息模版  
19 final_prompt = ChatPromptTemplate.from/messages(  
20 [  
21 ('system', 'You are a helpful AI Assistant'),  
22 few_shot_prompt,

23 ('human',{'input}},

24 ]

25 )

26 #6.格式化完整消息

27 #final_prompt.format(input ≡\equiv≡ "What is 4+4?4 + 4?4+4? 1

28 #或者

29 final_prompt.format/messages(input ≡\equiv≡ "What is 4+4?4 + 4?4+4? 1

latex 复制代码
\[ \text{SystemMessage(content='You are a helpful AI Assistant', additional_kwargs={'}, response_metadata={'}}\),  
\[ \text{HumanMessage(content='What is 2+2?', additional_kwargs={'}, response_metadata={'}}\),  
\[ \text{AIMessage(content='4', additional_kwargs={'}, response_metadata={'}}\),  
\[ \text{HumanMessage(content='What is 2+3?', additional_kwargs={'}, response_metadata={'}}\),  
\[ \text{AIMessage(content='5', additional_kwargs={'}, response_metadata={'}}\),  
\[ \text{HumanMessage(content='What is 4+4?', additional_kwargs={'}, response_metadata={'}}\} \] 

4.5.4 Example selectors(示例选择器)

前面FewShotPromptTemplate的特点是,无论输入什么问题,都会包含全部示例。在实际开发中,我们可以根据当前输入,使用示例选择器,从大量候选示例中选取最相关的示例子集。

使用的好处:避免盲目传递所有示例,减少 token 消耗的同时,还可以提升输出效果。

示例选择策略:语义相似选择、长度选择、最大边际相关示例选择等

语义相似选择 :通过余弦相似度等度量方式评估语义相关性,选择与输入问题最相似的 k 个示例。

长度选择 :根据输入文本的长度,从候选示例中筛选出长度最匹配的示例。增强模型对文本结构的理解。比语义相似度计算更轻量,适合对响应速度要求高的场景。

最大边际相关示例选择 :优先选择与输入问题语义相似的示例;同时,通过惩罚机制避免返回同质化的内容

余弦相似度是通过计算两个向量的夹⻆余弦值来衡量它们的相似性。它的值范围在-1到1之间:当两个向量⽅向相同时值为1;夹⻆为 90∘9 0 ^ { \circ }90∘ 时值为0;⽅向完全相反时为-1。

数学表达式:余弦相似度 =(A⋅B)/(∥A∥⋆∥B∥).= \left( { \mathrm { A } } { \cdot } { \mathrm { B } } \right) / \left( { \| \mathrm { A } \| } ^ { \star } \left\| \mathrm { B } \right\| \right) .=(A⋅B)/(∥A∥⋆∥B∥). === 。其中A·B是点积,||A||和||B||是向量的模(⻓度)

举例1:

1 pip install chromadb

python 复制代码
1 #1.导入相关包  
2 from langchaincommunity)."vectorstores import Chroma  
3 from langchain_core.example selectors import SemanticSimilarityExampleSelector  
4 import os  
5 import dotenv  
6 from langchain_openai import OpenAIEmbeddings  
7  
8 dotenv.load_dotenv()  
9  
10 #2.定义嵌入模型  
11 os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
txt 复制代码
os.environ['OPENAI_BASE_URL] = os.getenv("OPENAI_BASE_URL")  
embeddings_model = OpenAIEmbeddings(model="text-embedding-ada-002")  
14 embeddings_model = OpenAIEmbeddings(  
15 model="text-embedding-ada-002"  
16)  
17  
18 #3.定义示例组  
19 examples = [  
20 {  
21 "question": "谁活得更久,穆罕默德·阿里还是艾伦·图灵?";  
22 "answer": ""  
23 接下来还需要问什么问题吗?  
24 追问:穆罕默德·阿里去世时多大年纪?  
25 中间答案:穆罕默德·阿里去世时享年74岁。  
26 "";  
27 },  
28 {  
29 "question": "craigslist的创始人是什么时候出生的?";  
30 "answer": ""  
31 接下来还需要问什么问题吗?  
32 追问:谁是craigslist的创始人?  
33 中级答案:Craigslist是由克雷格·纽马克创立的。  
34 "";  
35 },  
36 {  
37 "question": "谁是乔治·华盛顿的外祖父?";  
38 "answer": ""  
39 接下来还需要问什么问题吗?  
40 追问:谁是乔治·华盛顿的母亲?  
41 中间答案:乔治·华盛顿的母亲是玛丽·鲍尔·华盛顿。  
42 "";  
43 },  
44 {  
45 "question": "《大白鲨》和《皇家赌场》的导演都来自同一个国家吗?";  
46 "answer": ""  
47 接下来还需要问什么问题吗?  
48 追问:《大白鲨》的导演是谁?  
49 中级答案:《大白鲨》的导演是史蒂文·斯皮尔伯格。  
50 "";  
51 },  
52 ]  
53  
54 #4.定义示例选择器  
55 example_selector = SemanticSimilarityExampleSelector.from/examples(  
56 #这是可供选择的示例列表  
57 examples,  
58 #这是用于生成嵌入的嵌入类,用于衡量语义相似性  
59 embeddings_model,  
60 #这是用于存储嵌入并进行相似性搜索的 VectorStore 类  
61 Chroma,  
62 #这是要生成的示例数量  
63 k=1,  
64 )  
65  
66 #选择与输入最相似的示例
python 复制代码
67 question = "玛丽·鲍尔·华盛顿的父亲是谁?"  
68 selected/examples = example_selector.select/examples({ "question": "question"})  
69 print(f"与输入最相似的示例:{selected/examples}")  
70  
71 # for example in selected/examples:  
72 # print("\\n")  
73 # for k, v in example.items():  
74 # print(f"[k]: {v}")

question: 谁是乔治·华盛顿的外祖⽗?

answer:

接下来还需要问什么问题吗?

追问:谁是乔治·华盛顿的⺟亲?

中间答案:乔治·华盛顿的⺟亲是玛丽·鲍尔·华盛顿

举例2:结合 FewShotPromptTemplate 使用

这里使用FAISS,需安装:

1 pip install faiss-cpu

#或2

3 conda install faiss-cpu

1.导入相关包1

2 from langchain_community.vectorstores import FAISS

3 from langchain_core.example_selectors import SemanticSimilarityExampleSelector

from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate4

5 from langchain_openai import OpenAIEmbeddings

2.定义示例提示词模版7

8 example_prompt === PromptTemplate.from_template(

9 template === "Input: {input}\nOutput: {output}", )10

3.创建一个示例提示词模版12

13 examples === [

{"input": "高兴", "output": "悲伤"},14

{"input": "高", "output": "矮"},15

{"input": "长", "output": "短"},16

{"input": "精力充沛", "output": "无精打采"},17

{"input": "阳光", "output": "阴暗"},18

{"input": "粗糙", "output": "光滑"},19

{"input": "干燥", "output": "潮湿"},20

{"input": "富裕", "output": "贫穷"},21] 2 2

4.定义嵌入模型24

embeddings25 === OpenAIEmbeddings(

26 model === "text-embedding-ada-002" )27

5.创建语义相似性示例选择器29

30 example_selector === SemanticSimilarityExampleSelector.fromexamples(

31 examples,

32 embeddings,

33 FAISS,

34 k=2\mathrm{k} = 2k=2 35 )

36 #或者

37 #example_selector === SemanticSimilarityExampleSelector(

38 # examples,

39 # embeddings,

40 # FAISS,

41 # k=2k = 2k=2 42 #)

43

44 #6.定义小样本提示词模版

45 similar_prompt === FewShotPromptTemplate(

46 example_selector === example_selector,

47 example_prompt === example_prompt,

48 prefix === "给出每个词组的反义词",

49 suffix === "Input:{word}\nOutput:"

50 input_variables === ["word"],

51 )

52

53 response === similar_prompt.invoke({"word":"忧郁"})

54 print(response.text)

给出每个词组的反义词

Input: ⾼兴

Output: 悲伤

Input: 阳光

Output: 阴暗

Input: 忧郁

Output:

4.6 具体使用:PipelinePromptTemplate(了解)

用于将多个提示模板按顺序组合成处理管道,实现分阶段、模块化的提示构建。它的核心作用类似于软件开发中的 管道模式 (Pipeline Pattern),通过串联多个提示处理步骤,实现复杂的提示生成逻辑。

特点:

将复杂提示拆解为多个处理阶段,每个阶段使用独立的提示模板

前一个模板的输出作为下一个模板的输入变量

使用场景:解决单一超大提示模板难以维护的问题

说明:PipelinePromptTemplate在langchain 0.3.22版本中被标记为过时,在 langchain-core ==1.0= = 1 . 0==1.0 之前不会删除它。

https://python.langchain.com/api_reference/core/prompts/langchain_core.prompts.pipeline.Pi pelinePromptTemplate.html

举例:

python 复制代码
1 from langchain_core.prompt.pipeline import PipelinePromptTemplate  
2 from langchain_core.prompt.pipeline import PromptTemplate  
3  
4  
5 #阶段1:问题分析  
6 analysis_template = PromptTemplate.from_template("")  
7 分析这个问题:{question}  
8 关键要素:  
9 ""  
10  
11 #阶段2:知识检索  
12 retrieval_template = PromptTemplate.from_template("")  
13 基于以下要素搜索资料:  
14 {analysis_result}  
15 搜索关键词:  
16 ""  
17  
18 #阶段3:生成最终回答  
19 answer_template = PromptTemplate.from_template("")  
20 综合以下信息回答问题:  
21 {retrieval_result}  
22 最终答案:  
23 ""  
24  
25 #构建管道  
26 pipeline = PipelinePromptTemplate(  
27 final_prompt=answer_template,  
28 pipeline_prompts=[  
30 ("analysis_result", analysis_template),  
31 ]  
32 )  
33  
34 print(pipeline.format(question="量子计算的优势是什么?"))

综合以下信息回答问题:

基于以下要素搜索资料:

分析这个问题:量⼦计算的优势是什么?

关键要素:

搜索关键词:

最终答案:

上述代码执行时,提示PipelinePromptTemplate已过时,代码更新如下:

from langchain_core.prompts.prompt import PromptTemplate 1

2

3 # 阶段1:问题分析

analysis_template4 === PromptTemplate.from_template("""

5 分析这个问题:{question}

6 关键要素:

7 "")

8

9 #阶段2:知识检索

10 retrieval_template ≡\equiv≡ PromptTemplate.from_template("""

11 基于以下要素搜索资料:

{analysis_result}

13 搜索关键词:

"")

15

16 #阶段3:生成最终回答

answer_template ≡\equiv≡ PromptTemplate.from_template("""

18 综合以下信息回答问题:

{retrieval_result}

20 最终答案:

"")

22

23 #逐步执行管道提示

pipeline_prompts ≡\equiv≡ [("analysis_result", analysis_template), ("retrieval_result", retrieval_template)

]

28

29

30 my_input === {"question":"量子计算的优势是什么?"}

31

#print(pipeline_prompts)

33

#['(analysis_result', PromptTemplate(input_variables=['question'], input_types=], partial_variables=}, template='\n分析这个问题:{question}\n关键要素:\n'), ('retrieval_result', PromptTemplate(input_variables=['analysis_result'], input_types=], partial_variables=], template='\n基于以下要素搜索资料:\n{analysis_result}\n搜索关键词:\n'))]

35

for name, prompt in pipeline_prompts:

#调用当前提示模板并获取字符串结果

result ≡\equiv≡ prompt.invoke(my_input).to_string()

#将结果添加到输入字典中供下一步使用

my_input[name] ≡\equiv≡ result

40

41

42 #生成最终答案

my_output ≡\equiv≡ answer_template.invoke(my_input).to_string()

44 print(my_output)

4.7 具体使用:自定义提示词模版(了解)

在创建prompt时,我们也可以按照自己的需求去创建自定义的提示模版。

步骤:

自定义类继承提示词基类模版BasePromptTemplate

重写format、format_prompt、from_template方法

举例:

python 复制代码
1 #1.导入相关包
2 from typing import List, Dict, Any
3 from langchain+prompts import BasePromptTemplate
4 from langchain+prompts import PromptTemplate
5 from langchain schema import PromptValue
6
7 # 2.自定义提示词模版
8 class SimpleCustomPrompt(BasePromptTemplate):
9     ""简单自定义提示词模板''
10 template: str
11
12 def __init__(self, template: str, **kwargs):
13 #使用PromptTemplate解析输入变量
14 prompt = PromptTemplate.from_template.template)
15 super().__init__(input_variables=prompt.input_variables,
16 template=template,
17         **kwargs
18         )
19         return self.template.format(**kwargs)
20
21
22 def format(self, **kwargs: Any) -> str:
23       ""格式化提示词''
24 #print("kwargs:", kwargs)
25 #print("self.template:", self.template)
26
27 return self.template.format(**kwargs)
28
29 def format_prompt(self, **kwargs: Any) -> PromptValue:
30         ""实现抽象方法''
31         return PromptValue(text= self.format(**kwargs))
32
33 @classmethod
34 def from_template(cls, template: str, **kwargs) -> "SimpleCustomPrompt".
35         ""从模板创建实例''
36         return cls/template=template, **kwargs)
37
38 #3.使用自定义提示词模版
39 custom_prompt = SimpleCustomPrompt.from_template(
40         template="请回答关于(subject)的问题: {question} "
41 )
42
43 #4.格式化提示词
44 formatted = custom_prompt.format(
45         subject="人工智能",
46         question="什么是LLM?
47 )
48
49 print(formatted)

4.8 从文档中加载Prompt(了解)

一方面,将想要设定prompt所支持的格式保存为JSON或者YAML格式文件。

另一方面,通过读取指定路径的格式化文件,获取相应的prompt。

目的与使用场景:

为了便于共享、存储和加强对prompt的版本控制。

当我们的prompt模板数据较大时,我们可以使用外部导入的方式进行管理和维护。

4.8.1 yaml格式提示词

asset下创建yaml文件:prompt.yaml

txt 复制代码
1_type:   
2 "prompt"   
3 input_variables:   
4 ["name","what"]   
5 template:   
6 "请给{name}讲一个关于{what}的故事"

代码:

python 复制代码
1 from langchain_core.prompts import load_prompt  
2 from dotenv import load_dotenv  
3  
4 load_dotenv()  
5  
6 prompt = load_prompt("asset/prompt.yaml", encoding="utf-8")  
7 # print_prompt)  
8 print(prompt.format(name= "年轻人", what= "滑稽"))

请给年轻⼈讲⼀个关于滑稽的笑话

4.8.2 json格式提示词

asset下创建json文件:prompt.json

jsonl 复制代码
1 {  
2 "_type": "prompt",  
3 "input_variables". ["name", "what"],  
4 "template": "请{name}讲一个{what}的故事。"  
5 }

代码:

python 复制代码
1 from langchain_core.prompts import load_prompt  
2 from dotenv import load_dotenv  
3  
4 load_dotenv()  
5  
6 prompt = load_prompt("asset/prompt.json", encoding="utf-8")  
7 print(prompt.format(name= "张三", what= "搞笑的"))

请张三讲⼀个搞笑的的故事。

5、Model I/O之Output Parsers

语言模型返回的内容通常都是字符串的格式(文本格式),但在实际AI应用开发过程中,往往希望model可以返回更直观、更格式化的内容,以确保应用能够顺利进行后续的逻辑处理。此时,LangChain提供的 输出解析器 就派上用场了。

输出解析器(Output Parser)负责获取 LLM 的输出并将其转换为更合适的格式。这在应用开发中及其重要。

5.1 输出解析器的分类

LangChain有许多不同类型的输出解析器

StrOutputParser :字符串解析器

JsonOutputParser :JSON解析器,确保输出符合特定JSON对象格式

XMLOutputParser :XML解析器,允许以流行的XML格式从LLM获取结果

CommaSeparatedListOutputParser :CSV解析器,模型的输出以逗号分隔,以列表形式返回输出

DatetimeOutputParser :日期时间解析器,可用于将 LLM 输出解析为日期时间格式

除了上述常用的输出解析器之外,还有:

EnumOutputParser :枚举解析器,将LLM的输出,解析为预定义的枚举值

StructuredOutputParser :将非结构化文本转换为预定义格式的结构化数据(如字典)

OutputFixingParser :输出修复解析器,用于自动修复格式错误的解析器,比如将返回的不符合预期格式的输出,尝试修正为正确的结构化数据(如 JSON)

RetryOutputParser :重试解析器,当主解析器(如 JSONOutputParser)因格式错误无法解析LLM 的输出时,通过调用另一个 LLM 自动修正错误,并重新尝试解析

5.2 具体解析器的使用

1◯\textcircled{1}1◯ 字符串解析器 StrOutputParser

StrOutputParser 简单地将 任何输入 转换为 字符串 。它是一个简单的解析器,从结果中提取content字段

举例:将一个对话模型的输出结果,解析为字符串输出

1 from langchain_core/messages import HumanMessage, SystemMessage

2 from langchain_core.output_parsers import StrOutputParser

3

4 import os

5 import dotenv

6 from langchain_openai import ChatOpenAI

7

8 dotenv.load_dotenv()

9

10 os.environ['OPENAI_API_KEY] = os.getenv("OPENAI_API_KEY1")

11 os.environ['OPENAI_BASE_url] = os.getenv("OPENAI_BASE_url")

12

13 chat_model ≡\equiv≡ ChatOpenAI(model ≡\equiv≡ "gpt-4o-mini")

txt 复制代码
1 messages = [  
2 SystemMessage(content = "将以下内容从英语翻译成中文"),  
3 HumanMessage(content = "It's a nice day today"),  
4 ]  
5  
6 result = chat_model.invoke/messages)  
7 print(type(result))  
8 print(result)  
9  
10 parser = StrOutputParser()  
11 #使用parser处理model返回的结果  
12 response = parser.invoke(result)  
13 print(type(response))  
14 print(response)
txt 复制代码
<class 'langchain_core/messages.ai.AIMessage'>  
content='今天是个好天。'additional_kwargs={'refusal':None} response_metadata=  
{'tokenusage':{'completion_tokens':7,'prompt_tokens':25,'total_tokens':32,  
'completion_tokens_details':{'accepted_prediction_tokens':0,'audio_tokens':0,  
'reasoning_tokens':0,'rejected_prediction_tokens':0},'prompt_tokens_details':  
{'audio_tokens':0,'cached_tokens':0}},'model_name':'gpt-4o-mini-2024-07-18',  
'system_fingerprint':'fp_efad92c60b',id':chatmpl-BpPd126GlvwFI3TpL2EMaInxruhk0',  
'serviceTier':None,'finish_reason':stop,'logprobs':None}id='run--690e05f2-39ad-4ff7-98fd ef3ad00e6133-0'usage_metadata={'input_tokens':25,'output_tokens':7,  
'total_tokens':32,'input_token_details':{'audio':0,'cache_read':0},'output_token_details':  
{'audio':0,'reasoning':0}}  
<class 'str'>  
今天是个好天。

2◯\textcircled{2}2◯ JSON解析器 JsonOutputParser

JsonOutputParser,即JSON输出解析器,是一种用于将大模型的 自由文本输出 转换为 结构化JSON数据 的工具。

适合场景:特别适用于需要严格结构化输出的场景,比如 API 调用、数据存储或下游任务处理。

实现方式

方式1:用户自己通过提示词指明返回Json格式

方式2:借助JsonOutputParser的 get_format_instructions() ,生成格式说明,指导模型输出JSON 结构

举例1:

1 from langchain_core.output_parser import JsonOutputParser

2 from langchain_core.prompts import ChatPromptTemplate

3 chat_model === ChatOpenAI(model ≡\equiv≡ "gpt-4o-mini")

5

6 chat_prompt_template === ChatPromptTemplate.from/messages([ ("system","你是一个靠谱的{role}"), ("human","{question}")

8 ])

9

10

11 parser === JsonOutputParser()

12

13 #方式1:

14 result === chat_model.invoke(chat_prompt_template.format/messages(root ≡\equiv≡ "人工智能专 家",question ≡\equiv≡ "人工智能用英文怎么说?问题用q表示,答案用a表示,返回一个JSON格式")

15 print(result)

16 print(type(result))

17

18 parser.invoke(result)

19

20 #方式2:

21 # chain === chat_prompt_template / chat_model / parser

22 #chain.invoke({"role":"人工智能专家","question":"人工智能用英文怎么说?问题用q表示,答案用a 表示,返回一个JSON格式")

javascript 复制代码
content='json\n{\n"q":"人工智能用英文怎么说?",\n"a":"Artificial Intelligence"\n}\n'  
additional_kwargs={'refusal':None} response_metadata={'tokenusage':'completion_tokens':28,'prompt_tokens':40,'total_tokens':68,'completion_tokens_details':{'accepted_prediction_tokens':0,'audio_tokens':0,  
'reasoning_tokens':0,'rejected_prediction_tokens':0}, 'prompt_tokens_details':  
{audio_tokens':0,'cached_tokens':0}}, 'model_name':'gpt-4o-mini-2024-07-18',  
'system_fingerprint':'fp_efad92c60b', 'id':'chatmpl-ByBTRPL6LKkHJgsjbRwVawe1L92jJ',  
'service-tier':None,'finish_reason':'stop','logprobs':None} id='run--aadc94df-3608-4b1b-adf6-4a53ef8b640c-0' usage_metadata={'input_tokens':40,'output_tokens':28,  
'total_tokens':68,'input_token_details':{'audio':0,'cache_read':0}, 'output_token_details':  
{audio':0,'reasoning':0}  
<class 'langchain_core/messages.ai.AIMessage'>  
{q':'人工智能用英文怎么说?', 'a':'Artificial Intelligence'}

举例2:使用指定的JSON格式

1 from langchain_core.output_parser import JsonOutputParser

2

3 output_parser ≡\equiv≡ JsonOutputParser()

4 #返回一些指令或模板,这些指令告诉系统如何解析或格式化输出数据

5 format Instructions === output_parser.get_formatInstructions()

6 print.format Instructions)

基于此:

python 复制代码
1 #引入依赖包
2 from langchain_core.output_parser import JsonOutputParser
3 from langchain_core.prompts import PromptTemplate
4
5 #初始化语言模型
6 chat_model = ChatOpenAI(model='gpt-4o-mini')
7
8 joke_query = "告诉我一个笑话."
9
10 #定义Json解析器
11 parser = JsonOutputParser()
12
13 #定义提示词模版
14 #注意,提示词模板中需要部分格式化解析器的格式要求formatinstructions
15 prompt = PromptTemplate(
    template="回答用户的查询.{n[formatInstructions]{n[query]{n},
    input_variables=['query'],
    partial_variables={'formatInstructions': parser.get_formatInstructions}},
) )
20
21 #5.使用LCEL语法组合一个简单的链
22 chain = prompt | chat_model | parser
23 #6.执行链
24 output = chain.invoke{'query': '给我讲一个笑话'}
25 print(output)

{joke: '为什么海洋总是咸的?因为它有太多的"海"湿的事情发⽣!'}

③ XML解析器 XMLOutputParser

XMLOutputParser,将模型的自由文本输出转换为可编程处理的 XML 数据。

如何实现:在 PromptTemplate 中指定 XML 格式要求,让模型返回 content 形式的数据。

注意:XMLOutputParser 不会直接将模型的输出保持为原始XML字符串,而是会解析XML并转换成Python字典 (或类似结构化的数据)。目的是为了方便程序后续处理数据,而不是单纯保留XML格式。

1 # 初始化语言模型

chat_model2 === ChatOpenAI(mode === "gpt-4o-mini")

34 # 测试模型的xml解析效果

actor_query5 === " 成汤姆·汉克斯的简短电影记录"

output6 === chat_model.invoke(f"""{actor_query}请将影片附在标签中"""

)7

8 print(type(output)) # <class 'langchain_core.messages.ai.AIMessage'>

9 print(output.content)

<class 'langchain_core.messages.ai.AIMessage'>1

以下是汤姆·汉克斯的一些著名电影记录,使用了<movie></movie>标签:2

3

4
大白鲨5

19756

汤姆·汉克斯并未参演该片,但它代表了他所崇拜的早期冒险和恐怖电影。7

8

9

10
费城故事11

199312

汉克斯在片中饰演一名因碍于艾滋病而遭受歧视的律师,展现了强大的表演能力。13

14

15

16
拯救大兵瑞恩17

199818

19 汤姆·汉克斯在这部二战电影中饰演一位军官,领导小队寻找失踪士兵,表现出勇气与人性。

20

21

22
阿甘正传23

199424

25 汉克斯饰演智力有所缺陷的阿甘,凭借其纯真和毅力走过了动荡的历史,成为经典角色。

26

27

28
云图29

201230

31 这部作品展示了不同历史时期的人物,汉克斯在其中扮演多个角色,体现了人与时间的关系。

32

34

txt 复制代码
35 <title>大地惊雷</title>  
36 <year>2000</year>  
37 <description>汉克斯在这部影片中担任制片人和主演,讲述了关于希望与重生的感人故事。</description>  
38 </movie>  
39  
40 <movie>  
41 <title>西线无战事</title>  
42 <year>2022</year>  
43 <description>虽然汉克斯并没有在片中出演,但作为制片人,他对反战主题的传播作出贡献。</description>  
44 </movie>  
45  
46 这些电影展示了汤姆·汉克斯在不同时期所做出的多样化和深刻的艺术贡献。

举例2:体会XMLOutputParser的格式

python 复制代码
1 from langchain_core.output_parser import XmlOutputParser  
2  
3 output_parser = XmlOutputParser()  
4 #返回一些指令或模板,这些指令告诉系统如何解析或格式化输出数据  
5 format Instructions = output_parser.get_formatInstructions()  
6 print.format Instructions)
txt 复制代码
1 The output should be formatted as a XML file.  
2 1. Output should conform to the tags below.  
3 2. If tags are not given, make them on your own.  
4 3. Remember to always open and close all the tags.  
5  
6 As an example, for the tags ["foo", "bar", "baz']:  
7 1. String "<foo>  
8 <bar>  
9 <baz></baz>  
10 </bar>  
11 </foo>" is a well-formatted instance of the schema.  
12 2. String "<foo>  
13 <bar>  
14 </foo>" is a badly-formatted instance.  
15 3. String "<foo>  
16 <tag>  
17 </tag>  
18 </foo>" is a badly-formatted instance.  
19  
20 Here are the output tags:  
21 ...  
22 None  
23 ... 

1.导入相关包

from langchain_core.output_parsers import XMLOutputParser

from langchain_core.prompts import PromptTemplate

from langchain_openai import ChatOpenAI

2. 初始化语言模型

chat_model === ChatOpenAI(mode === "gpt-4o-mini")

3.测试模型的xml解析效果

actor_query === " 成汤姆·汉克斯的简短电影记录,使用中文回复"

4.定义XMLOutputParser对象

parser === XMLOutputParser()

5.定义提示词模版对象

prompt === PromptTemplate(

template ∑\scriptscriptstyle \sum∑ "{query}\n{format_instructions}",

input_variables=["query","format_instructions"],

partial_variables={"format_instructions": parser.get_format_instructions()}, #)

prompt_template === PromptTemplate.from_template("{query}\n{format_instructions}")

prompt_template1 ===

prompt_template.partial(format_instructions === parser.get_format_instructions())

response === chat_model.invoke(prompt_template1.format(query :=: =:= actor_query))

print(response.content)

<汤姆汉克斯电影记录>1

2 <电影>

<名称>阿甘正传</名称>3

<年份>1994</年份>4

<角色>福里斯特·甘</角色>5

<类型>剧情/喜剧</类型>6

</电影>7

8 <电影>

<名称>拯救大兵瑞恩</名称>9

<年份>1998</年份>10

1 <角色>米勒上尉</角色>

2 <类型>战争/剧情</类型>

13 </电影>

<电影>14

15 <名称>沉默的羔羊</名称>

<年份>2001</年份>16

<角色>查克·诺兰</角色>17

<类型>冒险/剧情</类型>18

</电影>19

<电影>20

<名称>角斗士</名称>21

<年份>2000</年份>22

<角色>罗马指挥官</角色>23

txt 复制代码
24 <类型>历史/剧情</类型>  
25 </电影>  
26 <电影>  
27 <名称>大兵瑞恩</名称>  
28 <年份>1998</年份>  
29 <角色>米奇·布朗</角色>  
30 <类型>战争/动作</类型>  
31 </电影>  
32 </汤姆汉克斯电影记录>

继续:

1 #方式1

2 response === chat_model.invoke(prompt_template1.format(query ≡\equiv≡ actor_query))

3 result === parser.invoke(response)

4 print(result)

5 print(type(result))

6

7 #方式2

8 #chain === prompt_template1 / chat_model / parser

9 #result === chain.invoke({"query":actor_query})

10 #print(result)

11 #print(type(result))

javascript 复制代码
{电影记录': ['演员': ['名字': '汤姆·汉克斯'], {'代表作品': ['电影': ['标题': '阿甘正传'], {'年份': '1994'}, {'简介': '讲述了一个智力简单却拥有传奇人生的男子阿甘的故事。'}}], {'电影': ['标题': '拯救大兵瑞恩'], {'年份': '1998'}, {'简介': '一支美国小队在诺曼底登陆后,深入敌后,寻找并拯救被困的士兵瑞恩的故事。'}}], {'电影': ['标题': '绿色里小屋'], {'年份': '1999'}, {'简介': '改编自斯蒂芬·金的小说,讲述了一位狱警与一名死刑犯之间的奇妙关系。'}}], {'电影': ['标题': '玩具总动员'], {'年份': '1995'}, {'简介': '讲述了玩具在主人不在时的冒险故事,是首部全电脑动画电影。'}']}]]}} <class 'dict'>

举例4:与前例类似

1 from langchain_openai import ChatOpenAI

2 from langchain_core+prompts import PromptTemplate

3 from langchain_core.output_parser import XmlOutputParser

4

5

6 model === ChatOpenAI(model ≡\equiv≡ "gpt-4o-mini")

7

actor_query === "生成周星驰的简化电影作品列表,按照最新的时间降序,必要时使用中文"

9 #设置解析器 +^++ 将指令注入提示模板。

10 parser === XmlOutputParser()

11 prompt === PromptTemplate(

12 template === "回答用户的查询。{formatInstructions} \n\backslash n\n {query} \n\backslash n\n .

13 input_variables ≡\equiv≡ ["query"],

14 partial_variables === {"formatInstructions": parser.get_format Instructions(),

15 )

16

17 chain === prompt|model|parser

18 output ≡\equiv≡ chain.invoke({"query":actor_query}))

19 print(output)

{'周星驰电影作品列表': [{'电影': [{'标题': '西游伏妖篇'}, {'年份': '2017'}]}, {'电影': [{'标题': '美人鱼'},{'年份': '2016'}]}, {'电影': [{'标题': '长江7号'}, {'年份': '2008'}]}, {'电影': [{'标题': '大话西游之仙履奇缘'}, {'年份': '1995'}]}, {'电影': [{'标题': '国产凌凌漆'}, {'年份': '1994'}]}, {'电影': [{'标题': '逃学威龙'},{'年份': '1991'}]}]}

④ 列表解析器 CommaSeparatedListOutputParser

列表解析器:利用此解析器可以将模型的文本响应转换为一个用 逗号分隔的列表(List[str])

举例1:

python 复制代码
1 from langchain_core.output_parser import CommaSeparatedListOutputParser  
2  
3 output_parser = CommaSeparatedListOutputParser()  
4  
5 #返回一些指令或模板,这些指令告诉系统如何解析或格式化输出数据  
6 format Instructions = output_parser.get_formatInstructions()  
7 print.format Instructions)  
8  
9 messages = "大象,猩猩,狮子"  
10 result = output_parser.parse/messages)  
11 print(result)  
12 print(type(result))
txt 复制代码
Your response should be a list of comma separated values, eg: foo, bar, baz or foo, bar, baz  
['大象', '猩猩', '狮子']  
<class 'list'>

举例2:

1 from langchain_core.prompts import PromptTemplate

2 from langchain_openai import ChatOpenAI

3 from langchain.output_parsers import CommaSeparatedListOutputParser

4

5 #初始化语言模型

6 chat_model === ChatOpenAI(model ≡\equiv≡ "gpt-4o-mini")

7

8 #创建解析器

9 output_parser === CommaSeparatedListOutputParser()

10

11 #创建LangChain提示模板

12 chat_prompt === PromptTemplate.from_template(

13 "生成5个关于{text}的列表. \n\n\backslash n\backslash n\n\n {formatinstructions} ",

14 partial_variables ≡\equiv≡ {

15 "format Instructions":output_parser.get_formatInstructions()

16 }

17

18 #提示模板与输出解析器传递输出

19 #chat_prompt === chat_prompt_partial.format Instructions=output_parser.get_format Instructions())

20

21 #将提示和模型合并以进行调用

22 chain === chat_prompt | chat_model | output_parser

23 res === chain.invoke({"text":"电影"})

24 print(res)

25 print(type(res))

'经典电影', '现代电影', '动作电影', '爱情电影', '科幻电影'

举例3:

python 复制代码
1 from langchain+prompts chat import HumanMessagePromptTemplate  
2 from langchain_core+prompts import ChatPromptTemplate  
3 from langchain_openai import ChatOpenAI  
4 from langchain.output_parser import CommaSeparatedListOutputParser  
5  
6 #初始化语言模型  
7 chat_model = ChatOpenAI(model = "gpt-4o-mini")  
8  
9 output_parser = CommaSeparatedListOutputParser()  
10  
11 chat_prompt = ChatPromptTemplate.frommessages([  
    ("human", {"request"}\n{formatInstructions})  
    # HumanMessagePromptTemplate.from_template("request")\n{formatInstructions}"),  
14 ])  
15  
16 # model_request = chat Prompt.format_messages(  
    # request = "给我5个心情",  
18 # format Instructions=output_parser.get_format Instructions()  
19 #)  
20  
21 #方式1:  
22 # result = chat_model.invoke(model_request)  
23 #  
24 # resp = output_parser.parse(result.content)  
25 # print(resp)  
26 # print(type(resp))  
27  
28 #方式2:  
29 # result = chat_model.invoke(model_request)  
30 # resp = output_parser.invoke(result)  
31 # print(resp)  
32 # print(type(resp))  
33  
34 #方式3:

chain35 === chat_prompt | chat_model | output_parser

36 resp === chain.invoke({"request": "给我5个心情", "format_instructions":output_parser.get_format_instructions()})

print(resp) 37

38 print(type(resp))

'快乐', '忧伤', '愤怒', '兴奋', '宁静'

5◯\textcircled{5}5◯ 日期解析器 DatetimeOutputParser (了解)

利用此解析器可以直接将LLM输出解析为日期时间格式。

get_format_instructions(): 获取日期解析的格式化指令,指令为:"Write a datetime stringthat matches the following pattern: '%Y-%m-%dT%H:%M:%S.%fZ'。

举例:1206-08-16T17:39:06.176399Z

举例1:

from langchain.output_parsers import DatetimeOutputParser1

3 output_parser === DatetimeOutputParser()

format_instructions5 === output_parser.get_format_instructions()

6 print(format_instructions)

Write a datetime string that matches the following pattern: %Y−%m\% \mathrm { Y } { - } \% \mathrm { m }%Y−%m - %dT0/0H:0/0M:0/0S.0/0fZ1\% \mathrm { d T ^ { 0 } / 0 H : ^ { 0 } / 0 M : ^ { 0 } / 0 S . ^ { 0 } / 0 f Z ^ { 1 } }%dT0/0H:0/0M:0/0S.0/0fZ1 .

Examples: 1563-09-27T04:28:14.640366Z, 1786-06-24T23:46:01.984421Z, 1079-05- 27T08:43:24.266403Z

Return ONLY this string, no other words!

举例2:

1 from langchain_openai import ChatOpenAI

2 from langchain.promptss chat import HumanMessagePromptTemplate

3 from langchain_core.promptss import ChatPromptTemplate

4 from langchain.output_parsers import DatetimeOutputParser

5

6 chat_model === ChatOpenAI(model ≡\equiv≡ "gpt-4o-mini")

7

8

9 chat_prompt === ChatPromptTemplate.frommessages([ ("system","{formatInstructions}"), ("human","{request}").

10

11

12 1

13

14 output_parser === DatetimeOutputParser()

15

16 #方式1:

17 #model_request === chat_prompt.format_messages(

18 # request ≡\equiv≡ "中华人民共和国是什么时候成立的"

19 # format Instructions ≡\equiv≡ output_parser.get_formatInstructions()

20 #)

21

22 # response === chat_model.invoke(model_request)

23 # result === output_parser.invoke(response)

24 # print(result)

25 # print(type(result))

26

27 #方式2:

28 chain === chat_prompt|chat_model|output_parser

29 resp === chain.invoke({"request":"中华人民共和国是什么时候成立的", "format Instructions":output_parser.get_format Instructions}))

30 print(resp)

32 print(type(resp))

txt 复制代码
1949-10-01 00:00:00  
<class 'datetimedatetime'> 

6、LangChain调用本地模型

6.1 Ollama的介绍

Ollama是在Github上的一个开源项目,其项目定位是:一个本地运行大模型的集成框架。目前主要针对主流的LlaMA架构的开源大模型设计,可以实现如 Qwen、Deepseek 等主流大模型的下载、启动和本地运行的自动化部署及推理流程。

目前作为一个非常热门的大模型托管平台,已被包括LangChain、Taskweaver等在内的多个热门项目高度集成。

Ollama官方地址:https://ollama.com

6.2 Ollama的下载-安装

Ollama项目支持跨平台部署,目前已兼容Mac、Linux和Windows操作系统。特别地对于Windows用户提供了非常直观的预览版。

Download Ollama

macOs

Linux

Windows

Download for Windows

Requires Windows 10 or later

无论使用哪个操作系统,Ollama项目的安装过程都设计得非常简单。

访问 https://ollama.com/download 下载对应系统的安装文件。

Windows 系统执行 .exe 文件安装(大概671M大小)

Linux 系统执行以下命令安装:

1 curl -fsSL https://ollama.com/install.sh | sh

这行命令的目的是从 https://ollama.com/ 网站读取 install.sh 脚本,并立即通过 sh 执行该脚本,在安装过程中会包含以下几个主要的操作:

检查当前服务器的基础环境,如系统版本等;

下载Ollama的二进制文件;

配置系统服务,包括创建用户和用户组,添加Ollama的配置信息;

启动Ollama服务;

6.3 模型的下载-安装

访问 https://ollama.com/search 可以查看 Ollama 支持的模型。使用命令行可以下载并运行模型,例如运行 deepseek-r1:7b 模型:

1 ollama run deepseek-r1:7b

6.4 调用本地私有模型

举例1:

from langchain_community.chat_models import ChatOllama1

#from langchain_ollama import ChatOllama 2

ollama_llm4 === ChatOllama(mode === "deepseek-r1:7b")

from langchain_core.messages import HumanMessage1

3 messages = [

4 HumanMessage(content === "你好,请介绍一下你自己")

] 5

chat_model_response7 === ollama_llm.invoke(messages)

9 print(chat_model_response.content)

您好!我是由中国的深度求索(DeepSeek)公司开发的智能助⼿DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。

您好!我是由中国的深度求索(DeepSeek)公司开发的智能助⼿DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。

若 Ollama 不在本地默认端口运行,需指定 base_url ,即:

1 ollama_llm === ChatOllama(

2 mode === "deepseek-r1:7b",

3 base_url === "http://your-ip:port" # 自定义地址

) 4

1 print(chat_model_response.content)

您好!我是由中国的深度求索(DeepSeek)公司开发的智能助⼿DeepSeek-R1。如您有任何任何问题,我会尽我所能为您提供帮助。

举例2:

1 from langchain.prompts.chat import ChatPromptTemplate

2 from langchain_community.chat_models import ChatOllama

生成对话形式的聊天信息格式5

chat_prompt6 === ChatPromptTemplate.from_messages([

("system","你是一个有用的助手,可以将{input_language}翻译成{output_language}。"),7

8 ("human", "{text}"), 9 ])

10

格式化变量输入11

txt 复制代码
12 messages = chat_prompt.format/messages(input_language='中文', output_language='英语', text='我爱编程')  
13  
14 #实例化Ollama启动的模型  
15 ollama_Idm = ChatOllama(model='deepseek-r1:7b')  
16  
17 #执行推理  
18 result = ollama_Idm.invoke/messages)  
19  
20 print(result(content)

好,⽤⼾让我把"我爱编程"翻译成英⽂。⾸先,"我"翻译成"I",没问题。"爱"是"love",常⽤在表达情感上。"编程"⽐较合适的是"programming",这个词很常⻅,⽤来指代计算机编程。

所以组合起来就是"I love programming"。听起来挺⾃然的,符合英语的习惯⽤法。⽤⼾可能是在学习编程或者分享⾃⼰的兴趣,所以翻译得简洁明了就可以了。

I love programming.

相关推荐
chushiyunen2 小时前
langchain的流式事件监听astream_event()、todo运行机制
java·数据库·langchain
老王熬夜敲代码3 小时前
test_node节点
langchain
姚青&3 小时前
通过 Langchain 框架实现 ChatGPT 的使用
chatgpt·langchain
Dazer0073 小时前
Windows 11 关闭微软输入法 Ctrl+Shift+F 简繁切换快捷键
windows·microsoft
InKomorebi3 小时前
《LangChain 智能体从浅入门到深入门:模型配置、中间件体系、装饰器钩子与 invoke 调用模式全解析部分内容指南分享》(如有错误欢迎指正!)
langchain
老王熬夜敲代码3 小时前
LLM结构化的概念讲解
langchain
老王熬夜敲代码3 小时前
AI小demo
langchain
咚咚2343 小时前
Langchain 调用 Agent Skills
langchain
java资料站4 小时前
第01章:LangChain使用概述
langchain