模型配置与切换
基础模型配置
from deepagents import create_deep_agent
# 方式 1:直接传字符串(推荐)
agent = create_deep_agent(model="deepseek:deepseek-chat")
# 方式 2:使用 init_chat_model
from langchain.chat_models import init_chat_model
model = init_chat_model(
model="deepseek:deepseek-chat",
temperature=0.7,
max_tokens=4096,
)
agent = create_deep_agent(model=model)
DeepSeek 特定配置
from langchain_deepseek import ChatDeepSeek
model = ChatDeepSeek(
model="deepseek-chat", # 或 "deepseek-reasoner"
temperature=0.7,
max_tokens=4096,
timeout=60,
max_retries=2,
)
agent = create_deep_agent(model=model)
运行时动态切换模型
示例代码
from env_utils import DASHSCOPE_API_KEY, DASHSCOPE_BASE_URL, DEEPSEEK_BASE_URL, DEEPSEEK_API_KEY
from langchain.chat_models import init_chat_model
from langchain.agents import create_agent
from deepagents import create_deep_agent
from dataclasses import dataclass
from langchain.agents.middleware import wrap_model_call, ModelRequest, ModelResponse
from typing import Callable
# ============================================================================
# Demo 1: 基本使用 - 创建简单的 Agent
# ============================================================================
@dataclass
class Context:
# 运行时要切换到的模型名称
model: str
# 模型提供方,openai 表示使用 OpenAI 兼容协议
model_provider: str
# 兼容协议服务的鉴权 key,不传时会读取对应环境变量
api_key: str | None = None
# 兼容协议服务的接口地址,不传时使用 provider 默认地址
base_url: str | None = None
@wrap_model_call
def configurable_model(
request: ModelRequest,
handler: Callable[[ModelRequest], ModelResponse],
) -> ModelResponse:
# 从本次调用的运行时上下文中读取模型配置
context = request.runtime.context
# 使用上下文配置创建新模型,覆盖 agent 初始化时的默认模型
model = init_chat_model(
context.model,
model_provider=context.model_provider,
api_key=context.api_key,
base_url=context.base_url,
)
return handler(request.override(model=model))
def demo1_configurable_model():
"""运行时动态切换模型
**参考文档**:[Models](https://docs.langchain.com/oss/python/deepagents/models)
初使化 model 时使用的是 deepseek:deepseek-chat
在调用 agent.invoke 时,通过 context 传入不同的模型配置,model 被动态切换成了 qwen3.5-plus
"""
print("=" * 50)
print("Demo 1: 运行时动态切换模型")
print("=" * 50)
# 调用init_chat_model函数初始化模型,参数model用来指定模型名称,Langchain会根据模型名字自动设定base_url,并从环境变量中获取api_key
model = init_chat_model(
model="deepseek:deepseek-chat",
# model="qwen3.5-plus", # 模型名称,这里选择qwen3.5-plus,这是一个多模态模型,支持图片、文本、音频、视频
# model_provider="openai",
# base_url=DEEPSEEK_BASE_URL, # 这个参数没有用,Langchain会根据模型名字自动设定base_url
# api_key=DEEPSEEK_API_KEY,
temperature=1.5,
)
# 方式一:使用create_deep_agent 创建 agent,默认模型为 deepseek-chat,挂载动态切换中间件
# agent = create_deep_agent(
# model=model,
# # model="deepseek:deepseek-chat",
# middleware=[configurable_model],
# context_schema=Context,
# )
# 方式二:使用create_agent 创建 agent,
agent = create_agent(
model=model,
# configurable_model 执行模型切换的核心中间件
middleware=[configurable_model],
context_schema=Context,
)
# 通过 context 传入 qwen 模型配置,触发 configurable_model 动态切换
response = agent.invoke(
{"messages": [{"role": "user", "content": "你好!"}]},
context=Context(
model="qwen3.5-plus",
model_provider="openai",
api_key=DASHSCOPE_API_KEY,
base_url=DASHSCOPE_BASE_URL,
),
)
print(f"类型: {type(response)}")
print(f"响应: {response}")
print()
# output:
# 类型: <class 'dict'>
# 响应: {'messages': [HumanMessage(content='你好!', additional_kwargs={}, response_metadata={}, id='b15f0052-adca-44c9-afa5-11f329fc602e'), AIMessage(content='你好!👋 有什么我可以帮你的吗?无论是聊天、查询信息、写作还是其他问题,都可以随时告诉我哦!', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 750, 'prompt_tokens': 12, 'total_tokens': 762, 'completion_tokens_details': {'accepted_prediction_tokens': None, 'audio_tokens': None, 'reasoning_tokens': 717, 'rejected_prediction_tokens': None, 'text_tokens': 750}, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': None, 'text_tokens': 12}}, 'model_provider': 'openai', 'model_name': 'qwen3.5-plus', 'system_fingerprint': None, 'id': 'chatcmpl-02cf02be-f58f-93e4-a8c5-c1b66dffbed2', 'finish_reason': 'stop', 'logprobs': None}, id='lc_run--019ef84d-39f4-7e53-8d02-34073ecbde6a-0', tool_calls=[], invalid_tool_calls=[], usage_metadata={'input_tokens': 12, 'output_tokens': 750, 'total_tokens': 762, 'input_token_details': {}, 'output_token_details': {'reasoning': 717}})]}
# 从结果中提取消息列表
messages = response.get('messages', [])
if messages:
# 打印方式一:
# 获取最后一条消息(通常是最终的 AI 响应)
last_message = messages[-1]
print(f"最后一条消息类型: {type(last_message).__name__}")
print(f"内容: {last_message.content}")
# output:
# 最后一条消息类型: AIMessage
# 内容: 你好!👋 有什么我可以帮你的吗?无论是聊天、查询信息、写作还是其他问题,都可以随时告诉我哦!
# 打印方式二 美化打印
for message in messages:
# print()
message.pretty_print()
# output:
# ================================ Human Message =================================
# 你好!
# ================================== Ai Message ==================================
# 你好!👋 有什么我可以帮你的吗?无论是聊天、查询信息、写作还是其他问题,都可以随时告诉我哦!
# 打印方式三: json格式打印每一项结果
print("="*50)
print(message.model_dump_json(indent=2))
print("="*50)
# output:
# ==================================================
# {
# "content": "你好!",
# "additional_kwargs": {},
# "response_metadata": {},
# "type": "human",
# "name": null,
# "id": "5cff2bc8-cbe2-4099-922a-2b8f5b3d55a1"
# }
# ==================================================
# ================================== Ai Message ==================================
# 你好!很高兴见到你。有什么我可以帮你的吗? 👋
# ==================================================
# {
# "content": "你好!很高兴见到你。有什么我可以帮你的吗? 👋",
# "additional_kwargs": {
# "refusal": null
# },
# "response_metadata": {
# "token_usage": {
# "completion_tokens": 487,
# "prompt_tokens": 12,
# "total_tokens": 499,
# "completion_tokens_details": {
# "accepted_prediction_tokens": null,
# "audio_tokens": null,
# "reasoning_tokens": 468,
# "rejected_prediction_tokens": null,
# "text_tokens": 487
# },
# "prompt_tokens_details": {
# "audio_tokens": null,
# "cached_tokens": null,
# "text_tokens": 12
# }
# },
# "model_provider": "openai",
# "model_name": "qwen3.5-plus",
# "system_fingerprint": null,
# "id": "chatcmpl-907b7754-4aca-9a13-a34e-be3d9cd9c03b",
# "finish_reason": "stop",
# "logprobs": null
# },
# "type": "ai",
# "name": null,
# "id": "lc_run--019ef84f-f625-7502-be0c-55d42a00d6e4-0",
# "tool_calls": [],
# "invalid_tool_calls": [],
# "usage_metadata": {
# "input_tokens": 12,
# "output_tokens": 487,
# "total_tokens": 499,
# "input_token_details": {},
# "output_token_details": {
# "reasoning": 468
# }
# }
# }
# ==================================================
def main():
"""主函数,分别调用各个 demo"""
print("DASHSCOPE_API_KEY", DASHSCOPE_API_KEY)
print("DASHSCOPE_BASE_URL", DASHSCOPE_BASE_URL)
demo1_configurable_model()
if __name__ == "__main__":
main()
运行时动态切换模型的常见使用场景
运行时动态切换模型,指的是在同一个 Agent 或应用流程中,根据当前请求的上下文、任务类型、用户等级、成本预算或故障状态,动态选择实际调用的模型。
在当前示例中,agent 初始化时有一个默认模型,但在调用 agent.invoke(..., context=Context(...)) 时,会通过 configurable_model 中间件读取 context 中的模型配置,并把本次调用实际使用的模型替换掉。
1. 按任务复杂度切换模型
简单问题使用速度快、成本低的模型;复杂推理、代码分析、长文理解等任务切换到能力更强的模型。
if task_type == "simple_chat":
model = "qwen-turbo"
elif task_type == "reasoning":
model = "deepseek-reasoner"
适合场景:
- 普通闲聊
- 简单问答
- 复杂推理
- 代码分析
- 多步骤规划
2. 按用户等级切换模型
普通用户使用成本较低的模型,付费用户或高优先级用户使用更强的模型。
if user_plan == "pro":
model = "qwen3.5-plus"
else:
model = "qwen-turbo"
适合场景:
- 免费版和付费版能力区分
- 企业用户优先使用高质量模型
- 高价值请求使用更强模型
3. 按成本预算切换模型
当请求量较大或预算紧张时,自动切到低成本模型;重要任务再使用高质量模型。
适合场景:
- 高并发业务
- 成本敏感型应用
- 批量文本处理
- 非关键任务降成本
这种方式可以避免所有请求都打到最贵模型上。
4. 按模型能力切换模型
不同模型擅长不同任务,可以根据任务类型选择最合适的模型。
常见匹配方式:
- 代码生成:使用代码能力强的模型
- 数学推理:使用 reasoning 模型
- 多模态任务:使用支持图片、音频或视频的模型
- 中文问答:使用中文表现更好的模型
- 长文总结:使用长上下文模型
5. 按上下文长度切换模型
短上下文使用普通模型,长文档、长对话、RAG 场景切换到支持更大上下文窗口的模型。
适合场景:
- 文档问答
- 长对话总结
- RAG 检索增强生成
- 法律、论文、报告类长文本分析
如果检索出来的内容很长,就可以动态切换到长上下文模型。
6. 故障降级
如果主模型超时、限流或报错,可以切换到备用模型继续完成请求。
try:
use_model("qwen3.5-plus")
except Exception:
use_model("deepseek-chat")
适合场景:
- 主模型不可用
- 请求超时
- API 限流
- 服务商异常
- 生产系统容灾
7. A/B 测试和灰度发布
同一类请求随机分配到不同模型,用来比较回答质量、延迟、成本和用户满意度。
适合场景:
- 新模型上线前评估
- 比较不同模型效果
- 逐步灰度切流
- 收集用户反馈
8. 不同业务模块使用不同模型
一个系统中,不同业务模块可以使用不同模型。
例如:
- 客服对话:使用响应快的模型
- 工单总结:使用长上下文模型
- 代码审查:使用代码能力强的模型
- 复杂规划:使用推理模型
- 内容审核:使用分类或安全模型
9. Agent 内部不同步骤切换模型
一个 Agent 的不同步骤不一定都需要使用同一个模型。
例如:
- 第一步:使用便宜模型判断用户意图
- 第二步:使用强模型生成方案
- 第三步:使用快模型整理输出格式
这种方式可以在保证效果的同时控制成本和延迟。
当前代码中的对应关系
当前代码里的动态切换逻辑主要由三部分组成:
@dataclass
class Context:
model: str
model_provider: str
api_key: str | None = None
base_url: str | None = None
Context 用来保存本次调用要使用的模型配置。
@wrap_model_call
def configurable_model(request, handler):
context = request.runtime.context
model = init_chat_model(
context.model,
model_provider=context.model_provider,
api_key=context.api_key,
base_url=context.base_url,
)
return handler(request.override(model=model))
configurable_model 中间件从运行时上下文中读取模型配置,并覆盖默认模型。
response = agent.invoke(
{"messages": [{"role": "user", "content": "你好!"}]},
context=Context(
model="qwen3.5-plus",
model_provider="openai",
api_key=DASHSCOPE_API_KEY,
base_url=DASHSCOPE_BASE_URL,
),
)
agent.invoke 调用时通过 context 指定本次请求实际使用的模型。这样同一个 agent 实例就可以在不同请求中动态切换不同模型。
最后编辑:海马 更新时间:2026-07-01 20:05