当前位置: 首页 > news >正文

DeepSeek实战--Function Calling

1.背景

Function Calling由OpenAI提出,用于解决AI与外部系统交互的“桥梁”,通过将自然语言转化为结构化请求。允许模型根据用户输入的自然语言指令,自动识别需要调用的外部工具或API函数,并生成符合要求的结构化参数(如JSON格式)。这一技术让AI不仅能生成文本,还能与外部系统交互,完成更复杂的任务。
今天我们通过一个demo演示Function Calling 应用。

2.环境

  • python 版本:3.11
  • LLM: deepseek-chat
  • SDK:openai 1.63.2

3.步骤

1)先注册deepseek账号,并充值,获取到APIkey
在这里插入图片描述
链接:https://platform.deepseek.com/api_keys

2)写一个获取最新股价的tools

def get_closing_price(name):if name == "青岛啤酒":return "67.92"elif name == "贵州茅台":return "1488.21"else:return "未搜到该股票"

3)定义一个工具列表,用于结构化说明tools,便于大模型理解

tools = [# 定义一个字典,表示一个特定的工具{# 工具的类型是函数"type": "function",# 函数的具体信息"function": {# 函数的名称是get_closing_price"name": "get_closing_price",# 函数的描述,说明了该函数的用途"description": "使用该工具获取指定股票的收盘价",# 函数的参数信息"parameters": {# 参数的类型是对象"type": "object",# 参数的属性"properties": {# 需要一个名称参数"name": {# 参数类型是字符串"type": "string",# 参数的描述,说明了需要提供股票名称"description": "股票名称",}},# 表示在参数中,'name'字段是必须提供的"required": ["name"]},}},
]

4)写一个程序调用大模型 + tools

import json
import os
# 导入OpenAI库,用于与OpenAI的API进行交互
from openai import OpenAIclient = OpenAI(api_key="sk-xxx【自己申请】",base_url="https://api.deepseek.com/v1")def send_messages(messages):response = client.chat.completions.create(model="deepseek-chat",messages=messages,tools=tools,tool_choice="auto")return response# 定义一个工具列表,用于存储不同类型的工具信息
tools = [# 定义一个字典,表示一个特定的工具{# 工具的类型是函数"type": "function",# 函数的具体信息"function": {# 函数的名称是get_closing_price"name": "get_closing_price",# 函数的描述,说明了该函数的用途"description": "使用该工具获取指定股票的收盘价",# 函数的参数信息"parameters": {# 参数的类型是对象"type": "object",# 参数的属性"properties": {# 需要一个名称参数"name": {# 参数类型是字符串"type": "string",# 参数的描述,说明了需要提供股票名称"description": "股票名称",}},# 表示在参数中,'name'字段是必须提供的"required": ["name"]},}},
]def get_closing_price(name):if name == "青岛啤酒":return "67.92"elif name == "贵州茅台":return "1488.21"else:return "未搜到该股票"if __name__ == "__main__":messages = [{"role": "user", "content": "青岛啤酒的收盘价是多少?"}]response = send_messages(messages)# 将API响应中的第一个选择的消息添加到消息列表中messages.append(response.choices[0].message)print("回复:")# 打印回复消息的内容print(response.choices[0].message.content)print("工具选择:")# 打印AI模型的响应中第一个选择的消息的工具调用信息print(response.choices[0].message.tool_calls)# 检查响应中的第一个选择是否包含工具调用# 检查响应中是否包含工具调用if response.choices[0].message.tool_calls != None:# 如果包含工具调用,获取第一个工具调用对象tool_call = response.choices[0].message.tool_calls[0]# 检查工具调用的函数名称是否为获取收盘价的函数if tool_call.function.name == "get_closing_price":# 解析函数参数,获取股票名称arguments_dict = json.loads(tool_call.function.arguments)# 调用函数获取收盘价price = get_closing_price(arguments_dict['name'])# 将获取到的收盘价信息添加到消息列表中messages.append({"role": "tool","content": price,"tool_call_id": tool_call.id})# 打印消息列表print("messages: ",messages)# 发送消息列表并获取新的响应response = send_messages(messages)print("回复:")print(response.choices[0].message.content)

4.成果

回复:工具选择:
[ChatCompletionMessageToolCall(id='call_0_bcae63ee-55f4-49cd-9310-800f443a8ed8', function=Function(arguments='{"name":"青岛啤酒"}', name='get_closing_price'), type='function', index=0)]
messages:  [{'role': 'user', 'content': '青岛啤酒的收盘价是多少?'}, ChatCompletionMessage(content='', refusal=None, role='assistant', annotations=None, audio=None, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_0_bcae63ee-55f4-49cd-9310-800f443a8ed8', function=Function(arguments='{"name":"青岛啤酒"}', name='get_closing_price'), type='function', index=0)]), {'role': 'tool', 'content': '67.92', 'tool_call_id': 'call_0_bcae63ee-55f4-49cd-9310-800f443a8ed8'}]
回复:
青岛啤酒的收盘价是67.92元。

5.总结

1)我一直用的java开发,写python脚本比较吃力,借助“通义灵码”轻松多了
2) 为什么需要2次调用大模型?

第一次,交互用于触发工具调用;
第二次,交互用于将工具调用的结果返回给模型,使其能够整合信息并生成用户可理解的最终回复。
这种设计符合“工具调用”的典型使用模式:先由模型判断是否需要调用工具,再实际调用工具并将结果反馈回模型以生成完整回答。

3)为什么要导入OpenAI sdk ?
OpenAI sdk 调用大模型的协议,各个大模型都做了兼容。 这样底层换了LLM也不需要更改,接口定义及程序调用。

http://www.xdnf.cn/news/257599.html

相关文章:

  • Java 京东面试面试题及答案
  • 用Selenium开启自动化网页交互与数据抓取之旅
  • Linux管道识
  • 阿里通义千问 Qwen3 模型发布
  • 学习笔记:Qlib 量化投资平台框架 — OTHER COMPONENTS/FEATURES/TOPICS
  • 【2025年五一数学建模竞赛】C题 完整论文 模型建立与求解
  • 数据库索引优化实战: 如何设计高效的数据库索引
  • 「Mac畅玩AIGC与多模态14」开发篇10 - 固定文本输出工作流示例
  • 算法篇(九)【滑动窗口】
  • 题解传送门
  • SpringBoot商城平台系统设计与开发
  • 网络管理工具 iptable 详解
  • 第 7 篇:跳表 (Skip List):简单务实的概率性选手
  • 深度理解linux系统—— 进程切换和调度
  • 系统架构设计师:设计模式——结构型设计模式
  • 全国信息素养大赛 图形化挑战赛~复赛练习-在正方形内吗?
  • Python基本语法(自定义函数)
  • 雪碧图的原理,使用
  • 组件通信-$refs、$parent
  • C++--入门基础
  • MQTT 协议与 HTTP 协议的区别
  • 操作符详解:逗号表达式与下标访问和函数调用操作符
  • 论文阅读笔记——TesserAct: Learning 4D Embodied World Models
  • 【unity游戏开发入门到精通——UGUI】UGUI自动布局组件
  • 数值与字典解决方案第二十六讲:FILTER函数在去除数据的方法
  • 【大模型】多模态推理
  • 传奇各职业/战士/法师/道士戒指爆率及出处产出地/圣战/法神/天尊/虹魔/魔血/麻痹/超负载/求婚/隐身/传送/复活/护身/祈祷/火焰
  • 第Y3周:yolov5s.yaml文件解读
  • C++ set和map
  • 【dify—10】工作流实战——文生图工具