首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >构建AI智能体:Function Calling - 解锁大语言模型的实际行动力+案例解析

构建AI智能体:Function Calling - 解锁大语言模型的实际行动力+案例解析

原创
作者头像
未闻花名
发布2025-10-29 09:18:23
发布2025-10-29 09:18:23
11700
代码可运行
举报
运行总次数:0
代码可运行

先忽略Function Calling的名称,看看“解锁大语言模型的实际行动力”,为什么有此一说?难道大模型也会有到达不了的彼岸?如果接触过DeepSeek,我们都会惊叹于大语言模型(LLM)对答如流、才华横溢以及解答问题的能力。然而它本质上是一个知识丰富的聊天者,能让人惊叹的做出完美的解决方案,唯一缺陷的是没有办法做真正的事情处理,好比能告诉我们最优秀完美的旅游方案,却没有办法去定一张机票,鉴于此,Function Calling(函数调用)完美登场,助力解锁大语言模型的实际行动力,让AI不只是“说”,更能“做”,让我们今天就好好了解Function Calling原理与应用指南!

一、概念解析

Function Calling 是大模型提供的一项革新能力。它充当了模型思考与外部行动之间的关键桥梁。它允许开发者告诉模型:‘你拥有这些可用的工具(函数)’,模型则能在理解用户意图后,聪明地决定是否需要使用某个工具,并以结构化格式请求调用它。开发者收到请求后,执行实际的操作(如查询数据库、发送邮件、调用API),并将结果反馈给模型,模型最终整合信息,生成自然语言回复给用户。

1.什么是Function

函数(function)是用来组织和执行代码逻辑的基本单元,它们都封装了一段可重复使用的代码块,接收输入参数并可能返回结果;

每个函数有:名称、清晰描述、参数(名称、类型、描述);

2.Function Calling 过程拆解

  • 第一步(开发者):声明函数列表(名称、描述、参数)并告知大模型
  • 第二步(用户):发送请求,包含或不包含调用函数的请求
  • 第三步(大模型):理解用户意图,判断是否需要调用函数?如果需要,调用哪个函数? 生成结构化请求:输出一个标准的JSON对象,包含明确的 function_call 信息(name - 函数名,arguments - 符合函数参数定义的JSON字符串)。
  • 第四步(开发者):解析大模型输出的JSON,找到对应的函数实现 执行函数: 调用方法,传入解析后的参数,获取函数执行结果; 结果反馈:将函数执行结果(通常是JSON)反馈给大模型;
  • 第五步(大模型): 结合上下文信息以及函数执行结果,生成回复内容,向用户解释结果或进行下一步交互。

下面是即将调试的一个用例,可以先看看初步流程,稍后可以看看具体执行过程!

图示说明:

  • 开发者系统初始化
    • 预先向大模型注册函数定义(名称、描述、参数结构)
  • 用户触发流程
    • 用户输入自然语言请求(隐含需要外部操作)
  • 大模型智能决策
    • 解析意图 → 选择函数 → 提取参数 → 输出结构化JSON请求
  • 开发者系统关键操作
    • 参数校验(类型/范围/安全性检查)
    • 执行真实函数(API/数据库/服务调用)
    • 返回结构化结果给大模型
  • 大模型生成最终回复
    • 将原始数据转化为用户友好的自然语言

3.Function Calling 的优点

  • 解决“只说不做”的问题: 直接扩展大模型能力边界。
  • 超越Prompt的限制: 避免在Prompt中过度复杂指令逻辑或尝试让大模型想象结果,导致简单的问题复杂化,加大偏差。
  • 提高可靠性: 结构化请求比从自由文本中解析意图和参数更可靠、更稳定。
  • 提升效率: 大模型专注于意图理解和结果解释,将执行交给更擅长、更安全的专业代码。
  • 增强安全性: 实际代码执行在受控环境中,大模型本身不直接操作敏感系统。
  • 实现动态交互: 构建多步骤、依赖外部状态的复杂Agent工作流的基础。

4.应用场景

  • 智能助手/聊天机器人: 查天气、订餐、查航班酒店、查订单、控制智能家居
  • 数据查询与分析: 连接数据库(SQL查询)、CRM、ERP系统,用自然语言获取报告。
  • 内容增强与自动化: 根据用户描述生成图片(调用自定义API)、发送邮件/消息通知、生成日历事件。
  • 代码助手: 执行代码解释、单元测试、简单重构(调用本地工具)。
  • 工作流自动化: 作为复杂自动化流程的智能决策和交互节点。

5.注意事项

  • 大模型判断错误: 可能误判需要调用函数,或选错函数。需要设计回退/确认机制。
  • 参数提取错误: 大模型可能误解用户意图导致参数值错误。强调参数校验的重要性。
  • 描述优化: 编写高效的函数/参数描述需要技巧和迭代。
  • 复杂逻辑处理: 处理需要多次函数调用、状态依赖的复杂流程。
  • 安全性与权限: 确保函数调用在授权范围内执行,防止越权操作。
  • 成本与延迟: 多次交互可能增加Token消耗和整体响应时间。

二、应用示例

1.背景说明

基于Qwen-Plus的大模型创建一个指定城市的天气查询对话系统,利用大模型的函数调用(Function Calling)能力实现智能交互,看看整个流程的执行!

2.示例代码

代码语言:javascript
代码运行次数:0
运行
复制
import json
import os
import dashscope
from dashscope.api_entities.dashscope_response import Role
# 从环境变量中,获取 DASHSCOPE_API_KEY
api_key = os.environ.get('DASHSCOPE_API_KEY')
dashscope.api_key = api_key
# 编写天气函数,调用本地的函数看看Function Call的效果,此处可替换为天气的接口看真实数据
def get_current_weather(location, unit="摄氏度"):
    # 获取指定地点的天气
    temperature = -1
    if '杭州' in location or 'Hangzhou' in location:
        temperature = 10
    if '上海' in location or 'Shanghai' in location:
        temperature = 36
    if '深圳' in location or 'Shenzhen' in location:
        temperature = 37
    weather_info = {
        "location": location,
        "temperature": temperature,
        "unit": unit,
        "forecast": ["晴天", "微风"],
    }
    return json.dumps(weather_info)
# 封装模型响应函数
def get_response(messages):
    try:
        response = dashscope.Generation.call(
            model='qwen-plus',
            messages=messages,
            functions=functions,
            result_format='message'
        )
        return response
    except Exception as e:
        print(f"API调用出错: {str(e)}")
        return None
# 使用function call进行QA
def run_conversation():
    query = "杭州的天气怎样"
    messages=[{"role": "user", "content": query}]
    # 得到第一次响应
    response = get_response(messages)
    if not response or not response.output:
        print("获取响应失败")
        return None
    print('response=', response)
    message = response.output.choices[0].message
    messages.append(message)
    print('message=', message)
    # Step 2, 判断用户是否要call function
    if hasattr(message, 'function_call') and message.function_call:
        function_call = message.function_call
        tool_name = function_call['name']
        # Step 3, 执行function call
        arguments = json.loads(function_call['arguments'])
        print('arguments=', arguments)
        tool_response = get_current_weather(
            location=arguments.get('location'),
            unit=arguments.get('unit'),
        )
        tool_info = {"role": "function", "name": tool_name, "content": tool_response}
        print('tool_info=', tool_info)
        messages.append(tool_info)
        print('messages=', messages)
        #Step 4, 得到第二次响应
        response = get_response(messages)
        if not response or not response.output:
            print("获取第二次响应失败")
            return None
        print('response=', response)
        message = response.output.choices[0].message
        return message
    return message
functions = [
    {
      'name': 'get_current_weather',
      'description': '获取指定地点,指定温度单位的天气信息',
      'parameters': {
            'type': 'object',
            'properties': {
                'location': {
                    'type': 'string',
                    'description': '城市名称,例如:杭州,上海,深圳。'
                },
                'unit': {'type': 'string', 'enum': ['celsius', 'fahrenheit']}
            },
        'required': ['location']
      }
    }
]
if __name__ == "__main__":
    result = run_conversation()
    if result:
        print("最终结果:", result)
    else:
        print("对话执行失败")

最终结果:

代码语言:javascript
代码运行次数:0
运行
复制
 最终结果: {"role": "assistant", "content": "杭州当前的温度是10摄氏度,天气晴朗,微风。"}

3.执行流程

  1. 用户输入:“杭州的天气怎么样”
  2. 大模型输出:
代码语言:javascript
代码运行次数:0
运行
复制
{
  "function_call": {
    "name": "get_current_weather",
    "arguments": "{\"location\":\"杭州\"}"
  }
} 

3.执行函数:get_current_weather(location="杭州")

4.函数返回:

代码语言:javascript
代码运行次数:0
运行
复制
 {   "location": "杭州",   "temperature": 10,   "unit": "摄氏度",   "forecast": ["晴天", "微风"] }

5.大模型最终回复:

代码语言:javascript
代码运行次数:0
运行
复制
 "杭州当前气温10摄氏度,天气晴,微风"

4.代码分解

4.1. 天气函数 (get_current_weather)

代码语言:javascript
代码运行次数:0
运行
复制
def get_current_weather(location, unit="摄氏度"):
    # 模拟真实天气API(根据城市返回预设温度)
    temperature = -1
    if '杭州' in location: temperature = 10
    if '上海' in location: temperature = 36
    if '深圳' in location: temperature = 37
    return json.dumps({
        "location": location,
        "temperature": temperature,
        "unit": unit,
        "forecast": ["晴天", "微风"]
    })
  • 作用:模拟真实天气API,返回结构化天气数据
  • 特点
    • 支持中英文城市名识别(杭州/Hangzhou)
    • 返回JSON格式的标准数据结构
    • 可轻松替换为真实天气API(如高德、OpenWeather)

4.2. 函数注册 (functions)

代码语言:javascript
代码运行次数:0
运行
复制
functions = [{
    'name': 'get_current_weather',
    'description': '获取指定地点,指定温度单位的天气信息',
    'parameters': {
        'type': 'object',
        'properties': {
            'location': {
                'type': 'string',
                'description': '城市名称,例如:杭州,上海,深圳。'
            },
            'unit': {'type': 'string', 'enum': ['celsius', 'fahrenheit']}
        },
        'required': ['location']
    }
}]
  • 核心作用:告诉大模型何时调用函数及需要哪些参数
  • 关键字段
    • description:中文描述提升中文场景准确性
    • enum:限制unit参数的可选值(摄氏度/华氏度)
    • required:强制要求location参数

4.3. 对话引擎 (run_conversation)

代码语言:javascript
代码运行次数:0
运行
复制
def run_conversation():
    # 1. 用户输入
    query = "杭州的天气怎样"
    messages = [{"role": "user", "content": query}]
    # 2. 首次模型调用
    response = get_response(messages)
    message = response.output.choices[0].message
    # 3. 检测函数调用
    if hasattr(message, 'function_call'):
        # 解析参数
        arguments = json.loads(message.function_call['arguments'])
        # 4. 执行天气函数
        tool_response = get_current_weather(**arguments)
        # 5. 将结果加入上下文
        messages.append({
            "role": "function", 
            "name": "get_current_weather",
            "content": tool_response
        })
        # 6. 二次模型调用生成最终回复
        final_response = get_response(messages)
        return final_response.output.choices[0].message
  • 核心作用:程序入口,用户输入后检测函数调用,并按对应流程执行

5. 完整流程

  • 1. 用户输入自然语言查询
  • 2. 大模型判断需要调用天气函数
  • 3. 解析生成的参数(如{"location": "杭州"}
  • 4. 执行天气函数获取数据
  • 5. 将原始天气数据返回给大模型
  • 6. 大模型生成友好回复(如"杭州当前气温10摄氏度,晴天")

以上完整的阐述了此示例整个流程执行的各个节点细节,更好的帮助大家理解!

三、总结

  • 1.Function Calling是补充了大模型的短处,进一步挖掘了大模型更深的潜力,扩展了大模型的边界;
  • 2.函数是灵魂,函数的构造也至关重要,开发者明确目的,提供完整的、可用的、安全的函数助力大模型高效完成任务;
  • 3.安全是首当其冲的重点,参数校验是强制性的,绝不能省略,开发者后端代码必须: 检查参数是否存在(尤其是 required 的参数); 检查参数类型是否正确(传进来的字符串能否转成需要的数字/日期?); 检查参数值是否在有效范围内(日期是否合理?ID是否存在?); 进行必要的清理和转换(防止SQL注入、命令注入等)。
  • 4.错误处理机制也必不可少,函数执行可能失败(网络问题、权限不足、参数校验失败、内部错误等)要能及时反馈。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、概念解析
    • 1.什么是Function
    • 2.Function Calling 过程拆解
    • 3.Function Calling 的优点
    • 4.应用场景
    • 5.注意事项
  • 二、应用示例
    • 1.背景说明
    • 2.示例代码
    • 3.执行流程
    • 4.代码分解
    • 4.1. 天气函数 (get_current_weather)
    • 4.2. 函数注册 (functions)
    • 4.3. 对话引擎 (run_conversation)
    • 5. 完整流程
  • 三、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档