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…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
