通义千问的 Function Call - demo学习

1、理解 Function Call

让大模型能调用外部工具、函数,而非仅靠自身知识库回答问题。

2、流程步骤:

用户提问→模型判断调用函数→执行自定义函数→模型基于函数结果生成回答

第一调用模型

让模型分析用户问题,判断是否需要调用函数,并返回调用函数指令

第二次调用模型

把自定义函数执行的结果传给模型,模型基于真实数据生成自然语言回答(比如 "大连当前温度 10 摄氏度,晴天,微风")

3、代码

python 复制代码
# 导入JSON模块:用于序列化/反序列化函数参数和返回结果
import json
# 导入操作系统模块:读取环境变量中的API密钥
import os
# 导入通义千问SDK核心模块
import dashscope

# 从环境变量读取API密钥并配置
dashscope.api_key = os.environ.get('DASHSCOPE_API_KEY')

# 定义天气查询函数:模拟返回指定城市的天气(核心业务函数)
def get_current_weather(location, unit="摄氏度"):
    # 初始化温度(默认-1表示未匹配城市)
    temperature = -1
    # 按城市匹配模拟温度
    if '大连' in location: temperature = 10
    if '上海' in location: temperature = 36
    if '深圳' in location: temperature = 37
    # 构造天气信息字典并转为JSON字符串返回(符合Function Call格式要求)
    return json.dumps({
        "location": location,
        "temperature": temperature,
        "unit": unit,
        "forecast": ["晴天", "微风"]
    })

# 封装模型调用函数
def call_qwen(messages):
    try:
        # 调用通义千问qwen-max模型,指定函数列表和返回格式
        return dashscope.Generation.call(
            model='qwen-max',
            messages=messages,
            functions=functions,
            result_format='message'  # 结构化消息格式,便于解析函数调用
        )
    except Exception as e:
        # 捕获异常并打印,返回None标识调用失败
        print(f"API调用异常: {str(e)}")
        return None

# 核心对话逻辑:实现"提问→判断调用函数→执行函数→生成最终回答"
def weather_qa():
    # 1. 初始化用户问题和消息上下文(大模型对话必须的格式:role+content)
    messages = [{"role": "user", "content": "大连的天气怎样"}]
    
    # 2. 第一次调用模型:判断是否需要调用函数
    response = call_qwen(messages)

    # 校验响应有效性,失败则直接返回
    if not response or not response.output:
        return "模型响应失败"

    # 提取模型返回的核心消息
    assistant_msg = response.output.choices[0].message

    # 将模型消息加入上下文(保证对话连贯性)
    messages.append(assistant_msg)

    # 3. 判断模型是否要求调用函数
    if hasattr(assistant_msg, 'function_call') and assistant_msg.function_call:
        # 解析函数调用参数(JSON字符串转字典)
        args = json.loads(assistant_msg.function_call['arguments'])
        # 执行天气查询函数,获取结果
        weather_result = get_current_weather(
            location=args.get('location'),
            unit=args.get('unit', '摄氏度')  # 设默认值,避免参数缺失
        )

        # 构造函数调用结果消息(必须按role=function格式)
        function_msg = {
            "role": "function",
            "name": assistant_msg.function_call['name'],
            "content": weather_result
        }
        # 将函数结果加入上下文
        messages.append(function_msg)
        
        # 4. 第二次调用模型:基于函数结果生成最终回答
        final_response = call_qwen(messages)
        if final_response and final_response.output:
            return final_response.output.choices[0].message.content
    
    # 若无需调用函数,直接返回模型初始回答
    return assistant_msg.content

# 定义函数调用描述(核心:告诉模型可调用的函数及参数规则)
functions = [{
    'name': 'get_current_weather',  # 必须和自定义函数名一致
    'description': '获取指定城市的当前天气',  # 改为中文描述,更适配中文提问
    'parameters': {
        'type': 'object',
        'properties': {
            'location': {
                'type': 'string',
                'description': '城市名称,例如:大连、上海'  # 中文示例更直观
            },
            'unit': {'type': 'string', 'enum': ['摄氏度', '华氏度']}  # 改为中文枚举值
        },
        'required': ['location']  # 必填参数:location
    }
}]

# 主程序入口
if __name__ == "__main__":
    # 执行问答逻辑并打印最终结果
    print("最终回答:", weather_qa())
相关推荐
深蓝海拓10 小时前
PySide6从0开始学习的笔记(二十六) 重写Qt窗口对象的事件(QEvent)处理方法
笔记·python·qt·学习·pyqt
测试_AI_一辰10 小时前
Agent & RAG 测试工程05:把 RAG 的检索过程跑清楚:chunk 是什么、怎么来的、怎么被命中的
开发语言·人工智能·功能测试·自动化·ai编程
阿杰学AI11 小时前
AI核心知识75——大语言模型之MAS (简洁且通俗易懂版)
人工智能·ai·语言模型·自然语言处理·agent·多智能体协作·mas
星火开发设计11 小时前
C++ 预处理指令:#include、#define 与条件编译
java·开发语言·c++·学习·算法·知识
BackCatK Chen12 小时前
第 1 篇:软件视角扫盲|TMC2240 软件核心特性 + 学习路径(附工具清单)
c语言·stm32·单片机·学习·电机驱动·保姆级教程·tmc2240
深蓝海拓12 小时前
PySide6从0开始学习的笔记(二十五) Qt窗口对象的生命周期和及时销毁
笔记·python·qt·学习·pyqt
孪生质数-12 小时前
Windows安装OpenClaw(Clawdbot)教程
ai·npm·skill·minimax·clawdbot·openclaw
理人综艺好会12 小时前
Web学习之用户认证
前端·学习
xiayutian_c12 小时前
Claude code不能直接写ABAP?
ai编程
●VON12 小时前
React Native for OpenHarmony:项目目录结构与跨平台构建流程详解
javascript·学习·react native·react.js·架构·跨平台·von