基于Qwen大模型,采用“ReAct“模式(Reason + Act)完成天气调用Function Calling

基于Qwen3-max大模型实现,用户如要使用Qwen3大模型,需要注册阿里云百炼平台账户,获取DASHSCOPE_API_KEY。

本程序在Python中,使用DashScope调用Qwen3大模型的API接口。也可以使用OpenAI兼容接口。如使用DashScope,需要安装DashScope包。

从高德平台获取天气状况信息,需要注册高德平台,获取GAODE_API_KEY。

以下为实现的代码:

import os

import json

import requests

from dashscope import Generation

# ========================

# 1. 获取环境变量

# ========================

DASHSCOPE_API_KEY = os.getenv("DASHSCOPE_API_KEY")

GAODE_API_KEY = os.getenv("GAODE_API_KEY")

if not DASHSCOPE_API_KEY:

    raise EnvironmentError("请设置环境变量:DASHSCOPE_API_KEY")

if not GAODE_API_KEY:

    raise EnvironmentError("请设置环境变量:GAODE_API_KEY")

# ========================

# 2. 利用高德adcode API实现用户输入的地名和adcode的转换,否则无法识别"广州市天河区"这种格式

# ========================

def geocode_location(location_name):

    """

    根据地名(如“天河区”)查询对应的 adcode 和城市名

    使用高德「输入提示 API」

    """

    url = "https://restapi.amap.com/v3/assistant/inputtips"

    params = {

        "key": GAODE_API_KEY,

        "keywords": location_name,

        "city": "",           # 可选:限定城市,如“广州”

        "offset": 1,

        "page": 1,

        "output": "json"

    }

    try:

        response = requests.get(url, params=params, timeout=10)

        if response.status_code != 200:

            print("❌ 网络请求失败")

            return None, None

        data = response.json()

        if data.get("status") != "1":

            print(f"❌ 地名查询失败: {data.get('info')} (infocode: {data.get('infocode')})")

            return None, None

        tips = data.get("tips", [])

        if not tips:

            print("⚠️ 未找到匹配的地点")

            return None, None

        # 取第一个最匹配的结果

        place = tips[0]

        adcode = place.get("adcode")

        city_name = place.get("city") or place.get("name")  # 优先取 city,否则取 name

        return adcode, city_name

    except requests.exceptions.RequestException as e:

        print("❌ 请求异常:", e)

        return None, None



 

# ========================

# 3. 高德天气 API 封装

# ========================

def get_real_weather(location: str) -> dict:

    """

    调用高德地图天气 API 获取实时天气

    文档:https://lbs.amap.com/api/webservice/guide/api/weatherinfo

    """

    WEATHER_URL = "https://restapi.amap.com/v3/weather/weatherInfo"

    adcode, city = geocode_location(location)

    if adcode:

        params = {

            "key": GAODE_API_KEY,

            "city": adcode,         #使用高德的adcode代替location

            "extensions": "base",   # base: 实时天气;all: 预报

            "output": "json"

        }

    try:

        response = requests.get(WEATHER_URL, params=params, timeout=10)

       

        data = response.json()

        if data["status"] == "1" and data.get("lives"):

            w = data["lives"][0]

            return {

                "status": "success",

                "data": {

                    "city": w["city"],

                    "temperature": w["temperature"],

                    "weather": w["weather"],

                    "winddirection": w["winddirection"],

                    "windpower": w.get("windpower", "未知"),

                    "humidity": w["humidity"],

                    "report_time": w["reporttime"]

                }

            }

        else:

            return {"status": "error", "msg": data.get("info", "天气查询失败")}

    except Exception as e:

        return {"status": "error", "msg": str(e)}


 

# ========================

# 4. 主程序 采用业内广泛采用的"ReAct"模式(Reason + Act),两次调用大模型

# ========================

def main():

    print("🌤️ 欢迎使用通义千问 + 高德天气助手")

    print("💡 输入地区名称,例如:广州市天河区、北京市海淀区")

    user_input = input("\n📍 请输入要查询的地区:").strip()

    if not user_input:

        print("❌ 请输入有效地区名称。")

        return

    # 构建对话历史

    messages = [

        {

            "role": "system",

            "content": "你是一个天气助手。当用户查询天气时,如果要查询的地名为中国大陆的地名,你必须调用 get_real_weather 工具获取真实数据,禁止编造或猜测。如果要查询的地名根本不是中国大陆的地名,则直接告诉查询者没有这个地方。"

        },

        {

            "role": "user",

            "content": f"请查询 {user_input} 的实时天气"

        }

    ]

    # 定义工具

    tools = [

        {

            "type": "function",

            "function": {

                "name": "get_real_weather",

                "description": "获取指定城市的实时天气信息(温度、天气、风力等)",

                "parameters": {

                    "type": "object",

                    "properties": {

                        "location": {

                            "type": "string",

                            "description": "城市或区域名称,如'北京市'、'广州市天河区'"

                        }

                    },

                    "required": ["location"]

                }

            }

        }

    ]

    try:

        # 第一轮:调用模型,判断是否需要工具

        response = Generation.call(

            model="qwen-max",

            messages=messages,

            tools=tools,

            tool_choice="auto",  # 可改为强制调用

            result_format="message",  # 必须!才能正确返回 tool_calls

            api_key=DASHSCOPE_API_KEY

        )

        if response.status_code != 200:

            print(f"❌ 大模型调用失败:{response.message}")

            return

        output = response.output  # 返回的是完整结构

        # ========================

        # 解析 tool_calls(嵌套在 choices 中)

        # ========================

        if (

            isinstance(output, dict) and

            'choices' in output and

            len(output['choices']) > 0 and

            'message' in output['choices'][0] and

            'tool_calls' in output['choices'][0]['message']

        ):

            #解析tool_calls,需要调用外部工具

            tool_calls = output['choices'][0]['message']['tool_calls']

            if tool_calls and tool_calls[0]['function']['name'] == 'get_real_weather':

                tool_call = tool_calls[0]

                func_name = tool_call['function']['name']

                args_str = tool_call['function']['arguments']

               

                # 解析 arguments(是 JSON 字符串)

                try:

                    args = json.loads(args_str)

                except Exception as e:

                    print(f"❌ 参数解析失败:{e}")

                    args = {}

 #               location = args.get('location', user_input)

                location = args.get('location')

                print(f"\n🔍 正在通过高德查询 {location} 现在的天气状况...")

                weather_result = get_real_weather(location)

                if weather_result["status"] == "success":

                    w = weather_result["data"]

                    # 构造 tool 响应

                    tool_response = {

                        "role": "tool",

                        "content": f"城市:{w['city']},天气:{w['weather']},"

                                   f"温度:{w['temperature']}°C,风向:{w['winddirection']},"

                                   f"风力:{w['windpower']}级,湿度:{w['humidity']}%,"

                                   f"更新时间:{w['report_time']}",

                        "tool_call_id": tool_call["id"]  # 必须匹配

                    }

                    # 把模型的回复和 tool 响应都加入对话

                    messages.append(output['choices'][0]['message'])  # 模型的 tool_calls

                    messages.append(tool_response)

                    # 第二轮:让模型生成自然语言回复

                   

                    final_response = Generation.call(

                        model="qwen-max",

                        messages=messages,

                        result_format="message",

                        api_key=DASHSCOPE_API_KEY

                    )

                    if final_response.status_code == 200:

                        final_msg = final_response.output

                        content = ""

                        if isinstance(final_msg, dict):

                            content = final_response["output"]["choices"][0]["message"]["content"]

                        if content:

                            print(f"\n🌤️ 天气信息:\n{content}")

                        else:

                            print("❌ 模型未生成有效回复。")

                    else:

                        print(f"❌ 最终回复生成失败:{final_response.message}")

                else:

                    print(f"❌ 天气查询失败:{weather_result['msg']}")

            else:

                print("⚠️ 未调用 get_real_weather 函数。")

        else:

            # 没有 tool_calls,直接输出模型文本

            content = ""

            if isinstance(output, dict):

                if 'text' in output and output['text']:

                    content = output['text'].strip()

                elif 'choices' in output and len(output['choices']) > 0:

                    msg = output['choices'][0]['message'].get('content', '')

                    content = msg.strip()

            if content:

                print(f"\n🤖 回复:\n{content}")

            else:

                print("❌ 模型未返回有效内容。")

    except Exception as e:

        print(f"❌ 程序异常:{str(e)}")


 

# ========================

#5. 启动入口

# ========================

if __name__ == "__main__":

    main()

以上代码,在Python3.13.5版本运行正常。欢迎技术交流

### 调用 Qwen2.5 模型执行 Function Call 的方法 为了在 MindIE 中调用 Qwen2.5 模型来执行 function call,需要遵循特定的配置流程和 API 接口设计[^1]。 #### 配置环境变量 首先,在使用之前需确认已安装并正确设置了所需的依赖库以及访问凭证。通常情况下,这涉及到设置 API 密钥和其他必要的认证信息: ```bash export MIND_IE_API_KEY="your_api_key_here" ``` #### 初始化客户端实例 创建一个用于与服务端通信的客户端对象,并指定要使用的具体模型版本: ```python from mind_ie import Client client = Client(api_key=os.getenv('MIND_IE_API_KEY'), model_version='qwen-2_5') ``` #### 准备请求参数 构建包含目标函数名称及其所需输入参数的数据结构。这里假设有一个名为 `add_numbers` 的简单加法运算函数作为例子: ```json { "functions": [ { "name": "add_numbers", "arguments": {"a": 5, "b": 7} } ] } ``` 将其转换成 Python 字典形式以便于后续操作: ```python request_data = { 'functions': [{ 'name': 'add_numbers', 'arguments': {'a': 5, 'b': 7}, }] } ``` #### 发送请求并处理响应 通过客户端发送准备好的数据到远程服务器,并接收返回的结果: ```python response = client.call_function(request_data) if response['success']: result = response.get('result', None) else: error_message = response.get('error', '') raise Exception(f"Function call failed: {error_message}") ``` 以上就是完整的调用过程概述,实际应用时可根据需求调整细节部分[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值