从Deepseek接口到自创建简单Agent

📅 2026/7/8 3:50:15
从Deepseek接口到自创建简单Agent
摘要本文从大学生视角出发详细介绍了如何将 OpenAI 的 Function calling 工具调用机制与 DeepSeek 大模型结合使用。首先讲解了 DeepSeek API 的基本调用流程包括客户端初始化、网络连接建立、请求发送和响应接收。然后重点阐述了 Function calling 的三个核心步骤1) 定义本地工具函数2) 按照 OpenAI 规范定义工具 Schema3) 实现工具调用执行函数。文章通过完整的 Python 代码示例展示了如何实现一个支持星座运势查询、天气查询和数学计算的简单工具调用 Agent并详细解释了三种 tool_choice 模式auto、none、强制指定的使用方法。学习到工具Function calling时候突然想到deepseek好像介绍过自己的大模型如何接就想着把open ai的工具融到这里面来进行一些小娱乐# Please install OpenAI SDK first: pip3 install openai import os from openai import OpenAI client OpenAI( api_keyos.environ.get(DEEPSEEK_API_KEY), base_urlhttps://api.deepseek.com) response client.chat.completions.create( modeldeepseek-v4-pro, messages[ {role: system, content: You are a helpful assistant}, {role: user, content: Hello}, ], streamFalse, reasoning_efforthigh, extra_body{thinking: {type: enabled}} ) print(response.choices[0].message.content)这是deepseek官方的简单调用具体解释一下先实例化客户端仅初始化配置不建立连接属于懒连接机制client OpenAI( api_keyos.environ.get(DEEPSEEK_API_KEY), base_urlhttps://api.deepseek.com)后面重头戏完整链接链路也是等到*.create才真正建立连接阶段 1建立网络连接SDK 解析base_urlhttps://api.deepseek.comDNS 解析域名发起 HTTPS TCP 握手建立加密连接带上请求头Authorization 鉴权、Content-Type 等阶段 2向 DeepSeek 服务端发送完整请求体把model、messages、reasoning_effort、extra_body等参数打包成 JSON POST 请求发给服务端 服务端加载deepseek-v4-pro模型执行推理计算。阶段 3接收服务端返回的完整响应等模型推理完成服务端把结构化 JSON 返回给本地 SDKSDK 解析成ChatCompletion对象存入response变量。response client.chat.completions.create( modeldeepseek-v4-pro, messages[ {role: system, content: You are a helpful assistant}, {role: user, content: Hello}, ], streamFalse, reasoning_efforthigh, extra_body{thinking: {type: enabled}} )最后就是简单的打印出来print(response.choices[0].message.content)介绍完deepseek后也是到了今天的重头戏工具注册以及调用Function calling了Function calling基于Open ai 的SDK来进行讲解定义工具首先是定义函数def get_horoscope(sign: str) - str: 星座运势工具 return f{sign}: Next Tuesday you will befriend a baby otter. def get_weather(city: str, date: str today) - str: 查询城市天气 return f{city} {date}晴24~30℃微风 def calculate_math(expr: str) - str: 数学计算传入数学表达式 try: res eval(expr) return f计算结果 {expr} {res} except Exception as e: return f计算失败{str(e)}这里定义了三个本地工具分别是固定回答以及运算注意的是到这并未能直接使用因为你传给大模型它是有固定json格式的tools [ # 工具1星座运势 { type: function, function: { name: get_horoscope, description: Get todays horoscope for an astrological sign., parameters: { type: object, properties: { sign: { type: string, description: An astrological sign like Taurus or Aquarius, }, }, required: [sign], }, } } }这里我只定义一个如果需要多个的话就直接在后面加就完事了注意这里面五个属性及其重要Field 领域 / 范围描述type固定值为functionname函数名称示例get_weatherdescription说明该函数的适用场景、使用方式parameters定义函数入参的 JSON Schemastrict是否开启函数调用严格校验模式一般strict默认不严格而且可以看到刚开始定义的入参是要在这个json格式中声明并且确定好的定义完后肯定是要调用的那么工具调用函数怎么完成呢下一步工具调用从具体函数来讲解def run_all_tools(tool_calls): 批量执行模型返回的tool_call返回要追加到messages的tool消息列表 # 空列表存放所有工具执行完成后的标准消息 tool_messages [] # 循环遍历每一个模型要求调用的工具支持一次调用多个工具 for tool_call in tool_calls: # 1. 取出要执行的函数名称 func_name tool_call.function.name # 2. 解析参数模型返回的arguments是JSON字符串转成Python字典 func_args json.loads(tool_call.function.arguments) # 3. 函数映射字典key函数名value本地定义的函数 # 示例 tool_func_map {get_horoscope: get_horoscope, get_weather: get_weather} target_func tool_func_map[func_name] # 4. 解包字典调用本地函数拿到执行结果 func_result target_func(**func_args) # 5. 组装协议规定的tool消息 tool_msg { role: tool, tool_call_id: tool_call.id, name: func_name, content: func_result } tool_messages.append(tool_msg) # 返回全部工具消息直接 messages tool_messages 追加到对话上下文 return tool_messages直接看注释来进行理解对于tool_calls它的格式进行讲解tool_call { id: 随机唯一标识, function: { name: 要调用的函数名, arguments: {参数1:值1,参数2:123} # JSON字符串不是字典 }, type: function }这就是它的格式也是要遵循的协议按照这个你再去理解上面代码的一些参数就能理解了最后给出运行函数运行函数if __name__ __main__: # 对话上下文 messages [ {role: system, content: 优先使用工具完成用户问题无法用工具再自行回答}, {role: user, content: 帮我查武汉今天天气顺便算一下128*56我是水瓶座看看运势} ] # 三种tool_choice模式切换 # 模式1auto 自动选择是否调用、调用哪个工具默认推荐 tool_choice_mode auto # 模式2none 禁止调用任何工具模型直接回答 # tool_choice_mode none # 模式3强制指定必须调用某一个工具 # tool_choice_mode { # type: function, # function: {name: get_weather} # } # # 第一轮模型请求 response client.chat.completions.create( modelMODEL_NAME, toolstools, tool_choicetool_choice_mode, messagesmessages, temperature0.2 ) assistant_msg response.choices[0].message messages.append(assistant_msg.model_dump()) # 判断是否存在工具调用 if assistant_msg.tool_calls: # 批量执行所有工具获取工具返回消息 tool_msg_list run_all_tools(assistant_msg.tool_calls) messages.extend(tool_msg_list) print( 完整对话上下文含工具调用记录 ) print(json.dumps(messages, indent2, ensure_asciiFalse)) # 二次提交工具结果生成最终自然语言回答 final_res client.chat.completions.create( modelMODEL_NAME, messagesmessages, temperature0.2 ) print(\n 模型最终整合回答 ) print(final_res.choices[0].message.content) else: print(模型未触发工具调用直接输出) print(assistant_msg.content)到此基本讲完整个流程最后将完整代码呈上简单工具调用agentfrom openai import OpenAI import json # 【这里必须修改】 DEEPSEEK_API_KEY 自己key MODEL_NAME deepseek-chat # # 初始化DeepSeek客户端兼容OpenAI SDK client OpenAI( api_keyDEEPSEEK_API_KEY, base_urlhttps://api.deepseek.com ) # 1. 定义多个本地工具函数 def get_horoscope(sign: str) - str: 星座运势工具 return f{sign}: Next Tuesday you will befriend a baby otter. def get_weather(city: str, date: str today) - str: 查询城市天气 return f{city} {date}晴24~30℃微风 def calculate_math(expr: str) - str: 数学计算传入数学表达式 try: res eval(expr) return f计算结果 {expr} {res} except Exception as e: return f计算失败{str(e)} # 工具映射表函数名 - 实际函数核心通用分发 tool_func_map { get_horoscope: get_horoscope, get_weather: get_weather, calculate_math: calculate_math } # 2. 多工具Schema定义全部注册给模型 tools [ # 工具1星座运势 { type: function, function: { name: get_horoscope, description: Get todays horoscope for an astrological sign., parameters: { type: object, properties: { sign: { type: string, description: An astrological sign like Taurus or Aquarius, }, }, required: [sign], }, } }, # 工具2天气查询 { type: function, function: { name: get_weather, description: Query weather of target city, support custom date, parameters: { type: object, properties: { city: { type: string, description: City name, e.g. Beijing, Shanghai }, date: { type: string, description: Query date, default today, } }, required: [city] } } }, # 工具3数学计算器 { type: function, function: { name: calculate_math, description: Calculate math expression like 12*3, sqrt(16), parameters: { type: object, properties: { expr: { type: string, description: Mathematical expression string } }, required: [expr] } } } ] # 3. 通用工具调用执行函数 def run_all_tools(tool_calls): 批量执行模型返回的tool_call返回要追加到messages的tool消息列表 tool_messages [] for tool_call in tool_calls: func_name tool_call.function.name func_args json.loads(tool_call.function.arguments) # 根据函数名自动匹配本地函数 target_func tool_func_map[func_name] func_result target_func(**func_args) # 组装tool角色消息 tool_msg { role: tool, tool_call_id: tool_call.id, name: func_name, content: func_result } tool_messages.append(tool_msg) return tool_messages if __name__ __main__: # 对话上下文 messages [ {role: system, content: 优先使用工具完成用户问题无法用工具再自行回答}, {role: user, content: 帮我查武汉今天天气顺便算一下128*56我是水瓶座看看运势} ] # 三种tool_choice模式切换 # 模式1auto 自动选择是否调用、调用哪个工具默认推荐 tool_choice_mode auto # 模式2none 禁止调用任何工具模型直接回答 # tool_choice_mode none # 模式3强制指定必须调用某一个工具 # tool_choice_mode { # type: function, # function: {name: get_weather} # } # # 第一轮模型请求 response client.chat.completions.create( modelMODEL_NAME, toolstools, tool_choicetool_choice_mode, messagesmessages, temperature0.2 ) assistant_msg response.choices[0].message messages.append(assistant_msg.model_dump()) # 判断是否存在工具调用 if assistant_msg.tool_calls: # 批量执行所有工具获取工具返回消息 tool_msg_list run_all_tools(assistant_msg.tool_calls) messages.extend(tool_msg_list) print( 完整对话上下文含工具调用记录 ) print(json.dumps(messages, indent2, ensure_asciiFalse)) # 二次提交工具结果生成最终自然语言回答 final_res client.chat.completions.create( modelMODEL_NAME, messagesmessages, temperature0.2 ) print(\n 模型最终整合回答 ) print(final_res.choices[0].message.content) else: print(模型未触发工具调用直接输出) print(assistant_msg.content)希望对你们有所帮助也是从一个大学生视角来进行一步一步cang