一、Model I/O 核心定位
Model I/O 是 LangChain 中负责与大模型 "沟通" 的核心模块,相当于大模型的 "输入输出管家"。它主要解决三个关键问题:如何格式化输入 、如何调用模型 、如何解析输出,把 "用户需求→模型处理→结果反馈" 的流程标准化,让开发者不用关心底层通信细节,专注业务逻辑。
二、调用大模型:在线与本地两种方式
2.1 调用在线模型:对接主流大模型服务
在线模型是最常用的方式,只需通过 API-Key 对接第三方平台的大模型,无需本地部署算力。
2.1.1 主流大模型服务平台(附关键信息)
| 平台 | 官网地址 | API-Key 管理入口 | 核心优势 |
|---|---|---|---|
| CloseAI | https://platform.closeai-asia.com/ | 开发者中心→API | 稳定易用,支持多模型 |
| OpenRouter | https://openrouter.ai/ | 设置→Keys | 聚合多种模型,选择丰富 |
| 阿里云百炼 | https://bailian.console.aliyun.com/ | 模型→API-Key | 国内访问快,适配企业场景 |
| 百度千帆 | https://console.bce.baidu.com/qianfan/overview | 千帆平台→API Key | 文心一言生态,中文支持好 |
| 硅基流动 | https://www.siliconflow.cn/ | 账号→API 密钥 | 性价比高,模型种类全 |
2.1.2 两种调用方式
-
直接用 OpenAI SDK 调用由于 GPT 系列模型定义了行业主流的调用规范,大部分大模型(如通义千问、ChatGLM)都兼容该规范,代码示例如下:
# 安装依赖 # pip install langchain langchain-openai from openai import OpenAI # 初始化客户端 client = OpenAI( base_url="平台API地址", # 如OpenRouter的https://openrouter.ai/api/v1 api_key="你的API-Key" # 平台申请的密钥 ) # 调用模型(翻译示例) completion = client.chat.completions.create( model="模型名称", # 如openai/gpt-oss-20b:free messages=[{"role": "user", "content": "将'你好'翻译成意大利语"}] ) print(completion.choices[0].message.content) -
**用 LangChain API 调用(推荐)**LangChain 封装了统一接口,切换模型时无需修改核心代码,兼容性更强:
import os from langchain.chat_models import init_chat_model from langchain.messages import SystemMessage, HumanMessage # 初始化模型 llm = init_chat_model( model="模型名称", model_provider="openai", # 兼容大部分平台 base_url="平台API地址", api_key=os.getenv("API_KEY") # 从环境变量读取密钥 ) # 发送多角色消息(如设定角色+用户提问) messages = [ SystemMessage(content="你是一个诗人"), HumanMessage(content="写一首关于春天的诗") ] resp = llm.invoke(messages) print(resp.content)
2.1.3 API-Key 安全管理(避免泄露!)
硬编码密钥会有泄露风险,推荐两种安全方式:
-
用 .env 文件管理 创建
.env文件存储密钥,通过python-dotenv加载:# .env 文件内容 OPENAI_API_KEY="sk-xxx" OPENAI_BASE_URL="https://openrouter.ai/api/v1"代码中加载:
# pip install python-dotenv import os from dotenv import load_dotenv from openai import OpenAI load_dotenv() # 自动加载.env文件 client = OpenAI( base_url=os.getenv("OPENAI_BASE_URL"), api_key=os.getenv("OPENAI_API_KEY") ) -
系统环境变量配置终端临时设置(Linux/Mac):
export OPENAI_API_KEY="sk-xxx"Windows CMD:
cmd
set OPENAI_API_KEY="sk-xxx"代码中直接读取:
os.getenv("OPENAI_API_KEY")
2.1.4 模型初始化关键参数
| 参数 | 作用 | 示例值 |
|---|---|---|
| model | 指定模型名称 | "openai/gpt-oss-20b:free" |
| temperature | 控制输出随机性(0-1) | 0.3(严谨)、0.8(有创意) |
| max_tokens | 限制输出长度 | 500(最多 500 个 token) |
| timeout | 超时时间(秒) | 30(超过 30 秒取消请求) |
| max_retries | 失败重试次数 | 2(失败后重试 2 次) |
小知识:Token 是大模型处理的最小单位,1 个中文 Token≈1.5 个汉字,1 个英文 Token≈3-4 个字母。可以用 OpenAI 的 Token 计算器(https://platform.openai.com/tokenizer)估算文本长度。
2.2 调用本地模型:隐私安全优先
如果需要处理敏感数据(如企业机密),本地部署模型更安全。LangChain 推荐用 Ollama 框架管理本地模型。
2.2.1 Ollama 快速上手
-
安装 Ollama 访问官网(https://ollama.com/download)下载对应系统的安装包,Windows 直接运行
.exe,Linux 执行命令:curl -fsSL https://ollama.com/install.sh | sh -
下载并运行模型终端执行命令(以 deepseek-r1:7b 为例):
ollama run deepseek-r1:7b若模型文件已下载,可在 Ollama 设置中指定模型目录,避免重复下载。
-
LangChain 调用本地模型
# 安装依赖 # pip install langchain-ollama from langchain_ollama import ChatOllama # 初始化本地模型 ollm_llm = ChatOllama( model="deepseek-r1:7b", # 本地已有的模型名称 base_url="http://localhost:11434" # Ollama默认端口 ) # 调用模型 resp = ollm_llm.invoke({"role": "user", "content": "介绍一下你自己"}) print(resp.content)
三、Prompt Template:让输入更灵活
固定的提示词无法适配多场景,Prompt Template 允许通过 "变量占位符" 动态生成提示词,就像填写表单一样灵活。
3.1 两种核心模板类型
3.1.1 PromptTemplate(普通文本模板)
适用于简单的单轮文本生成场景,支持变量替换:
from langchain_core.prompts import PromptTemplate
# 方式1:构造方法实例化
template = PromptTemplate(
template="评价{产品}的{维度}优缺点",
input_variables=["产品", "维度"] # 必须指定变量名
)
# 方式2:简化实例化(推荐)
template = PromptTemplate.from_template("评价{产品}的{维度}优缺点")
# 生成提示词
prompt = template.format(产品="智能手机", 维度="拍照功能")
print(prompt) # 输出:评价智能手机的拍照功能优缺点
3.1.2 ChatPromptTemplate(多角色聊天模板)
适用于多轮对话、需要设定角色的场景(如系统指令 + 用户提问 + AI 回复):
from langchain_core.prompts import ChatPromptTemplate
template = ChatPromptTemplate(
[
("system", "你是{职业},说话风格{风格}"), # 系统角色
("human", "我想了解{话题}"), # 用户角色
("ai", "好的!{话题}的核心信息如下:"), # AI历史回复(可选)
("human", "{补充问题}") # 用户补充提问
]
)
# 生成消息列表
prompt = template.format_messages(
职业="科普博主",
风格="通俗易懂",
话题="量子力学",
补充问题="什么是量子纠缠?"
)
print(prompt) # 输出包含多角色的消息列表
3.2 实用技巧
-
部分变量默认值:预先填充固定变量,后续只需传递动态变量:
# 预先设定"职业"为固定值 partial_template = template.partial(职业="科普博主") prompt = partial_template.format(风格="幽默", 话题="黑洞", 补充问题="黑洞会吞噬光吗?") -
外部加载模板:将提示词保存在 JSON/YAML 文件中,方便管理和复用:
yaml
# prompt.yaml 文件 _type: "prompt" input_variables: ["姓名", "事件"] template: "请{姓名}描述{事件}的经过"代码加载:
from langchain_core.prompts import load_prompt template = load_prompt("prompt.yaml", encoding="utf-8") prompt = template.format(姓名="小明", 事件="参加马拉松") -
多模态提示词:支持插入图片链接等多模态输入(需模型支持):
template = ChatPromptTemplate( [ ("system", "用中文简短描述图片内容"), ("user", "content": [{"image_url": "{图片链接}"}]) ] ) prompt = template.format_messages(图片链接="https://xxx.jpg")
四、Output Parsers:让输出更规整
大模型默认输出文本字符串,若需要用于后续逻辑处理(如存入数据库、调用 API),需要将输出解析为结构化数据(如 JSON、列表)。
4.1 常用解析器
4.1.1 StrOutputParser(字符串解析器)
最简单的解析器,直接提取模型输出的文本内容:
import os
from langchain.chat_models import init_chat_model
from langchain_core.output_parsers import StrOutputParser
llm = init_chat_model(
model="openai/gpt-oss-20b:free",
base_url="https://openrouter.ai/api/v1",
api_key=os.getenv("API_KEY")
)
# 调用模型
resp = llm.invoke({"role": "user", "content": "你好"})
print(resp) # 输出包含元数据的完整响应对象
# 解析为纯字符串
str_resp = StrOutputParser().invoke(resp)
print(str_resp) # 输出:你好!有什么我可以帮忙的吗?
4.1.2 JsonOutputParser(JSON 解析器)
将输出解析为 JSON 格式,支持字段验证(需配合 Pydantic 模型),适合结构化数据场景:
from pydantic import BaseModel, Field
from langchain_core.output_parsers import JsonOutputParser
# 定义JSON结构(字段验证)
class PrimeData(BaseModel):
prime: list[int] = Field(description="1000-100000之间的素数")
count: list[int] = Field(description="每个素数对应的小于它的素数个数")
# 初始化解析器
json_parser = JsonOutputParser(pydantic_object=PrimeData)
# 调用模型(让模型按指定JSON格式输出)
messages = [
("system", json_parser.get_format_instructions()), # 告诉模型输出格式
("user", "生成5个符合要求的素数及对应count")
]
resp = llm.invoke(messages)
json_resp = json_parser.invoke(resp)
print(json_resp) # 输出:{'prime': [1009, 2003, ...], 'count': [168, 303, ...]}
4.2 结构化输出进阶:直接指定输出模式
LangChain 支持直接让模型按指定模式输出,无需手动写解析逻辑,支持三种模式:
- TypedDict(简单无验证):适合快速结构化,无字段校验
- Pydantic(推荐,带验证):支持字段类型、描述校验,出错会提示
- JSON Schema(灵活可控):最大程度自定义输出结构,适配复杂场景
示例(Pydantic 模式,生成动物表情列表):
from pydantic import BaseModel, Field
# 定义输出结构
class Animal(BaseModel):
animal: str = Field(description="动物名称")
emoji: str = Field(description="对应的emoji表情")
class AnimalList(BaseModel):
animals: list[Animal] = Field(description="动物与表情列表")
# 让模型按结构输出
llm_with_structured_output = llm.with_structured_output(AnimalList)
resp = llm_with_structured_output.invoke("生成3种动物及表情")
print(resp) # 输出:animals=[Animal(animal='猫', emoji='🐱'), ...]
五、核心调用方法:同步 / 异步、流式 / 批量
5.1 输出模式
-
非流式输出:模型生成完整结果后一次性返回,适合简单场景(如短文本生成)
-
流式输出 :模型逐个 Token 返回结果,适合聊天机器人等需要实时反馈的场景:
# 流式输出示例 for chunk in llm.stream(messages): print(chunk.content, end="", flush=True) # 实时打印每个字符
5.2 调用方式
-
同步调用(invoke):逐个执行请求,适合少量任务
-
异步调用(ainvoke):并发执行多个请求,效率更高(需配合 asyncio):
import asyncio async def async_call(): tasks = [llm.ainvoke(msg) for msg in messages_list] return await asyncio.gather(*tasks) # 并发执行 -
批量调用(batch):一次性发送多个请求,适合批量处理(如批量生成文案):
# 批量生成三首不同主题的诗 messages_list = [ [("system", "你是诗人"), ("user", "写春天的诗")], [("system", "你是诗人"), ("user", "写夏天的诗")], [("system", "你是诗人"), ("user", "写秋天的诗")] ] resps = llm.batch(messages_list) # 批量调用
总结
Model I/O 模块的核心价值是 "标准化" 和 "简化"------ 标准化大模型的输入输出流程,简化模型调用、提示词管理和结果解析的复杂度。无论是对接在线模型还是部署本地模型,无论是简单文本生成还是复杂结构化输出,Model I/O 都能提供一致的开发体验。
掌握这一章的核心技能后,你可以轻松实现:多平台模型切换、动态提示词生成、结构化结果输出等基础功能,为后续构建复杂的大模型应用(如问答系统、聊天机器人)打下坚实基础。