文章目录
- [一、什么是 Model I/O](#一、什么是 Model I/O)
- 二、三种模型类型,别搞混了
- 三、统一接口:写一遍,哪都能跑
- [四、ChatOpenAI 核心参数](#四、ChatOpenAI 核心参数)
-
- [temperature 怎么选?](#temperature 怎么选?)
- [Token 到底是什么?](#Token 到底是什么?)
- [五、四种消息类型 & 三种传入方式](#五、四种消息类型 & 三种传入方式)
- [六、四种调用方式:invoke / ainvoke / stream / batch](#六、四种调用方式:invoke / ainvoke / stream / batch)
-
- [6.1 invoke() --- 同步调用](#6.1 invoke() — 同步调用)
- [6.2 ainvoke() --- 异步调用](#6.2 ainvoke() — 异步调用)
- [6.3 stream() --- 流式输出](#6.3 stream() — 流式输出)
- [6.4 batch() --- 批量调用](#6.4 batch() — 批量调用)
- 七、多平台接入实战
-
- [7.1 兼容 OpenAI 格式的平台](#7.1 兼容 OpenAI 格式的平台)
- [7.2 不兼容 OpenAI 格式的平台](#7.2 不兼容 OpenAI 格式的平台)
- [7.3 各平台速查表](#7.3 各平台速查表)
- 八、本地模型:Ollama
- 九、几个值得了解的高级特性
-
- [9.1 多模态输入](#9.1 多模态输入)
- [9.2 速率限制](#9.2 速率限制)
- [9.3 Token 用量追踪](#9.3 Token 用量追踪)
- [9.4 提示词缓存](#9.4 提示词缓存)
- [9.5 运行时动态切换模型](#9.5 运行时动态切换模型)
- 十、小结
一、什么是 Model I/O
Model I/O 是 LangChain 与大语言模型交互的核心流程。它回答一个最基本的问题:怎么把问题喂给模型,并拿到有用的结果?
整个流程拆成三个环节:
#mermaid-svg-00rQaurS9xBCs7Xk{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-00rQaurS9xBCs7Xk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-00rQaurS9xBCs7Xk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-00rQaurS9xBCs7Xk .error-icon{fill:#552222;}#mermaid-svg-00rQaurS9xBCs7Xk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-00rQaurS9xBCs7Xk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-00rQaurS9xBCs7Xk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-00rQaurS9xBCs7Xk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-00rQaurS9xBCs7Xk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-00rQaurS9xBCs7Xk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-00rQaurS9xBCs7Xk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-00rQaurS9xBCs7Xk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-00rQaurS9xBCs7Xk .marker.cross{stroke:#333333;}#mermaid-svg-00rQaurS9xBCs7Xk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-00rQaurS9xBCs7Xk p{margin:0;}#mermaid-svg-00rQaurS9xBCs7Xk .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-00rQaurS9xBCs7Xk .cluster-label text{fill:#333;}#mermaid-svg-00rQaurS9xBCs7Xk .cluster-label span{color:#333;}#mermaid-svg-00rQaurS9xBCs7Xk .cluster-label span p{background-color:transparent;}#mermaid-svg-00rQaurS9xBCs7Xk .label text,#mermaid-svg-00rQaurS9xBCs7Xk span{fill:#333;color:#333;}#mermaid-svg-00rQaurS9xBCs7Xk .node rect,#mermaid-svg-00rQaurS9xBCs7Xk .node circle,#mermaid-svg-00rQaurS9xBCs7Xk .node ellipse,#mermaid-svg-00rQaurS9xBCs7Xk .node polygon,#mermaid-svg-00rQaurS9xBCs7Xk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-00rQaurS9xBCs7Xk .rough-node .label text,#mermaid-svg-00rQaurS9xBCs7Xk .node .label text,#mermaid-svg-00rQaurS9xBCs7Xk .image-shape .label,#mermaid-svg-00rQaurS9xBCs7Xk .icon-shape .label{text-anchor:middle;}#mermaid-svg-00rQaurS9xBCs7Xk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-00rQaurS9xBCs7Xk .rough-node .label,#mermaid-svg-00rQaurS9xBCs7Xk .node .label,#mermaid-svg-00rQaurS9xBCs7Xk .image-shape .label,#mermaid-svg-00rQaurS9xBCs7Xk .icon-shape .label{text-align:center;}#mermaid-svg-00rQaurS9xBCs7Xk .node.clickable{cursor:pointer;}#mermaid-svg-00rQaurS9xBCs7Xk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-00rQaurS9xBCs7Xk .arrowheadPath{fill:#333333;}#mermaid-svg-00rQaurS9xBCs7Xk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-00rQaurS9xBCs7Xk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-00rQaurS9xBCs7Xk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-00rQaurS9xBCs7Xk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-00rQaurS9xBCs7Xk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-00rQaurS9xBCs7Xk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-00rQaurS9xBCs7Xk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-00rQaurS9xBCs7Xk .cluster text{fill:#333;}#mermaid-svg-00rQaurS9xBCs7Xk .cluster span{color:#333;}#mermaid-svg-00rQaurS9xBCs7Xk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-00rQaurS9xBCs7Xk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-00rQaurS9xBCs7Xk rect.text{fill:none;stroke-width:0;}#mermaid-svg-00rQaurS9xBCs7Xk .icon-shape,#mermaid-svg-00rQaurS9xBCs7Xk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-00rQaurS9xBCs7Xk .icon-shape p,#mermaid-svg-00rQaurS9xBCs7Xk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-00rQaurS9xBCs7Xk .icon-shape .label rect,#mermaid-svg-00rQaurS9xBCs7Xk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-00rQaurS9xBCs7Xk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-00rQaurS9xBCs7Xk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-00rQaurS9xBCs7Xk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 格式化消息
统一接口调用
文本→JSON/Pydantic
你的问题
Prompts
提示词模板
Models
模型调用
Output Parsers
输出解析
结构化结果
- Prompts:把用户输入和系统指令格式化成模型能理解的消息
- Models:统一接口调用不同平台的模型(OpenAI、DeepSeek、本地模型等)
- Output Parsers:把模型返回的文本转换为 JSON、Pydantic 对象等结构化数据
本文聚焦中间环节------Models(模型调用)。
二、三种模型类型,别搞混了
LangChain 把模型分成了三类,命名很容易让人糊涂,先理清楚:
| 类型 | 输入 → 输出 | 代表类 | 现状 |
|---|---|---|---|
| Chat Models(对话型) | 消息列表 → AI 消息 | ChatOpenAI、ChatAnthropic、ChatOllama |
当前主流,GPT-4o、Claude、DeepSeek 都走这个 |
| LLMs(补全型) | 字符串 → 字符串 | OpenAI(旧版) |
基本淘汰,GPT-3 时代的 text-davinci 遗留产物 |
| Embeddings(向量型) | 文本 → 浮点数向量 | OpenAIEmbeddings |
不生成文本,专用于语义搜索和 RAG |
结论:除非特别说明,"模型调用"都是指 Chat Models。LLMs 这个遗留接口可以无视。
Chat Models 的核心设计理念是:输入是一组消息(有角色、有上下文),输出也是一个有角色标注的消息对象。这和直接 requests.post 拿回一段裸文本有本质区别------消息对象携带了角色信息、token 用量、模型名称等元数据,后续链路里的 Agent、Memory、Tools 都会用到这些信息。
三、统一接口:写一遍,哪都能跑
LangChain 的 Models 层最大的价值不是"帮你调 API",而是"让你不用关心调的是谁的 API"。
python
# 不同平台,同一个调用姿势
llm = ChatOpenAI(model="gpt-4o-mini") # OpenAI
llm = ChatOpenAI(model="deepseek-chat", ...) # DeepSeek
llm = ChatAnthropic(model="claude-sonnet-4-20250514") # Anthropic
llm = ChatOllama(model="qwen2.5:7b") # 本地模型
# 以下调用方式全部通用
response = llm.invoke("你好") # 同步调用
response = await llm.ainvoke("你好") # 异步调用
for chunk in llm.stream("你好"): # 流式输出
print(chunk.content, end="")
responses = llm.batch(["问题1", "问题2"]) # 批量调用
原生 SDK 的世界里,从 OpenAI 换到 Anthropic 意味着从 client.chat.completions.create() 变成 client.messages.create(),取结果从 .choices[0].message.content 变成 .content[0].text。每换一个平台,重写一遍取值逻辑。LangChain 把这些差异全部封装了进去,你只需要换一行初始化。
#mermaid-svg-5CnECrMEt8NrG6qo{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5CnECrMEt8NrG6qo .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5CnECrMEt8NrG6qo .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5CnECrMEt8NrG6qo .error-icon{fill:#552222;}#mermaid-svg-5CnECrMEt8NrG6qo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5CnECrMEt8NrG6qo .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5CnECrMEt8NrG6qo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5CnECrMEt8NrG6qo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5CnECrMEt8NrG6qo .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5CnECrMEt8NrG6qo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5CnECrMEt8NrG6qo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5CnECrMEt8NrG6qo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5CnECrMEt8NrG6qo .marker.cross{stroke:#333333;}#mermaid-svg-5CnECrMEt8NrG6qo svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5CnECrMEt8NrG6qo p{margin:0;}#mermaid-svg-5CnECrMEt8NrG6qo .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5CnECrMEt8NrG6qo .cluster-label text{fill:#333;}#mermaid-svg-5CnECrMEt8NrG6qo .cluster-label span{color:#333;}#mermaid-svg-5CnECrMEt8NrG6qo .cluster-label span p{background-color:transparent;}#mermaid-svg-5CnECrMEt8NrG6qo .label text,#mermaid-svg-5CnECrMEt8NrG6qo span{fill:#333;color:#333;}#mermaid-svg-5CnECrMEt8NrG6qo .node rect,#mermaid-svg-5CnECrMEt8NrG6qo .node circle,#mermaid-svg-5CnECrMEt8NrG6qo .node ellipse,#mermaid-svg-5CnECrMEt8NrG6qo .node polygon,#mermaid-svg-5CnECrMEt8NrG6qo .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5CnECrMEt8NrG6qo .rough-node .label text,#mermaid-svg-5CnECrMEt8NrG6qo .node .label text,#mermaid-svg-5CnECrMEt8NrG6qo .image-shape .label,#mermaid-svg-5CnECrMEt8NrG6qo .icon-shape .label{text-anchor:middle;}#mermaid-svg-5CnECrMEt8NrG6qo .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5CnECrMEt8NrG6qo .rough-node .label,#mermaid-svg-5CnECrMEt8NrG6qo .node .label,#mermaid-svg-5CnECrMEt8NrG6qo .image-shape .label,#mermaid-svg-5CnECrMEt8NrG6qo .icon-shape .label{text-align:center;}#mermaid-svg-5CnECrMEt8NrG6qo .node.clickable{cursor:pointer;}#mermaid-svg-5CnECrMEt8NrG6qo .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5CnECrMEt8NrG6qo .arrowheadPath{fill:#333333;}#mermaid-svg-5CnECrMEt8NrG6qo .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5CnECrMEt8NrG6qo .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5CnECrMEt8NrG6qo .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5CnECrMEt8NrG6qo .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5CnECrMEt8NrG6qo .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5CnECrMEt8NrG6qo .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5CnECrMEt8NrG6qo .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5CnECrMEt8NrG6qo .cluster text{fill:#333;}#mermaid-svg-5CnECrMEt8NrG6qo .cluster span{color:#333;}#mermaid-svg-5CnECrMEt8NrG6qo div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5CnECrMEt8NrG6qo .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5CnECrMEt8NrG6qo rect.text{fill:none;stroke-width:0;}#mermaid-svg-5CnECrMEt8NrG6qo .icon-shape,#mermaid-svg-5CnECrMEt8NrG6qo .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5CnECrMEt8NrG6qo .icon-shape p,#mermaid-svg-5CnECrMEt8NrG6qo .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5CnECrMEt8NrG6qo .icon-shape .label rect,#mermaid-svg-5CnECrMEt8NrG6qo .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5CnECrMEt8NrG6qo .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5CnECrMEt8NrG6qo .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5CnECrMEt8NrG6qo :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 切换成本:高
LangChain:只改一行初始化
统一 .invoke() → .content
统一 .invoke() → .content
ChatOpenAI(model='gpt-4o-mini')
ChatAnthropic(model='claude-...')
ChatOpenAI(model='deepseek-chat', base_url=...)
原生 SDK:每换一次平台,改一堆代码
OpenAI SDK
client.chat.completions.create()
取 .choices0.message.content
Anthropic SDK
client.messages.create()
取 .content0.text
(参数、返回格式完全不同)
DeepSeek SDK
兼容 OpenAI 但参数不同
四、ChatOpenAI 核心参数
日常开发大多场景用的都是 ChatOpenAI,初始化参数不多,但每个都有实际影响:
python
llm = ChatOpenAI(
model="gpt-4o-mini", # 模型名称,必填
temperature=0.7, # 随机性,决定"创造力"
max_tokens=1000, # 最大输出长度
timeout=60, # 超时秒数
max_retries=2, # 失败重试次数
)
temperature 怎么选?
temperature 直接控制输出的"确定性"和"创造性",不同场景有比较明确的取值区间:
| 场景 | 推荐 temperature | 原因 |
|---|---|---|
| 代码生成、数据提取、翻译 | 0 ~ 0.3 | 需要稳定、准确 |
| 问答、摘要、分析 | 0.3 ~ 0.7 | 兼顾准确和流畅 |
| 创意写作、头脑风暴 | 0.7 ~ 1.0 | 需要多样性 |
temperature=0 时每次调用结果几乎一致,temperature=1 时每次都可能不同。别被名字误导,它不等于"温度",本质上是一个控制概率分布的参数。
补充说明
针对于temperature取值范围存在以下说明
不同厂商的 API 存在细微差异:例如 OpenAI GPT 系列官方取值范围为 0~2;部分国内大模型、轻量化推理框架会将上限设为 1,超出范围的取值可能被自动截断。
Token 到底是什么?
Token 不是字数,不是单词数,是大模型处理文本的最小单位。同一个"你好世界",中文模型可能切成 2 个 token,英文模型可能切成 3 个 token,完全取决于分词器。
| 语言 | 1 个 Token 大约等于 |
|---|---|
| 中文 | 1 ~ 1.8 个汉字 |
| 英文 | 3 ~ 4 个字母 |
不同模型的分词器不一样。OpenAI 的 GPT-4o 用 o200k_base,Claude 有自己的分词器,两者切同一段文本的 token 数可能差 10%~20%。所以"1000 token 能出多少字"这个问题没法给统一答案,得看具体模型。
调用成本不是只看回答长短,输入 token 也计费。喂给模型的上下文越长,单次调用越贵。
max_tokens 限制的是输出最大 token 数,如果发现回答被截断,多半是它设小了。
五、四种消息类型 & 三种传入方式
消息类型
模型不接收纯字符串,而是接收有角色标注的消息列表。四个角色各有分工:
| 消息类型 | 类名 | 干什么 |
|---|---|---|
| 系统消息 | SystemMessage |
设定 AI 的人设、行为规则 |
| 用户消息 | HumanMessage |
用户的问题或指令 |
| AI 消息 | AIMessage |
AI 的回复,用于填充对话历史 |
| 工具消息 | ToolMessage |
工具调用返回的结果 |
记忆口诀:系统定规则,用户提问题,AI 给回复,工具报结果。
python
from langchain_core.messages import HumanMessage, SystemMessage, AIMessage
conversation = [
SystemMessage(content="你是一个专业的 Python 编程助手"),
HumanMessage(content="什么是装饰器?"),
AIMessage(content="装饰器是用于修改函数行为的..."),
HumanMessage(content="举一个实际例子"),
]
response = llm.invoke(conversation)
传入方式:三种写法怎么选
#mermaid-svg-CXzgYS4TtPSjBFAk{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CXzgYS4TtPSjBFAk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CXzgYS4TtPSjBFAk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CXzgYS4TtPSjBFAk .error-icon{fill:#552222;}#mermaid-svg-CXzgYS4TtPSjBFAk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CXzgYS4TtPSjBFAk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CXzgYS4TtPSjBFAk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CXzgYS4TtPSjBFAk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CXzgYS4TtPSjBFAk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CXzgYS4TtPSjBFAk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CXzgYS4TtPSjBFAk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CXzgYS4TtPSjBFAk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CXzgYS4TtPSjBFAk .marker.cross{stroke:#333333;}#mermaid-svg-CXzgYS4TtPSjBFAk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CXzgYS4TtPSjBFAk p{margin:0;}#mermaid-svg-CXzgYS4TtPSjBFAk .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-CXzgYS4TtPSjBFAk .cluster-label text{fill:#333;}#mermaid-svg-CXzgYS4TtPSjBFAk .cluster-label span{color:#333;}#mermaid-svg-CXzgYS4TtPSjBFAk .cluster-label span p{background-color:transparent;}#mermaid-svg-CXzgYS4TtPSjBFAk .label text,#mermaid-svg-CXzgYS4TtPSjBFAk span{fill:#333;color:#333;}#mermaid-svg-CXzgYS4TtPSjBFAk .node rect,#mermaid-svg-CXzgYS4TtPSjBFAk .node circle,#mermaid-svg-CXzgYS4TtPSjBFAk .node ellipse,#mermaid-svg-CXzgYS4TtPSjBFAk .node polygon,#mermaid-svg-CXzgYS4TtPSjBFAk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CXzgYS4TtPSjBFAk .rough-node .label text,#mermaid-svg-CXzgYS4TtPSjBFAk .node .label text,#mermaid-svg-CXzgYS4TtPSjBFAk .image-shape .label,#mermaid-svg-CXzgYS4TtPSjBFAk .icon-shape .label{text-anchor:middle;}#mermaid-svg-CXzgYS4TtPSjBFAk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-CXzgYS4TtPSjBFAk .rough-node .label,#mermaid-svg-CXzgYS4TtPSjBFAk .node .label,#mermaid-svg-CXzgYS4TtPSjBFAk .image-shape .label,#mermaid-svg-CXzgYS4TtPSjBFAk .icon-shape .label{text-align:center;}#mermaid-svg-CXzgYS4TtPSjBFAk .node.clickable{cursor:pointer;}#mermaid-svg-CXzgYS4TtPSjBFAk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-CXzgYS4TtPSjBFAk .arrowheadPath{fill:#333333;}#mermaid-svg-CXzgYS4TtPSjBFAk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CXzgYS4TtPSjBFAk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CXzgYS4TtPSjBFAk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CXzgYS4TtPSjBFAk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CXzgYS4TtPSjBFAk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CXzgYS4TtPSjBFAk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-CXzgYS4TtPSjBFAk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CXzgYS4TtPSjBFAk .cluster text{fill:#333;}#mermaid-svg-CXzgYS4TtPSjBFAk .cluster span{color:#333;}#mermaid-svg-CXzgYS4TtPSjBFAk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CXzgYS4TtPSjBFAk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CXzgYS4TtPSjBFAk rect.text{fill:none;stroke-width:0;}#mermaid-svg-CXzgYS4TtPSjBFAk .icon-shape,#mermaid-svg-CXzgYS4TtPSjBFAk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CXzgYS4TtPSjBFAk .icon-shape p,#mermaid-svg-CXzgYS4TtPSjBFAk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-CXzgYS4TtPSjBFAk .icon-shape .label rect,#mermaid-svg-CXzgYS4TtPSjBFAk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CXzgYS4TtPSjBFAk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-CXzgYS4TtPSjBFAk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-CXzgYS4TtPSjBFAk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 不需要
需要
是
否
我要调用模型
需要角色设定
或对话历史吗?
方式一:直接传字符串
llm.invoke('你好')
消息是动态构建的吗?
比如从模板/配置读取
方式三:元组或字典
('system', '...'), ('user', '...')
方式二:消息列表
SystemMessage(...), HumanMessage(...)
| 方式 | 代码 | 适用场景 |
|---|---|---|
| 直接字符串 | llm.invoke("你好") |
简单问答,不需要上下文 |
| 消息列表 | llm.invoke([SystemMessage(...), HumanMessage(...)]) |
需角色设定或对话历史,最常用 |
| 元组/字典 | llm.invoke([("system", "..."), ("user", "...")]) |
动态构建消息,从配置读取模板 |
用消息列表的好处不只是能设角色------当你需要保留对话上下文时,把历史 AIMessage 继续拼在列表尾部就行,模型就能"记得"刚才聊过什么。
六、四种调用方式:invoke / ainvoke / stream / batch
这是日常开发里用得最多的四个方法,各自有明确的适用场景。
6.1 invoke() --- 同步调用
最基础的方式,调一次、等结果、拿内容:
python
response = llm.invoke("什么是 LangChain?")
print(response.content) # 注意:返回的是 AIMessage 对象,不是字符串
适合脚本、Jupyter 原型开发、不需要并发的场景。
6.2 ainvoke() --- 异步调用
invoke 加上 a 前缀,搭配 asyncio.gather 能把多个请求的等待时间重叠起来。先建立一个直觉:
- 同步 invoke = 在奶茶店排队:你点一杯,等 10 分钟做好,再点下一杯,再等 10 分钟。5 杯 = 50 分钟
- 异步 ainvoke + gather = 扫码同时下 5 单:哪杯好了取哪杯,5 杯 ≈ 10 分钟
API 服务 主线程 API 服务 主线程 #mermaid-svg-zHkA3Q8KFI8n0l8Z{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zHkA3Q8KFI8n0l8Z .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .error-icon{fill:#552222;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .marker.cross{stroke:#333333;}#mermaid-svg-zHkA3Q8KFI8n0l8Z svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zHkA3Q8KFI8n0l8Z p{margin:0;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-zHkA3Q8KFI8n0l8Z text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-zHkA3Q8KFI8n0l8Z .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-zHkA3Q8KFI8n0l8Z #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .sequenceNumber{fill:white;}#mermaid-svg-zHkA3Q8KFI8n0l8Z #sequencenumber{fill:#333;}#mermaid-svg-zHkA3Q8KFI8n0l8Z #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .messageText{fill:#333;stroke:none;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .labelText,#mermaid-svg-zHkA3Q8KFI8n0l8Z .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .loopText,#mermaid-svg-zHkA3Q8KFI8n0l8Z .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-zHkA3Q8KFI8n0l8Z .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .noteText,#mermaid-svg-zHkA3Q8KFI8n0l8Z .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .actorPopupMenu{position:absolute;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-zHkA3Q8KFI8n0l8Z .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-zHkA3Q8KFI8n0l8Z .actor-man circle,#mermaid-svg-zHkA3Q8KFI8n0l8Z line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-zHkA3Q8KFI8n0l8Z :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 同步 invoke(串行) 异步 ainvoke + gather(并行) 请求 1 响应 1(等了 2s) 请求 2 响应 2(等了 2s) 请求 3 响应 3(等了 2s) 请求 1、2、3 同时发出 三个响应几乎同时返回(≈2s)
关键代码:
python
import asyncio
async def parallel_calls():
tasks = [
llm.ainvoke("问题1"),
llm.ainvoke("问题2"),
llm.ainvoke("问题3"),
]
results = await asyncio.gather(*tasks)
# 三个请求同时发出,总耗时 ≈ 最慢的那个
一个容易踩的坑:用 await llm.ainvoke() 一个一个调还是串行的,只有配合 asyncio.gather 才有并行效果。ainvoke 负责"能让出 CPU",gather 负责"同时跑",缺一不可。
Jupyter 里直接 await,普通 .py 文件用 asyncio.run()。
6.3 stream() --- 流式输出
逐 token 返回结果,实现"打字机效果":
python
for chunk in llm.stream("请写一首关于春天的诗"):
print(chunk.content, end="", flush=True)
flush=True 让内容立刻推到屏幕,不攒在缓冲区。适合聊天机器人、长文本生成等需要让用户看到进度的场景。
高级用法 astream_events 可以监听每个 token 的事件时间线:
python
async for event in llm.astream_events("你好"):
if event["event"] == "on_chat_model_stream":
print(event["data"]["chunk"].content, end="", flush=True)
6.4 batch() --- 批量调用
一次给多个问题,LangChain 内部并行处理:
python
questions = ["什么是 Python?", "什么是 JavaScript?", "什么是 Go?"]
responses = llm.batch(questions)
for q, r in zip(questions, responses):
print(f"{q} → {r.content}")
适合批量处理独立请求、数据分析、内容生成。异步版用 abatch()。
七、多平台接入实战
7.1 兼容 OpenAI 格式的平台
凡是兼容 OpenAI 接口的平台,直接用 ChatOpenAI,只改 base_url 和 api_key 就行。这是 LangChain 统一接口理念最直观的体现。
python
# CloseAI 代理(国内直连)
llm = ChatOpenAI(model="gpt-4o-mini")
# 自动读 OPENAI_API_KEY 和 OPENAI_BASE_URL 环境变量
# DeepSeek
llm = ChatOpenAI(
model="deepseek-chat",
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com/v1",
)
# 硅基流动(50+ 开源模型)
llm = ChatOpenAI(
model="Qwen/Qwen3-8B",
api_key=os.getenv("SILICONFLOW_API_KEY"),
base_url="https://api.siliconflow.cn/v1",
)
7.2 不兼容 OpenAI 格式的平台
Anthropic、Google 有自己的 API 格式,需要用专属类或 init_chat_model:
python
from langchain.chat_models import init_chat_model
# 一个函数统一管理所有平台
llm_openai = init_chat_model("gpt-5.4-nano-2026-03-17", model_provider="openai", ...)
llm_claude = init_chat_model("claude-opus-4-7", model_provider="anthropic", ...)
llm_gemini = init_chat_model("gemini-3.1-flash-lite-preview", model_provider="google_genai", ...)
# 调用方式一样
for llm in [llm_openai, llm_claude, llm_gemini]:
print(llm.invoke("用一句话介绍你自己").content)
7.3 各平台速查表
| 平台 | 用哪个类 | 示例模型名 | 关键环境变量 |
|---|---|---|---|
| OpenAI(CloseAI 代理) | ChatOpenAI |
gpt-4o-mini |
OPENAI_API_KEY + OPENAI_BASE_URL |
| DeepSeek | ChatOpenAI |
deepseek-chat |
DEEPSEEK_API_KEY |
| 硅基流动 | ChatOpenAI |
Qwen/Qwen3-8B |
SILICONFLOW_API_KEY |
| Anthropic | ChatAnthropic |
claude-sonnet-4-20250514 |
ANTHROPIC_API_KEY |
ChatGoogleGenerativeAI |
gemini-2.5-flash |
GOOGLE_API_KEY |
|
| Ollama(本地) | ChatOllama |
qwen2.5:7b |
无需 API Key |
规律:兼容 OpenAI 格式的用
ChatOpenAI,不兼容的用init_chat_model或对应的专属类。
八、本地模型:Ollama
学习阶段频繁调 API 是一笔开销,Ollama 让你在本地跑模型,完全免费。
bash
# 下载安装:https://ollama.com/download
# 下载并运行模型
ollama run qwen2.5:7b
# 查看已下载的模型
ollama list
LangChain 里调用:
python
from langchain_ollama import ChatOllama
llm = ChatOllama(model="qwen2.5:7b", base_url="http://localhost:11434")
response = llm.invoke("你好,介绍一下你自己")
print(response.content)
API 的调用姿势和云端模型一模一样,改一行初始化即可。
九、几个值得了解的高级特性
9.1 多模态输入
支持图片输入的前提是用视觉语言模型(VLM),普通文本模型不行:
python
import base64
from langchain_core.messages import HumanMessage
with open("image.jpg", "rb") as f:
image_data = base64.b64encode(f.read()).decode()
message = HumanMessage(content=[
{"type": "text", "text": "描述这张图片"},
{"type": "image_url", "image_url": {
"url": f"data:image/jpeg;base64,{image_data}"
}}
])
response = llm.invoke([message])
Base64 编码把二进制图片转成纯文本,嵌在 JSON 里传输。注意区分:视觉模型只能"看懂"图片(比如 OCR 提取文字),视觉语言模型既能看懂图片内容也能用自然语言描述出来。
9.2 速率限制
当 API 有频率上限时,用 InMemoryRateLimiter 来自动排队:
python
from langchain_core.rate_limiters import InMemoryRateLimiter
rate_limiter = InMemoryRateLimiter(requests_per_second=0.1)
llm = ChatOpenAI(model="gpt-4o-mini", rate_limiter=rate_limiter)
requests_per_second=0.1 表示 10 秒发一个请求,超出就自动等。
9.3 Token 用量追踪
想知道这次调用到底花了多少 token:
python
from langchain_core.callbacks import get_usage_metadata_callback
with get_usage_metadata_callback() as cb:
llm.invoke("你好")
llm.invoke("再见")
print(cb.usage_metadata)
# {'input_tokens': ..., 'output_tokens': ..., 'total_tokens': ...}
9.4 提示词缓存
当你反复使用同一段很长的系统提示词时(比如 3000 字的角色设定),模型每次都要重新"读"一遍,费 token 又费时间。提示词缓存让服务商在服务器端缓存已处理的提示词,后续调用直接跳过重复计算。
- OpenAI:全自动,你什么都不用做,API 自动识别相同前缀并缓存,命中后费用减半
- Anthropic :需要显式标记,用
AnthropicPromptCachingMiddleware中间件告诉 API 哪段可以缓存,命中后费用降低 90%
python
# Anthropic 缓存中间件
from langchain_anthropic import ChatAnthropic, AnthropicPromptCachingMiddleware
llm = ChatAnthropic(
model="claude-sonnet-4-20250514",
middleware=[AnthropicPromptCachingMiddleware()]
)
注意这和 LLM 本地缓存(相同问题直接返回缓存结果,不调 API)是两回事。提示词缓存在服务端,缓存的是已计算的中间状态;本地缓存在你机器上,缓存的是完整的"问题→回答"键值对。
9.5 运行时动态切换模型
不重新初始化对象,通过 config 在调用时切换模型:
python
configurable_model = init_chat_model(temperature=0)
result1 = configurable_model.invoke(
"你好", config={"configurable": {"model": "gpt-4o-mini"}}
)
result2 = configurable_model.invoke(
"你好", config={"configurable": {"model": "claude-sonnet-4-6"}}
)
这对 A/B 测试、多租户系统、根据用户选择切换模型的场景很方便。
十、小结
本节聚焦 Model I/O 的模型调用部分,核心就几件事:
#mermaid-svg-59cwhrAEDHYCR7K0{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-59cwhrAEDHYCR7K0 .error-icon{fill:#552222;}#mermaid-svg-59cwhrAEDHYCR7K0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-59cwhrAEDHYCR7K0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-59cwhrAEDHYCR7K0 .marker.cross{stroke:#333333;}#mermaid-svg-59cwhrAEDHYCR7K0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-59cwhrAEDHYCR7K0 p{margin:0;}#mermaid-svg-59cwhrAEDHYCR7K0 .edge{stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .section--1 rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section--1 path,#mermaid-svg-59cwhrAEDHYCR7K0 .section--1 circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section--1 polygon,#mermaid-svg-59cwhrAEDHYCR7K0 .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section--1 text{fill:#ffffff;}#mermaid-svg-59cwhrAEDHYCR7K0 .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-depth--1{stroke-width:17;}#mermaid-svg-59cwhrAEDHYCR7K0 .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled circle,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:lightgray;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:#efefef;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-0 rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section-0 path,#mermaid-svg-59cwhrAEDHYCR7K0 .section-0 circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section-0 polygon,#mermaid-svg-59cwhrAEDHYCR7K0 .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section-0 text{fill:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .node-icon-0{font-size:40px;color:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-depth-0{stroke-width:14;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled circle,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:lightgray;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:#efefef;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-1 rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section-1 path,#mermaid-svg-59cwhrAEDHYCR7K0 .section-1 circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section-1 polygon,#mermaid-svg-59cwhrAEDHYCR7K0 .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section-1 text{fill:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .node-icon-1{font-size:40px;color:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-depth-1{stroke-width:11;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled circle,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:lightgray;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:#efefef;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-2 rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section-2 path,#mermaid-svg-59cwhrAEDHYCR7K0 .section-2 circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section-2 polygon,#mermaid-svg-59cwhrAEDHYCR7K0 .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section-2 text{fill:#ffffff;}#mermaid-svg-59cwhrAEDHYCR7K0 .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-depth-2{stroke-width:8;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled circle,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:lightgray;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:#efefef;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-3 rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section-3 path,#mermaid-svg-59cwhrAEDHYCR7K0 .section-3 circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section-3 polygon,#mermaid-svg-59cwhrAEDHYCR7K0 .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section-3 text{fill:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .node-icon-3{font-size:40px;color:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-depth-3{stroke-width:5;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled circle,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:lightgray;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:#efefef;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-4 rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section-4 path,#mermaid-svg-59cwhrAEDHYCR7K0 .section-4 circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section-4 polygon,#mermaid-svg-59cwhrAEDHYCR7K0 .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section-4 text{fill:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .node-icon-4{font-size:40px;color:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-depth-4{stroke-width:2;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled circle,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:lightgray;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:#efefef;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-5 rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section-5 path,#mermaid-svg-59cwhrAEDHYCR7K0 .section-5 circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section-5 polygon,#mermaid-svg-59cwhrAEDHYCR7K0 .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section-5 text{fill:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .node-icon-5{font-size:40px;color:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-depth-5{stroke-width:-1;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled circle,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:lightgray;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:#efefef;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-6 rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section-6 path,#mermaid-svg-59cwhrAEDHYCR7K0 .section-6 circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section-6 polygon,#mermaid-svg-59cwhrAEDHYCR7K0 .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section-6 text{fill:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .node-icon-6{font-size:40px;color:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-depth-6{stroke-width:-4;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled circle,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:lightgray;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:#efefef;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-7 rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section-7 path,#mermaid-svg-59cwhrAEDHYCR7K0 .section-7 circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section-7 polygon,#mermaid-svg-59cwhrAEDHYCR7K0 .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section-7 text{fill:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .node-icon-7{font-size:40px;color:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-depth-7{stroke-width:-7;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled circle,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:lightgray;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:#efefef;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-8 rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section-8 path,#mermaid-svg-59cwhrAEDHYCR7K0 .section-8 circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section-8 polygon,#mermaid-svg-59cwhrAEDHYCR7K0 .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section-8 text{fill:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .node-icon-8{font-size:40px;color:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-depth-8{stroke-width:-10;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled circle,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:lightgray;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:#efefef;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-9 rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section-9 path,#mermaid-svg-59cwhrAEDHYCR7K0 .section-9 circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section-9 polygon,#mermaid-svg-59cwhrAEDHYCR7K0 .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section-9 text{fill:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .node-icon-9{font-size:40px;color:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-depth-9{stroke-width:-13;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled circle,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:lightgray;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:#efefef;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-10 rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section-10 path,#mermaid-svg-59cwhrAEDHYCR7K0 .section-10 circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section-10 polygon,#mermaid-svg-59cwhrAEDHYCR7K0 .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section-10 text{fill:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .node-icon-10{font-size:40px;color:black;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .edge-depth-10{stroke-width:-16;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled circle,#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:lightgray;}#mermaid-svg-59cwhrAEDHYCR7K0 .disabled text{fill:#efefef;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-root rect,#mermaid-svg-59cwhrAEDHYCR7K0 .section-root path,#mermaid-svg-59cwhrAEDHYCR7K0 .section-root circle,#mermaid-svg-59cwhrAEDHYCR7K0 .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-59cwhrAEDHYCR7K0 .section-root text{fill:#ffffff;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-root span{color:#ffffff;}#mermaid-svg-59cwhrAEDHYCR7K0 .section-2 span{color:#ffffff;}#mermaid-svg-59cwhrAEDHYCR7K0 .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-59cwhrAEDHYCR7K0 .edge{fill:none;}#mermaid-svg-59cwhrAEDHYCR7K0 .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-59cwhrAEDHYCR7K0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Model I/O
模型调用
模型选择
Chat Models 主流
LLMs 淘汰
Embeddings 不同用途
初始化
ChatOpenAI 最常用
init_chat_model 动态切换
核心参数
temperature 控制随机性
max_tokens 限制输出长度
timeout / max_retries
调用方式
invoke 同步
ainvoke 异步+并发
stream 逐token输出
batch 批量并行
跨平台
兼容OpenAI格式 → ChatOpenAI
不兼容 → init_chat_model
本地 → ChatOllama