LangChain Model I/O 完全指南:从模型调用到多平台实战 一套代码调用所有大模型——OpenAI、Claude、DeepSeek、本地模型全搞定前言当你开始写第一个模型调用时会面临什么假设你现在要做一个 AI 应用第一步自然是“让模型能回答问题”。看起来很简单对吧直接调 API 就行了。但当你真正开始做时问题接踵而来换个模型从 GPT-4 换成 Claude整个调用代码要重写——连返回值的取法都不一样想实现多轮对话得自己维护消息列表还得区分系统指令、用户输入、AI 回复想同时问 5 个问题同步调用要等 10 秒用户体验稀碎想让用户看到“打字机效果”得自己处理流式输出的解析和拼接想统计这次调用花了多少 token还得从响应里一层层扒数据这些杂活跟“业务逻辑”毫无关系却占了大量开发时间。Model I/O 就是 LangChain 用来解决这些问题的答案。它是你与大模型交互的“标准接口”——统一了“传什么”“怎么传”“怎么调”三个环节让你把精力放回真正重要的地方。1. Model I/O 是什么Model I/O 回答的是一个最基本的问题“怎么把问题喂给模型并拿到有用的结果”它由三个环节组成环节做什么解决什么问题Prompts提示词模板把用户输入和系统指令格式化成模型能理解的消息“怎么组织输入”Models模型调用调用大模型获取响应“怎么传给模型”Output Parsers输出解析把模型输出解析成需要的格式“怎么拿有用结果”本文聚焦于Models这一层也就是“怎么调模型”。关于 Prompts 和 Output Parsers会在后续章节详细介绍。2. 三类模型别搞混了LangChain 中有三类“模型”用途完全不同类型输入→输出代表类说明Chat Models消息列表 → AI消息ChatOpenAI, ChatAnthropic本课程核心。所有现代模型GPT-4o、Claude、DeepSeek都是对话模型LLMs旧版字符串→字符串OpenAI旧版已基本淘汰。早期文本补全模型如 GPT-3 text-davinciEmbeddings文本→浮点数向量OpenAIEmbeddings不生成文本而是将文本转为数字向量用于语义搜索和 RAG本课程全程使用 Chat Models除非特别说明“模型调用”都指这一类。3. 统一接口LangChain 最核心的价值不管你用的是 OpenAI、DeepSeek、Claude 还是本地的 OllamaLangChain 都提供了完全一致的调用方式python# 不同平台同一套代码 llm ChatOpenAI(modelgpt-4o-mini) # OpenAI llm ChatOpenAI(modeldeepseek-chat, ...) # DeepSeek llm ChatAnthropic(modelclaude-sonnet-4) # Anthropic llm ChatOllama(modelqwen2.5:7b) # 本地模型 # 调用方式完全一致 response llm.invoke(你好) # 同步 response await llm.ainvoke(你好) # 异步 for chunk in llm.stream(你好): # 流式 print(chunk.content, end) responses llm.batch([问题1, 问题2]) # 批量这就是 Model I/O 中 Models 层的核心价值一次学会到处能用。4. 为什么不用原生 SDK很多同学会问“OpenAI 的 SDK 已经很好用了为什么还要学 LangChain”原生 SDK 的痛点切换模型假设你想用 GPT-4o-mini、DeepSeek、Claude 三个模型跑同一个任务对比结果用原生 SDK每换一个平台改一堆代码python# OpenAI client_openai OpenAI(api_key..., base_url...) resp1 client_openai.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: 解释量子计算}] ) print(resp1.choices[0].message.content) # DeepSeek接口兼容OpenAI但要改 client、api_key、base_url、model client_deepseek OpenAI(api_key..., base_urlhttps://api.deepseek.com/v1) resp2 client_deepseek.chat.completions.create( modeldeepseek-chat, messages[{role: user, content: 解释量子计算}] ) print(resp2.choices[0].message.content) # Anthropic Claude不兼容OpenAI格式整套代码重写 client_claude anthropic.Anthropic(api_key...) message client_claude.messages.create( modelclaude-sonnet-4, messages[{role: user, content: 解释量子计算}] ) print(message.content[0].text) # 注意取值方式都不一样三个平台三套 client三种取值方式。如果还要加流式、重试、对话记忆……代码量会爆炸。用 LangChain只改一行初始化python# 调用 OpenAI llm ChatOpenAI(modelgpt-4o-mini) print(llm.invoke(解释量子计算).content) # 换成 DeepSeek改一行 llm ChatOpenAI( modeldeepseek-chat, api_keyos.getenv(DEEPSEEK_API_KEY), base_urlhttps://api.deepseek.com/v1 ) print(llm.invoke(解释量子计算).content) # 调用代码完全一样 # 换成 Claude还是改一行 llm ChatAnthropic(modelclaude-sonnet-4) print(llm.invoke(解释量子计算).content) # 调用代码还是一样模型只有一两个时感觉差不多但当你需要对比 3~5 个模型、加上流式输出、再接上 RAG 管道时原生 SDK 的代码量会呈指数增长而 LangChain 始终保持简洁。5. 消息类型传什么LangChain 用标准化的消息格式来传递不同角色的内容消息类型类名用途示例系统消息SystemMessage设定 AI 的行为、角色和规则“你是一个有帮助的助手”用户消息HumanMessage用户的输入“帮我解释一下量子计算”AI 消息AIMessageAI 的回复用于对话历史“量子计算是…”工具消息ToolMessage工具执行返回的结果工具调用的输出记忆口诀系统定规则用户提问题AI 给回复工具报结果。实战多轮对话pythonfrom langchain_core.messages import HumanMessage, SystemMessage, AIMessage from langchain_openai import ChatOpenAI llm ChatOpenAI(modelgpt-4o-mini) # 对话历史——模拟多轮对话 conversation [ SystemMessage(content你是一个有帮助的AI助手), HumanMessage(content你好我叫小明), AIMessage(content你好小明有什么我可以帮助你的吗), HumanMessage(content我叫什么名字) # 这依赖上一轮的上下文 ] response llm.invoke(conversation) print(response.content) # 你叫小明6. 传入方式怎么传知道“传什么”之后下一个问题是“怎么传给模型”你的需求推荐方式代码示例简单问答不需要上下文直接传字符串llm.invoke(你好)需要角色设定或对话历史传消息列表llm.invoke([SystemMessage(...), HumanMessage(...)])动态构建消息用元组/字典llm.invoke([(system, ...), (user, ...)])一句话记忆能用字符串就用字符串最简单需要对话/角色时用消息列表最常见动态构建时用元组/字典最灵活。7. 调用方式怎么调LangChain 提供了四种调用方式适应不同场景7.1 同步调用invoke()—— 最常用适合大多数场景pythonresponse llm.invoke(什么是 LangChain) print(response.content)7.2 异步调用ainvoke()—— 高并发适用于需要同时处理多个请求的场景。理解异步invoke()就像排队买奶茶——站在柜台前死等拿到一杯才点下一杯。ainvoke()就像扫码下单——点了 5 杯去旁边坐着哪杯好了取哪杯总时间 ≈ 单杯制作时间。性能对比5 个请求方式写法总耗时同步串行llm.invoke()× 5~9 秒异步并行asyncio.gather(*[llm.ainvoke(p) for p in prompts])~2 秒关键理解ainvoke()解决的是“等待时不阻塞”让出控制权asyncio.gather()解决的是“同时跑多个任务”利用控制权塞入更多任务两者缺一不可。pythonimport asyncio from langchain_openai import ChatOpenAI llm ChatOpenAI(modelgpt-4o-mini) prompts [介绍北京, 介绍上海, 介绍广州] # 正确写法ainvoke gather 同时跑 async def parallel_call(): tasks [llm.ainvoke(p) for p in prompts] results await asyncio.gather(*tasks) for r in results: print(r.content[:20]) # Jupyter 中直接 await await parallel_call() # 普通 .py 文件中用 asyncio.run() # asyncio.run(parallel_call())7.3 流式调用stream()—— 打字机效果提升用户体验pythonprint(AI回答, end) full None for chunk in llm.stream(请写一首关于春天的诗): full chunk if full is None else full chunk print(chunk.content, end, flushTrue) # flushTrue 强制立即显示7.4 批次调用batch()—— 并行处理多个独立请求pythonquestions [什么是Python, 什么是JavaScript, 什么是Go语言] responses llm.batch(questions) for q, r in zip(questions, responses): print(fQ: {q}\nA: {r.content}\n)8. 多平台实战8.1 各平台接入速查表平台用哪个类模型名称示例环境变量OpenAICloseAI 代理ChatOpenAIgpt-4o-miniOPENAI_API_KEYOPENAI_BASE_URLDeepSeekChatOpenAIdeepseek-chatDEEPSEEK_API_KEYDEEPSEEK_BASE_URL硅基流动ChatOpenAIQwen/Qwen3-8BSILICONFLOW_API_KEYSILICONFLOW_BASE_URLAnthropic ClaudeChatAnthropicclaude-sonnet-4ANTHROPIC_API_KEYGoogle Geminiinit_chat_modelgemini-2.5-flashGEMINI_API_KEY规律凡是兼容 OpenAI 接口格式的平台DeepSeek、硅基流动等都可以直接用ChatOpenAI只需改base_url和api_key。8.2 一键切换多平台init_chat_model当你需要在运行时动态切换不同提供商的模型时init_chat_model比单独 import 更方便pythonfrom langchain.chat_models import init_chat_model # 一个函数搞定所有提供商 llm_openai init_chat_model(gpt-4o-mini, model_provideropenai) llm_claude init_chat_model(claude-sonnet-4, model_provideranthropic) llm_gemini init_chat_model(gemini-2.5-flash, model_providergoogle_genai) # 调用方式完全一致 for name, llm in [(OpenAI, llm_openai), (Claude, llm_claude)]: response llm.invoke(用一句话介绍你自己) print(f{name}: {response.content})9. 调用本地模型OllamaOllama 让你在本地运行开源模型无需联网也无需 API 费用。安装与运行bash# 安装 OllamaLinux curl -fsSL https://ollama.com/install.sh | sh # 下载并运行模型 ollama run qwen2.5:7b # 列出已下载的模型 ollama listLangChain 调用pythonfrom langchain_ollama import ChatOllama llm ChatOllama(modelqwen2.5:7b, base_urlhttp://localhost:11434) response llm.invoke(你好介绍一下你自己) print(response.content)10. 高级特性10.1 多模态输入视觉模型支持图像等多模态输入适用于 GPT-4o 等视觉语言模型VLMpythonimport base64 from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage llm ChatOpenAI(modelgpt-4o) # 读取图片并转为 Base64 with open(image.jpg, rb) as f: image_data base64.b64encode(f.read()).decode(utf-8) # 构造多模态消息 message HumanMessage(content[ {type: text, text: 描述这张图片}, {type: image_url, image_url: {url: fdata:image/jpeg;base64,{image_data}}} ]) response llm.invoke([message]) print(response.content)Base64 的作用将二进制图片数据编码为可打印文本以便在 JSON 协议中传输。10.2 速率限制避免触发 API 限流pythonfrom langchain_core.rate_limiter import InMemoryRateLimiter from langchain_openai import ChatOpenAI rate_limiter InMemoryRateLimiter( requests_per_second0.1, # 10 秒只能发 1 个请求 check_every_n_seconds0.1 ) llm ChatOpenAI(modelgpt-4o-mini, rate_limiterrate_limiter)10.3 Token 使用追踪统计每次调用的 token 消耗pythonfrom langchain_core.callbacks import get_usage_metadata_callback llm ChatOpenAI(modelgpt-4o-mini) with get_usage_metadata_callback() as cb: llm.invoke(你好) llm.invoke(再见) print(cb.usage_metadata) # {input_tokens: 总输入token数, output_tokens: 总输出token数, total_tokens: 总token数}10.4 提示词缓存Prompt Caching当你反复使用同一段很长的系统提示词时模型服务商可以在服务端缓存已处理的提示词后续调用跳过重复计算大幅省钱。平台缓存方式省钱效果OpenAI全自动零配置缓存命中的 token 费用减半Anthropic需中间件标记缓存命中 token 费用降低 90%python# OpenAI全自动什么都不用做 llm ChatOpenAI(modelgpt-4o-mini) response llm.invoke(你好) # 自动缓存 # Anthropic需要中间件 from langchain_anthropic import ChatAnthropic, AnthropicPromptCachingMiddleware llm ChatAnthropic( modelclaude-sonnet-4, middleware[AnthropicPromptCachingMiddleware()] # 自动标记长提示词为可缓存 )注意这里的缓存发生在模型服务商的服务器上不是你本地的磁盘缓存。如果你想要“相同问题直接本地返回、不打 API”的缓存那是 LangChain 的LLMCache机制属于另一个话题。11. 小结本文介绍了 Model I/O 中的模型调用部分主题核心要点统一接口一套代码调用所有模型切换只需改初始化消息类型SystemMessage, HumanMessage, AIMessage, ToolMessage传入方式字符串 / 消息列表 / 元组或字典调用方式invoke, ainvoke, stream, batch多平台接入CloseAI、DeepSeek、硅基流动、Anthropic、Gemini、Ollama高级特性多模态、速率限制、Token追踪、提示词缓存核心收获python# 同样的代码只需更换初始化方式即可切换模型 llm init_chat_model(gpt-4o-mini, model_provideropenai) llm init_chat_model(claude-sonnet-4, model_provideranthropic) llm init_chat_model(gemini-2.5-flash, model_providergoogle_genai) llm ChatOllama(modelqwen2.5:7b) # 本地模型 # 调用方式完全一致 response llm.invoke(你好)这就是 LangChain Model I/O 的力量把“怎么调模型”这件事彻底标准化让你专注于“拿模型做什么”。下一节预告我们将进入Prompts提示词模板的学习——如何用模板化方式管理提示词让代码更干净、更可维护。 本文基于 LangChain 官方文档及实战课程整理所有代码示例均可在 Python 3.12 uv 环境下运行。如有疑问欢迎在评论区交流讨论。