LangChain 大模型6大调用指南
目录
消息类型
在 LangChain 中,Message 是大模型对话的基本单元,就像聊天记录里的每一条消息。
三种核心消息类型
| 类型 | 谁说的 | 作用 | 代码示例 |
|---|---|---|---|
| SystemMessage | 系统/开发者 | 给AI定角色、定规则 | SystemMessage(content="你是一个法律助手") |
| HumanMessage | 用户 | 用户的提问 | HumanMessage(content="酒驾了怎么办") |
| AIMessage | AI | AI的回复 | AIMessage(content="非法律问题无可奉告") |
SystemMessage(系统消息)
是什么:定义 AI 的身份、角色和行为规则
SystemMessage(content="你是一个法律助手,只回答法律问题,超出范围的统一回答,非法律问题无可奉告")
就像:给 AI 定了一个"岗位说明书"
HumanMessage(用户消息)
是什么:模拟用户的输入/提问
HumanMessage(content="1+1等于几") # 用户随便输入的内容
就像:用户发给 AI 的每一条消息
AIMessage(AI消息)
是什么 :模拟 AI 的回复
AIMessage(content="非法律问题无可奉告")
就像:AI 回复的每一条消息
为什么要区分消息类型?
多轮对话需要记忆:
# 错误做法:每次只问当前问题
HumanMessage(content="北京人口有多少?")
# 正确做法:带上对话历史
messages = [
SystemMessage(content="你是一个旅游助手"),
HumanMessage(content="北京有什么景点?"), # 第1轮
AIMessage(content="推荐故宫、长城、颐和园"), # AI回答
HumanMessage(content="故宫要门票吗?"), # 第2轮(带上了上文)
]
调用方式
LangChain 提供 6 种 调用大模型的方式,分为 同步 和 异步 两组。
一张图总结
| 文件 | 调用方式 | 关键字 | 特点 |
|---|---|---|---|
| LLM_Invoke.py | 普通调用 | invoke() |
简单直接,等完整响应 |
| LLM_Stream.py | 流式调用 | stream() |
逐字输出,用户体验好 |
| LLM_Batch.py | 批量调用 | batch() |
一次多问,节省时间 |
| LLM_aInvoke.py | 异步调用 | ainvoke() |
非阻塞,适合Web服务 |
| LLM_aStream.py | 异步流式 | astream() |
高效流式 |
| LLM_aBatch.py | 异步批量 | abatch() |
高并发 |
同步调用
1. 普通调用 - LLM_Invoke.py
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage, SystemMessage
import os
from dotenv import load_dotenv
load_dotenv(encoding='utf-8')
# 初始化模型
model = init_chat_model(
model="qwen-plus",
model_provider="openai",
api_key=os.getenv("aliQwen-api"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
# 构建消息列表
messages = [
SystemMessage(content="你是一个法律助手,只回答法律问题,超出范围的统一回答,非法律问题无可奉告"),
HumanMessage(content="酒驾了怎么办")
]
# 调用模型
response = model.invoke(messages)
print(response.content)
特点 :等模型完全回答完后才返回,速度较慢但稳定
2. 流式调用 - LLM_Stream.py
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage, SystemMessage
import os
from dotenv import load_dotenv
load_dotenv()
model = init_chat_model(
model="qwen-plus",
model_provider="openai",
api_key=os.getenv("aliQwen-api"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
messages = [
SystemMessage(content="你叫小问,是一个乐于助人的AI人工助手"),
HumanMessage(content="你是谁")
]
# 流式调用
response = model.stream(messages)
for chunk in response:
print(chunk.content, end="", flush=True) # 逐字输出
特点:
-
一个字一个字往外蹦
-
用户体验好,像打字机
-
需要用
flush=True刷新缓冲区实现即时输出
3. 批量调用 - LLM_Batch.py
from langchain.chat_models import init_chat_model
import os
from dotenv import load_dotenv
load_dotenv()
model = init_chat_model(
model="qwen-plus",
model_provider="openai",
api_key=os.getenv("aliQwen-api"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
# 问题列表
questions = [
"什么是redis?简洁回答,字数控制在100以内",
"Python的生成器是做什么的?简洁回答,字数控制在100以内",
"解释一下Docker和Kubernetes的关系?简洁回答,字数控制在100以内"
]
# 批量调用
response = model.batch(questions)
for q, r in zip(questions, response):
print(f"问题:{q}\n回答:{r.content}\n")
特点:
-
一次发送多个问题
-
节省 API 调用时间
-
返回结果顺序与输入一致
异步调用
异步调用使用 asyncio 库,适合 Web 服务(FastAPI) 和 高并发场景。
4. 异步普通调用 - LLM_aInvoke.py
from langchain.chat_models import init_chat_model
import asyncio
import os
from dotenv import load_dotenv
load_dotenv()
model = init_chat_model(
model="qwen-plus",
model_provider="openai",
api_key=os.getenv("aliQwen-api"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
async def main():
# 异步调用一条请求
response = await model.ainvoke("解释一下LangChain是什么,简洁回答100字以内")
print(response.content)
# 运行异步函数
asyncio.run(main())
核心作用 :让你同时调用多个模型请求而不阻塞主线程 ------ 特别适合大批量请求或 Web 服务场景
5. 异步流式调用 - LLM_aStream.py
from langchain.chat_models import init_chat_model
from langchain.messages import HumanMessage, SystemMessage
import asyncio
import os
from dotenv import load_dotenv
load_dotenv()
model = init_chat_model(
model="qwen-plus",
model_provider="openai",
api_key=os.getenv("aliQwen-api"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
messages = [
SystemMessage(content="你叫小问,是一个乐于助人的AI人工助手"),
HumanMessage(content="你是谁")
]
async def async_stream_call():
# astream 返回异步生成器
response = model.astream(messages)
print(f"响应类型:{type(response)}") # <class 'async_generator'>
# 必须使用 async for 遍历异步生成器
async for chunk in response:
print(chunk.content, end="", flush=True)
asyncio.run(async_stream_call())
关键点:
-
model.astream()返回 异步生成器(async_generator) -
必须用
async for遍历,不能用普通for -
需要
asyncio.run()驱动执行
6. 异步批量调用 - LLM_aBatch.py
from langchain.chat_models import init_chat_model
import asyncio
import os
from dotenv import load_dotenv
load_dotenv()
model = init_chat_model(
model="qwen-plus",
model_provider="openai",
api_key=os.getenv("aliQwen-api"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
questions = [
"什么是redis?简洁回答,字数控制在100以内",
"Python的生成器是做什么的?简洁回答,字数控制在100以内",
"解释一下Docker和Kubernetes的关系?简洁回答,字数控制在100以内"
]
async def async_batch_call():
# 异步批量调用
response = await model.abatch(questions)
for q, r in zip(questions, response):
print(f"问题:{q}\n回答:{r.content}\n")
asyncio.run(async_batch_call())
同步 vs 异步 怎么选?
| 场景 | 推荐 |
|---|---|
| 学习/测试 | 同步(简单易懂) |
| 命令行脚本 | 同步流式(stream) |
| Web 服务(FastAPI) | 异步(ainvoke/astream) |
| 需要同时发多个请求 | 批量(batch/abatch) |
注意事项
1. load_dotenv() 必须放在最前面
# 错误:load_dotenv 被注释
#load_dotenv()
# 正确:放在最前面
load_dotenv(encoding='utf-8')
2. 响应对象没有 content_blocks 属性
# 错误
print(response.content_blocks) # 不存在这个属性
# 正确
print(response.content) # 正确获取回复内容
3. 异步调用必须用 asyncio.run()
# 正确
asyncio.run(async_function())
# 错误
async_function() # 不会执行
完整示例:结合消息模板 + Token计算
from langchain_openai import ChatOpenAI
from langchain.messages import SystemMessage, HumanMessage
import os
from dotenv import load_dotenv
import tiktoken
load_dotenv(encoding='utf-8')
# 初始化模型
llm = ChatOpenAI(
model="qwen-plus",
api_key=os.getenv("aliQwen-api"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
temperature=0.7
)
# 构建消息
messages = [
SystemMessage(content="你是一个幽默的助手"),
HumanMessage(content="给我讲个笑话"),
]
# 流式调用
print("AI:", end="")
full_response = ""
for chunk in llm.stream(messages):
print(chunk.content, end="", flush=True)
full_response += chunk.content
# 计算Token数量
encoding = tiktoken.get_encoding("cl100k_base")
tokens = len(encoding.encode(full_response))
print(f"\n\n回答Token数:{tokens}")