一、【调用方法:invoke】
1. 概念与参数
在 LangChain (Chain是指链式)中,invoke 是 LangChain 中最基础的同步调用入口,是 Runnable 协议的核心同步调用方法。它常见用法既可拼接模板,又可调用模型,起了"链"的作用。
【语法格式】: invoke(input, config=None)
(1) input 的格式由组件决定。
(2) config 用于高级控制:追踪、标签、回调、超时等。
(3) 在构建Chain(链)时,invoke 会自动处理组件间的数据流转(如 Prompt 的输出自动传给 Model)。
(4) 对于生产级应用,且需要异步和流式输出,则考虑使用 ainvoke、stream 等方法。
【核心参数】
|-------------|--------------------|--------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 参数 | 类型 | 必填 | 默认值 | 详细说明 |
| input | Any | 是 | | (1)输入数据。具体格式取决于调用该方法的组件类型。 (2)Prompt: 通常为字典 dict,键对应模板变量。 (3)Model: 可以是字符串 str、消息列表 ListBaseMessage 或 PromptValue。 (4)Retriever: 通常为查询字符串 str。 (5)Chain: 取决于链条第一个组件的要求。 |
| config | RunnableConfig | 否 | None | 运行时配置对象,用于控制执行行为。 |
【注意】
(1) input 是位置参数,必须提供。
(2) config 是关键字参数,通常用于高级场景。在简单脚本中常省略。
2. 【不同组件的 invoke 用法与输入输出规范】
【高级用法:input 参数详解】
LangChain 的核心优势在于统一接口,但不同组件对 input 的解释和返回结果不同。
(1) 提示词模板 (PromptTemplate / ChatPromptTemplate)
功能:将动态变量填充到静态模板中,生成最终的结构化提示。
Input (input):字典 (dict)。键 (Key) 必须与模板中的占位符变量名完全一致。
Output:PromptValue 对象。
ChatPromptTemplate 返回 ChatPromptValue(包含消息列表)。
PromptTemplate 返回 StringPromptValue(包含字符串)。
(2) 聊天模型 (ChatModel, 如 ChatOpenAI, ChatTongyi)
功能:接收提示并生成 AI 回复。
Input (input):灵活支持多种类型。
ListBaseMessage: 标准消息列表(推荐)。
str: 单个字符串(会自动包裹为 HumanMessage)。
PromptValue: 由 Prompt 模板 invoke 生成的对象(推荐链式调用时使用)。
Output:AIMessage 对象。
主要内容包括 content (文本)、tool_calls (工具调用信息) 等。
(3) 传统语言模型 (LLM, 如 OpenAI legacy)
功能:接收提示并生成纯文本字符串。
Input (input):字符串 str、消息列表或 PromptValue。
Output:字符串 (str)。直接返回生成的文本,不包含消息对象结构。
(4) 输出解析器 (OutputParser)
功能:将模型的原始输出转换为结构化数据。
Input (input):BaseMessage 或 str。
通常是前一步 Model 的输出。
Output:取决于解析器类型。
StrOutputParser: 返回 str。
JsonOutputParser: 返回 dict 或 list。
PydanticOutputParser: 返回 Pydantic 模型实例。
(5) 检索器 (Retriever)
功能:根据查询字符串从向量数据库或其他源检索文档。
Input (input):字符串 (str)。即用户的查询问题。
Output:ListDocument。
文档列表,每个文档包含 page_content 和 metadata。
【高级用法:Config 参数详解】
config 参数虽然可选,但在生产环境中非常重要。它允许你在不修改代码逻辑的情况下改变运行行为。
【示例说明】
python
from langchain_core.runnables import RunnableConfig
config = RunnableConfig(
tags=["production", "math-bot"], # 添加标签,便于在 LangSmith 中过滤
metadata={"user_id": "12345"}, # 添加元数据,关联用户信息
run_name="MathExplanationChain", # 自定义运行名称
callbacks=[my_custom_handler], # 自定义回调处理器
max_concurrency=5 # 限制并发数
)
# 在 invoke 中传入 config
response = chain.invoke({"question": "1+1=?"}, config=config)
常见应用场景:
追踪与调试 (LangSmith):通过 tags 和 run_name 区分不同环境或功能的调用,便于后续分析成本和质量。
超时控制:防止某个步骤卡死整个应用。
回调监控:记录 Token 消耗、响应时间等指标。
二、【提示语模板:PromptTemplat】
1. 【安装Python 及调用大模型的 Langchain 包】
(1)安装 Python3.12 或 以上版本
(2)在虚拟环境终端安装包 或 在CMD环境安装包(全局可用)
安装 【angchain-community】包来调用大模型(不推荐)
pip install langchain==0.3.30
pip install "langchain-community==0.3.27" #【因包里面有"-"这符号,所以包名要加冒号。】
pip install dashscope==1.27.4 # 【用通义大模型(LLM)时须安装。】
bash
pip install langchain==0.3.30
pip install "langchain-community==0.3.27"
pip install dashscope==1.27.4
或 安装 【langchain-openai】包来调用大模型**(强烈推荐,无特别说明后面示例都用此法)**
pip install langchain==1.4.0
pip install langchain-openai==1.6.1
bash
pip install langchain==1.4.0
pip install langchain-openai==1.6.1
【强调】:无特别说明后面示例代码都是在:Windows10\11平台、
Python3.12或以上、langchain==1.4.0、langchain-openai==1.6.1环境中运行。
2.【LangChain 关键对象--提示词模板】
(1)LangChain 的提示词模板引擎(Prompt Template Engine)是其核心组件之一,主要用于构建和管理与大语言模型(LLM)交互的提示词(Prompt)。
(2)它的作用是将用户的输入或 动态数据 结构化地嵌入到预定义的模板中,从而生成适合模型处理的提示词,提升模型输出的准确性和一致性。
3.【模板的核心价值】
(1) 标准化:确保提示结构一致性;
(2) 参数化:动态注入变量,提高复用性;
**(3) 可维护:集中管理提示逻辑。
4. 【提示模板分类】
(1)PromptTemplate:最基础的模板,用于将变量填入一个字符串模板中,生成给 LLM 的输入。
(2)ChatPromptTemplate:专为聊天模型设计,支持多轮对话结构,包含不同角色的消息。
# 组成:
# SystemMessagePromptTemplate: 设定系统角色(如"你是一个翻译助手")
# HumanMessagePromptTemplate: 用户输入
# AIMessagePromptTemplate: AI 的历史回复(用于上下文)
# ChatMessagePromptTemplate: 通用角色消息(可自定义角色名
(3)FewShotPromptTemplate: 通过提供少量示例来引导模型行为,常用于提升模型在特定任务上的表现。**
5.【选择模板策略】
|--------------|---------------------------|---------------|---------------|
| Agent类型 | 推荐模板 | 关键特性 | 适用场景 |
| 任务型Agent | PromptTemplate | 结构固定,参数明确 | 数据提取、格式转换 |
| 对话型Agent | ChatPromptTemplate | 多轮对话,角色扮演 | 客服、角色扮演聊天 |
| 推理型Agent | FewShotPromptTemplate | 示例驱动,类比推理 | 逻辑推理、代码生成 |
三、【分步执行 与 链式执行(LCEL)】
LangChain 的发展史中经历了一次重要的编程范式变革:从早期基于 传统 Chain 类(如 LLMChain、SimpleSequentialChain、SequentialChain)分步调用的命令式写法,演进到 2023 年 8 月推出的 LCEL(LangChain Expression Language) 声明式链式写法。
1.【 PromptTemplate 模板 与 分步执行】:显式调用每个组件,自己管理数据流转
【PromptTemplate 模板写法1与format方式填充变量 --示例展示1(分步执行)】
示例里面有更详细的讲解和注释,且可直接复制运行。
python
# 从 langchain_openai 库导入 ChatOpenAI 类
# 这是 LangChain 对 OpenAI 兼容 API 的封装,提供了统一的聊天模型接口
# 它内部仍然依赖 openai 库来发送实际的 HTTP 请求
from langchain_core.prompts import PromptTemplate
# 导入 os 模块,用于读取系统环境变量
from langchain_openai import ChatOpenAI
# 从 python-dotenv 库导入 load_dotenv 函数
# 该函数的作用是将项目根目录下 .env 文件中定义的键值对加载到系统环境变量中
import os
from dotenv import load_dotenv
# 加载 .env 文件中的环境变量
load_dotenv()
# 从环境变量中读取阿里云百炼平台的 API 地址
# os.getenv("ALI_URL") 会查找名为 "ALI_URL" 的环境变量,
# 如果找不到则返回 None。这里对应 .env 文件中配置的 base_url
url = os.getenv("ALI_URL")
# 从环境变量中读取 API 密钥
# 这是调用大模型接口时的身份认证凭证,
# 通常以 "sk-xxx" 格式存在,绝不能硬编码在代码中
key = os.getenv("API_KEY")
# 实例化 ChatOpenAI 对象,配置大语言模型的各项参数
llm = ChatOpenAI(
# model:指定要使用的模型名称
# 这里使用的是通义千问的 qwen3.8-max 模型
model="qwen3.8-max",
# base_url:指定 API 的基础地址
# 因为通义千问兼容 OpenAI 的 API 格式,
# 所以可以通过修改 base_url 将请求转发到阿里云的接口
base_url=url,
# api_key:传入 API 密钥,用于身份认证
api_key=key,
# temperature:控制模型输出的随机性/创造性
# 取值范围通常为 0~2,值越大输出越随机多样,值越小输出越确定保守
# 设为 1 表示使用默认的随机程度
temperature=1,
# streaming:是否开启流式输出
# 设为 True 后,模型不会等全部生成完毕再返回,
# 而是每生成一小段文本就立即推送一个 chunk,
# 这是实现"打字机效果"(逐字显示)的前提条件
streaming=True,
# extra_body:向 API 请求体中注入额外的自定义参数
# 这些参数会被直接附加到发送给模型的 HTTP 请求体中
extra_body={
# thinking:开启模型的"思考"能力(思维链推理)
# {"type": "enabled"} 表示启用深度思考模式,
# 模型在生成最终回答前会先进行内部推理
"thinking": {"type": "enabled"},
# search:开启联网搜索能力
# {"type": "enabled"} 表示允许模型在回答时调用搜索引擎,
# 获取最新的实时信息来辅助回答
"search": {"type": "enabled"},
},
)
# # 定义模板
template = '你是一个{role},请用{style}风格回答问题:{question}'
# # 创建对象构造模板时直接把参数写好。【input_variables 不是强约束参数,少写不影响后面。主要为了方便维护,要保持一致。】
prompt_template = PromptTemplate(template=template, input_variables=["role", "style", "question"])
# # 创建对象构造模板时用【from_template方法】也可实现与上述一模一样的功能
# prompt_template = PromptTemplate.from_template(template)
# # 填充变量【format】方式,传入类型为字符型的函数参数(参数名称与上面自定义动态变量名称一致)
filled_format = prompt_template.format(role='金融分析师', style='通俗易懂', question='今天A股市场的热点是什么?')
print("format填充的效果:", filled_format, "\n", "format填充的类型", type(filled_format))
# # 调用模型
response = llm.invoke(filled_format) # 传递字符串而非对象
print("=====【format】方式填充的输出======", "\n", response.content)
【PromptTemplate 模板写法2与invoke方式填充变量--示例展示2(分步执行)】
示例里面有更详细的讲解和注释,且可直接复制运行。
python
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
import os
from dotenv import load_dotenv
# 加载 .env 文件中的环境变量
load_dotenv()
# 从环境变量中读取阿里云百炼平台的 API 地址
# os.getenv("ALI_URL") 会查找名为 "ALI_URL" 的环境变量,
# 如果找不到则返回 None。这里对应 .env 文件中配置的 base_url
url = os.getenv("ALI_URL")
# 从环境变量中读取 API 密钥
# 这是调用大模型接口时的身份认证凭证,
# 通常以 "sk-xxx" 格式存在,绝不能硬编码在代码中
key = os.getenv("API_KEY")
# 实例化 ChatOpenAI 对象,配置大语言模型的各项参数
llm = ChatOpenAI(
# model:指定要使用的模型名称
# 这里使用的是通义千问的 qwen3.8-max 模型
model="qwen3.8-max",
# base_url:指定 API 的基础地址
# 因为通义千问兼容 OpenAI 的 API 格式,
# 所以可以通过修改 base_url 将请求转发到阿里云的接口
base_url=url,
# api_key:传入 API 密钥,用于身份认证
api_key=key,
# temperature:控制模型输出的随机性/创造性
# 取值范围通常为 0~2,值越大输出越随机多样,值越小输出越确定保守
# 设为 1 表示使用默认的随机程度
temperature=1,
# streaming:是否开启流式输出
# 设为 True 后,模型不会等全部生成完毕再返回,
# 而是每生成一小段文本就立即推送一个 chunk,
# 这是实现"打字机效果"(逐字显示)的前提条件
streaming=True,
# extra_body:向 API 请求体中注入额外的自定义参数
# 这些参数会被直接附加到发送给模型的 HTTP 请求体中
extra_body={
# thinking:开启模型的"思考"能力(思维链推理)
# {"type": "enabled"} 表示启用深度思考模式,
# 模型在生成最终回答前会先进行内部推理
"thinking": {"type": "enabled"},
# search:开启联网搜索能力
# {"type": "enabled"} 表示允许模型在回答时调用搜索引擎,
# 获取最新的实时信息来辅助回答
"search": {"type": "enabled"},
},
)
# # 定义模板
template = '你是一个{role},请用{style}风格回答问题:{question}'
# # 创建对象构造模板时直接把参数写好。【input_variables 不是强约束参数,少写不影响后面。主要为了方便维护,要保持一致。】
prompt_template = PromptTemplate(template=template, input_variables=["role", "style", "question"])
# # 填充变量【invoke】方式,传类型为字典型(字典中的"键key"为自定义动态变量名称一致)
filled_invoke = prompt_template.invoke({'role': '金融分析师', 'style': '通俗易懂', 'question': '今天A股市场的热点是什么?'})
print("invoke填充的效果:", filled_invoke, "\n", "invoke填充的类型", type(filled_invoke))
# # 调用模型
response = llm.invoke(filled_invoke) # 传递字符串而非对象
print("=====【invoke】方式填充的输出======", "\n", response.content)
【PromptTemplate 模板写法3--示例展示3(分步执行)】
示例里面有更详细的讲解和注释,且可直接复制运行。
python
# 从 langchain_openai 库导入 ChatOpenAI 类
# 这是 LangChain 对 OpenAI 兼容 API 的封装,提供了统一的聊天模型接口
# 它内部仍然依赖 openai 库来发送实际的 HTTP 请求
from langchain_core.prompts import PromptTemplate
# 导入 os 模块,用于读取系统环境变量
from langchain_openai import ChatOpenAI
# 从 python-dotenv 库导入 load_dotenv 函数
# 该函数的作用是将项目根目录下 .env 文件中定义的键值对加载到系统环境变量中
import os
from dotenv import load_dotenv
# 执行加载操作,将 .env 文件中的变量(如 API_KEY)注入到当前进程的环境变量中
# 如果 .env 文件不存在或没有对应变量,后续 os.getenv() 将返回 None
load_dotenv()
# 从环境变量中安全地获取名为 "API_KEY" 的值
# 这种写法避免了在代码中硬编码密钥,是生产环境推荐的安全实践
key = os.getenv("API_KEY")
# 定义阿里云百炼平台提供的 OpenAI 兼容接口地址
# 通义千问系列模型通过这个端点对外提供服务
url = os.getenv("ALI_URL")
# 实例化 ChatOpenAI 对象,配置大语言模型的各项参数
llm = ChatOpenAI(
# model:指定要使用的模型名称
# 这里使用的是通义千问的 qwen3.8-max 模型
model="qwen3.8-max",
# base_url:指定 API 的基础地址
# 因为通义千问兼容 OpenAI 的 API 格式,
# 所以可以通过修改 base_url 将请求转发到阿里云的接口
base_url=url,
# api_key:传入 API 密钥,用于身份认证
api_key=key,
# temperature:控制模型输出的随机性/创造性
# 取值范围通常为 0~2,值越大输出越随机多样,值越小输出越确定保守
# 设为 1 表示使用默认的随机程度
temperature=1,
# streaming:是否开启流式输出
# 设为 True 后,模型不会等全部生成完毕再返回,
# 而是每生成一小段文本就立即推送一个 chunk,
# 这是实现"打字机效果"(逐字显示)的前提条件
streaming=True,
# extra_body:向 API 请求体中注入额外的自定义参数
# 这些参数会被直接附加到发送给模型的 HTTP 请求体中
extra_body={
# thinking:开启模型的"思考"能力(思维链推理)
# {"type": "enabled"} 表示启用深度思考模式,
# 模型在生成最终回答前会先进行内部推理
"thinking": {"type": "enabled"},
# search:开启联网搜索能力
# {"type": "enabled"} 表示允许模型在回答时调用搜索引擎,
# 获取最新的实时信息来辅助回答
"search": {"type": "enabled"},
},
)
# # 创建对象构造模板时直接把参数写好。
prompt_template = PromptTemplate(
template = '你是一个{role},请用{style}风格回答问题:{question}',
input_variables = ["role", "style", "question"],
partial_variables = {'role': '金融分析师', 'style': '通俗易懂'} # 字典类型,用于预设模板中部分 变量的固定值。这些变量在后续调用时 无需重复传入
)
# # 创建对象构造模板时用【partial方法】也可实现与上述一模一样的功能
# prompt_template = PromptTemplate(
# template = '你是一个{role},请用{style}风格回答问题:{question}',
# input_variables = ["role", "style", "question"],
# )
# prompt = PromptTemplate.partial(role = '金融分析师', style = '通俗易懂')
# # 填充变量【format】方式,传入类型为字符型的函数参数(参数名称与上面自定义动态变量名称一致)
filled_format = prompt_template.format(question='今天A股市场的热点是什么?')
print("format填充的效果:", filled_format, "\n", "format填充的类型", type(filled_format))
# # 调用模型
response = llm.invoke(filled_format) # 传递字符串而非对象
print("=====【format】方式填充的输出======", "\n", response.content)
【PromptTemplate 模板 与 分步执行--示例展示3】
示例里面有更详细的讲解和注释,且可直接复制运行。
python
# 从 langchain_openai 库导入 ChatOpenAI 类
# 这是 LangChain 对 OpenAI 兼容 API 的封装,提供了统一的聊天模型接口
# 它内部仍然依赖 openai 库来发送实际的 HTTP 请求
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
# 导入 os 模块,用于读取系统环境变量
import re
# 从 python-dotenv 库导入 load_dotenv 函数
# 该函数的作用是将项目根目录下 .env 文件中定义的键值对加载到系统环境变量中
import os
from dotenv import load_dotenv
# 执行加载操作,将 .env 文件中的变量(如 API_KEY)注入到当前进程的环境变量中
# 如果 .env 文件不存在或没有对应变量,后续 os.getenv() 将返回 None
load_dotenv()
# 从环境变量中安全地获取名为 "API_KEY" 的值
# 这种写法避免了在代码中硬编码密钥,是生产环境推荐的安全实践
key = os.getenv("API_KEY")
# 定义阿里云百炼平台提供的 OpenAI 兼容接口地址
# 通义千问系列模型通过这个端点对外提供服务
url = os.getenv("ALI_URL")
# 实例化 ChatOpenAI 对象,配置大语言模型的各项参数
llm = ChatOpenAI(
# model:指定要使用的模型名称
# 这里使用的是通义千问的 qwen3.8-max 模型
model="qwen3.8-max",
# base_url:指定 API 的基础地址
# 因为通义千问兼容 OpenAI 的 API 格式,
# 所以可以通过修改 base_url 将请求转发到阿里云的接口
base_url=url,
# api_key:传入 API 密钥,用于身份认证
api_key=key,
# temperature:控制模型输出的随机性/创造性
# 取值范围通常为 0~2,值越大输出越随机多样,值越小输出越确定保守
# 设为 1 表示使用默认的随机程度
temperature=1,
# streaming:是否开启流式输出
# 设为 True 后,模型不会等全部生成完毕再返回,
# 而是每生成一小段文本就立即推送一个 chunk,
# 这是实现"打字机效果"(逐字显示)的前提条件
streaming=True,
# extra_body:向 API 请求体中注入额外的自定义参数
# 这些参数会被直接附加到发送给模型的 HTTP 请求体中
extra_body={
# thinking:开启模型的"思考"能力(思维链推理)
# {"type": "enabled"} 表示启用深度思考模式,
# 模型在生成最终回答前会先进行内部推理
"thinking": {"type": "enabled"},
# search:开启联网搜索能力
# {"type": "enabled"} 表示允许模型在回答时调用搜索引擎,
# 获取最新的实时信息来辅助回答
"search": {"type": "enabled"},
},
)
# # 定义模板
template = '''你是一个{role},请分析在A股上市的{share}最新{question},要求从以下维度进行分析:
1.研发投入与创新(占25%权重):研发费用占比、专利数、新产品收入占比;
2.未来增长潜力(占8%权重):产能扩张、新市场布局、战略投资、数字化转型;
3.财务表现(占15%权重):营收、净利润、ROE、毛利率、净利率;
4.负债与偿债(占5%权重):资产负债率、流动比率、利息保障倍数;
5.行业地位与竞争力(占15%权重):市场份额、客户集中度、技术壁垒、品牌影响力;
6.管理与治理(占10%权重):管理层稳定性、股权激励、董事会独立性;
7.行业前景与政策(占10%权重):行业增长率、政策支持/限制、宏观环境;
8.盈利质量(占5%权重):净利润现金含量、非经常性损益占比;
9.国际化能力(占5%权重):海外营收、国际化程度;
10.其它(占2%权重):风险因素、ESG表现;
11.以上每项都是100分制;
12.总综合评分计算方法:总综合评分=研发投入与创新得分*0.25 + 未来增长潜力得分*0.08 + 财务表现得分*0.15 + 负债与偿债得分*0.05 + 行业地位与竞争力得分*0.15 + 管理与治理得分*0.1 + 行业前景与政策*0.1 + 盈利质量得分*0.05 + 国际化能力得分*0.05 + 其它得分*0.02;
13.把总综合用评分用【综合评分:XXX分】的方式输出。'''
# # 创建模板对象
prompt_template = PromptTemplate.from_template(template)
# # 填充变量【invoke】方式
filled_prompt1 = prompt_template.invoke({'role': '资深证券分析师', 'share': '股票名称', 'question': '财报'})
# # 调用模型
response1 = llm.invoke(filled_prompt1) # 传递字符串而非对象
text = response1.content
print(text)
pattern = r"综合评分:(\d+\.?\d*)分" # 匹配整数或小数
matches = re.findall(pattern, text)
print("匹配到的数字:", matches)
**2.【 PromptTemplate 模板 与 链式执行(LCEL)】
LCEL 是一种声明式语法,其设计基石是统一的 Runnable 接口。LangChain 中所有组件------提示模板、模型、输出解析器、检索器、工具、自定义函数------都实现了 Runnable 接口,因而都拥有统一的调用方法。**组件之间用 管道操作符 |(借鉴 Unix 管道思想)串联,前一个组件的输出自动作为后一个组件的输入。
【LCEL 的优势】
**(1)****语法简洁:****一行 prompt | llm | parser 即可表达完整数据流,取代了大段类实例化代码。
(2)****原生流式输出:****链可以边计算边把 token 推给下游,chain.stream() 开箱即用。
(3)****原生异步支持:****ainvoke/astream/abatch 直接可用,适合高并发。
(4)****自动并行执行:****RunnableParallel 让多分支任务并行运行,显著降低延迟。
(5)****统一接口、灵活路由:****所有组件调用方式一致,支持条件分支、动态逻辑、容错降级。
(6)**免费获得生产级特性:
自动接入 LangSmith 追踪调试;
回调系统(Callbacks)广播每一步执行,便于日志与 token 统计;
自动重试、with_fallbacks 降级;
部署为 API(LangServe)时无需改动代码。
可视化:chain.get_graph().print_ascii() 可图形化打印链结构。
【LCEL 的劣势】
**(1)****复杂控制流表达吃力:****LCEL 适合线性/分支/并行的 DAG 式流程,但面对循环、回溯、重试跳出、人工审批、多 Agent 协作等复杂状态机式控制流时仍力不从心------这正是官方推出 LangGraph(Graph是指图) 的原因;
(2)****调试细节:**传统的 set_verbose(True) 在 LCEL 中不再如预期工作,需改用回调处理器(如 ConsoleCallbackHandler)查看中间步骤。
**============================================================
最基础的 LCEL 链示例(Prompt → Model → Parser)
对应 LCEL 三个核心组件:提示模板 → 调用大模型 → 格式化输出
用 | 管道符将三个组件串联成一条完整的处理流水线
============================================================**
示例里面有更详细的讲解和注释,且可直接复制运行。
python
# ---------- 第一步:导入所需的库 ----------
# 从 langchain_openai 库导入 ChatOpenAI 类
from langchain_openai import ChatOpenAI
# # 新的导入方式
# from langchain_alibaba import ChatTongyi
# 从 langchain_core 导入聊天提示模板类
# ChatPromptTemplate 用于定义结构化的聊天提示,
# 支持 system / human / ai 等不同角色的消息模板
from langchain_core.prompts import PromptTemplate
# 从 langchain_core 导入字符串输出解析器
# StrOutputParser 的作用是将模型返回的原始消息对象(AIMessage)
# 提取为纯字符串,方便后续直接使用
from langchain_core.output_parsers import StrOutputParser
# 导入 os 模块,用于读取系统环境变量
import os
# 导入 python-dotenv 库的 load_dotenv 函数
# 它的作用是加载 .env 文件中的键值对到系统环境变量中,
# 避免在代码中硬编码 API 密钥等敏感信息
from dotenv import load_dotenv
# ---------- 第二步:加载环境变量,获取 API 密钥 ----------
# 执行加载操作,将 .env 文件中的变量(如 API_KEY)注入到当前进程的环境变量中
# 如果 .env 文件不存在或没有对应变量,后续 os.getenv() 将返回 None
load_dotenv()
# 从环境变量中安全地获取名为 "API_KEY" 的值
# 这种写法避免了在代码中硬编码密钥,是生产环境推荐的安全实践
key = os.getenv("API_KEY")
# 定义阿里云百炼平台提供的 OpenAI 兼容接口地址
# 通义千问系列模型通过这个端点对外提供服务
url = os.getenv("ALI_URL")
# ---------- 第三步:设置模型 ----------
# 实例化 ChatOpenAI 对象,配置大语言模型的各项参数
llm = ChatOpenAI(
# model:指定要使用的模型名称
# 这里使用的是通义千问的 qwen3.8-max 模型
model="qwen3.8-max",
# base_url:指定 API 的基础地址
# 因为通义千问兼容 OpenAI 的 API 格式,
# 所以可以通过修改 base_url 将请求转发到阿里云的接口
base_url=url,
# api_key:传入 API 密钥,用于身份认证
api_key=key,
# temperature:控制模型输出的随机性/创造性
# 取值范围通常为 0~2,值越大输出越随机多样,值越小输出越确定保守
# 设为 1 表示使用默认的随机程度
temperature=1,
# streaming:是否开启流式输出
# 设为 True 后,模型不会等全部生成完毕再返回,
# 而是每生成一小段文本就立即推送一个 chunk,
# 这是实现"打字机效果"(逐字显示)的前提条件
streaming=True,
# extra_body:向 API 请求体中注入额外的自定义参数
# 这些参数会被直接附加到发送给模型的 HTTP 请求体中
extra_body={
# thinking:开启模型的"思考"能力(思维链推理)
# {"type": "enabled"} 表示启用深度思考模式,
# 模型在生成最终回答前会先进行内部推理
"thinking": {"type": "enabled"},
# search:开启联网搜索能力
# {"type": "enabled"} 表示允许模型在回答时调用搜索引擎,
# 获取最新的实时信息来辅助回答
"search": {"type": "enabled"},
},
)
# ---------- 第四步:定义链的三个核心组件 ----------
# 【组件1】定义提示模板(Prompt)
# from_template 方法接收一个字符串模板,其中 {user_input} 是占位符变量
# 运行时,invoke 传入的字典 {"user_input": "人工智能"} 会自动替换该占位符
# 最终生成类似 "用一句话介绍人工智能" 的完整提示,发送给模型
prompt = PromptTemplate.from_template("用一句话介绍{user_input}")
# 填充变量【invoke】方式
# 输入 {"user_input": "人工智能"}将占位符替换,生成完整提示
filled_prompt = prompt.invoke({"user_input": "人工智能"})
# 【组件2】定义输出解析器(Parser)
# StrOutputParser 会将模型返回的 AIMessage 对象中的 content 字段提取出来
# 例如模型返回 AIMessage(content="人工智能是...") → 解析后得到纯字符串 "人工智能是..."
parser = StrOutputParser()
# ---------- 第五步:用管道符 | 将三个组件串联成链 ----------
# | 是 LCEL 的核心语法,等价于"把左边的输出作为右边的输入"
# 执行流程:
# → prompt 生成完整提示
# → llm 接收提示,调用通义千问 API 进行推理
# → parser 提取模型返回的纯文本内容
# → 最终返回一个字符串
chain = prompt | llm | parser
# ---------- 第六步:调用链并输出结果 ----------
# invoke() 是 LCEL 链的统一调用方法(同步、单条)
result = chain.invoke(filled_prompt)
# 打印最终结果(此时 result 已经是纯字符串)
print(result)