smolagents 模型层指南:Model 接口契约、内置模型与自定义 LLM 接入
2026/9/19 8:43:11 网站建设 项目流程

smolagents 模型层指南:Model 接口契约、内置模型与自定义 LLM 接入

【免费下载链接】smolagents🤗 smolagents: a barebones library for agents that think in code.项目地址: https://gitcode.com/gh_mirrors/smo/smolagents

本篇基于 smolagents 仓库中的模型参考文档(docs/source/zh/reference/models.md)与模型层核心实现(src/smolagents/models.py)整理。文章围绕 smolagents 的模型抽象展开:先讲清“什么对象可以充当 Agent 的模型”这一接口契约,再逐一拆解 TransformersModel、InferenceClientModel、LiteLLMModel、OpenAIModel、AzureOpenAIModel、MLXModel 等内置模型类,最后深入到 API 模型的限流与重试机制、参数优先级和序列化安全机制。读完后你可以直接选型内置模型驱动 CodeAgent,也能按契约快速接入任意自研 LLM。

需要说明的前提:smolagents 是一个实验性 API,官方文档明确提示其可能随时变化,底层 API 或模型变动都可能导致 Agent 结果不同;当前仓库版本为1.27.0.dev0(见 pyproject.toml)。

模型接口契约:任何可调用对象都能驱动 Agent

smolagents 对模型没有强绑定,你可以自由创建和使用自己的模型为智能体提供支持。文档给出的准入条件只有两条:

  1. 它遵循消息格式(List[Dict[str, str]]),将其作为输入messages,并返回一个包含.content属性的对象,其中包含生成的文本;
  2. 它在生成的序列到达stop_sequences参数中指定的内容之前停止生成输出。

要定义你的 LLM,可以创建一个custom_model方法,它接受一个 messages 列表,并返回包含.content属性的对象。此可调用对象还需要接受一个stop_sequences参数,用于指示何时停止生成。文档给出的示例基于 Hugging Face InferenceClient:

from huggingface_hub import login, InferenceClient login("<YOUR_HUGGINGFACEHUB_API_TOKEN>") model_id = "meta-llama/Llama-3.3-70B-Instruct" client = InferenceClient(model=model_id) def custom_model(messages, stop_sequences=["Task"]): response = client.chat_completion(messages, stop=stop_sequences, max_tokens=1000) answer = response.choices[0].message return answer

此外,custom_model还可以接受一个grammar参数。如果在智能体初始化时指定了grammar,则此参数将在调用模型时传递,以便进行约束生成,从而强制生成格式正确的智能体输出。

从源码结构看,这套契约的正式承载者是 models.py 中的Model基类:

  • 所有模型实现必须实现generate(messages, stop_sequences=None, response_format=None, tools_to_call_from=None, **kwargs),返回值是统一的ChatMessage数据类(见 ChatMessage 定义),其中content即生成文本,tool_callstoken_usageraw分别承载工具调用、token 统计和原始响应;
  • Model.__call__直接委托给generate,所以文档中“可调用对象”的写法与基类语义一致;
  • 基类还暴露了tool_name_key(默认"name")与tool_arguments_key(默认"arguments"),用于从纯文本响应中解析工具调用(parse_tool_calls方法,models.py),这正是 CodeAgent 依赖“输出以Task等停止序列结束”这类文本协议的原因。

_prepare_completion_kwargs(models.py)是参数装配的中枢,值得注意两点:

  1. 参数优先级:文档化的优先级为“模型初始化时的self.kwargs(最高)> 调用时显式传入的 kwargs > 具体参数(stop_sequences、response_format 等)”。测试 tests/test_models.py 专门验证了这一点:初始化时写Model(max_tokens=100)会覆盖调用时传入的max_tokens=50
  2. REMOVE_PARAMETER 哨兵:把某个参数设为REMOVE_PARAMETER可以从最终请求中移除该参数(同样有测试覆盖)。

另外,当传入tools_to_call_from时,默认tool_choice="required"(测试 tests/test_models.py 覆盖了required/auto/工具名/字典/显式None等组合),这保证了 API 模型在工具场景下倾向发出结构化 tool call。

消息格式与内部数据流

文档提到的消息格式List[Dict[str, str]]在仓库中由get_clean_message_list(models.py)统一清洗:它接受ChatMessage或 dict 混合列表,支持自定义role_conversions角色映射,可把图片编码为 base64 或image_url,并在flatten_messages_as_text=True时把相邻同角色消息合并为纯文本。默认的角色映射是tool_role_conversions = {TOOL_CALL: ASSISTANT, TOOL_RESPONSE: USER}。角色集合由MessageRole枚举定义:userassistantsystemtool-calltool-response(models.py)。

一个容易被忽略的实现细节是stop_sequences 的“事后截断”。部分推理模型(如 openai/o3、o4-mini、gpt-5 系列及部分 grok 模型)的 API 不支持stop参数,supports_stop_parameter(models.py)会根据model_id判断:不支持时不向 API 传stop,而在拿到响应后调用remove_content_after_stop_sequences把停止序列之后的内容切掉。测试 test_supports_stop_parameter 用大量模型 ID 覆盖了该正则(含带路径前缀、带日期后缀、o3-mini例外等边缘情况),test_stop_sequence_cutting_for_o4_mini 则验证了事后截断行为。

内置模型一:TransformersModel(本地推理)

TransformersModel为初始化时指定的model_id构建一个本地transformerspipeline 来实现上述功能:

from smolagents import TransformersModel model = TransformersModel(model_id="HuggingFaceTB/SmolLM-135M-Instruct") print(model([{"role": "user", "content": [{"type": "text", "text": "Ok!"}]}], stop_sequences=["great"]))
>>> What a

必须在机器上安装transformerstorch。如果尚未安装,请运行pip install 'smolagents[transformers]'(该 extra 实际还包含accelerate和 torch 依赖,见 pyproject.toml 的[project.optional-dependencies])。

结合 TransformersModel 源码 可以补充若干文档未展开的参数:

  • max_new_tokens默认4096max_tokens是其别名且优先级更高;
  • device_map不传时自动选择cuda(若可用)否则cpu
  • torch_dtypetrust_remote_code(Hub 上需要远程代码的模型须置True)、model_kwargs(透传给from_pretrained)、apply_chat_template_kwargs均可用;
  • 它会先尝试AutoModelForImageTextToText加载视觉语言模型(配合AutoProcessor),失败且报错为 "Unrecognized configuration class" 时回退到AutoModelForCausalLM+AutoTokenizer——因此非视觉模型的消息会被展平为纯文本(flatten_messages_as_text由是否 VLM 自动决定);
  • 停止序列通过自定义StoppingCriteria实现(逐 token 解码后检查流是否以任一 stop 字符串结尾),生成后仍会再做一次remove_content_after_stop_sequences截断兜底;
  • 它不支持response_format(结构化输出),源码中直接抛出ValueError并提示“use VLLMModel for this”;
  • 额外提供generate_stream,用TextIteratorStreamer在独立线程中逐 token 输出(测试 test_transformers_message_no_tool 验证了非流式与流式输出一致)。

内置模型二:InferenceClientModel(Hugging Face 推理网络)

InferenceClientModel封装了 huggingface_hub 的 InferenceClient 用于执行 LLM,支持 HF 的 Inference API 以及 Hub 上所有可用的 Inference Providers(Cerebras、Cohere、Fal、Fireworks、HF-Inference、Hyperbolic、Nebius、Novita、Replicate、SambaNova、Together 等):

from smolagents import InferenceClientModel messages = [ {"role": "user", "content": [{"type": "text", "text": "Hello, how are you?"}]} ] model = InferenceClientModel() print(model(messages))
>>> Of course! If you change your mind, feel free to reach out. Take care!

从 InferenceClientModel 源码 可见其关键参数与默认值:

  • model_id默认"Qwen/Qwen3-Next-80B-A3B-Thinking"(注释标明未来可能变更);provider默认"auto",即选取该模型可用的第一个 Provider;传入base_urlprovider不生效;
  • tokenapi_key二选一(api_key是为了对齐 OpenAI 客户端命名而设的别名),都不传时读取环境变量HF_TOKEN,否则回退到 HF CLI 本地配置;timeout默认 120 秒;
  • 支持requests_per_minute限流(经由ApiModel,见下文“API 模型的公共机制”);
  • 结构化输出(response_format)仅限STRUCTURED_GENERATION_PROVIDERS = ["cerebras", "fireworks-ai"]两个 provider,否则会抛出ValueError(有对应测试 test_structured_outputs_with_unsupported_provider);
  • 同样提供generate_stream流式接口。

内置模型三:LiteLLMModel 与 LiteLLMRouterModel(100+ 提供商)

LiteLLMModel利用 LiteLLM 支持来自不同提供商的 100+ 个 LLM。你可以在模型初始化时传递kwargs,这些参数将在每次使用模型时被使用,例如下面的示例中传递了temperature

from smolagents import LiteLLMModel messages = [ {"role": "user", "content": [{"type": "text", "text": "Hello, how are you?"}]} ] model = LiteLLMModel(model_id="anthropic/claude-3-5-sonnet-latest", temperature=0.2, max_tokens=10) print(model(messages))

安装方式为pip install 'smolagents[litellm]'。从 LiteLLMModel 源码 补充:model_id缺省时默认anthropic/claude-3-5-sonnet-20240620(并给出将变为必传的未来警告);flatten_messages_as_textollamagroqcerebras前缀的模型默认置True,其余默认False;图片内容会以image_url(data URL)形式传给 API。

LiteLLMRouterModel则继承 LiteLLM 的 Router,提供跨多部署的负载均衡、队列化、冷却/回退与指数退避重试等路由策略,适合把同一模型名挂到多个后端:

from smolagents import LiteLLMRouterModel messages = [ {"role": "user", "content": [{"type": "text", "text": "Hello, how are you?"}]} ] model = LiteLLMRouterModel( model_id="llama-3.3-70b", model_list=[ { "model_name": "llama-3.3-70b", "litellm_params": {"model": "groq/llama-3.3-70b", "api_key": os.getenv("GROQ_API_KEY")}, }, { "model_name": "llama-3.3-70b", "litellm_params": {"model": "cerebras/llama-3.3-70b", "api_key": os.getenv("CEREBRAS_API_KEY")}, }, ], client_kwargs={ "routing_strategy": "simple-shuffle", }, ) print(model(messages))

测试 TestLiteLLMRouterModel 验证了model_listclient_kwargs会原样传给litellm.router.Router构造函数。

内置模型四:OpenAIModel 与 AzureOpenAIModel

OpenAIModel允许你调用任何 OpenAI 兼容(OpenAI Server)模型,可通过api_base指向其他服务器:

import os from smolagents import OpenAIModel model = OpenAIModel( model_id="gpt-4o", api_base="https://api.openai.com/v1", api_key=os.environ["OPENAI_API_KEY"], )

需要安装pip install 'smolagents[openai]'。从 OpenAIModel 源码 看,它还有organizationprojectclient_kwargs(如max_retries)等参数,全部透传给openai.OpenAI客户端(测试 test_client_kwargs_passed_correctly 验证了透传);generate_stream支持流式 tool call 聚合(测试 test_streaming_tool_calls 覆盖了并行final_answer工具调用场景)。仓库中OpenAIServerModel是它的别名。

AzureOpenAIModel允许你连接到任何 Azure OpenAI 部署。下面是设置示例,请注意,如果已经设置了相应的环境变量,你可以省略azure_endpointapi_keyapi_version参数——环境变量包括AZURE_OPENAI_ENDPOINTAZURE_OPENAI_API_KEYOPENAI_API_VERSION

请注意,OPENAI_API_VERSION没有AZURE_前缀,这是由于底层 openai 包的设计所致。

import os from smolagents import AzureOpenAIModel model = AzureOpenAIModel( model_id = os.environ.get("AZURE_OPENAI_MODEL"), azure_endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"), api_key=os.environ.get("AZURE_OPENAI_API_KEY"), api_version=os.environ.get("OPENAI_API_VERSION") )

实现上AzureOpenAIModel继承OpenAIModel,仅在create_client中改用openai.AzureOpenAI并把api_versionazure_endpoint注入客户端参数(models.py),测试 TestAzureOpenAIModel 验证了参数组装。

内置模型五:MLXModel(Apple Silicon 本地推理)

from smolagents import MLXModel model = MLXModel(model_id="HuggingFaceTB/SmolLM-135M-Instruct") print(model([{"role": "user", "content": "Ok!"}], stop_sequences=["great"]))
>>> What a

必须在机器上安装mlx-lm。如果尚未安装,请运行pip install 'smolagents[mlx-lm]'。从 MLXModel 源码 可补充:load_kwargs透传给mlx_lm.loadtrust_remote_code默认Falseapply_chat_template_kwargs默认带add_generation_prompt=True;mlx-lm 不支持视觉模型,消息一律展平为纯文本;流式生成中逐 token 检查 stop 序列并以text.rfind精确截断(测试 test_get_mlx_message_tricky_stop_sequence 专门覆盖了 stop 序列后紧跟其他字符的场景);MLX 不支持结构化输出,传response_format会报错。该测试仅在 macOS 上运行(skipif not darwin)。

模型注册表中的其他成员

除文档主体覆盖的模型外,模型注册表 MODEL_REGISTRY 还登记了VLLMModel(本地 vLLM 服务,pip install 'smolagents[vllm]',支持 JSON schema 结构化输出与model_kwargs/apply_chat_template_kwargs)和AmazonBedrockModelpip install 'smolagents[bedrock]',基于 boto3bedrock-runtimeconverse接口,默认把所有角色映射为user,且不支持response_format)。这两个类与上述模型一样通过from_dict参与模型序列化。

API 模型的公共机制:限流、重试与停止序列兜底

所有 API 系模型(InferenceClientModelLiteLLMModelOpenAIModelAzureOpenAIModelAmazonBedrockModel)都继承ApiModel(models.py),共享三套基础设施:

  1. 客户端注入client参数允许传入预配置的客户端实例,否则调用子类的create_client()
  2. 限流requests_per_minute参数经RateLimiter(utils.py)实现,按60/requests_per_minute秒的最小间隔节流,None时禁用;
  3. 限流错误重试retry=True时,请求经由Retrying(utils.py)执行,最多RETRY_MAX_ATTEMPTS = 3次,基准等待RETRY_WAIT = 60秒、指数底数 2、带抖动(常量定义)。重试谓词is_rate_limit_error通过错误信息中是否含429rate limittoo many requestsrate_limit判定。测试 test_retry_on_rate_limit_error 用 mock 验证了“两次 429 后成功、共调用 3 次”以及指数退避的耗时区间。

每次generate返回的ChatMessage都携带token_usage(input/output token 数)与raw原始响应,供记忆、监控(monitoring.py)与运行日志使用。

安装、依赖与模型序列化

结合 pyproject.toml,与模型相关的可选依赖(extras)如下:

模型类安装命令依赖要点
TransformersModelpip install 'smolagents[transformers]'accelerate+transformers>=4.0.0(排除 5.13.0)+ torch/torchvision/numpy
InferenceClientModel核心依赖即可huggingface-hub已是基础依赖
LiteLLMModel/LiteLLMRouterModelpip install 'smolagents[litellm]'litellm>=1.60.2
OpenAIModel/AzureOpenAIModelpip install 'smolagents[openai]'openai>=1.58.1
AmazonBedrockModelpip install 'smolagents[bedrock]'boto3>=1.36.18
MLXModelpip install 'smolagents[mlx-lm]'mlx-lm
VLLMModelpip install 'smolagents[vllm]'vllm>=0.10.2+ torch

每个模型类在缺失对应依赖时会抛出带安装提示的ModuleNotFoundError(例如VLLMModel的检查见 models.py),可据此快速定位环境问题。

最后,模型实例可以安全地序列化进 Agent 存档:Model.to_dict(models.py)导出model_id与采样参数(temperaturemax_tokensproviderapi_basedevice_map等),但出于安全考虑不导出token/api_key,并打印提示需手动导出;反序列化时只允许MODEL_REGISTRY中登记的类名实例化,防止任意代码执行。这一机制配合from_dict使保存/恢复智能体成为可能。

小结

  • 自定义模型只需满足两个条件:接受messagesList[Dict[str, str]])+stop_sequences,返回带.content的对象;进阶可实现Model子类并支持grammar约束生成;
  • 参数传递遵循“初始化 kwargs 最高优先级”,可用REMOVE_PARAMETER移除参数;
  • 停止序列在不支持的模型上会自动退化为事后截断,行为可预期(有完整测试矩阵);
  • API 模型统一具备requests_per_minute限流与 429 指数退避重试;
  • 选型建议:本地小模型用TransformersModel/MLXModel/VLLMModel,托管推理用InferenceClientModel,多厂商统一接入用LiteLLMModel,多后端负载均衡用LiteLLMRouterModel,Azure/Bedrock 云部署用对应专属类。

更多 API 细节可直接查阅 模型参考文档 与 tests/test_models.py 中的用例。

【免费下载链接】smolagents🤗 smolagents: a barebones library for agents that think in code.项目地址: https://gitcode.com/gh_mirrors/smo/smolagents

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询