详解大模型是如何理解并使用 tools ?

前文

大家肯定对使用大模型的函数回调或者说 Tools 已经耳熟能详了,那么他们具体内部是如何运作的呢,本文就此事会详细给大家介绍具体的细节。

tools

首先是大家最熟悉的环节,定义两个 tool 的具体实现,其实就是两个函数:

  • get_current_weather:基于给定的城市获取天气
  • get_current_time:查询当前时间

我这里为了演示说明,所以只是简单实现了功能,里面的逻辑并不复杂,大家可以看下面的代码,然后将这两个函数的具体功能描述以及对参数的定义使用 json 格式存放在列表 tools 中。tools 中的这些对于函数的功能描述或者参数的定义描述等等信息后面会传入到大模型中,大模型会解析改写成它能理解的 prompt 。所以这里按照固定的格式写 tools ,就是为了源代码中能够解析出相关的内容。具体可以看继续后面。

python
复制代码def get_current_weather(location):if '上海' in location.lower():return json.dumps({'location': '上海', 'temperature': '10度'}, ensure_ascii=False)elif '杭州' in location.lower():return json.dumps({'location': '杭州', 'temperature': '12度'}, ensure_ascii=False)else:return json.dumps({'location': location, 'temperature': 'unknown'}, ensure_ascii=False)def get_current_time():current_datetime = datetime.now()formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S')return f"当前时间:{formatted_time}。"tools = [{'name': 'get_current_weather','description': '基于给定的城市获取天气','parameters': {'type': 'object','properties': {'location': {'type': 'string','description': '城市名称',},},'required': ['location'],},},{"name": "get_current_time","description": "获取当前时间","parameters": {}}
]

查询天气

首先演示查询天气的 tool ,此时我们先给大模型定义一个 system 级别的角色定义,将其设定为一个可以使用工具的帮手,可以从我在 tools 定义的两个工具中挑出合适的工具完成任务。理论上我提问“上海天气如何”,然后大模型能够自动挑选出 get_current_weather 这个工具来完成天气查询任务。我这里使用的是 qwen-max 模型,大家可以换成自己的,大模型选用不是本文重点,大家不必特别关心。

整个过程分为以下几步:

  1. 给大模型传入问题 上海天气如何
  2. 大模型自己从 tools 中挑选可以解决用户问题的工具 get_current_weather
  3. 使用工具 get_current_weather 和大模型提取出来的参数 上海 获取天气情况
  4. 将天气情况传给大模型
  5. 大模型结合用户的问题,以及得到的天气情况,总结返回最后的结果。

具体第 2 和 3 步是如何实现的呢,其实大模型在拿到我们定义的存放函数信息的 json 格式的 tools 之后,将里面所有的 tools 内容拼接成了一个很长的 prompt,通过 debug ,我这里拿到了使用 qwen-max 的中间结果如下,可以看出其实就是将我们最原始的 system 定义的内容填充入了 tools 的内容供大模型理解,并按照固定的参数定义从用户的问题中提取参数,这些对原有的对话信息进行修改的过程普通用户是没有感觉的,也不会改变用户真实的对话信息,因为已经封装入了 api 中直接供大家使用了。

csharp
复制代码
[Message({'role': 'system', 'content': '你是一个有用的帮手,可以使用合适的工具解决我的我问题
# 工具
## 你拥有如下工具:
### get_current_weather
get_current_weather: 基于给定的城市获取天气 输入参数:{"type": "object", "properties": {"location": {"type": "string", "description": "城市名称"}}, "required": ["location"]}
### get_current_time
get_current_time: 获取当前时间 输入参数:{}
## 你可以在回复中插入零次、一次或多次以下命令以调用工具:
✿FUNCTION✿: 工具名称,必须是[get_current_weather,get_current_time]之一。
✿ARGS✿: 工具输入
✿RESULT✿: 工具结果,需将图片用![](url)渲染出来。
✿RETURN✿: 根据工具结果进行回复'}),Message({'role': 'user', 'content': '上海天气如何'})]

代码如下:

ini
复制代码def get_weather():llm = get_chat_model({'model': 'qwen-max',  'model_server': 'dashscope', 'api_key': 'sk-c69985b9a3c94cd5a56f8cd003a3cf08'})messages = [{'role': 'system', 'content': "你是一个有用的帮手,可以使用合适的工具解决我的我问题"}, {'role': 'user', 'content': "上海天气如何"}]response = llm.chat(messages=messages, functions=tools, stream=False)print(f'# Assistant 回复 1:\n{response}')messages.extend(response)if messages:last_response = messages[-1]if last_response.get('function_call', None):function_name = last_response['function_call']['name']if function_name == 'get_current_weather':function_args = json.loads(last_response['function_call']['arguments'])function_response = get_current_weather(function_args.get('location'))print(f'# Function 回复:\n{function_response}')messages.append({'role': 'function', 'name': function_name, 'content': function_response, })print(f'# All messages:\n {messages}')response = llm.chat(messages=messages,  functions=tools, stream=False)print(f'# Assistant 回复 2:{response}')

日志打印:

css
复制代码# Assistant 回复 1:[{'role': 'assistant', 'content': '', 'function_call': {'name': 'get_current_weather', 'arguments': '{"location": "上海"}'}}]# Function 回复:{"location": "上海", "temperature": "10度"}# All messages:[{'role': 'system', 'content': '你是一个有用的帮手,可以使用合适的工具解决我的我问题'},
{'role': 'user', 'content': '上海天气如何'},
{'role': 'assistant', 'content': '', 'function_call': {'name': 'get_current_weather', 'arguments': '{"location": "上海"}'}},
{'role': 'function', 'name': 'get_current_weather', 'content': '{"location": "上海", "temperature": "10度"}'}]# Assistant 回复 2:[{'role': 'assistant', 'content': '上海现在的天气是10度。'}]

查询时间

相信大家看了上面的解释已经对整个内部的细节有了一个新的认识,这里我在简单举例,让大模型自动挑选 tools 中的工具完成查看时间的任务。过程和上面一样,不再具体赘述。

大模型结合 tools 改写的 prompt 如下:

vbnet
复制代码[Message({'role': 'system', 'content': '你是一个有用的帮手,可以使用合适的工具解决我的我问题# 工具## 你拥有如下工具:### get_current_weatherget_current_weather: 基于给定的城市获取天气 输入参数:{"type": "object", "properties": {"location": {"type": "string", "description": "城市名称"}}, "required": ["location"]}### get_current_timeget_current_time: 获取当前时间 输入参数:{}## 你可以在回复中插入零次、一次或多次以下命令以调用工具:✿FUNCTION✿: 工具名称,必须是[get_current_weather,get_current_time]之一。
✿ARGS✿: 工具输入
✿RESULT✿: 工具结果,需将图片用![转存失败,建议直接上传图片文件](<转存失败,建议直接上传图片文件 url>)渲染出来。
✿RETURN✿: 根据工具结果进行回复'}),Message({'role': 'user', 'content': '当前时间几点了'})]

代码如下:

ini
复制代码def get_time():llm = get_chat_model({'model': 'qwen-max',  'model_server': 'dashscope', 'api_key': '你的key'})messages = [{'role': 'system', 'content': "你是一个有用的帮手,可以使用合适的工具解决我的我问题"}, {'role': 'user', 'content': "当前时间几点了"}]response = llm.chat(messages=messages, functions=tools, stream=False)print(f'# Assistant 回复 1:\n{response}')messages.extend(response)if messages:last_response = messages[-1]if last_response.get('function_call', None):function_name = last_response['function_call']['name']if function_name == 'get_current_time':function_response = get_current_time()print(f'# Function 回复:\n{function_response}')messages.append({'role': 'function', 'name': function_name, 'content': function_response, })print(f'# All messages:\n {messages}')response = llm.chat(messages=messages,  functions=tools, stream=False)print(f'# Assistant 回复 2:{response}')

日志打印:

bash
复制代码# Assistant 回复 1:[{'role': 'assistant', 'content': '', 'function_call': {'name': 'get_current_time', 'arguments': '{}'}}]# Function 回复:当前时间:2024-06-12 19:00:48。# All messages:[{'role': 'system', 'content': '你是一个有用的帮手,可以使用合适的工具解决我的我问题'},
{'role': 'user', 'content': '当前时间几点了'},
{'role': 'assistant', 'content': '', 'function_call': {'name': 'get_current_time', 'arguments': '{}'}},
{'role': 'function', 'name': 'get_current_time', 'content': '当前时间:2024-06-12 19:00:48。'}]# Assistant 回复 2:[{'role': 'assistant', 'content': '当前时间是2024年6月12日19点00分48秒。'}]

总结

所以从上面的例子可以看出来,本质上大模型理解 tools 还是在拼写 prompt ,我们如果不使用 api ,直接自己拼写可以使用的函数信息,其实也是可以实现上述的功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/39360.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

校园兼职小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;商家管理&#xff0c;管理员管理&#xff0c;用户管理&#xff0c;兼职管理&#xff0c;论坛管理&#xff0c;公告管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;公告&#xff0c;兼职&…

Docker 一篇到位

目录 01. Docker使用导航 02. Build Share Run 样例 03. 理解容器 04. 安装 Docker 05. Docker 样例&#xff08;常见命令使用&#xff09; 下载镜像 启动容器 修改页面 保存镜像 docker commit docker save docker load 分享社区 docker login docker tag do…

730天的创作之旅:我的技术写作之路

机缘 两年前的今天&#xff0c;我作为一名测试工程师&#xff0c;带着对技术的热爱和对分享的渴望&#xff0c;开启了我的创作者之旅。最初&#xff0c;我希望通过我的文章&#xff0c;将我在实战项目中的经验、日常学习过程中的点滴记录下来&#xff0c;并通过这些文字与更多…

EtherCAT主站IGH-- 5 -- IGH之debug.h/c文件解析

EtherCAT主站IGH-- 5 -- IGH之debug.h/c文件解析 0 预览一 该文件功能`debug.c` 文件功能函数预览二 函数功能介绍`debug.c` 中主要函数的作用1. `ec_debug_init`2. `ec_debug_clear`3. `ec_debug_register`4. `ec_debug_unregister`5. `ec_debug_send`6. `ec_dbgdev_open`7. `…

【408考点之数据结构】二叉树的概念与实现

二叉树的概念与实现 一、二叉树的概念 二叉树是一种特殊的树结构&#xff0c;其中每个节点最多有两个子节点&#xff0c;分别称为左子节点和右子节点。二叉树广泛应用于许多计算机科学领域&#xff0c;如表达式解析、排序、搜索算法等。 二、二叉树的性质 性质1&#xff1a…

数字化转型过程中企业会遇到哪些挑战?该如何应对?

你是否与我一样&#xff0c;也曾有过类似的疑惑&#xff1a; 企业数字化转型过程中会遇到哪些挑战&#xff1f;其中苦难&#xff0c;我们又该如何应对&#xff1f;有什么可借鉴的方法&#xff1f; 有了这些疑问&#xff0c;你肯定想知道答案。 为了解决你的心头之患&#xf…

高级队列实现代理穿透及迁移

一、参数调优 1.1、登录穿透专用数据库 su - oracle 1.2、通过sqlplus登录 sqlplus create pfile =/home/oracle/pfile11.ora from spfile; alter system set processes=8000 scope=spfile; alter system set sessions=10400 scope=spfile; alter system set result_ca…

rocketmq实现多数据源配置

rocketmq实现多数据源配置 背景&#xff1a;一 添加ExtRocketMQTemplateConfiguration配置类二 添加非标mq的配置参数三 非标准RocketMQTemplate 背景&#xff1a; 在实际项目中我们可能会遇到在springboot项目中使用多个mq数据源&#xff0c;那我们该如何配置呢&#xff1f; …

基于若依(ruoyi-vue)的周报管理系统

喂wangyinlon 填报人页面 审批人 审批不通过,填报人需要重新填写.

自动编码器简单理解及简单使用描述

1. 什么是自动编码器&#xff1f; 自动编码器分为编码器和解码器&#xff0c;其中解码器只在训练阶段用到。具体过程就是&#xff1a; 首先&#xff0c;输入训练样本&#xff0c;编码器对输入样本进行编码&#xff0c;对其进行降维&#xff0c;直到到达某个瓶颈层&#xff1b…

Python基础总结之什么是迭代?迭代的概念介绍

Python基础总结之什么是迭代&#xff1f;迭代的概念介绍 在Python中&#xff0c;迭代&#xff08;Iteration&#xff09;是一种基本的编程概念&#xff0c;用于逐个访问集合&#xff08;如列表、元组、字典、集合等&#xff09;中的每个元素。迭代是Python编程中不可或缺的一部…

高考后如何进入IT领域:详细学习路线图与实战经验分享

高考终于告一段落&#xff0c;是不是感觉整个人都轻松了许多&#xff1f;先恭喜你&#xff0c;顺利迈过了这一重要的阶段&#xff01;但别忘了&#xff0c;高考的结束只是一个新的开始&#xff0c;特别是对于那些有志于进入IT领域的同学们。这个暑假&#xff0c;是你们开启IT世…

2024年江西省研究生数学建模竞赛B题投标中的竞争策略问题论文和代码分析

2024年江西省研究生数学建模竞赛B题投标中的竞争策略问题论文和代码已完成&#xff0c;代码为B题全部问题的代码&#xff0c;论文包括摘要、问题重述、问题分析、模型假设、符号说明、模型的建立和求解&#xff08;问题1模型的建立和求解、问题2模型的建立和求解、问题3模型的建…

oracle体系结构详解(实例+数据文件)

提示&#xff1a;主要总结oracle数据库&#xff1a;物理结构&#xff0c;逻辑结构&#xff0c;内存结构以及oracle进程 文章目录 Oracle服务器由&#xff08;实例和数据库文件组成&#xff09;1、实例2、数据文件1.oracle物理体系结构2.oracle数据库逻辑结构3oracle数据库内存结…

如何通过指纹浏览器使用代理IP?

1.指纹浏览器定义 指纹浏览器是 一种浏览器技术&#xff0c;它根据用户设备的硬件、软件和配置等特征生成唯一标识符&#xff08;称为“指纹”&#xff09;。此指纹用于识别和追踪用户身份&#xff0c;即使用户更改其 IP 地址或清除浏览器数据&#xff08;如缓存和 Cookie&…

AI生成商品图软件哪个好用

&#x1f31f; AI生成商品图软件哪个好用 —— 触站AI&#x1f680; &#x1f3a8;在AI技术的浪潮中&#xff0c;触站AI以其专业和创新&#xff0c;成为广州AI设计服务的领军企业。 专注于企业AI图像领域的技术解决方案&#xff0c;触站AI提供包括AI绘画模型训练、AI绘图模型定…

实现抽象方法、实现接口 题目

题目 JAVA25 实现抽象方法分析&#xff1a;代码&#xff1a; JAVA26 实现接口分析&#xff1a;代码&#xff1a; JAVA25 实现抽象方法 描述 已知抽象类Base中定义了calculate方法&#xff0c;该方法的计算过程依赖于sum()和avg()&#xff0c;而后两个方法均为抽象方法。要求定义…

python处理txt文件, 如果第一列和第二列的值在连续的行中重复,则只保留一行

处理txt文件, 如果第一列和第二列的值在连续的行中重复,则只保留一个实例,使用Python的内置函数来读取文件,并逐行检查和处理数据。 一个txt文件,里面的数据是893.554382324,-119.955825806,0.0299997832626,-0.133618548512,28.1155740884,112.876833236,46.7922,19.62582…

Python应对反爬虫的策略

Python应对反爬虫的策略 概述User-Agent 伪造应对302重定向IP限制与代理使用Cookies和Session管理动态内容加载数据加密与混淆请求频率限制爬虫检测算法法律与道德考量结语 概述 在数字化时代&#xff0c;网络数据采集已成为获取信息的重要手段之一。然而&#xff0c;随着技术…

【场景题】数据库优化和接口优化——优化深分页问题

深分页问题是什么 深分页问题指的是在数据库查询中&#xff0c;当请求的页码数非常大&#xff0c;即OFFSET&#xff08;偏移量&#xff09;数值非常大时&#xff0c;查询性能会急剧下降的问题。 在MySQL等关系型数据库中&#xff0c;深分页查询通常使用LIMIT offset, limit语句…