Qwen学习笔记4:Qwen 7B模型调用天气API实现天气的实时查询

news2024/7/6 19:20:22

前言

在学习Qwen模型的函数调用功能后,进一步尝试利用本地的Qwen模型访问OpenWeather API来获取实时的天气情况。

参考代码来源于视频教程:

简单粗暴,轻松配置Qwen模型查询实时数据功能_哔哩哔哩_bilibili

说明

该代码运行前,确保Qwen模型在本地以Openai-api的方式启动了服务,Qwen模型的部署和启动可以参考我之前的笔记。

主要代码

首先定义一个类实现获取实时天气的功能:

import requests
class WeatherQuery:
    def __init__(self):
        """
        初始化Weather类
        :param api_key:必要参数字符串类型
        """
        self.api_key = "XXXX" # 请自行到https://home.openweathermap.org/注册,在个人中心查看自己的key
        self.base_url = "https://api.openweathermap.org/data/2.5/weather"

    def get_weather(self, loc):

        params = {
            "q": loc,
            "appid": self.api_key,
            "units": "metric",
            "lang": "zh_cn"
        }

        response = requests.get(self.base_url, params=params)
        print(response)
        if response.status_code == 200:
            data = response.json()
            return data

        else:
            return {"error": "无法获取到天气信息,请检查城市名称是否正确"}
        

OpenWeather API的获取需要到Members (openweathermap.org)进行注册,然后到个人中心去获取自己的访问API。

该类和方法示例使用:

# 示例使用
# APIkey
weather_query = WeatherQuery()
result = weather_query.get_weather('Beijing')
print(result)
<Response [200]>
{'coord': {'lon': 116.3972, 'lat': 39.9075}, 'weather': [{'id': 800, 'main': 'Clear', 'description': '晴', 'icon': '01d'}], 'base': 'stations', 'main': {'temp': 27.94, 'feels_like': 26.56, 'temp_min': 27.94, 'temp_max': 27.94, 'pressure': 1017, 'humidity': 7, 'sea_level': 1017, 'grnd_level': 1012}, 'visibility': 10000, 'wind': {'speed': 3.75, 'deg': 267, 'gust': 6.55}, 'clouds': {'all': 0}, 'dt': 1715760908, 'sys': {'type': 1, 'id': 9609, 'country': 'CN', 'sunrise': 1715720372, 'sunset': 1715772131}, 'timezone': 28800, 'id': 1816670, 'name': 'Beijing', 'cod': 200}

可以看到,该代码能正确请求到接口返回的数据。如果上述代码出现报错,例如没有requests包,使用pip install requests安装即可。

修改调用本地千问模型的函数代码(该代码的拆解详见之前的笔记内容):

def run_conversation(messages, functions_list=None):
    """
    能够自动执行外部函数的chat对话模型
    :param messages: 必要参数,字典类型,输入到Chat模型的messages参数对象
    :param functions_list: 可选参数,默认为None,可以设置为包含全部外部函数的列表对象
    :param model: Chat模型,可选参数,,默认模式是gpt-4
    :return: Chat模型输出结果
    """
    # 如果没有外部函数库,则执行普通的对话任务
    # 修改一:修改为Qwen的对话逻辑
    if functions_list == None:
        response = openai.ChatCompletion.create(
            model="Qwen",
            messages=messages,
        )
        response_message = response["choices"][0]["message"]
        final_response = response_message["conten"]
    # 若存在外部函数库则需要灵活选取外部函数并进行回答j
    else:
        # 创建function对象c
        functions = functions_list

        # first response
        response = openai.ChatCompletion.create(
            model="Qwen",
            messages=messages,
            functions=functions
        )
        response_message = response["choices"][0]["message"]

        # 修改2从函数API编写方式,改为类的编写方式h
        # 判断返回结果是否存在function_call,即判断是否需要调用外部函数来回答问题
        if response_message.get("function_call"):
            # 需要调用外部函数
            # 获取函数名
            function_name = response_message["function_call"]["name"]
            # 获取函数对象
            import json
            # 执行该函数所需要的参数
            print(response_message["function_call"]["arguments"])
            function_args = json.loads(response_message["function_call"]["arguments"].replace("'", '"'))
            
            tool_instance = eval(function_name)()
            # 实例化类中的方法
            tool_func = getattr(tool_instance, next(iter(function_args)))
            first_result = tool_func(function_args[next(iter(function_args))])
            # 修改3:按照Qwen的对话History,添加system message
            messages.append(
                {
                    "role": "assistant",
                    "content": response.choices[0].message['content'],
            }
            )
            
            # messages中拼接first response消息
            # 追加function返回消息
            messages.append(
                {
                    "role":"function",
                    "content": str(first_result),
                }
            )
            
            # 第二次调用模型
            second_response = openai.ChatCompletion.create(
                model='Qwen',
                messages=messages,
            )
            # 获取最终结果
            final_response = second_response["choices"][0]["message"]["content"]
        else:
            final_response = second_response["content"]
    return final_response

这里与之前不同的地方只有一处:

定义一个工具的jsonSchema,用于模型调用的参数:

weather_tools = [
    {
        'name_for_human': '即时天气查询工具',
        'name_for_model': 'WeatherQuery',
        'description_for_model': '即时天气查询工具使用OpenWeather API查询指定城市的即时天气状况。该工具需要城市的名称需要转换为其对应的英文名称,例如北京需要转换为Beijing。',
        'parameters': [{
            'name': 'get_weather',
            'description': '必要参数,字符串类型,用于表示查询天气的具体城市名称,中国的城市需要用英文名称替代,例如“北京”需要替换为“Beijing”',
            'required': True,
            'schema': {
                'type': 'string'
            },
        }],
    },
    # 其他工具的定义可以在这里继续添加
] 

调用模型,返回结果

messages = [{'role': 'user', 'content': '现在北京的天气怎么样?'}]
run_conversation(messages = messages,functions_list=weather_tools)
{"get_weather": "Beijing"}
<Response [200]>
" API返回的数据格式为json,看起来包含一个叫做'weather'的列表,它里面存储了当前的天气情况。此外,还包含了其他一些数据,如压力、湿度等。\n\nResponse: 北京现在的天气是晴朗的,温度大约在27度左右,空气比较干燥。"

我们再调用之前定义的类和方法,查看一下是不是模型杜撰的。

weather_query = WeatherQuery()
result = weather_query.get_weather('Beijing')
print(result)
<Response [200]>
{'coord': {'lon': 116.3972, 'lat': 39.9075}, 'weather': [{'id': 800, 'main': 'Clear', 'description': '晴', 'icon': '01d'}], 'base': 'stations', 'main': {'temp': 27.94, 'feels_like': 26.56, 'temp_min': 27.94, 'temp_max': 27.94, 'pressure': 1017, 'humidity': 7, 'sea_level': 1017, 'grnd_level': 1012}, 'visibility': 10000, 'wind': {'speed': 3.75, 'deg': 267, 'gust': 6.55}, 'clouds': {'all': 0}, 'dt': 1715761584, 'sys': {'type': 1, 'id': 9609, 'country': 'CN', 'sunrise': 1715720372, 'sunset': 1715772131}, 'timezone': 28800, 'id': 1816670, 'name': 'Beijing', 'cod': 200}

可以看到,模型返回的结果确实是OpenWeather API返回的结果。模型正确的请求并返回了结果。

结语

到这篇笔记为止,我们已经通过学习ReAct原理,以及手动拆解代码,一步步分析Qwen模式是如何进入思考模式,实现函数调用的功能的。

后边封装的代码也能够快速的调用工具来实现之前模型不具备的能力,这为大模型的应用增加了不少的可能性。这些思考和方法,以及实现的代码可以作为后续模型的应用开发、上层开发提供思路和借鉴。

后续也可以进一步深入学习。

我自己这边,对于千问模型,后续再将其升级到Qwen1.5,再大概测试一下其性能,直观感受一下吧,以及了解下功能上是否有更新,可能就不会耗费更多的时间,接下来的重点将会转到对chatGLM和langchain框架的学习。

如果大家看到这篇笔记,有疑问的可以提出来,我们可以一起探讨。

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

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

相关文章

线性系统(二)

线性系统&#xff08;二&#xff09; 1.直观理解线性方程组结构2. 不同解的结论3. 更一般的高斯-约旦消元法4.齐次线性方程组 链接: 线性系统&#xff08;一&#xff09; 1.直观理解线性方程组结构 长这样&#xff0c;方程就有解&#xff0c;即相交坐标。 长这样&#xff0c;…

Python | Leetcode Python题解之第92题反转链表II

题目&#xff1a; 题解&#xff1a; class Solution:def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:# 设置 dummyNode 是这一类问题的一般做法dummy_node ListNode(-1)dummy_node.next headpre dummy_nodefor _ in range(left - 1):pre…

Cadence 16.6 PCB Edito如何将鼠标中键反向拉拽改为正向拖拽

Cadence 16.6 PCB Editor如何将鼠标中键反向拉拽改为正向拖拽 Cadence 16.6 PCB Editor默认鼠标中键是反向的拉拽&#xff0c;让我很不适应&#xff0c;在网上找的可行的方法&#xff0c;在这里总结出来&#xff0c;希望能帮到其他工程师。 按照以下步骤进行操作&#xff1a; …

设计模式:外观模式(Facade)

设计模式&#xff1a;外观模式&#xff08;Facade&#xff09; 设计模式&#xff1a;外观模式&#xff08;Facade&#xff09;模式动机模式定义模式结构时序图模式实现在单线程环境下的测试在多线程环境下的测试模式分析优缺点适用场景应用场景模式扩展参考 设计模式&#xff1…

Golang | Leetcode Golang题解之第91题解码方法

题目&#xff1a; 题解&#xff1a; func numDecodings(s string) int {n : len(s)// a f[i-2], b f[i-1], c f[i]a, b, c : 0, 1, 0for i : 1; i < n; i {c 0if s[i-1] ! 0 {c b}if i > 1 && s[i-2] ! 0 && ((s[i-2]-0)*10(s[i-1]-0) < 26) {c…

SAP BSEG VS ACDOCA 差异

温习一下 ACDOCA VS BSEG matinal&#xff1a;S4 HANA 详解ACDOCA与BSEG的区别都在这了_sap acdoca-CSDN博客

16.投影矩阵,最小二乘

文章目录 1. 投影矩阵1.1 投影矩阵P1.2 投影向量 1. 投影矩阵 1.1 投影矩阵P 根据上节知识&#xff0c;我们知道当我们在解 A X b AXb AXb的时候&#xff0c;发现当向量b不在矩阵A的列空间的时候&#xff0c;我们希望的是通过投影&#xff0c;将向量b投影到矩阵A的列空间中&…

机器学习—聚类算法

聚类算法 小白的机器学习笔记 2024/5/15 9:52 文章目录 聚类算法步骤K-means算法优缺点 示例 聚类算法的核心思想&#xff1a; 样本点到每个中心点的距离&#xff0c;最近的就是这个类 步骤 要聚成3类&#xff0c;先初始化3个点 第一步大致确定类别 第二步更新中心点 第三…

Vue的学习 —— <网络请求库Axios>

目录 前言 正文 一、Axios基本概念 二、安装Axios 三、Axios使用方法 四、向服务器发送请求 前言 在之前的开发案例中&#xff0c;我们通常直接在组件中定义数据。但在实际的项目开发中&#xff0c;我们需要从服务器获取数据。当其他用户希望访问我们自己编写的网页时&a…

AI绘画Midjourney 和 Stable Diffusion的区别是什么?如何使用和安装?超详细AI绘画小白零基础入门教程建议收藏!(附资料)

大家好&#xff0c;我是画画的小强 关于AI绘画&#xff0c;大家多多少少都听过Midjourney 和 Stable Diffusion的大名&#xff0c;号称目前市面上最强的两款AI绘画软件。那么今天我们就来分析一下这两款软件的区别在哪里。 Midjourney是一个在线网站&#xff0c;使用它需要用…

码农慎入 | 入坑软路由,退烧IDC,Homelab折腾记

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 封面 / 姝琦Midjourney 产品统筹 / bobo 场地支持 / 声湃轩北京录音间 俗话说&#xff0c;入门软路由&#xff0c;退坑IDC 这一期&#xff0c;我们将深入探讨一个许多科技爱好者…

小白git

克隆 &#xff1a;git clone 链接地址 如果没有.git文件的话&#xff1a;git init 切换分支&#xff1a;cd 目录 拉代码&#xff1a;git pull 查看你自己改了那些文件&#xff1a;git status 添加道本地暂存区&#xff1a;git add * 提交到远端&#xff1a;git commit …

网络安全快速入门(十三)linux及vmware软件的网络配置

13.1 前言 在通过我们前面的了解&#xff0c;我们现在已经对Linux的基础知识有了大致的了解&#xff0c;今天我们来大概讲一下关于linux系统及vmware的网络配置问题&#xff0c;在这之前&#xff0c;我们需要对网络有一个大概的认识和了解&#xff0c;话不多说&#xff0c;我们…

windows驱动开发-PCI讨论(一)

前面描述中断的时候&#xff0c;我们曾经多次体积PCI&#xff0c;甚至提供了一些PCI的相关知识&#xff0c;但是整个PCI是一个很大的体系&#xff0c;专门记录这个体系超出了这个系列的范畴&#xff0c;有兴趣的可以到PCI官网了解详细的情况。 但是还是会花费一些时间讨论PCI技…

AI办公自动化:用kimi批量把word转换成txt文本

在Kimichat中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个Python脚本编写的任务&#xff0c;具体步骤如下&#xff1a; 打开文件夹&#xff1a;F:\aword 读取里面docx格式的word文档&#xff0c; 提取word文档中的第一行文字作为txt文本文档的标题…

写后端项目时上传文件接口使用阿里云oss-规范写法

文章目录 开通对象存储服务密钥管理点击头像点击密钥管理创建新密钥AccessKey 写在yml配置文件中相关配置1.pom依赖2.全局配置类3.AliOssUtil 工具类3.AliOssProperties类&#xff0c;用于读取yml文件中写入的密钥4.controller层&#xff0c;用于写传输文件的接口 开通对象存储…

线程同步--互斥锁,读写锁

线程同步 基本概念 线程的能力在于能够方便地通过全局变量或共享内存来交换信息&#xff0c;但这也带来了并发控制的复杂性&#xff0c;主要表现在如何安全地管理多个线程对共享资源的访问。这里涉及到几个关键的概念和技术&#xff1a; 临界区&#xff08;Critical Section…

【C语言】指针(二)

目录 一、传值调用和传址调用 二、数组名的理解 三、通过指针访问数组 四、一维数组传参的本质 五、指针数组 六、指针数组模拟实现二维数组 一、传值调用和传址调用 指针可以用在哪里呢&#xff1f;我们看下面一段代码&#xff1a; #include <stdio.h>void Swap(i…

【Week Y9】yolo-v8网络结构的主要模块学习

文章目录 一、...\ultralytics-main\ultralytics\nn\modules\conv.py&#xff1a;&#xff08;1&#xff09;__all__说明&#xff1a;&#xff08;2&#xff09;autopad()说明&#xff1a;&#xff08;3&#xff09;conv()说明&#xff1a;&#xff08;4&#xff09;Focus()说明…

ue引擎游戏开发笔记(40)——行为树的建立:丰富ai行动

1.需求分析&#xff1a; 敌人的ai行为随着开发的不断更新&#xff0c;会不断增加&#xff0c;如果每次都进入c中编写会很不方便&#xff0c;也无法凸显ue引擎中行为树的优势作用&#xff0c;因此有必要将敌人的ai行为&#xff0c;全部转到行为树中实现。 2.操作实现&#xff1…