LangChain 调大模型:模板拼接 + invoke / stream / batch

LangChain 调大模型:模板拼接 + invoke / stream / batch

读完你会什么

跟着本文走一遍,你能掌握 LangChain 调大模型的完整链路:

  1. 拼消息 --- 用 ChatPromptTemplate 模板拼接(本文重点,生产最常用
  2. 调模型 --- 用 invoke / stream / batch 三种方式发出请求(日常必会前两个

文末附有完整可运行脚本,复制即可跑通全文示例。

记忆口诀 :先 from_messages 建模板 → format_messages 填变量 → llm.invoke(messages) 调模型。要做聊天 UI 就把 invoke 换成 stream

注意先申请大模型的秘钥和配置环境


一、模板拼接(重点掌握)

为什么要用模板

直接手写 SystemMessage + HumanMessage 能跑,但问题一多、变量一多,字符串拼接很快变得难维护。

模板的做法 :在 Prompt 里留 {变量名} 占位,运行时填值,自动生成消息列表。

python 复制代码
# ❌ 手写拼接:难维护
f"你是{role},请回答:{question}"

# ✅ 模板:结构清晰、可复用
("system", "你是{role}"),
("human", "{question}"),

聊天模型用 ChatPromptTemplate (产出 SystemMessage / HumanMessage 等)。老式纯文本补全的 PromptTemplate 本文不涉及。

标准写法:from_messages + format_messages

日常只用这一套,记住 三步

python 复制代码
import os
from langchain.chat_models import init_chat_model
from langchain_core.prompts import ChatPromptTemplate

os.environ["OPENAI_API_KEY"] = os.getenv("SILICON_KEY")
os.environ["OPENAI_BASE_URL"] = os.getenv("SILICON_BASE_URL")

llm = init_chat_model("openai:deepseek-ai/DeepSeek-V3")

# ① 创建模板
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是{role},回答要简洁"),
    ("human", "{question}"),
])

# ② 填值 → 消息列表
messages = prompt.format_messages(role="数学老师", question="什么是余数?")

# ③ 调模型
answer = llm.invoke(messages)
print(answer.content)

输出(示例,模型每次略有不同):

ini 复制代码
余数是整数除法后剩下的部分。例如 7÷3=2......1,这里的 1 就是余数。
步骤 做什么 产出
from_messages 定义 Prompt 结构 模板对象 prompt
format_messages 填入 {role}{question} 消息列表 messages
llm.invoke 发给大模型 AIMessage 回复

元组第一个位置常用 "system" / "human" / "ai",对应系统指令、用户输入、模型示例回复。

占位符语法同 Python f-string{变量名}。模板里要写 literal 花括号用 {{ / }}
其他模板写法(遇到再查)

写法 适用场景
from_template("{question}") 只有一条 human 消息
MessagesPlaceholder("history") 多轮聊天,历史条数不固定
prompt.partial(role="...") 角色固定,只换 {question}

prompt.invoke({...})format_messages 效果相同,用在chain的链式调用里,后续再说;直接调模型时 format_messages 更直观


二、三种调用方式(总览)

模板拼好 messages 之后,用 llm.xxx(...) 发出。LangChain 提供三种同步调用方式,第一个参数的写法规则相同,区别只在「怎么等结果」。

方法 等什么 返回什么 要不要学
invoke 全文生成完 1 个 AIMessage ⭐ 必学
stream 边生成边返回 多个 AIMessageChunk ⭐ 必学
batch 多个问题并行跑 N 个 AIMessage 特定场景再学
典型场景 用哪个
脚本调试、后端 API、只要最终结果 invoke
Web / App 聊天、打字机效果 stream
批量翻译 / 摘要、离线跑几百条 batch

同一批 messages换方法名即可,输入不用改

python 复制代码
llm.invoke(messages)              # 同步,一次拿全文
llm.stream(messages)              # 流式,边生成边输出
llm.batch([messages1, messages2]) # 批量,两个独立问题

异步版本(FastAPI 等场景,了解即可)

ainvoke / astream / abatch 与上表一一对应,用于 async/await 项目,本文不展开。

第一个参数怎么传

关键区别:invoke / stream 是一维,batch 是二维。

方法 维度 含义
invoke / stream 一维 一个聊天框
batch 二维 多个聊天框,各聊各的
css 复制代码
invoke / stream:  [消息, 消息, 消息]     → 1 条回复
batch:           [[框1...], [框2...], ...]    → N 条回复

一维示例 --- 一个聊天框,消息之间有上下文:

python 复制代码
messages = [
    ("system", "你是数学老师"),
    ("human", "什么是余数?"),
    ("ai", "除法剩下的部分......"),
    ("human", "再举个例子"),
]
llm.invoke(messages)   # 1 个框 → 1 条回复

二维示例 --- 多个聊天框,互不相干:

python 复制代码
llm.batch([
    [("system", "你是诗人"), ("human", "写首诗")],
    [("system", "你是程序员"), ("human", "解释变量")],
    "1+1等于几?",
])
# 3 个框 → 3 条回复
一维参数的五种写法

batch 里每个聊天框也适用以下任意一种。

# 写法 示例 什么时候用
1 字符串 llm.invoke("问题") 调试、单条提问
2 模板填值 llm.invoke(messages) ⭐ 生产默认
3 Message 对象 llm.invoke([SystemMessage(...), HumanMessage(...)]) 封装层、类型要明确
4 元组 llm.invoke([("system", "..."), ("human", "...")]) 和模板风格一致
5 字典 llm.invoke([{"role": "user", "content": "..."}]) 对齐 OpenAI API 格式
python 复制代码
# 1. 字符串 --- 自动当 HumanMessage
llm.invoke("小学生怎么学余数?")

# 2. 模板填值 --- 第一节的标准链路
messages = prompt.format_messages(role="数学老师", question="什么是余数?")
llm.invoke(messages)

# 3. Message 对象 --- 最显式
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
llm.invoke([
    SystemMessage(content="你是数学老师"),
    HumanMessage(content="什么是余数?"),
    AIMessage(content="除法剩下的部分......"),
    HumanMessage(content="再举个例子"),
])

# 4. 元组 --- 和 from_messages 写法一样
llm.invoke([("system", "你是助手"), ("human", "你好")])

# 5. 字典 --- 和 OpenAI JSON 一致
llm.invoke([{"role": "system", "content": "你是助手"}, {"role": "user", "content": "你好"}])

写法 3 / 4 / 5 本质相同,LangChain 都会转成 SystemMessage / HumanMessage / AIMessage新手优先记 1(调试)和 2(生产)。


三、invoke --- 同步拿全文

场景:脚本、后端 API、不需要打字机效果。

python 复制代码
# 最简
llm.invoke("用一句话介绍你自己").content

# 配合模板(推荐)
messages = prompt.format_messages(role="数学老师", question="什么是余数?")
answer = llm.invoke(messages)
print(answer.content)

输出:

shell 复制代码
# 最简 → '我是 DeepSeek,由深度求索打造的 AI 助手......'
# 模板 → '余数是除法运算后剩下的部分,例如 7÷3=2 余 1......'

invoke = 给一个输入,同步等待,返回完整结果。

返回值AIMessage,取文本用 .content

python 复制代码
response = llm.invoke("你好")
response.content            # 回复文本
response.response_metadata  # token 用量等

四、stream --- 流式打字机

场景:Web / App 聊天窗口,边生成边展示。

第一个参数与 invoke 相同(一维、一个聊天框),区别在怎么读返回值

python 复制代码
for chunk in llm.stream("用一句话介绍你自己"):
    print(chunk.content, end="", flush=True)

输出(逐字打印,不换行直到结束):

复制代码
我是 DeepSeek,由深度求索公司打造的 AI 助手,乐意为你解答问题!

配合模板:

python 复制代码
messages = prompt.format_messages(role="数学老师", question="什么是余数?")

for chunk in llm.stream(messages):
    print(chunk.content, end="", flush=True)

输出:

ini 复制代码
余数就是除法里除不尽剩下的那部分。比如 10÷3=3 余 1......

返回值 :每次迭代一个 AIMessageChunk ,同样用 .content 取文本。部分 chunk 可能为空,打印前建议判断:

python 复制代码
full_text = ""
for chunk in llm.stream(messages):
    if chunk.content:
        full_text += chunk.content
        print(chunk.content, end="", flush=True)

五、batch --- 批量多个问题

场景 :批量翻译、批量摘要、离线一次跑很多条。日常开发用得少,需要时再查本节。

第一个参数是二维 的:外层 list 的每个元素 = 一个独立聊天框 = 一次 invoke

python 复制代码
answers = llm.batch([
    "1+1等于几?",
    "北京是哪个国家的首都?",
    "用一句话介绍 Python",
])

for i, ans in enumerate(answers):
    print(f"Q{i + 1}: {ans.content}")

输出:

makefile 复制代码
Q1: 1+1 等于 2。
Q2: 北京是中华人民共和国的首都。
Q3: Python 是一门简洁易读、用途广泛的编程语言。

每个框也可以是一组 messages:

python 复制代码
answers = llm.batch([
    [("system", "你是诗人"), ("human", "写一首短诗")],
    [("system", "你是程序员"), ("human", "解释变量")],
])

配合模板 --- 每个问题各填一次值:

python 复制代码
questions = ["什么是余数?", "什么是分数?", "什么是小数?"]
message_lists = [prompt.format_messages(role="数学老师", question=q) for q in questions]
answers = llm.batch(message_lists)

LangChain 默认用线程池并行 执行,返回 list[AIMessage],顺序与输入一一对应。


小结

scss 复制代码
拼消息(重点)                    调模型(按场景选)
─────────────────                ─────────────────
ChatPromptTemplate               invoke  → 同步,拿全文     ⭐ 必学
  .from_messages([...])          stream  → 流式,打字机     ⭐ 必学
  .format_messages(...)  →       batch   → 批量,多框并行    特定场景
    messages
方法 参数维度 返回 一句话
invoke 一维(一个聊天框) 1 个 AIMessage 等全文,一次拿完
stream 一维(一个聊天框) 多个 AIMessageChunk 边生成边输出
batch 二维(多个聊天框) N 个 AIMessage 多个独立问题并行

新手路径 :先把第一节三步链路跑通 → 会用 invoke → 做聊天 UI 时换 stream → 遇到批处理再看 batch


附录:完整可运行脚本

前文有怎么在系统上配置硅基流动的秘钥和baseUrl

复制保存为 demo.py,配置好环境变量后执行 python demo.py

环境准备 (写入 ~/.zshrc.env):

bash 复制代码
export SILICON_KEY="sk-xxx"
export SILICON_BASE_URL="https://api.siliconflow.cn/v1"

依赖安装

bash 复制代码
pip install langchain langchain-openai

完整代码

python 复制代码
import os
import sys

from langchain.chat_models import init_chat_model
from langchain_core.prompts import ChatPromptTemplate

api_key = os.getenv("SILICON_KEY")
base_url = os.getenv("SILICON_BASE_URL", "https://api.siliconflow.cn/v1")

if not api_key:
    sys.exit("缺少 SILICON_KEY,请配置环境变量")

os.environ["OPENAI_API_KEY"] = api_key
os.environ["OPENAI_BASE_URL"] = base_url

# 本机若开了系统代理,访问国内 API 时建议 trust_env=False

llm = init_chat_model(
    "openai:deepseek-ai/DeepSeek-V3",
)

# ── 1. 模板拼接 + invoke ──
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是{role},回答要简洁"),
    ("human", "{question}"),
])
messages = prompt.format_messages(role="数学老师", question="什么是余数?")

print("【invoke】")
answer = llm.invoke(messages)
print(answer.content)

# ── 2. stream ──
print("\n【stream】")
for chunk in llm.stream("用一句话介绍你自己"):
    print(chunk.content, end="", flush=True)
print()

# ── 3. batch ──
print("\n【batch】")
answers = llm.batch([
    "1+1等于几?",
    "北京是哪个国家的首都?",
])
for i, ans in enumerate(answers):
    print(f"Q{i + 1}: {ans.content}")

运行结果(示例)

ini 复制代码
【invoke】
余数是整数除法后剩下的部分。例如 7÷3=2......1,这里的 1 就是余数。

【stream】
我是 DeepSeek,由深度求索公司打造的 AI 助手,乐意为你解答问题!

【batch】
Q1: 1+1 等于 2。
Q2: 北京是中华人民共和国的首都。

实际输出因模型随机性会略有不同,看到类似结构即表示跑通。

相关推荐
ice8130331811 小时前
【Python】调用opencv识别图片人脸位置
人工智能·python·opencv
Full Stack Developme1 小时前
Hutool CollUtil 教程
java·开发语言·windows·python
2601_950368911 小时前
镁钆稀土合金粉末,专业供应助力精密制造升级
python·制造
染指11101 小时前
19.LangChain框架7-LangChain1.0版本使用Agent(中间件实例)
人工智能·python·机器学习·langchain·agent·rag
装不满的克莱因瓶1 小时前
从梯度下降到 Adam 优化器:掌握神经网络参数优化的核心原理
人工智能·python·深度学习·神经网络·机器学习·计算机视觉·ai
糖果店的幽灵2 小时前
时间序列处理
开发语言·python·pandas
喵叔哟2 小时前
第2周学习笔记
笔记·python·学习·langchain
copyer_xyf2 小时前
Python 迭代器与生成器
前端·后端·python
小小测试开发9 小时前
安装 Python 3.10+
开发语言·人工智能·python