FeelingLife FeelingLife
首页
  • Go

    • Go基础知识
  • Python

    • Python进阶
  • 操作系统
  • 计算机网络
  • MySQL
  • 学习笔记
  • 常用到的算法
  • Docker
  • Kubernetes
  • Observability
  • 容器底层
其他技术
  • 友情链接
  • 收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

xuqil

一介帆夫
首页
  • Go

    • Go基础知识
  • Python

    • Python进阶
  • 操作系统
  • 计算机网络
  • MySQL
  • 学习笔记
  • 常用到的算法
  • Docker
  • Kubernetes
  • Observability
  • 容器底层
其他技术
  • 友情链接
  • 收藏
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • FunctionCalling原理
    • 引言
    • Function Calling诞生的背后故事
      • 大模型的知识局限性
      • 传统解决方案的不足
      • Function Calling的诞生
    • Function Calling的原理
      • 工作流程概述
      • 核心原理剖析
    • Function Calling的架构
      • 技术栈与关键特征
      • 实现模式
      • 应用架构设计示例
      • 性能优化策略
      • 安全与治理框架
    • 开发实践
      • 原生代码实现
      • OpenAI SDK实现
      • LangChain实现
      • LLamaIndex实现
    • 总结
      • Function Calling的优势总结
      • 面临的挑战
      • 未来展望
  • 《大模型应用开发》
xuqil
2025-05-27
目录

FunctionCalling原理

# Function Calling是什么

# 引言

在人工智能领域,大语言模型(LLM)的发展日新月异。从最初只能进行简单文本生成的基础模型,到如今具备强大语言理解和生成能力的先进系统,大语言模型已经深刻改变了我们与计算机交互的方式。然而,传统大语言模型存在着一些局限性,如无法获取实时数据、难以执行复杂任务等。为了克服这些问题,Function Calling应运而生,它为大语言模型与外部世界的交互提供了一种全新的解决方案,使得大语言模型能够更加智能、高效地完成各种任务。

# Function Calling诞生的背后故事

# 大模型的知识局限性

我们常见的大模型,如OpenAI的GPT-4、智谱AI的GLM4等,大多是预训练大模型。这些模型的知识基于其训练数据的时间范围,例如2024年2月更新的GPT-4-0125-preview,其训练数据截止在2023年12月,因此对于2024年发生的事情它一无所知,甚至无法获知当前时间。这就导致大模型在面对需要实时信息的问题时显得无能为力。

# 传统解决方案的不足

在2023年6月13日之前,大模型本身并没有调用外部函数的能力。开发AI应用通常依赖特定的框架或平台,如Semantic Kernel或Langchain来实现互联网搜索或调用外部API。在这个过程中,设计提示词是关键,但由于每个人编写的提示词结构不同,无法实现标准化,导致准确率大打折扣。

此外,OpenAI曾引入插件功能,但该功能存在诸多缺陷。例如,同时使用的插件数量受限,同一时间最多只能激活和使用三个插件,用户无法构建具有一定复杂性和强大功能的AI应用;缺乏有效的Agent调度机制,用户只能手动选择有限数量的插件,限制了功能的灵活性和扩展性;无法为特定场景提供完整的端到端解决方案,影响了用户体验和解决问题的效率;需要多次与GPT进行交互,导致整体响应延迟高,使得插件在实际应用中的性能表现不佳。最终,插件商店在2024年4月被废弃。

# Function Calling的诞生

为了解决上述问题,Function Calling机制在2023年6月13日随着OpenAI的GPT大模型的更新发布而为人所知。它允许大模型直接调用外部函数和API,以获取实时数据和执行特定任务,大大简化了开发过程,推动了大模型技术的实际应用。

# Function Calling的原理

# 工作流程概述

Function Calling的工作流程通常包括以下几个关键步骤:

  1. 定义函数:开发者需要定义外部函数及其参数。例如,定义一个查询天气的函数:
def get_weather(location: str) -> str:
    """获取指定城市的实时温度"""
    mock_data = {"北京": 28, "上海": 30, "深圳": 32}
    return f"{location}当前气温:{mock_data.get(location, 26)}℃"
1
2
3
4
  1. 用户请求:用户向模型提出请求,如“深圳现在多少度?”
  2. 模型生成函数调用:模型识别需要调用外部函数的部分,并生成函数调用参数。例如,模型可能生成如下调用信息:
{

    "index": 0,
    "id": "call_667d5e06ea7243c38b9082",
    "type": "function",
    "function": {
        "name": "get_weather",
        "arguments": "{\"location\": \"深圳\"}"
    }
}
1
2
3
4
5
6
7
8
9
10
  1. 调用外部函数:开发者根据模型生成的参数调用外部函数。

    get_weather("深圳")
    
    1
  2. 返回结果给模型:将函数调用的结果返回给模型。例如,将获取到的天气信息返回给模型,模型再将其整合为自然语言回复给用户。

  3. 整理最终结果:模型根据函数调用的结果整理最终答案。

工作流:

FunctionCalling

# 核心原理剖析

  1. 意图识别:模型通过语义分析理解用户请求的目标,例如识别出用户是在查询天气。训练时会引入函数调用的示例数据,使模型学习何时触发调用。例如,标注“深圳现在多少度?”对应调用天气API,并提取参数{location: "深圳"}。
  2. 函数匹配:模型内部有一个函数目录或知识库,存储了各种可调用函数的信息,包括函数的功能描述、参数要求等,也可以使用提示词吧函数喂给大模型。模型会将解析出的语义与这些函数信息进行匹配,找到最适合的函数。
  3. 参数生成:确定要调用的函数后,模型会根据文本中的相关内容生成正确的参数,将自然语言描述转换为函数能够接受的参数格式。
  4. 执行回调与结果整合:开发者的代码执行真实业务逻辑,调用外部函数并获取结果。然后将结果反馈给模型,模型将其融入自然语言回复。同时,支持多轮对话,模型可根据函数返回结果决定后续操作,如数据不足时调用其他API。

# Function Calling的架构

# 技术栈与关键特征

Function Calling的技术栈具有一些关键特征:

  1. 语义理解层:基于few - shot learning的意图识别准确率可达92%以上,能够准确理解用户的意图。
  2. 参数结构化:支持JSON Schema定义复杂数据结构,确保模型生成的参数格式符合函数要求,便于函数的准确调用。
  3. 动态上下文:支持多轮对话中的持续状态维护,使得模型在多轮交互中能够保持对上下文的理解,更好地完成任务。

# 实现模式

常见的实现模式有以下几种:

模式 适用场景 延迟 安全性
同步直连 内部系统调用 <2s 高
异步队列 批处理任务 可变 中
沙箱执行 代码解释器 3 - 5s 低
插件市场 第三方服务集成 2 - 4s 可变

# 应用架构设计示例

以智能工单系统为例,其架构设计如下:

  1. 用户发起请求:用户向大语言模型反馈“产线设备报错代码E105”。
  2. 模型调用工具:大语言模型调用ToolGateway的get_error_code手册。
  3. 查询数据:ToolGateway向ERP系统进行SQL查询E105。
  4. 返回结果:ERP系统返回散热系统故障信息给ToolGateway,ToolGateway再将故障解决方案反馈给大语言模型。
  5. 生成工单:大语言模型调用ToolGateway创建维修工单,ToolGateway将工单信息写入ERP系统。
  6. 反馈用户:大语言模型告知用户已安排工程师处理。

# 性能优化策略

为了提高Function Calling的性能,可采用以下策略:

  1. 缓存机制:对高频查询结果建立向量缓存,可将命中率提升40%,减少重复查询的开销。
  2. 批量处理:合并同类请求降低API调用次数,提高系统的处理效率。
  3. 模型蒸馏:构建轻量级路由模型,可将模型体积缩小80%,减少计算资源的占用。
  4. 流式响应:分段返回降低首字节时间,提升用户体验。

# 安全与治理框架

  1. 权限控制矩阵:明确不同用户角色对不同工具的使用权限,例如“financial_data”只能由“L3 + 管理者”访问,“production_data”可由“生产部员工”访问,“system_config”仅“IT管理员”可操作。
  2. 审计追踪设计:采用全链路请求追踪(如X - Ray集成),对敏感操作设置二次确认机制,并建立动态权限回收系统,确保系统的安全性和可追溯性。

# 开发实践

# 原生代码实现

以OpenAI API为例,典型的开发流程如下:

  1. 定义函数库:开发者预先声明可用函数及参数格式。例如:

    def get_weather(location: str) -> str:
        """获取指定城市的实时温度(示例数据)"""
        mock_data = {"北京": 28, "上海": 30, "深圳": 32}
        return f"{location}当前气温:{mock_data.get(location, 26)}℃"
    
    1
    2
    3
    4
  2. 用户请求与模型响应:用户输入问题,如“深圳现在多少度?”,模型返回函数调用指令。

    1. url:/chat/completions
    2. 用户的请求体:
    {
      "model": "qwen-plus",
      "messages": [
        {
          "role": "user",
          "content": "深圳现在多少度?"
        }
      ],
      "tools": [ // 必须带上 tools 声明
        {
          "type": "function", // tool 类型
          "function": {
            "name": "get_weather",
            "description": "获取指定城市的实时温度", // tool 描述 
            "parameters": { // 参数信息
              "type": "object",
              "properties": {
                "location": {
                  "type": "string",
                  "description": "城市名称,如:北京"
                }
              },
              "required": [
                "location"
              ]
            }
          }
        }
      ],
      "tool_choice": "auto"
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
  3. 模型生成函数调用:模型识别需要调用外部函数的部分,并选择和生成函数调用参数。模型返回的响应:

    {
        "choices": [ // 选择的 tools
            {
                "message": {
                    "content": "",
                    "role": "assistant",  // 角色为assistant
                    "tool_calls": [
                        {
                            "index": 0,
                            "id": "call_667d5e06ea7243c38b9082", // tool的ID
                            "type": "function",
                            "function": {
                                "name": "get_weather", // tool名称
                                "arguments": "{\"location\": \"深圳\"}" // 参数
                            }
                        }
                    ]
                },
                "finish_reason": "tool_calls",
                "index": 0,
                "logprobs": null
            }
        ],
        "object": "chat.completion",
        "usage": {
            "prompt_tokens": 174,
            "completion_tokens": 17,
            "total_tokens": 191,
            "prompt_tokens_details": {
                "cached_tokens": 0
            }
        },
        "created": 1748228293,
        "system_fingerprint": null,
        "model": "qwen-plus",
        "id": "chatcmpl-a8dafc1f-8092-9456-953e-7a55ff7be5c8"
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
  4. 用户执行函数:用户根据模型选择的tool来执行函数。

    get_weather("深圳")
    
    1
  5. 返回结果给模型:用户系统调用天气API获取数据后,将结果返回模型,生成最终回答。

    1. url:/chat/completions。
    2. 请求体:
    {
      "model": "qwen-plus",
      "messages": [
        { // 带上历史 message
          "role": "user",
          "content": "深圳现在多少度?"
        },
        { // 模型选择的 tool
          "content": "",
          "role": "assistant",
          "tool_calls": [
            {
              "index": 0,
              "id": "call_667d5e06ea7243c38b9082", // tool 的 ID
              "type": "function",
              "function": {
                "name": "get_weather",
                "arguments": "{\"location\": \"深圳\"}"
              }
            }
          ]
        },
        { // 执行 tool 的结果
          "tool_call_id": "call_667d5e06ea7243c38b9082", // tool 的 ID
          "role": "tool",
          "name": "get_weather",
          "content": "深圳当前气温:32℃"
        }
      ],
      "tools": null,
      "tool_choice": "auto"
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
  6. 整理最终结果:模型根据函数调用的结果整理最终答案。

    {
        "choices": [
            {
                "message": {
                    "content": "深圳当前的气温是 **32℃**。请注意,气温可能会随时间和天气变化而有所波动,建议关注最新的天气预报,尤其是在户外活动时做好防暑降温措施! ☀️",
                    "role": "assistant"
                },
                "finish_reason": "stop",
                "index": 0,
                "logprobs": null
            }
        ],
        "object": "chat.completion",
        "usage": {
            "prompt_tokens": 31,
            "completion_tokens": 42,
            "total_tokens": 73,
            "prompt_tokens_details": {
                "cached_tokens": 0
            }
        },
        "created": 1748228369,
        "system_fingerprint": null,
        "model": "qwen-plus",
        "id": "chatcmpl-06026535-5586-95ba-aa4b-75ddaa6a9baf"
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

完整的代码见:。

# OpenAI SDK实现

# 初始化OpenAI客户端
client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url=os.environ.get("DASHSCOPE_API_BASE"),
)

def create_chat_completion(messages: list, use_tools: bool = False):
    """创建带工具调用的聊天完成"""
    tools = [
        {
            "type": "function",
            "function": {
                "name": "get_weather",
                "description": "获取指定城市的实时温度",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "城市名称,如:北京"
                        }
                    },
                    "required": ["location"]
                }
            }
        }
    ]
    return client.chat.completions.create(
        model=MODEL_NAME,
        messages=messages,
        tools=tools,
        tool_choice="auto" if use_tools else None
    )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

完整代码见:

# LangChain实现

def main():
    llm = ChatOpenAI(
        api_key=API_KEY,
        base_url=BASE_URL,
        model=MODEL_NAME,
    )
    llm_with_tools = llm.bind_tools([get_weather])

    query = "深圳现在多少度?"

    messages = [HumanMessage(query)]
    ai_msg = llm_with_tools.invoke(messages)
    messages.append(ai_msg)  # 添加tool的选择

    print("调用的tools:", ai_msg.tool_calls)
    for tool_call in ai_msg.tool_calls:
        selected_tool = {"get_weather": get_weather}[tool_call["name"].lower()]
        tool_msg = selected_tool.invoke(tool_call)
        messages.append(tool_msg)

    print("messages:", messages)
    res = llm_with_tools.invoke(messages)
    print(res.model_dump_json())
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# LLamaIndex实现

def get_weather(location: str) -> str:
    """获取指定城市的实时温度"""
    mock_data = {"北京": 28, "上海": 30, "深圳": 32}
    return f"{location}当前气温:{mock_data.get(location, 26)}℃"


def main():
    tool = FunctionTool.from_defaults(fn=get_weather)

    llm = OpenAILike(
        model=MODEL_NAME,
        api_base=BASE_URL,
        api_key=API_KEY,
        is_chat_model=True,
        is_function_calling_model=True,
    )
    response = llm.predict_and_call(
        [tool],
        "深圳现在多少度?",
    )
    print(str(response))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 总结

# Function Calling的优势总结

Function Calling为大语言模型带来了诸多优势:

  1. 扩展模型能力:突破了模型固有知识的限制,使模型能够获取实时信息,处理更复杂的任务,如查询数据库、调用API、执行计算等。
  2. 精准控制:约束输出格式(如JSON/XML),确保下游系统能够更好地兼容模型的输出,提高了数据处理的准确性和效率。
  3. 动态任务处理:模型可以根据用户请求动态选择需要调用的函数,实现灵活的任务处理,满足不同场景的需求。

# 面临的挑战

尽管Function Calling具有强大的功能,但也面临一些挑战:

  1. 函数定义的一致性:不同大模型供应商的接口格式略有差异,开发者在支持多个大模型时需要进行适配,增加了开发的复杂性。
  2. 准确性问题:模型可能错误匹配函数或参数,需要强化训练和参数校验,提高调用的准确性。
  3. 安全性风险:函数调用涉及与外部系统的交互,需要严格控制权限,防止恶意请求和数据泄露。
  4. 不兼容:部分大模型不支持Function Calling,例如DeepSeek R1。

# 未来展望

随着技术的不断发展,Function Calling有望在更多领域发挥重要作用:

  1. Agent生态系统:构建自主智能体协作网络,使多个智能体能够通过Function Calling相互协作,完成更复杂的任务。
  2. 物理世界接口:实现与IoT设备的直接控制,通过Function Calling让大模型能够控制现实世界中的各种设备,如智能家居、工业设备等。
  3. 动态工具发现:基于语义的自动工具组合,使模型能够根据任务需求自动发现和组合合适的工具,提高任务处理的效率和灵活性。

Function Calling是大语言模型发展中的一项重要技术,它为大模型与外部世界的交互提供了强大的支持。尽管面临一些挑战,但随着技术的不断进步和完善,Function Calling必将在人工智能领域发挥越来越重要的作用,推动AI应用向更加智能、高效的方向发展。

上次更新: 2025/05/27, 08:22:54
最近更新
01
VXLAN互通实验
05-13
02
VXLAN
05-13
03
VLAN
05-13
更多文章>
Theme by Vdoing | Copyright © 2018-2025 FeelingLife | 粤ICP备2022093535号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式