smolagents学习笔记系列(番外一)使用DeepSeek API Key + CodeAgent
这篇文章是在 smolagents 官方教程结束后的番外篇,实现了如何使用 DeepSeek API Key + CodeAgent 执行你的提示词。
之所以写这篇文章是因为 smolagents 没有提供 DeepSeek 的模型接口,尽管可以通过 HfApiModel
这个类来指定使用与 DeepSeek 相关的模型,但这些都不是直接使用 API 接口,因为 HuggingFace 官网的 DeepSeek-R1
页面直接写了下面这句话:
现在还不支持 HuggingFace 的 Tramsformers 调用,因此如果确实想通过 DeepSeek 的 API 接口调用模型,我们就需要自己实现一个类来为 CodeAgent
提供可操作的模型。
Step1. 购买 DeepSeek API Key
在日前(2025年02月27日,星期四)DeepSeek 官方已经重新恢复了 API Key 的购买,在此之前服务器爆满暂停了一段时间公开销售,登录 Platform
页面在完成实名认证后就可以直接购买:https://platform.deepseek.com/top_up
。由于DeepSeek 是本土公司,所以在购买步骤上也更加人性化,可以直接使用支付宝或微信以预付的方式存放一些额度,不需要绑定信用卡也就不必担心自己将Token用超一夜破产的情况发生。
我购买的是最低额度的 10 元档位,根据使用经验直到我把代码调通总计消耗了不到 0.01 元的 Token,因此初学者也可以放心使用。
【注意】:这个API Key也是需要立即找一个地方记下来,后期也不能二次查看的。
Step2. 自定义 DeepSeek 的Model
- 官网链接:https://api-docs.deepseek.com/;
查看 DeepSeek API 平台官网中 Your First API Call
可以的发现API接口是兼容 OpenAI 格式的,我们需要参考官网demo编写自己的Model,首先要安装依赖:
【注意】demo中提到的 base_url
和 model
后期可以根据需求进行修改,官网提供了多个url与模型,但这里为了教学就用下面写的内容。
$ pip3 install openai
然后我们去查看 HfApiModel
这个类发现其通过继承 smolagents.Model
这个基类实现对 Qwen-Coder
模型的调用,并且至少需要对 __init__
和 __call__
这两个成员函数进行重写:
最快的方法就是仿照其实现一个,这里直接给出我实现好的代码,我将这个写成一个文件后面就可以放在 smolagents 库里,未来就能直接通过 from somlagents import DeekSeekModel
的方式导入了:
DeepSeekModel.py
from smolagents import Model
from smolagents import Model, Tool
from typing import TYPE_CHECKING, Any, Dict, List, Optional
from smolagents.models import parse_tool_args_if_needed, ChatMessage
from openai import OpenAI
class DeepSeekModel(Model):
"""This model connects to [DeepSeek]("https://api.deepseek.com") as a gateway to hundreds of LLMs.
Parameters:
model_id (`str`):
The model identifier to use on the server (e.g. "deepseek-chat").
api_base (`str`, *optional*):
The base URL of the OpenAI-compatible API server.
api_key (`str`, *optional*):
The API key to use for authentication.
custom_role_conversions (`dict[str, str]`, *optional*):
Custom role conversion mapping to convert message roles in others.
Useful for specific models that do not support specific message roles like "system".
**kwargs:
Additional keyword arguments to pass to the OpenAI API.
"""
def __init__(
self,
model_id: str = "deepseek-chat",
api_base="https://api.deepseek.com",
api_key=None,
custom_role_conversions: Optional[Dict[str, str]] = None,
**kwargs,
):
super().__init__(**kwargs)
self.model_id = model_id
self.api_base = api_base
self.api_key = api_key
self.custom_role_conversions = custom_role_conversions
self.flatten_messages_as_text = (
kwargs.get("flatten_messages_as_text")
if "flatten_messages_as_text" in kwargs
else self.model_id.startswith(("ollama", "groq", "cerebras"))
)
self.client = OpenAI(api_key=self.api_key, base_url=self.api_base)
def __call__(
self,
messages: List[Dict[str, Any]], # 允许 content 是 str 或 list
stop_sequences: Optional[List[str]] = None,
grammar: Optional[str] = None,
tools_to_call_from: Optional[List[Tool]] = None,
**kwargs,
) -> ChatMessage:
completion_kwargs = self._prepare_completion_kwargs(
messages=messages,
stop_sequences=stop_sequences,
grammar=grammar,
tools_to_call_from=tools_to_call_from,
model=self.model_id,
api_base=self.api_base,
api_key=self.api_key,
convert_images_to_image_urls=True,
flatten_messages_as_text=self.flatten_messages_as_text,
custom_role_conversions=self.custom_role_conversions,
**kwargs,
)
def format_content(content):
if isinstance(content, list):
return "\n".join(map(str, content)) # 处理 list -> str
return str(content)
response = self.client.chat.completions.create(
model=self.model_id,
messages=[
{"role": "system", "content": "You are a helpful assistant"},
{"role": "user", "content": "\n".join(format_content(msg["content"]) for msg in messages)},
],
stream=False
)
self.last_input_token_count = response.usage.prompt_tokens
self.last_output_token_count = response.usage.completion_tokens
message = ChatMessage.from_dict(
response.choices[0].message.model_dump(include={"role", "content", "tool_calls"})
)
message.raw = response.choices[0].message.content
if tools_to_call_from is not None:
return parse_tool_args_if_needed(message)
return message
Step3. Agent调用
在实现了 DeepSeekModel
这个类后就可以直接编写Agent进行调用了,和之前使用 HfApiModel
完全一致:
from DeepSeekModel import DeepSeekModel
from smolagents import CodeAgent
deepseek_api_key = "你的DeepSeek API Key"
model = DeepSeekModel(api_key=deepseek_api_key)
agent = CodeAgent(
model=model,
tools=[]
)
agent.max_steps = 3
agent.run("Could you give me the 118th number in the Fibonacci sequence?",)
运行如下:
$ python demo.py
可以看到 Agent 已经正确解析了我们自定义的模型,并将模型名 deepseek-chat
打印在控制台上: