1 Model I/O 介绍
Model I/O 部分是与语言模型进行交互的核心组件,包括输入提示(Prompt Template)、调用模型(Model)、输出解析(Output Parser)。
简单来说,就是输入、处理、输出这三个步骤。
结合你刚才那段 OpenAI key 的代码,你大概率在学 LangChain 。"Model I/O" 是 LangChain 的核心模块之一,负责"把输入交给模型、拿到输出 "。
它拆成三块:
1.1 Prompts(提示词管理)
- 把提示词做成可复用的模板
python
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("system", "你是翻译助手"),
("human", "把这句话翻成英文:{text}")
])
# 填充变量
final_prompt = prompt.invoke({"text": "你好"})
1.2. Models(模型接口)
- 统一了各家模型(OpenAI、Anthropic、国产等)的调用方式
- 三类:
- LLM :纯文本模型(
OpenAI(...)) - Chat Model :对话模型,带消息角色(
ChatOpenAI(...),最常用) - Embeddings:文本向量化,用于检索
- LLM :纯文本模型(
python
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
api_key=api_key, # 就是你刚读出来的
base_url=base_url,
model="gpt-4o-mini"
)
resp = llm.invoke("你好")
1.3. Output Parsers(输出解析)
- 把模型输出的字符串解析成结构化数据(字典、列表、JSON)
python
from langchain_core.output_parsers import StrOutputParser
parser = StrOutputParser()
text = parser.invoke(resp) # 把聊天对象转成纯文本
1.4 三者的关系(一条流水线)
Prompt(拼好问题)→ Model(交给大模型)→ Output Parser(解析结果)
再往下走,LangChain 还有两块
- Retrieval(检索):把文档切块→向量化→存库→检索,做 RAG
- Chain / Agent(链与智能体):把上面这些串起来,实现多步逻辑
2 调用在线模型
2.1 常用大模型服务平台介绍
有许多提供大模型API服务的平台,如下所示:
- CloseAI:https://platform.closeai-asia.com/,可提供国外OpenAI, Anthropic,Google等公司最新模型调用代理;
- OpenRouter:https://openrouter.ai/,提供闭源模型和开源模型调用代理;
- 阿里云百炼:https://bailian.console.aliyun.com/,提供大模型API调用、模型微调、模型评测等一系列服务,是一站式大模型应用开发平台;
- 百度千帆:https://console.bce.baidu.com/qianfan/overview,类似于阿里云百炼,同样为一站式企业级大模型开发与应用平台;
- 硅基流动:https://www.siliconflow.cn/,类似上两个平台,不再赘述。
使用时只需要注册、充值并创建API-Key,之后即可使用API-Key与BASE_URL来调用平台提供的相应的模型的服务。
2.2 API_KEY的安全问题
API_KEY 为敏感信息,在不同的平台获取到API_KEY之后,需要将 API_KEY和BASE_URL 通过环境变量存储起来,后续在实际调用时,需要加载环境变量后,从环境变量当中读取,而不是直接硬编码在业务代码当中。
在实际开发过程中,一定要注意:不要将.env放在git管理目录当中,避免数据泄露。
配置环境变量有两种方式:
2.2.1)通过.env文件配置,适用于实际项目当中
通过.env配置过程如下:
- 在项目根目录中创建.env文件,添加环境变量:此处以OPENAI_BASE_URL和OPENAI_API_KEY为例
- 在代码当中通过dot_env模块(需要安装包:python-dotenv)的load_dotenv方法加载环境变量
- 在代码当中通过os模块读取环境变量
.env文件内容如下所示:
python
OPENAI_API_KEY=sk-xxx
OPENAI_BASE_URL=https://api.openai-proxy.org/v1
读取示例如下所示:
python
# pip install python-dotenv
# 1、从dotenv导入load_dotenv方法
from dotenv import load_dotenv
# 2、调用load_dotenv方法加载.env文件
load_dotenv()
# 3、通过os模块读取环境变量
import os
api_key = os.getenv("OPENAI_API_KEY")
print(api_key)
3.2.2.2)在Windows当中配置全局环境变量
适用于学习环境下,经常需要使用到的某些环境变量。

2.2 OpenAI SDK 调用模型
-- OpenAI 的 GPT 系列模型影响了大模型技术发展的开发范式和标准。大部分模型,例如 Qwen、ChatGLM、DeepSeek 等模型,它们的使用方法和函数调用逻辑基本遵循 OpenAI 定义的规范,都可以使用OpenAI SDK来进行调用。
-- OpenAI的接口调用方式也经历的一些转变,其中最为经典的一套API,称之为ChatCompletionsAPI(官方文档链接:https://platform.openai.com/docs/api-reference/chat)。
-- 而在2025年年中,OpenAI又发布了一套新的API: ResponsesAPI(官方文档链接:https://platform.openai.com/docs/api-reference/responses)。
-- ResponsesAPI是当前OpenAI中最先进的一套API,对ChatCompletionsAPI做了多处升级,例如,支持服务端内置工具调用,支持服务端维护状态(短期记忆)等。
2.2.1)ChatCompletionAPI 调用示例
python
# pip install openai
from openai import OpenAI
import os
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(
base_url=os.getenv("OPENAI_BASE_URL"), # 平台提供的 URL
api_key=os.getenv("OPENAI_API_KEY"), # 平台提供的 API-Key
)
completion = client.chat.completions.create(
model="gpt-4o-mini", # 模型名称
messages=[{"role": "user", "content": "将'你好'翻译成意大利语"}], # 用户输入
)
print(completion.choices[0].message.content)
python
from openai import OpenAI
导入 OpenAI 官方 SDK 的客户端类。后续要用 OpenAI(...) 创建客户端,再调用 client.chat.completions.create(...) 等方法发请求。没有它就无法调用 OpenAI 接口。
python
import os
提供读取环境变量的能力(os.getenv(...))。用来从系统环境或 .env 文件里取 OPENAI_API_KEY、OPENAI_BASE_URL 等配置。
python
from dotenv import load_dotenv
导入 python-dotenv 库的函数,用于把项目根目录 .env 文件里的键值对加载进环境变量。方便本地开发时管理密钥,不用每次手动 export。
2.2.2)ResponsesAPI调用示例
python
import os
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5.1",
input="中国国内今天发生了哪些大事儿?",
tools=[{"type": "web_search"}] # 可以自动调用内置工具
)
print(response.output_text)
2.3 LangChain API 调用模型
-- 通过上面两个例子,可以看到,对于不同厂商的模型,需要学习不同的SDK的API来进行调用(注意:虽然大部分模型厂商可以兼容OpenAI SDK规范,但是对于复杂场景下,例如结构化输出等场景,各厂商之间具体构造参数的方式仍有差别),
-- 而通过LangChain调用API,其封装了不同模型调用时,复杂的出入参的构建和解析,得到llm对象之后,我们可以通过统一的方法来进行模型调用和结果解析。
-- 在使用langchain进行模型调用时,需要先安装相应的包。对于OpenAI,需要安装langchain-openai包,而如果需要使用DeepSeek的模型,则需要安装langchain-deepseek。(具体可参考官网:https://docs.langchain.com/oss/python/integrations/providers/overview)。
使用LangChainAPI进行调用的步骤如下:
- 1)构造LLM ChatModel实例
- 2)传递Message对象列表或普通字符串对象,调用LLM实例
- 3)解析调用结果

2.3.1 构造 LLM ChatModel 实例
LLM ChatModel 实例代表了一个可调用的LLM对象,有两种方式进行初始化,
- 1)langchain 提供的统一方法 init_chat_model;
- 2)使用特定包下(例如 langchain-openai)下的 ChatModel类(例如langchain_openai 下的 ChatOpenAI类)。
下面首先介绍 init_chat_model 的初始化参数,代码示例如下:
python
# pip install langchain
# pip install langchain-openai
def get_model_from_init():
import os
import dotenv
dotenv.load_dotenv()
from langchain.chat_models import init_chat_model
llm = init_chat_model(
model="gpt-4o-mini",
model_provider="openai",
base_url=os.getenv("OPENAI_BASE_URL"),
api_key=os.getenv("OPENAI_API_KEY"),
)
resp = llm.invoke("你好")
print(type(resp)) # <class 'langchain_core.messages.ai.AIMessage'>
print(resp.content) # 获取结果
init_chat_model 所接收的相关参数如下面所示:
| 参数 | 说明 |
|---|---|
| model | 模型名称或标识符,例如gpt-4o-mini |
| model_provider | 模型提供厂商,例如:openai |
| base_url | 发送请求的 API 端点的 URL。常由模型的提供商提供 |
| api_key | 与模型提供商进行身份验证所需的 API 密钥 |
| temperature | 控制模型输出的随机性。数字越高,回答越有创意;数字越低,回答越确定,涉及到大模型采样相关内容(https://zhuanlan.zhihu.com/p/1981752176578667658) |
| timeout | 在取消请求之前,等待模型响应的最大时间(以秒为单位) |
| max_tokens | 限制响应中的总tokens 数量,控制输出长度 |
| max_retries | 请求失败时系统尝试重新发送请求的最大次数 |
在此处介绍下 max_tokens 所涉及到的 token 的概念:大模型处理的最小单位是 token(相当于自然语言中的词或字),输出时逐个 token 依次生成。
模型提供商通常也是以 token 的数量作为其计量或收费的依据。1个中文Token≈1-1.8个汉字,1个英文Token≈3-4字母。
Token与字符转化的可视化工具:
- OpenAI提供:https://platform.openai.com/tokenizer
- 百度智能云提供:https://console.bce.baidu.com/support/#/tokenizer
使用特定包下的类构造 LLM实例和 init_chat_model 在本质上是一样的(init_chat_model 底层就是调用特定包下的类构造LLM实例),参考代码如下所示:
python
def get_model_from_openai_package():
import os
import dotenv
dotenv.load_dotenv()
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0.0,
base_url=os.getenv("OPENAI_BASE_URL"),
api_key=os.getenv("OPENAI_API_KEY"),
)
resp = llm.invoke("詹姆斯厉害吗")
print(type(resp))
print(resp.content)
if __name__ == "__main__":
get_model_from_openai_package()
运行结果 :

对于其他厂商,代码类似。
2.3.2 调用LLM实例
调用LLM实例时,有两处需要关注:调用传入的对象类型和调用方式。
2.3.2.1)调用传入对象类型
前面的例子当中,我们直接传入字符串对象,这通常适用于不需要保留对话历史的直接生成任务。
除此以外,更加好的方式是传入一个消息列表:
python
def invoke_llm_with_message_list():
import os
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage,SystemMessage,AIMessage
llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0.0,
base_url=os.getenv("OPENAI_BASE_URL"),
api_key=os.getenv("OPENAI_API_KEY"),
)
resp = llm.invoke([SystemMessage(content="你是一个专业的篮球评论家"),HumanMessage(content="欧文怎么样")])
print(type(resp))
print(resp.content)
if __name__ == "__main__":
invoke_llm_with_message_list()
运行结果 :

消息列表表示了一段"聊天记录历史";而不同的消息类型,则代表了不同的角色,各种类型及相关描述如下:
| 消息类型 | 描述 |
|---|---|
| SystemMessage | 代表一组初始指令,用于引导模型的行为。可以使用系统消息来设定语气、定义模型的角色,并建立响应的指导方针 |
| HumanMessage | 表示用户输入,可以在message当中传递其他元数据信息 |
| AIMessage | 模型生成的响应,包括文本内容、工具调用和token使用量等元数据信息 |
| ToolMessage | 表示工具调用的输出 |
HumanMessage、AIMessage 和 SystemMessage 是常用的消息类型。
ToolMessage 是在工具调用场景下才会使用的特殊消息类型。
消息对象,除了使用 HumanMessage 等类以外,还可以通过元组对象 来表示,元组对象第一个元素表示角色 ,第二个元素表示具体消息内容 ;
也可以通过OpenAI官方使用的dict 来表示,dict当中有两个键,第一个为role,表示角色,第二个为content,表示内容。
示例代码如下:
python
def invoke_llm_with_message_list_use_tuple():
import os
import dotenv
dotenv.load_dotenv()
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage, AIMessage
llm = ChatOpenAI(
model = "gpt-6-luna",
base_url = os.getenv("OPENAI_BASE_URL"),
api_key = os.getenv("OPENAI_API_KEY"),
)
# 以下两种方式是等价的
messages_list = [("system", "你是一个专业的篮球评论家"), ("user", "你怎么看待詹姆斯转会76人")]
message_list = [{"role": "system", "content": "你是一个专业的篮球评论家"}, {"role": "user", "content": "你怎么看待詹姆斯转会76人"}]
resp = llm.invoke(message_list)
print(type(resp))
print(resp.content)
if __name__ == "__main__":
invoke_llm_with_message_list_use_tuple()
运行结果 : (还没有更新最新)

2.3.2.2)调用方式
除了上述调用方式外,LangChain 的 LLM对象还支持异步调用、流式调用、批调用等多种方式。
异步调用在实际生产环境下非常实用,可以大大提高程序的响应性能,
示例代码如下:
python
import asyncio
async def call_llm_async():
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-4o-mini"
)
response = await llm.ainvoke(
input=[("user", "什么是LangChain")]
)
print(response.content)
if __name__ == "__main__":
asyncio.run(call_llm_async())
运行结果 :

流式调用 ,可以让大模型输出结果实现打字机效果,
示例代码如下:
python
def call_llm_streaming_mode():
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-4o-mini"
)
# 调用stream方法,返回迭代器对象
response = llm.stream(
input=[("user", "怎么看待16年的欧文")]
)
# 遍历迭代器对象,打印每个chunk的内容
for chunk in response:
print(chunk.content,end="")
call_llm_streaming_mode()
运行结果 :

批次调用 ,可以并行发出多个请求,统一回收相关结果,
示例代码如下:
python
def call_llm_batch_mode():
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-6-luna"
)
# 调用batch方法,底部通过thread 并行调用模型
response = llm.batch(
inputs=[[("user", "詹姆斯的死亡之瞳是什么情况")], ("user", "评价一下")]
)
# 打印每个问题的回答
for question_chunk in response:
print(question_chunk.content)
call_llm_batch_mode()
运行结果 :

3 调用本地模型 - Ollama
3.1 Ollama介绍
-- Ollama是一个开源项目,其项目定位是:一个本地运行大模型的集成框架。
-- 目前主要针对主流的 LlaMA 架构的开源大模型设计,可以实现如 Qwen、Deepseek 等主流大模型的下载、启动和本地运行的自动化部署及推理流程。
-- 注意:Ollma主要用于原型设计和本地开发等,实际生产环境下做大模型部署会使用VLLM等框架。
-- Ollama目前作为一个非常热门的大模型托管平台,已被包括LangChain、Taskweaver等在内的多个热门项目高度集成。
Ollama官方地址:https://ollama.com
Ollama Github开源地址:https://github.com/ollama/ollama
3.2 Ollama安装
Ollama项目支持跨平台部署,目前已兼容Mac、Linux和Windows操作系统。

无论使用哪个操作系统,Ollama项目的安装过程都设计得非常简单。
访问 https://ollama.com/download 下载对应系统的安装文件。
- Windows 系统执行.exe文件安装
- Linux 系统执行以下命令安装:
python
curl -fsSL https://ollama.com/install.sh | sh
这行命令的目的是从https://ollama.com/ 网站读取 install.sh脚本,并立即通过 sh 执行该脚本,在安装过程中会包含以下几个主要的操作:
检查当前服务器的基础环境,如系统版本等;
下载Ollama的二进制文件;
配置系统服务,包括创建用户和用户组,添加Ollama的配置信息;
启动Ollama服务;
调用本地模型
举例:
python
# pip install langchain-ollama
from langchain_ollama import ChatOllama
ollama_llm = ChatOllama(model="qwen3:8b")
messages = {"role": "user", "content": "你好,请介绍一下你自己"}
resp = ollama_llm.invoke(messages)
print(resp.content)
若 Ollama 不在本地默认端口运行,需指定 base_url,即:
# pip install langchain-ollama
from langchain_ollama import ChatOllama
ollama_llm = ChatOllama(
model="qwen3", base_url="http://localhost:11434",
)
messages = {"role": "user", "content": "你好,请介绍一下你自己"}
resp = ollama_llm.invoke(messages)
print(resp.content)
4 模型调用结果解析
当我们和模型进行对话时,模型会通过自然语言进行回复。在对话式场景下,这没有什么问题,但是对于在实际生产环境当中,将大模型用以非对话场景,或者对话场景下的中间产出时,我们希望模型以一种更加结构化的方式进行输入 ,例如JSON等,而LangChain设计了一系列包(例如langchain_core.output_parsers)和方法专门用来解决此类问题。
4.1 获取JSON结果
要想大模型输出Json字符串,有两种方式:
- 在 Prompt 当中明确约束大模型输出Json;
- 通过部分厂商直接提供的接口参数进行限制。
4.1.2 通过 Prompt约束
要使用 Prompt 明确约束大模型输出,需要使用到langchain所提供的JSONOutputParser,整体流程如下:
- 1)通过 Pydantic定义 Json schema;
- 2)使用构造好的 JSON Schem 构造 JsonOutputParser实例j son_parser;
- 3)调用 json_parser 的 get_format_instrucions() 方法,将 json 结构输出约束,放到 SystemMessage 当中;
- 4)将 SystemMessage和 UserMessage 都给到 LLM,进行调用,结果使用 json_parser.parse() 方法,解析成 PythonDict 对象。
下面以一个具体实例来讲解,定义JSON结构:
python
def json_output_parser():
import os
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field
llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0.0,
base_url=os.getenv("OPENAI_BASE_URL"),
api_key=os.getenv("OPENAI_API_KEY")
)
class Prime(BaseModel):
prime: list[int] = Field(description="素数")
count: list[int] = Field(description="小于该素数的素数个数")
json_parser = JsonOutputParser(pydantic_object=Prime)
# print(json_parser.get_format_instructions())
res = llm.invoke([("system",json_parser.get_format_instructions()),("user","任意生成5个1000-100000之间素数,并标出小于该素数的素数个数")])
print(res.content)
parsed_res = json_parser.invoke(res)
print(type(parsed_res))
if __name__ == "__main__":
json_output_parser()
运行结果 :

Prompt约束,对于模型能力有一定依赖,如果模型参数不够强,容易出现幻觉,从而导致生成的JSON字符串语法有问题,或者是不符合我们所定义的JSON结构。
4.1.3 通过厂商能力
-- 对于主流大模型厂商,其API已经提供了专门的参数,用以限制模型输出内容符合我们所定义的schema结构。
-- 以OpenAI为例,其官方文档如下:https://platform.openai.com/docs/guides/structured-outputs
示例代码如下所示:
python
def openai_json_output_demo():
import os
from openai import OpenAI
from pydantic import BaseModel
client = OpenAI()
class CalendarEvent(BaseModel):
name: str
date: str
participants: list[str]
response = client.chat.completions.parse(
model="gpt-4o-mini",
messages=[
{
"role": "user",
"content": "Alice and Bob are going to a science fair on Friday.",
}
],
response_format=CalendarEvent
)
print(response.choices[0].message.parsed)
if __name__ == "__main__":
openai_json_output_demo()
运行结果:

再以Google Gemini为例,
python
def gemini_json_output_demo():
import os
from google import genai
from pydantic import BaseModel, Field
from typing import List, Optional
# 1、定义一个Pydantic模型,用于表示日历事件
class CalendarEvent(BaseModel):
name: str
date: str
participants: list[str]
# 2、初始化Gemini客户端
client = genai.Client(
api_key=os.getenv("OPENAI_API_KEY"),
vertexai=True, # 可选,优先使用vertexai协议访问,稳定性更高
http_options={
"base_url": 'https://api.openai-proxy.org/google',
},
)
# 3、定义一个提示模板,用于生成日历事件
prompt = """
Alice and Bob are going to a science fair on Friday.
"""
# 4、调用Gemini模型生成内容
response = client.models.generate_content(
model="gemini-2.5-flash-lite",
contents=prompt,
config={
"response_mime_type": "application/json",
"response_json_schema": CalendarEvent.model_json_schema(),
},
)
print(response.text)
# 5、解析Gemini模型的响应,将JSON字符串转换为CalendarEvent对象
event = CalendarEvent.model_validate_json(response.text)
print(event)
if __name__ == "__main__":
gemini_json_output_demo()
运行结果 :

两个案例当中,都没有在Prompt当中明确指定以JSON输出,但是调用API返回结果仍然能够正确得到结果。
LangChain 也对这种能力提供了封装:不同厂商的模型都是继承了ChatModel基类,而 ChatModel 提供了 with_structured_output方法,传入pydantic base model类作为 schema 对象,得到一个新的 llm对象,调用新的 llm对象即可。
具体代码如下所示:
python
def json_output_use_langchain():
import os
from langchain_openai import ChatOpenAI
from langchain_google_genai import ChatGoogleGenerativeAI
from langchain_core.messages import HumanMessage,SystemMessage,AIMessage
from langchain_core.output_parsers import JsonOutputParser
from pydantic import BaseModel, Field
# 1、初始化llm: 可以使用OpenAI,也可以使用Gemini
llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0.0,
base_url=os.getenv("OPENAI_BASE_URL"),
api_key=os.getenv("OPENAI_API_KEY")
)
# llm = ChatGoogleGenerativeAI(
# model="gemini-2.5-flash-lite",
# temperature=0.0,
# base_url='https://api.openai-proxy.org/google',
# api_key=os.getenv("OPENAI_API_KEY"),
# )
# 2、定义一个Pydantic模型,用于表示日历事件
class CalendarEvent(BaseModel):
name: str
date: str
participants: list[str]
#3、使用with_structured_output,得到一个新的llm,用于生成结构化输出
new_llm=llm.with_structured_output(schema=CalendarEvent)
#4、调用新的llm,生成结构化输出
res = new_llm.invoke("Alice and Bob are going to a science fair on Friday.")
print(res)
print(type(res))
if __name__ == "__main__":
json_output_use_langchain()
运行结果 :

不管使用什么模型,都是调用统一的方法,就能够实现相关的需求,如果需要换模型,只需要调整 llm实例化代码即可,其余代码无需改动,这正是 LangChain框架的强大之处。
4.2 获取其他类型的解析结果
要想获取其他形式的结果,例如XML等,也可通过output_parser当中的其他类来实现,在output_parser包中提供的parser有如下:
python
__all__ = [
"BaseCumulativeTransformOutputParser",
"BaseGenerationOutputParser",
"BaseLLMOutputParser",
"BaseOutputParser",
"BaseTransformOutputParser",
"CommaSeparatedListOutputParser",
"JsonOutputKeyToolsParser",
"JsonOutputParser",
"JsonOutputToolsParser",
"ListOutputParser",
"MarkdownListOutputParser",
"NumberedListOutputParser",
"PydanticOutputParser",
"PydanticToolsParser",
"SimpleJsonOutputParser",
"StrOutputParser",
"XMLOutputParser",
]
由于JSON的强大,对于其他类型,此处不再赘述,大部分场景下,使用JSON输出即可满足需求。
5 提示词模板
-- 在应用开发中,固定的提示词限制了模型的灵活性和适用范围。通过提示词模板,我们可以将变量插入到模板中,从而创建出不同的 Prompt。
-- LangChain当中有多种类型的提示模板,常用的有 PromptTemplate (字符串提示模板)和 ChatPromptTemplate (聊天提示模板)。
-- 提示词模板以字典 作为输入,其中每个键代表要填充的提示模板中的变量。并输出一个 PromptValue。这个 PromptValue 可以传递给聊天模型,也可以转换为字符串或消息列表。
-- PromptValue 存在的目的是为了方便在字符串和消息之间切换。
以下使用PromptTemplate为例子做一个介绍:
python
# pip install openai
from openai import OpenAI
import os
from dotenv import load_dotenv
load_dotenv()
def prompt_template_demo():
from langchain_core.prompts import ChatPromptTemplate
from langchain.chat_models import init_chat_model
# 使用构造方法实例化提示词模板
chat_prompt_template = ChatPromptTemplate.from_messages(
messages=[
("system", "你是一个专业的评论员"),
("human", "请评价{product}的优缺点,包括{aspect1}和{aspect2}。"),
],
)
chat_message_list = chat_prompt_template.invoke({"product": "詹姆斯", "aspect1": "能力", "aspect2": "影响力"})
llm = init_chat_model(
model="gpt-4o-mini",
model_provider="openai",
)
resp= llm.invoke(chat_message_list)
print(resp.content)
if __name__ == "__main__":
prompt_template_demo()
运行结果 :

6 Chains
-- 在前面的例子当中所涉及到的 模型调用、解析器调用,以及对PromptTemplate调用,都使用到了invoke方法,这是因为这些类都实现了LangChain最底层定义的Runnable接口,其代表了 LangChain 中可以调用、批处理、流式传输、转换和组合的工作单元,是使用 LangChain 组件的基础,它在许多组件中实现,例如语言模型、输出解析器、检索器、编译的 LangGraph 图等。
-- Runnable 接口定义了一系列标准的方法,如下所示:
- invoke / ainvoke -- 将单个输入转换为输出
- batch / abatch -- 批量将多个输入转换为输出
- stream / astream -- 从单个输入生成流式输出
为什么需要统一调用方式?
假设没有统一调用方式,每个组件调用方式不同,组合时需要手动适配:
- 提示词渲染用 .format()
- 模型调用用 .generate()
- 解析器解析用 .parse()
- 工具调用用 .run()
代码会变成:
python
prompt_text = prompt.format(topic="猫") # 方法1
model_out = model.generate(prompt_text) # 方法2
result = parser.parse(model_out) # 方法3
Runnable 统一调用方式:
python
# 分步调用
prompt_text = prompt.invoke({"topic": "猫"}) # 方法1
model_out = model.invoke(prompt_text) # 方法2
result = parser.invoke(model_out) # 方法3
而所有实现了Runnable接口的组件,均可以通过一种特定的方式,将其连接起来,打包成一整个可调用对象,这也就是 LangChain 当中的Chain的由来,而这种方式则称之为LCEL。
LCEL (LangChain Expression Language),中文名称为LangChain 表达式语言,是一种从现有的 Runnable 构建新的 Runnable 的声明式方法,用于声明、组合和执行各种组件(模型、提示、工具、函数等)。
python
# LCEL管道式
chain = prompt | model | parser # 用管道符组合
result = chain.invoke({"topic": "猫"}) # 所有组件统一用invoke
-- 无论组件的功能多复杂(模型/提示词/工具),调用方式完全相同。并且可以通过管道符 | 组合,自动处理类型匹配和中间结果传递。
-- 我们称使用 LCEL 创建的 Runnable 为"链","链"本身就是 Runnable。
-- LCEL 两个主要的组合原语是 RunnableSequence 和 RunnableParallel。许多其他组合原语可以被认为是这两个原语的变体。
6.1 RunnableSequence 可运行序列
RunnableSequence 按顺序"链接"多个可运行对象,其中一个对象的输出作为下一个对象的输入。
LCEL重载了 | 运算符,以便从两个 Runnables 创建
python
RunnableSequence。
chain = runnable1 | runnable2
# 等同于
chain = RunnableSequence([runnable1, runnable2])
举例:提示模板➡️模型➡️输出解析器
python
# 1. 导入模板类
from langchain_core.prompts import PromptTemplate
# 2. 导入字符串解析器
from langchain_core.output_parsers import StrOutputParser
# 3. 导入统一模型初始化函数
from langchain.chat_models import init_chat_model
# 4. 加载环境变量工具
from dotenv import load_dotenv
# 5. 操作系统环境变量
import os
# 6. 读取 .env 文件里面的密钥、地址
load_dotenv()
# 7. 定义提示词模板
prompt_template = PromptTemplate(
template="讲一个关于{topic}的笑话",
input_variables=["topic"],
)
# 8. 初始化大模型对象
llm = init_chat_model(
model="gpt-4o-mini",
model_provider="openai",
)
# 9. 创建输出解析器
parser = StrOutputParser()
# 10. LCEL 拼接链:模板 → 模型 → 解析器
chain = prompt_template | llm | parser
# 11. 执行链,传入参数 topic=人工智能
resp = chain.invoke({"topic": "人工智能"})
# 12. 打印结果
print(resp)
运行结果 :

6.2 RunnableParallel 可运行并行
RunnableParallel 同时运行多个可运行对象,并为每个对象提供相同的输入。
对于同步执行,RunnableParallel 使用 ThreadPoolExecutor 来同时运行可运行对象。对于异步执行,RunnableParallel 使用 asyncio.gather 来同时运行可运行对象。
构造RunnableParallel实例时,参数列表是可变数量关键字参数,一个参数名对应着一个可运行组件,每个可运行组件输出结果将作为参数名key所对应的值,封装到整个运行实例的结果当中。
具体代码如下所示:
python
# 定义主函数
def runnable_parallel_demo():
import os
from langchain.chat_models import init_chat_model
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnableParallel
from langchain_core.output_parsers import StrOutputParser
# 初始化大模型实例
llm = init_chat_model(
model="gpt-4o-mini",
model_provider="openai",
)
# 第一条链:翻译成英文
english_chain = (
PromptTemplate.from_template("把这个句子{topic}翻译成英文") | llm | StrOutputParser()
)
# 第二条链:翻译成韩文
korean_chain = (
PromptTemplate.from_template("把这个句子{topic}翻译成韩文") | llm | StrOutputParser()
)
# 组装并行链:两个子链同时执行
map_chain = RunnableParallel(english=english_chain, korean=korean_chain)
# 执行并行链,传入参数 topic="人工智能是一种智能技术"
resp = map_chain.invoke({"topic": "人工智能是一种智能技术"})
# 打印最终返回的字典结果
print(resp)
# 程序入口:直接运行本文件时,执行函数
if __name__ == "__main__":
runnable_parallel_demo()
运行结果:

6.3 其他 Runnable 结构
LangChain所提供的其他Runnable组件,如下表所示,此处不再详细介绍。
| 名称 | 描述 |
|---|---|
| RunnableLambda | 将普通函数,封装成符合Runnable接口的可运行组件 |
| RunnableBranch | 对输入进行if-else判断,并路由到不同的函数中 |
| RunnablePassthrough | 接收输入并将其原样输出;LCEL 体系中的"无操作节点",用于在流水线中透传输入或保留上下文,也可以用于向输出中添加键 |
| RunnableWithFallbacks | 对Runnable组件进行兜底,使得 Runnable 失败后可以回退到其他 Runnable |