function calling实现调用理杏仁api获取数据
LLM是不存在真正逻辑的且并不是知晓万事万物的(至少目前是这样)在很多更垂直的环境下LLM并不能很好的赋能。
function calling的实现使LLM可以对接真正的世界以及真正有逻辑的系统,这将很大程度上改变LLM的可用范围(当然安全问题依旧是不容忽视的事)。
环境简述
model: gpt-3.5-turbo
api: 理杏仁开放平台
tools
首先我们需要分析需求涉及到什么逻辑功能(函数),并且将该功能的用途,参数及参数的用途进行格式化整理(json/yaml格式)。
针对理杏仁的使用,以下为一个简单的需求:
- 可以获取到某天某指数的PE-TTM的当前分位点
针对上述需求可以拆分出如下几点:
- 针对需求有两个api是我们将会调用的:基础信息(获取所有指数),基本面数据(获取日期的指数数据)
- 我们需要保证user指定的指数是存在的,基础信息api,从中拿到指数代码,当无法找到时结束当前对话【get_code】
- 我们需要指定日期,user可能会使用类似今天昨天等词汇,我们需要自构建函数可以处理日期【date】
- 当我们有了指数代码和日期后便可以调用基本面数据api获得对应的数据【get_cvpos】
step1: 构建函数
针对上述分析,我们需要三个函数,其中两个函数主要工作是调用api(get_code
和 get_cvpos
)另外一个是获取当前日期的函数(date
)
具体函数内容如下:
def get_code(self, name: str):print(f"name: {name}")response = requests.post(f"{self.url}", json=self.base_json).json()for item in response["data"]:if item["name"] == name:return {"stockcode": item["stockCode"]}return {"stockcode": f"未找到{name}, 请检查输入!"}def get_cvpos(self, stockcode: str, date: str):print(f"stockcode: {stockcode}, date: {date}")data = self.base_jsondata.update({"date": date,"stockCodes": [stockcode],"metricsList": ["pe_ttm.y5.mcw.cvpos"]})response = requests.post(url=f"{self.url}/fundamental", json=data)response = response.json()if not response["data"]:return {"cvpos": f"所指定日期暂无数据,请确定{date}是否为交易日"}return {"cvpos": response["data"][0]["pe_ttm.y5.mcw.cvpos"]}def date(self, delta: str = 0):print(f"delta: {delta}")day = datetime.date.today() + datetime.timedelta(int(delta))return {"date": day}
有了函数之后我们需要通过用户的输入来判断我们什么时间需要调用哪一个函数,且需要判断写入什么样的参数。从日常语言转换为结构化数据是一个复杂的过程,当然我们可以通过各种方式约束用户的描述(例如表单等)但随着需要的参数越来越多逻辑就可能会越来越复杂。
step2: 传递tools
function calling就可以很好的实现自然语言到结构化数据的转变,我们只需要将每个函数的作用及调用规则告诉模型即可,模型会根据user的问题返回需要调用的函数及作为参数的结构化数据。
针对上述需求我们构建出如下 TOOLS
来描述函数:
TOOLS = [{"type": "function","function": {"name": "get_code","description": "获取某个指数的代码","parameters": {"type": "object","properties": {"name": {"type": "string","description": "指数名称, 例如: 沪深300, 上证50",}},"required": ["name"],}}},{"type": "function","function": {"name": "date","description": "获取前天/昨天/今天的日期, 如果直接指定了日期则无需调用该function","parameters": {"type": "object","properties": {"delta": {"type": "string","description": "今天为0, 昨天为-1, 前天为-2"}}}}},{"type": "function","function": {"name": "get_cvpos","description": "获取某天给定代码的指数指标","parameters": {"type": "object","properties": {"stockcode": {"type": "string","description": "所给定的指数代码"},"date": {"type": "string","description": "日期, 格式为2024-06-25"}},"required": ["code", "date"],}}}
]
TOOLS的内容最终也会作为prompt的一部分交给大模型,因此使用时也需要考虑token消耗带来的费用。
我们只需要将TOOLS通过tools参数传递给模型即可。
response = client.chat.completions.create(model=model,messages=messages,temperature=0,seed=1024,tool_choice="auto",tools = TOOLS)
step3: 模型响应内容及函数调用
user提问:可以告诉我沪深300的代码吗?
正常情况下模型将会返回如下结果:
{"content": null,"role": "assistant","function_call": null,"tool_calls": [{"id": "call_WeIPPDsWwzOLH90IV0dSEp1q","function": {"arguments": "{\"name\":\"沪深300\"}","name": "get_code"},"type": "function"}]
}
在返回的结果中我们可以清楚的知道对于user的提问需要要调用get_code函数且入参为{“name”: “沪深300”},此时我们便可以轻松使用 getattr() 的方式来调用函数。
messages完整流程
user的一次对话可能会不止一次调用模型,因此需要使用列表存储过程中产生的所有message来保证对话的连续。如下:
messages = [{"role": "system", "content": "你是一个指数查询器(此处的指数是指金融上的指数)"},{"role": "user", "content": "xxxx"}]
response = self.get_completion(messages)
messages.append(response)while (response.tool_calls is not None):for tool_call in response.tool_calls:print(f"=== start function {tool_call.function.name} ===")args = json.loads(tool_call.function.arguments)result = getattr(self.tools, tool_call.function.name)(**args)messages.append({"tool_call_id": tool_call.id, # 用于标识函数调用的 ID"role": "tool","name": tool_call.function.name,"content": str(result) # 数值result 必须转成字符串})response = self.get_completion(messages)messages.append(response)print("===== 最终回复 =====")
print(response.content)
结果展示
user提供的prompt为:请告诉我昨天沪深300的数据
注:该文章完成时间为2024年7月16日,因此昨天应为2024-07-15
1. 最终回复
昨天(2024年7月15日)沪深300指数的收盘点位为0.4026。
2. 完整打印
{"role": "system","content": "你是一个指数查询器(此处的指数是指金融上的指数)"
}
{"role": "user","content": "请告诉我昨天沪深300的数据"
}
{"content": null,"role": "assistant","function_call": null,"tool_calls": [{"id": "call_fLWvI0BVRsuzUEj4TTwvAnke","function": {"arguments": "{\"delta\":\"-1\"}","name": "date"},"type": "function"}]
}
{"tool_call_id": "call_fLWvI0BVRsuzUEj4TTwvAnke","role": "tool","name": "date","content": "{'date': datetime.date(2024, 7, 15)}"
}
{"content": null,"role": "assistant","function_call": null,"tool_calls": [{"id": "call_eDB0nZu5V5xLAZWs3osXdAXS","function": {"arguments": "{\"name\":\"沪深300\"}","name": "get_code"},"type": "function"}]
}
{"tool_call_id": "call_eDB0nZu5V5xLAZWs3osXdAXS","role": "tool","name": "get_code","content": "{'stockcode': '000300'}"
}
{"content": null,"role": "assistant","function_call": null,"tool_calls": [{"id": "call_XtS9TkIngpdCVlRLNx5kYmeh","function": {"arguments": "{\"stockcode\":\"000300\",\"date\":\"2024-07-15\"}","name": "get_cvpos"},"type": "function"}]
}
{"tool_call_id": "call_XtS9TkIngpdCVlRLNx5kYmeh","role": "tool","name": "get_cvpos","content": "{'cvpos': 0.40264026402640263}"
}
{"content": "昨天(2024年7月15日)沪深300的收盘指数为0.4026。","role": "assistant","function_call": null,"tool_calls": null
}
相关文章:
function calling实现调用理杏仁api获取数据
LLM是不存在真正逻辑的且并不是知晓万事万物的(至少目前是这样)在很多更垂直的环境下LLM并不能很好的赋能。 function calling的实现使LLM可以对接真正的世界以及真正有逻辑的系统,这将很大程度上改变LLM的可用范围(当然安全问题依…...
Excel中用VBA实现Outlook发送当前工作簿
Excel中用VBA实现Outlook发送当前工作簿,首先按AltF11打开VBA编辑器,插入模块,并在工具-引用中勾选 Microseft Outlook .0 Object Library(其中为你Microseft Outlook的版本号。 Sub 发送邮件() 保存当前excel ThisWorkbook.Save让excel连接…...

从 ArcMap 迁移到 ArcGIS Pro
许多 ArcMap 用户正在因 ArcGIS Pro 所具有的现代 GIS 桌面工作流优势而向其迁移。 ArcGIS Pro 与其余 ArcGIS 平台紧密集成,使您可以更有效地共享和使用内容。 它还将 2D 和 3D 组合到一个应用程序中,使您可以在同一工程中使用多个地图和多个布局。 Arc…...

WSL2 的安装与运行 Linux 系统
前言 适用于 Linux 的 Windows 子系统 (WSL) 是 Windows 的一项功能,允许开发人员在 Windows 系统上直接安装并使用 Linux 发行版。不用进行任何修改,也无需承担传统虚拟机或双启动设置的开销。 可以将 WSL 看作也是一个虚拟机,但是它更为便…...

业务终端动态分配IP-DHCP技术、DHCP中继技术
一、为什么需要DHCP? 1、许多设备(主机、无线WiFi终端等)需要动态地址的分配; 2、人工手工配置任务繁琐、容易出错,比如:IP地址冲突; 3、网络规模扩大、复杂度提高,网络配置越来越复杂,计算机的位置变化和数量超过可分配IP地址的数量,造成IP地址变法频繁以及IP地址…...

新一代大语言模型 GPT-5 对工作与生活的影响及应对策略
文章目录 📒一、引言 📒二、GPT-5 的发展背景 🚀(一)GPT-4 的表现与特点 🚀(二)GPT-5 的预期进步 📒三、GPT-5 对工作的影响 🚀(一…...

AI基于大模型语言存在的网络安全风险
目的: 随着大语言模型(LLM)各领域的广泛应用,我们迫切需要了解其中潜在的风险和威胁,及时进行有效的防御。 申明: AI技术的普及正当的使用大模型技术带来的便利,切勿使用与非法用途ÿ…...
探索Perl语言:入门学习与实战指南
文章目录 探索Perl语言:入门学习与实战指南一、Perl语言概述二、Perl的安装与配置安装PerlWindowsmacOSLinux 配置Perl 三、基本语法与数据类型标量变量数组哈希 四、控制结构条件语句循环语句 五、子程序与模块子程序模块 六、文件操作与正则表达式文件读取与写入正…...

dp or 数学问题
看一下数据量,只有一千,说明这个不是数学问题 #include<bits/stdc.h> using namespace std;#define int long long const int mo 100000007; int n, s, a, b; const int N 1005;// 2 -3 // 1 3 5 2 -1 // 1 -2 -5 -3 -1 int dp[N][N]; int fun…...

kibana连接elasticsearch(版本8.11.3)
前言 elasticsearch在8版本之后就出现了很大变化,由于kibana版本需要需elasticsearch进行版本对象,kibana连接方式也出现了很大变化。我在这里记录下自己的踩坑记录。 服务部署 本文中的服务都是在docker环境中部署的。其中elasticsearch版本和kibana版…...

基于python的图像去水印
1 代码 import cv2 import numpy as npdef remove_watermark(image_path, output_path):# 读取图片image cv2.imread(image_path)# 转换为灰度图gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 使用中值滤波去除噪声median_filtered cv2.medianBlur(gray, 5)# 计算图像的梯…...
Linux下Supervisor的安装与配置
软件工程中,守护进程是非常行之有效的方案。能够让我们的一些指令在崩溃之后可以自我重新启动,从而保障业务上的持续使用。 这里就从0开始教大家安装Supervisor。 一,下载安装 安装有好多种方法,直接下载安装包安装,或者yum安装或者pip安装都可以。这次我们选择的是pip…...
使用Pandas读取Excel文件将特定列转成str格式方法汇总
文章目录 读取Excel文件并确保列为字符串类型使用 dtype 参数使用 converters 参数 读取Excel文件的正确拼写示例:读取Excel文件并过滤包含特定值的行详细解释 读取Excel文件并确保列为字符串类型 正确的方法是使用 pd.read_excel 函数,并指定 dtype 或…...

FPGA CFGBVS 管脚接法
说明 新设计了1个KU040 FPGA板子,回来之后接上JTAG FPGA不识别。做如下检查: 1、电源测试点均正常; 2、查看贴片是否有漏焊,检查无异常,设计上NC的才NC; 3、反复检查JTAG接线是否异常,贴片是…...

快速排序及归并排序的实现与排序的稳定性
目录 快速排序 一. 快速排序递归的实现方法 1. 左右指针法 步骤思路 为什么要让end先走? 2. 挖坑法 步骤思路 3. 前后指针法 步骤思路 二. 快速排序的时间和空间复杂度 1. 时间复杂度 2. 空间复杂度 三. 快速排序的优化方法 1. 三数取中优化 2. 小区…...

【系统架构设计】数据库系统(一)
数据库系统(一) 数据库模式与范式数据库的结构与模式数据模型关系代数数据的规范化反规范化 数据库设计事务管理备份与恢复分布式数据库系统数据仓库数据挖掘NoSQL大数据 数据库模式与范式 数据库的结构与模式 数据库技术中采用分级的方法将数据库的结…...

泛微e-cology WorkflowServiceXml SQL注入漏洞(POC)
漏洞描述: 泛微 e-cology 是泛微公司开发的协同管理应用平台。泛微 e-cology v10.64.1的/services/接口默认对内网暴露,用于服务调用,未经身份认证的攻击者可向 /services/WorkflowServiceXml 接口发送恶意的SOAP请求进行SQL注入,…...

<Rust><GUI>rust语言GUI库tauri体验:前、后端结合创建一个窗口并修改其样式
前言 本文是rust语言下的GUI库:tauri来创建一个窗口的简单演示,主要说明一下,使用tauri这个库如何创建GUI以及如何添加部件、如何编写逻辑、如何修改风格等,所以,这也是一个专栏,将包括tauri库的多个方面。…...

OBD诊断(ISO15031) 09服务
文章目录 功能简介ISO 9141-2、ISO 14230-4和SAE J1850的诊断服务定义1、请求车辆信息请求消息(读取支持的INFOTYPE)2、请求车辆信息响应消息(报告支持INFOTYPE)3、请求车辆信息请求消息(读取INFOTYPE值)4、请求车辆信息响应消息&…...
客户端与服务端之间的通信连接
目录 那什么是Socket? 什么是ServerSocket? 代码展示: 代码解析: 补充: 输入流(InputStream): 输出流(OutputStream): BufferedReader 是如何提高读取效率的&a…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...