目录

  1. Model I/O 体系总览
  2. 模型初始化
  3. 消息类型
  4. 四种调用方式
  5. 多平台接入实战
  6. 高级主题
  7. 知识点总览

1. Model I/O 体系总览

LangChain 的 Model I/O 模块是整个框架的骨架,把和大语言模型交互拆成三个清晰的步骤:

Prompts (构造提示词) --> Models (调用模型) --> Output Parsers (解析输出)

// 其实 Model I/O 这个命名很直觉:输入(I)是 Prompts,处理(O)是 Models,再输出(I)给 Parsers。但这个 I/O 更像是管道的上下游,不是传统意义上的设备 I/O。

[Prompts] --输入--> [Models] --输出--> [Output Parsers]
   提示词构造          模型调用           输出解析

2. 模型初始化

2.1 统一入口: init_chat_model

LangChain 提供了一个统一初始化函数,不管用什么模型,一个函数搞定:

from langchain.chat_models import init_chat_model

llm = init_chat_model("gpt-4o-mini", model_provider="openai")
response = llm.invoke("Hello!")
print(response.content)

支持的 provider 包括 openaianthropicgoogle_genai 等。

注意: init_chat_model 是 LangChain 核心包自带的,但如果要用特定 provider,还是需要安装对应的包。比如 OpenAI 需要 pip install langchain-openai

2.2 两种初始化路径对比

方式 优点 缺点 适用场景
init_chat_model 统一入口,切换模型只需改两个参数 需要多装 provider 包 频繁切换模型
Provider 类 (ChatOpenAI) 直接、细粒度配置 代码与 provider 耦合 只用一种模型

2.3 关键参数一览

Parameter Type Description Example
model str 模型名称 "gpt-4o-mini"
model_provider str 提供商 "openai", "anthropic"
temperature float 随机性控制 (0-2) 0 = 确定性输出
api_key str API 密钥 (也可用环境变量) 推荐用 .env 文件
base_url str 自定义 API 端点 代理 / 兼容平台

TODO: 实际项目中 API Key 千万不要硬编码到代码里!用 python-dotenv 的 .env 文件管理。


3. 消息类型

LangChain 用标准化的消息对象来封装对话内容,一共有 四种核心消息类型

Message Type Role Usage Example
SystemMessage 系统 设定模型角色和行为规则 “你是一个翻译助手”
HumanMessage 用户 用户的实际输入 “翻译:Hello World”
AIMessage AI 模型的回复(可用于多轮对话上下文) “你好世界”
ToolMessage 工具 Agent 调用外部工具后的返回结果 { "result": 42 }
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage

messages = [
    SystemMessage(content="你是一个 Python 教学助手,用简洁的方式回答"),
    HumanMessage(content="什么是装饰器?"),
]

response = llm.invoke(messages)
print(response.content)

// 留意:AIMessage 不只是用来"展示"模型回复的。在多轮对话中,你需要把之前的 AI 回复也塞进 messages 列表里,模型才知道上下文。这和 OpenAI API 的 messages 数组是一样的逻辑。

消息传递的两种写法

# 方式1: Messages 列表 (推荐)
llm.invoke([
    SystemMessage("..."),
    HumanMessage("...")
])

# 方式2: 字符串快捷方式
# LangChain 会自动包装成 HumanMessage
llm.invoke("直接传字符串")

4. 四种调用方式

LangChain 提供了 四种调用模式,覆盖同步、异步、流式、批量四大场景。

4.1 invoke – 同步调用 (最常用)

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o-mini")
response = llm.invoke("用一句话解释什么是量子计算")
print(response.content)

Tip: 同步 = 发出请求后代码会阻塞等待,直到模型返回结果才继续执行下一行。适合脚本、命令行工具等简单场景。

4.2 ainvoke – 异步调用

import asyncio
from langchain_openai import ChatOpenAI

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

async def main():
    response = await llm.ainvoke("你好")
    print(response.content)

asyncio.run(main())

// Jupyter vs .py 的区别:Jupyter 里已有事件循环,直接 await main();普通 .py 文件需要 asyncio.run(main())。这个坑我踩过不止一次…

4.3 stream – 流式调用 (打字机效果)

def streaming_example():
    llm = ChatOpenAI(model="gpt-4o-mini")
    for chunk in llm.stream("请写一首关于春天的诗"):
        print(chunk.content, end="", flush=True)

flush=True 强制立即输出,不攒缓冲区。这是实现打字机效果的关键。

Advanced: 异步流式事件监听 astream_events 可以捕获更细粒度的事件:on_chat_model_starton_chat_model_streamon_chat_model_end,适合需要精细控制 UI 更新的场景。

4.4 batch – 批次调用

questions = ["什么是Python?", "什么是JavaScript?"]
responses = llm.batch(questions)  # 并行处理

// batch 和手动 for 循环 invoke 的区别:batch 是并行发的,底层用了 asyncio.gather。就像同时下单 5 杯咖啡,谁好了取谁,而不是一杯一杯排队等。

4.5 调用模式速查

Method Async Version Feature Best For
invoke() ainvoke() 单次同步/异步调用 简单脚本、命令行工具
stream() astream() 逐 Token 流式返回 聊天机器人、长文本生成
batch() abatch() 并行批量处理 数据分析、批量内容生成

5. 多平台接入实战

这节最有意思的地方是:凡是兼容 OpenAI 接口格式的平台,都可以直接用 ChatOpenAI,只需要改 base_urlapi_key。这就是标准化接口的威力。

5.1 平台接入一览

Platform Class Model Example Env Variables Note
OpenAI / CloseAI ChatOpenAI gpt-4o-mini OPENAI_API_KEY + OPENAI_BASE_URL CloseAI 完全兼容
DeepSeek ChatOpenAI deepseek-chat DEEPSEEK_API_KEY + DEEPSEEK_BASE_URL 兼容 OpenAI 格式
SiliconFlow ChatOpenAI Qwen/Qwen3-8B SILICONFLOW_API_KEY + SILICONFLOW_BASE_URL 新用户送 2000 万 Token
Anthropic ChatAnthropic claude-sonnet-4 ANTHROPIC_API_KEY 自有 API 格式
Google ChatGoogleGenerativeAI gemini-2.5-flash GOOGLE_API_KEY 自有 API 格式
Ollama (本地) ChatOllama qwen3.5:4b 无需 API Key 适合原型开发和本地测试

5.2 Ollama: 本地模型自由

# 下载并运行模型(首次使用会自动下载)
ollama run qwen3.5:4b
from langchain_ollama import ChatOllama

llm = ChatOllama(model="qwen3.5:4b", base_url="http://localhost:11434")
response = llm.invoke("你好,介绍一下你自己")

Tip: 学习阶段强烈推荐硅基流动 + Qwen3-8B(完全免费),或者本地 Ollama。零成本跑通所有实验。

5.3 不兼容平台用 init_chat_model 统管

llm_openai  = init_chat_model("gpt-4o-mini",
    model_provider="openai", api_key=os.getenv("OPENAI_API_KEY"))
llm_claude = init_chat_model("claude-sonnet-4",
    model_provider="anthropic", api_key=os.getenv("ANTHROPIC_API_KEY"))
llm_gemini = init_chat_model("gemini-2.5-flash",
    model_provider="google_genai", api_key=os.getenv("GEMINI_API_KEY"))

# 调用方式完全一致!
for name, llm in [("OpenAI", llm_openai), ("Claude", llm_claude), ("Gemini", llm_gemini)]:
    response = llm.invoke("用一句话介绍你自己")
    print(f"{name}: {response.content}")

// 这就是 LangChain 设计哲学的核心体现:统一接口,模型无关。切换模型就像换鞋一样简单,你的业务代码完全不用动。


6. 高级主题

6.1 多模态输入 (Vision)

LangChain 支持将图像等多模态数据传给支持视觉的模型。原理是将图片编码为 Base64,然后通过 Data URL 嵌入消息:

import base64
from langchain_core.messages import HumanMessage

with open("image.jpg", "rb") as f:
    image_data = f.read()

base64_string = base64.b64encode(image_data).decode("utf-8")

message = HumanMessage(content=[
    {"type": "text", "text": "描述这张图片"},
    {"type": "image_url",
     "image_url": {"url": f"data:image/jpeg;base64,{base64_string}"}}
])
response = llm.invoke([message])

Base64 编码原理: 将每 3 字节 (24 bit) 切为 4 组 (每组 6 bit),每组映射到 A-Z、a-z、0-9、+、/ 共 64 个可打印字符。末尾不足 3 字节用 = 填充。这样二进制数据就能放进 JSON 文本协议里传输了。

6.2 速率限制 (Rate Limiting)

from langchain_core.rate_limiters import InMemoryRateLimiter

rate_limiter = InMemoryRateLimiter(
    requests_per_second=0.1,   # 10秒1个请求
    check_every_n_seconds=0.1  # 每0.1秒检查一次令牌桶
)
llm = ChatOpenAI(model="gpt-4o-mini", rate_limiter=rate_limiter)

用的是令牌桶算法(Token Bucket)。适合控制调用频率,避免触发 API 的 rate limit 报错。

6.3 Token 使用追踪

from langchain_core.callbacks import get_usage_metadata_callback

llm = ChatOpenAI(model="gpt-4o-mini")
with get_usage_metadata_callback() as cb:
    llm.invoke("你好")
    llm.invoke("再见")
    print(cb.usage_metadata)
    # {'input_tokens': ..., 'output_tokens': ..., 'total_tokens': ...}

6.4 提示词缓存 (Prompt Caching)

这个知识点很多人容易搞混,一定要分清楚两个概念:

Dimension Prompt Caching LLM Cache (本地缓存)
缓存位置 模型服务商的服务器 你本地的内存/磁盘
缓存内容 已计算的提示词中间状态 (KV cache) 完整的"问题->回答"键值对
效果 减少 token 费用和延迟 相同问题完全不调 API
可控性 不能控制 完全可控

OpenAI: 全自动,零配置,自动识别相同前缀并缓存,缓存命中 token 费用减半。

Anthropic: 需要显式标记,通过 AnthropicPromptCachingMiddleware 中间件,缓存命中 token 费用降低 90%。

// 这里的"缓存"发生在模型服务商的服务器上,不是本地硬盘。你的项目目录里不会多出 cache.sqlite 之类的东西。这是个很容易误解的点。


7. 知识点总览

主题 核心 状态
模型输入输出总览 Prompts -> Models -> Output Parsers 已完成
初始化 init_chat_model /provider-specific classes 已完成
消息类型 System / Human / AI / Tool Message 已完成
调用模式 invoke /ainvoke/stream /batch 已完成
平台集成 OpenAI / DeepSeek / Claude / Gemini / Ollama 已完成
高级功能 Multimodal / Rate Limit / Token Tracking / Caching 已完成
输出解析器 Next lecture… 待处理

总结

LangChain Model I/O 的核心设计哲学就是 统一接口,模型无关。不管底层用的是 GPT、Claude、Gemini 还是本地 Ollama,你的调用代码可以做到几乎一模一样。这对于需要做多模型对比、A/B 测试、多租户系统的项目来说,是巨大的优势。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐