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

前言

在学习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框架的学习。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯-线性动态规划问题背包问题进阶策略详解-青蛙吃虫

题目&#xff1a;蓝桥云课-青蛙吃虫 解题代码&#xff1a; #include <iostream> #include<cstring> #include<algorithm> using namespace std;const int N106;int f[N][N]; int a[N]; int t,l,r,k,n;int main() {cin>>t;while(t--){scanf("%d%…

入职java开发第一天,不会VUE竟然被.........

Vue2 技术栈 第 1 章&#xff1a;Vue 核心1.1. Vue 简介1.1.1. 官网1.1.2. 介绍与描述1.1.3. Vue 的特点1.1.4. 与其它 JS 框架的关联1.1.5. Vue 周边库 1.2. 初识 Vue1.3. 模板语法1.3.1. 效果1.3.2. 模板的理解1.3.3. 插值语法1.3.4. 指令语法 1.4. 数据绑定1.4.1. 效果1.4.2…

Java官网下载JDK17版本详细教程(下载、安装、环境变量配置)

第一步&#xff0c;去百度搜索甲骨文官网 第二步 第三步 第四步 第五步 第六步 第七步 第八步 第九步 第十步 然后在系统变量里面找到path-编辑-新建添加这个,点击确定就好了 %JAVA_HOME%\bin 就完成了&#xff0c;接下来测试是否成功。 测试&#xff1a; 第一步&a…

Vue3学习笔记 - 禹神YYDS

1. 教程介绍 https://www.bilibili.com/video/BV1Za4y1r7KE?p1 本篇vue3&#xff0c;内容比较新&#xff0c;比如有setup语法糖用法&#xff1b;只是他使用TS&#xff0c;并不是JS&#xff1b;不过JS也比较熟悉了&#xff0c;也可以学习下TS的语法&#xff0c;课程使用 TypeSc…

Clickhouse

概念 来源 ClickHouse背后的研发团队是俄罗斯的Yandex公司。Yandex是一家俄罗斯的搜索引擎公司&#xff0c;类似于我国的百度&#xff0c;Yandex于2011年在纳斯达克上市。 架构演变 特点 Clickhouse使用的是列式存储 图中第二个使用的列式存储在提取某一部分的全部数据时&a…

KING大咖直播 | KES RAC如何成为核心系统首选?

核心系统负载高 停机代价大 KES RAC来了 KingbaseES共享存储集群 不仅满足您对数据库 扩展性与可用性的严苛要求 更能在保障性能的同时 实现低成本、高效益 是企业核心系统的理想选择 5月16日19:30-20:30 锁定金仓数据库视频号 人大金仓高级研发工程师 深度揭秘如何实现 Kingba…

PXE+Kickstart无人值守安装操作系统

文章目录 什么是PXE&#xff1f;PXE工作原理示意图说明一、环境二、安装前准备三、DHCP服务器配置四、TFTP服务准备五、VSftpd服务准备六、PXE菜单七、重启服务八、创建虚拟机-自动安装系统 什么是PXE&#xff1f; PXE&#xff0c;全名Pre-boot Execution Environment&#xf…

接口自动化框架篇:接口框架中的常归断言封装!

在接口自动化测试中&#xff0c;断言&#xff08;Assertion&#xff09;是非常重要的一部分。通过对接口的返回结果进行断言&#xff0c;我们可以确认接口是否返回了正确的数据&#xff0c;从而验证接口的正确性。 为了提高代码的可读性和可维护性&#xff0c;我们通常会将常用…

前沿动态 | 关于AI大模型,你知道多少?

AI大模型含义 AI 大模型是人工智能预训练大模型的简称&#xff0c;包含了“预训练”和“大模型”两层含义&#xff0c;二者结合产生了新的人工智能模式&#xff0c;即模型在大规模数据集上完成预训练后&#xff0c;仅需少量数据的微调甚至无需微调&#xff0c;就能直接支撑各类…

python高级爱心代码

python高级爱心代码实现&#xff1a; import turtle import random # 设置画布 screen turtle.Screen() screen.bgcolor("black") # 创建画笔 pen turtle.Turtle() pen.speed(0) pen.color("red") pen.penup() # 移动画笔到起始位置 pen.goto(0, -20…

伪头部校验

本章问题 UDP和TCP的伪首部只用于计算校验和&#xff0c;在UDP和TCP的报文中是不存在的&#xff0c;为什么要引入伪首部呢&#xff1f;为什么伪首部的要有这些字段&#xff1f;这里我们就先看一下TCP和UDP的首部格式。 TCP和UDP首部 源端口目的端口&#xff1a;是0-65535任…

代码随想录-算法训练营day41【动态规划04:01背包问题-滚动数组、分割等和子集】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第九章 动态规划part04● 01背包问题,你该了解这些! ● 01背包问题,你该了解这些! 滚动数组 ● 416. 分割等和子集 正式开始背包问题,背包问题还是挺难的,虽然大家可能看了很多背包问题模板代码,感觉挺简单,…

2024汽车行业用户洞察与营销趋势白皮书

来源&#xff1a;小红书&寰球汽车&#xff1a;

晶振的振荡模式有哪些?

晶振&#xff0c;即晶体振荡器&#xff0c;是一种能够产生精确振荡频率的电子元件&#xff0c;它利用石英晶体的压电效应来产生稳定的振荡信号。晶振的振荡模式主要有以下几种&#xff1a;1. 串联谐振&#xff08;Series Resonance&#xff09;&#xff1a; 在这种模式下&am…

Moe 混合多专家模型 原理 + 大模型的有性繁殖 + DIY 自己的 Moe 专家系统

Moe 混合多专家模型 原理 大模型的有性繁殖 DIY 自己的 Moe 专家系统 MoE 介绍标准 Transformer 编码器MoE Transformer 编码器专家网络层 大模型的有性繁殖mergekit 合并 多个专家模型 的方式1. SLERP&#xff08;球面线性插值&#xff09;2. TIES3. DARE4. Passthrough5. L…

露营涮火锅小朋友不慎烫伤大腿 家长抱娃涮河急救获医生点赞

近日&#xff0c;陈女士一家三口在西安市长安区附近露营涮火锅&#xff0c;却不料小朋友在起身时不小心打翻了吃火锅的锅&#xff0c;导致腿被烫伤&#xff0c;陈女士急忙抱着孩子到临近河边&#xff0c;用河水来冲洗小朋友烫伤的腿&#xff0c;随后立刻赶至西安国际医学中心医…

Kroma宣布推出Spectrum:以太坊Layer-2的先进原生质押服务

Kroma宣布推出备受期待的Spectrum&#xff0c;这是一项先进的原生质押服务&#xff0c;旨在彻底改变以太坊 Layer-2格局。Spectrum将于2024年5月14日开始运营&#xff0c;为用户提供利用质押ETH、stETH和eETH的奖励机会&#xff0c;助力用户在去中心化金融&#xff08;DeFi&…

Python 海龟画图(Turtle)命令大全

移动和绘制 forward() | fd() 使用语法&#xff1a; ​​turtle.forward(距离)​​ ​​turtle.fd(距离)​​ 参数说明: 距离 一个数字 (整数 或者 浮点) &#xff08;注&#xff1a;单位是像素&#xff09; 代码示例&#xff1a; import turtle turtle.forward(200) …

docker镜像中搭建FastDfs

docker镜像中搭建FastDfs 一、搭建过程二、docker端口映射三、映射的方法三、配置Tracker 和 Storage 环境&#xff1a;腾讯云服务器上 ubuntu20.04镜像 一、搭建过程 正常直接在云服务器上搭建过程参考博客&#xff1a; https://blog.csdn.net/qq_38531706/article/details/…

分享如何通过定时任务调用lighthouse前端测试脚本+在持续集成测试中调用lighthouse前端测试脚本

最近写了个小工具来优化lighthouse在实际工作中的使用&#xff0c;具体实现了&#xff1a;通过定时任务调用前端测试脚本在持续集成测试中调用前端测试脚本。由于在公司中已经应用&#xff0c;所以就不能提供源码了&#xff0c;这里简单说一下实现思路&#xff0c;希望可以帮助…