Gorilla:连接大量 API 的大型语言模型

这篇文章介绍了 Berkeley 函数调用排行榜(BFCL),这是首个对大语言模型(LLM)函数调用能力的全面评估基准。文章详细阐述了:

  • 评估数据集的构成(包含 2000 个测试用例,涵盖 Python、Java、JavaScript、REST API 等多种语言)
  • 评估方法(包括 AST 分析和可执行函数验证)
  • 不同类型的函数调用测试(简单、多重、并行等场景)
  • 各个模型的成本和延迟数据
  • 常见的函数调用错误模式

研究发现,在简单函数调用场景下,经过微调的开源模型可以达到与专有模型相当的效果。文章还介绍了他们开发的开源模型 Gorilla Open Functions v2。

原文链接:https://gorilla.cs.berkeley.edu/blogs/8_berkeley_function_calling_leaderboard.html

除了聊天之外,将大型语言模型(LLM)集成到许多应用程序和软件中(例如,Langchain、Llama Index、AutoGPT、Voyager)也变得越来越普遍。像 GPT、Gemini、Llama、Mistral 等模型,已通过函数调用(也称为工具调用)能力展示了这方面的巨大潜力。

我们提出了伯克利函数调用排行榜(BFCL),这是对 LLM 调用函数和工具的能力进行的首次全面评估。我们从实践经验中构建了这个数据集,使其能代表大多数用户的函数调用场景,例如在智能体中或作为企业工作流的一部分等。我们考虑了各种形式的函数调用,包括并行调用(一个函数输入,多个函数输出)和多重调用 (多个函数输入,一个函数输出),涵盖了 Java、JavaScript 等多种编程语言。此外,我们还会执行这些函数来测试模型,并评估模型在没有合适函数可用时是否能够正确地避免选择函数。另外,排行榜现在还包含了所有不同模型的成本和延迟数据!

2024 年 8 月 19 日,我们发布了 BFCL V2 数据集,其特点是包含企业贡献的数据,解决了偏见和数据污染等问题,并专注于动态的真实场景。查看 BFCL V2 · Live 博客文章了解更多详情。

2024 年 9 月 19 日,我们发布了 BFCL V3 数据集,其特点是包含多轮和多步骤函数调用评估。查看 BFCL V3 博客文章了解更多详情!

快速链接:

Berkeley 函数调用排行榜 🏆

Berkeley 函数调用排行榜 (BFCL) 旨在对不同 LLM 的函数调用能力进行全面研究。它包含 2000 个问题-函数-答案对,涵盖多种语言 (Python、Java、JavaScript、REST API),多样化的应用领域和复杂用例 (多函数调用,LLM 需要从多个提供的函数中选择一个或多个函数;以及并行函数调用,LLM 需要同时进行多个函数调用)。我们还研究了函数相关性检测,以确定当提供的函数不适合回答用户问题时模型会如何反应(在这种情况下会提供“错误信息“)。更具体地说,BFCL 包含 100 个 Java、50 个 JavaScript、70 个 REST API、100 个 SQL 和 1,680 个 Python 测试,涵盖了简单、并行、多重、可执行函数调用场景以及函数相关性检测

如下图所示的排行榜中,我们可以看到 OpenAI 的最新 GPT-4 版本领先评估,紧随其后的是开源模型 (OpenFunctions-v2)、Mistral AI 的 Mistral-medium 模型和 Anthropic 的 Claude-2.1。这篇博文包含了更多关于数据集、评估方法、常见失败模式等信息!

Berkeley 函数调用排行榜 (BFCL) LLM 在 Berkeley 函数调用排行榜 (BFCL) 上的表现

为了改进我们对结果的理解和可视化,我们引入了一个交互式的轮辐图工具,允许用户比较各种模型。这种比较分为九个不同的类别:函数相关性检测、AST(抽象语法树)分析,以及在简单、多重和并行多重函数场景下的执行函数调用验证。通过这种方法,可以清楚地看到测试揭示了模型的不理想表现。具体来说,在简单函数调用方面,专有和开源模型表现相当。然而,在处理多重和并行函数调用时,GPT 系列模型表现优于开源对手。

Berkeley 函数调用排行榜 (BFCL) 轮辐图 使用 Berkeley 函数调用排行榜 (BFCL) 轮辐图进行的详细分析

数据集构成

Gorilla OpenFunctions 评估数据集从之前的 OpenFunctions-v0 的 100 个数据点增长到了 2,000 个数据点!除了质量改进外,扩展后的数据集在以下方面展示了多样性:

我们的评估 JSON 函数是从不同网站来源抓取和生成的。我们有意包含了与 数学-代数体育-足球金融-抵押 等相关的函数领域。我们在通用评估中包含了 40 个函数子领域。这使我们能够理解模型在计算、云计算等数据丰富领域以及体育、法律等小众领域的表现。

Gorilla 输入和输出伯克利函数调用排行榜 (BFCL) 数据组成

评估类别 📊

我们将大部分评估分为两个类别:

Python 评估

**简单函数:**单函数评估包含最简单但最常见的格式,用户提供单个 JSON 函数文档,且只会调用一个函数。

**多重函数:**多重函数类别包含一个用户问题,该问题只从 2 到 4 个 JSON 函数文档中调用一个函数。模型需要能够根据用户提供的上下文选择最佳函数来调用。

**并行函数:**并行函数定义为通过一个用户查询并行调用多个函数。模型需要理解需要进行多少次函数调用,问题可以是单句或多句。

**并行多重函数:**并行多重函数是并行函数和多重函数的组合。换句话说,模型会收到多个函数文档,每个相应的函数调用将被调用零次或多次。

每个类别都有 AST 和相应的可执行评估。在可执行评估数据中,我们手动编写了 Python 函数,这些函数从免费的 REST API 端点 (例如获取天气) 和直接计算的函数 (例如线性回归) 中获取灵感。可执行类别旨在了解函数调用生成是否能在现实世界的应用程序中稳定使用函数调用。

非 Python 评估

虽然前面的类别构成了我们评估的主要部分,但我们还包括了其他特定类别,即聊天能力、函数相关性检测、REST API、SQL、Java 和 JavaScript,以评估模型在不同场景下的表现、对多种编程语言的支持,以及对不相关问题和函数文档的适应能力。

**聊天能力:**在聊天能力中,我们设计了不传入函数的场景,用户提出一般性问题 ⸺ 这类似于将模型用作通用聊天机器人。我们评估模型是否能够输出聊天消息并认识到不需要调用任何函数。注意与 “相关性” 的区别,在 “相关性” 中,模型还需要评估任何函数输入是否相关。我们将此类别用于内部模型评估,并从实时排行榜中排除统计数据。我们目前正在努力改进聊天能力的评估,确保聊天与用户请求相关且连贯,并欢迎社区提供建议和反馈。

**函数相关性检测:**在函数相关性检测中,我们设计了场景,其中没有任何提供的函数是相关的且应该被调用的。我们期望模型的输出是没有函数调用。这种场景可以洞察模型是否会在缺乏函数信息或用户指令的情况下,对其函数和参数产生幻觉来生成函数代码。

REST API: 现实世界中的大多数 API 调用都是 REST API 调用。Python 主要通过 Python requests 库中包含的 requests.get()requests.post()requests.delete() 等进行 REST API 调用。GET 请求是现实世界中最常用的。因此,我们包括了真实世界的 GET 请求,以测试模型通过复杂函数文档生成可执行 REST API 调用的能力,使用 requests.get() 以及 API 的硬编码 URL 和函数及其参数的描述。

我们的评估包括两种变体。第一种需要在 URL 中传递参数,称为路径参数,例如 GET /api/v3/PublicHolidays/{Year}/{CountryCode} 中的 {Year}{CountryCode}。第二种需要模型将参数作为键值对放入 requests.get(.)params 和/或 headers 中。例如,函数调用中的 params={'lang': 'fr'}。模型并不会被告知将要进行哪种类型的 REST API 调用,而是需要自行决定如何调用。

对于 REST API,我们使用可执行评估来检查可执行输出的有效执行、响应类型和响应 JSON 键的一致性。在 AST 方面,我们选择不对 REST 执行 AST 评估,主要是因为复杂定义的 API 可能有大量可能的答案,枚举所有可能的答案是很耗费资源的。

SQL: SQL 评估数据包括我们自定义的 sql.execute 函数,其中包含 sql_keyword、table_name、columns 和 conditions。这四个参数提供了构造简单 SQL 查询所需的信息,如 SELECT column_A from table_B where column_C == D。通过这种方式,我们想看看是否可以通过函数调用可靠地构造和使用 SQL 查询,而不是训练特定的 SQL 模型。在我们的评估数据集中,我们限制了场景并支持简单的关键字,包括 SELECTINSERT INTOUPDATEDELETECREATE。我们包含了 100 个用于 SQL AST 评估的示例。注意,SQL AST 评估不会显示在我们的排行榜计算中。我们使用 SQL 评估来测试函数调用对于未包含在 Gorilla OpenFunctions-v2 训练集中的编程语言的泛化能力。由于构造 SQL 函数调用实现相同结果的方法有多种,我们选择从 BFCL 的 AST 评估中排除 SQL 性能。我们目前正在努力改进 SQL 评估,并欢迎社区提供建议和反馈。因此,当前排行榜中已省略 SQL,为后续迭代中更全面的评估铺平道路。

Java + Javascript: 尽管函数调用格式在大多数编程语言中都是相同的,但每种编程语言都有特定的类型。例如,Java 有 HashMap 类型。这个测试类别的目标是了解函数调用模型不仅可以扩展到 Python 类型,还可以扩展到所有特定语言的类型。我们包含了 100 个用于 Java AST 评估的示例和 70 个用于 Javascript AST 评估的示例。

上述类别提供了不同模型在流行的 API 调用场景中的性能洞察,为函数调用模型的潜力提供了有价值的视角。

排行榜评估类别

我们对现有类别进行了层次分类,在 Berkeley 函数调用排行榜 BFCL 中展示了九个类别,这些类别按评估方法(AST 或执行)和函数类型(简单、并行、多重、并行多重函数)进行分组。这里,我们展示了一个表格,组织了每个排行榜类别的评估数据点计数,这些类别由博客中列出的更细粒度的类别组成。具体来说,我们将 REST 可执行评估归类为“简单函数(通过执行 API 评估)“,因为我们考虑了调用一个 REST API 的情况。对于 Java + Javascript 评估,我们将其归类为“简单函数(抽象语法树 (AST) 评估)”,因为我们当前版本的评估集没有包含多种编程语言的多重、并行和并行多重情况。

BFCL 中显示的九个类别的最终计数以及更细粒度类型的组成如下表所示:

Abstract Syntax Tree (AST) Evaluation 🌳Evaluation by Executing APIs ⚙️Relevance Detection
Simple FunctionMultiple FunctionsParallel FunctionsParallel MultipleSimple FunctionMultiple FunctionsParallel FunctionsParallel Multiple
Py: 400Java: 100JS: 50Py: 200Py: 200Py: 200Py: 100REST: 70Py: 50Py: 50Py: 40Py: 240

评估指标 📈

我们使用两种流行的方法来评估模型生成答案的准确性 :AST 评估和可执行评估。理想情况下应该使用执行评估,但在评估答案时,并非所有结果都容易执行 (例如 Java 函数)。因此我们使用 AST 作为执行评估的补充。

抽象语法树 (AST) 评估 🌳

对于简单函数评估,评估过程主要关注比较_单个模型输出函数_与其_函数文档_和_可能的答案_。下面的流程图展示了逐步评估过程。

模型评估流程图 评估函数调用。使用函数描述和可能的答案来评估模型的输出函数。

通过 AST 解析函数

评估过程从使用 AST 树解析函数调用开始。

示例:

calculate_triangle_area(base=10, height=5)

解析:

Module(body=[
        Expr(value=List(elts=[
            Call(
                func=Name(id='calculate_triangle_area', ctx=Load()), 
                args=[], 
                keywords=[
                    keyword(arg='base', value=Constant(value=10)), 
                    keyword(arg='height', value=Constant(value=5))
                ]
            )
        ], ctx=Load()))
    ], type_ignores=[])
函数匹配

该过程首先提取函数名称,并验证其与可能答案中的函数名称是否一致。

必需参数匹配

然后,它从 AST 中提取参数,并检查每个参数是否能在可能的答案中找到并精确匹配。

参数类型和值匹配

评估过程对类型要求严格。以下是每种数据类型可接受的答案:

以下是一些可能答案的示例:

{"calculate_triangle_area": {"base": [10], "height": [5], "unit": ["units", "unit"]}}
{"predict_house_price": {"bedrooms": [3], "bathrooms": [2], "area": [1800], "location": ["San Francisco", "San Francisco, CA"]}}
多重/并行/并行多重函数的 AST 评估

多重、并行或并行多重函数的 AST 评估过程扩展了简单函数评估的思路,以支持多个模型输出和可能的答案。

可执行函数评估 ⚙️

可执行测试类别中,我们执行生成的 API 调用以检查响应的正确性。由于非 RESTREST 测试的特点不同,评估过程也有所不同:

可执行函数(非 REST)评估:
可执行函数 (REST) 评估:

声明: 考虑到 RESTAPI 响应结构可能会被其开发者更新,评估方法包含了一个可选的 API 健康检查,以确保在运行任何可执行类别测试之前,评估过程中涉及的所有 API 都按预期工作。REST 类别的基准数据也会定期审查和更新,以确保评估保持准确和相关性。

多重/并行/并行多重可执行函数评估

多重、并行或并行多重可执行函数评估过程扩展了简单可执行函数评估的思路。

成本和延迟

在我们最近的更新中,我们也特别关注了成本延迟

对于 firefunctions-v1、Nexusflow-Raven-v2 和 Meetkai-Functionary,我们在他们的服务免费期间使用他们的端点,所以我们没有包含这些模型的成本。

这一特定见解将帮助个人或企业根据需求和预算决定采用哪个模型。

何时使用函数调用 (工具调用),何时使用提示? 🖊️

下面的模型卡片展示了我们评估的不同模型支持的见解和函数调用功能。

从上面的模型卡片中,我们强调我们的评估同时涉及函数调用和非函数调用模型。对于函数调用模型,由于它们是专门设计用来生成函数调用的,我们没有提供任何系统提示,而是打开函数调用模式并将函数定义放在应该在的位置。对于非函数调用模型,我们只是用系统消息提示它们。我们提供了所有用于评估专有和开源模型的提示。

  1. 对于所有函数调用模型,我们没有提供任何系统提示,而是打开函数调用模式并将函数定义放在应该在的位置。

  2. 对于聊天模型,我们明确提供了一个系统消息:

    SYSTEM_PROMPT_FOR_CHAT_MODEL = """
    你是一个编写函数的专家。你会收到一个问题和一组可能的函数。
    根据问题,你需要进行一次或多次函数/工具调用来实现目的。
    如果没有可以使用的函数,请指出。如果给定的问题缺少函数所需的参数,也请指出。你应该只在工具调用部分返回函数调用。
    """
    
    USER_MESSAGE_FOR_CHAT_MODEL = "问题:{user_prompt}\n这里是你可以调用的 JSON 格式函数列表:\n{functions}。如果你决定返回函数调用,不能包含任何其他文本。"
    

常见错误

通过我们的基准测试 BFCL,我们能够识别出 LLM 在生成函数调用时的一些常见错误。这些错误很有趣,因为它们帮助我们理解当前模型的局限性,并为如何改进它们提供见解。

  1. GPT 的_函数文档难以格式化_,并且它们的_类型在现实场景中过于严格_。

    "Function": 
    {
        "name": "calculate_binomial_probability",
        ...
        "parameters": 
        {
            "type": "object", 
            "properties": 
            {
                "number_of_trials": 
                {
                    "type": "integer", 
                    "description": "The total number of trials."
                },
                "number_of_successes": 
                {
                    "type": "integer", 
                    "description": "The desired number of successful outcomes."
                },
                "probability_of_success": 
                {
                    "type": "float", 
                    The probability of a successful outcome on any given trial.", 
                    "default": 0.5
                }
                ...
            }
            "required": ["number_of_trials", "number_of_successes"]
        }
    }
    

在这种情况下,我们需要手动将 float 转换为 number 以使函数与 OpenAI 兼容。此外,在精度和类型一致性方面,number 相比 float 传递的信息更少。

在 Gorilla OpenFunctions-v2 中,我们通过不限制参数的类型来提高函数文档的灵活性。换句话说,用户可以使用 TupleFloat,甚至像 Java 中的 HashmapLinked List 这样的特定语言类型!

  1. GPT 在_参数不能直接从用户问题中获得_而需要进行一些隐式转换的场景中表现不佳。以下是一个例子:

    "Function": 
    {
        "name": "finance.predict_future_value",
        ...
        "parameters": 
        {
            "type": "object", 
            "properties": 
            {
                "present_value": 
                {
                    "type": "number", 
                    "description": "The present value of the investment."
                },
                
                "annual_interest_rate": 
                {
                    "type": "number", 
                    "description": "The annual interest rate of the investment."
                },
                
                "compounding_periods_per_year": 
                {
                    "type": "integer", 
                    "description": "The number of times that interest is compounded per year.", 
                },
                "time_years": 
                {
                    "type": "integer", 
                    "description": "The investment horizon in years."
                }
                ...
            }
            "required": ["present_value", "annual_interest_rate", "time_years"]
        }
    }
    

问题: 预测一笔 5000 美元的投资,年利率为 5%,按月复利计算,3 年后的未来价值。

GPT-4 output:
[{
    "name": "finance.predict_future_value",
    "parameters": 
    {
        "present_value": 5000,
        "annual_interest_rate": 5,
        "compounding_periods_per_year": 12,
        "time_years": 3
    }
}]
Gorilla-openfunctions-v2 output:
[{
    "name": "finance.predict_future_value",
    "parameters": 
    {
        "present_value": 5000,
        "annual_interest_rate": 0.05,
        "compounding_periods_per_year": 12,
        "time_years": 3
    }
}]
  1. 聊天模型倾向于生成_格式错误的函数调用_,其中参数可以提取但无法执行

    示例: mistral-medium 生成的结果如 solve\\_quadratic\\_equation(a=2, b=6, c=5)。而使用 gorilla-openfunctions-v2,我们可以直接输出 solve_quadratic_equation(a=3, b=2, c=1),这在收到结果时是可执行的。

  2. REST API 缺少 URL:

    由于 GPT-4 在获取天气数据的 REST API 请求中缺少必需的 URL 而产生差异。虽然 GPT-4 输出省略了必要的 URL,但 Gorilla Openfunctions-v2 模型成功包含了正确的 API 端点,使其能够成功执行并检索指定坐标和预报期的天气信息。

    "User": "Can you fetch me the weather data for the coordinates 
    37.8651 N, 119.5383 W, including the hourly forecast for temperature, 
    wind speed, and precipitation for the next 10 days?"
    
    "Function": 
    {
        "name": "requests.get",
        ...
        "parameters": 
        {
            "type": "object", 
            "properties": 
            {
                "url": 
                {
                    "type": "string", 
                    "description": "The API endpoint for fetching
                    weather data from the Open-Meteo API for the 
                    given latitude and longitude, default 
                    https://api.open-meteo.com/v1/forecast"
                }
                ...
            }
        }
    }
    
    GPT-4 output:
    {
        "name": "requests.get",
        "parameters": {
            "url": "Missing",
            "params": 
            {
                "latitude": "37.8651",
                "longitude": "-119.5383",
                "forecast_days": 10
            },
        }
    }
    
    Gorilla-Openfunctions-v2 output:
    {
        "name": "requests.get",
        "parameters": {
            "url": "https://api.open-meteo.com/v1/forecast",
            "params": 
            {
                "latitude": "37.8651",
                "longitude": "-119.5383",
                "forecast_days": 10
            },
        }
    }
    

结论

我们通过 Berkeley 函数调用排行榜对 LLM 的函数调用能力提供了全面和系统的评估。这里的研究表明,就简单的函数调用而言 (不涉及复杂规划和链式函数调用),微调开源模型可以达到与专有模型相当的效果。此外,我们提供了 Gorilla Open Functions v2,这是一个开源模型,可以帮助用户构建具有函数调用功能并能与 JSON 兼容输出交互的 AI 应用程序。

我们希望你喜欢这篇博文。我们很乐意在 DiscordTwitter (#GorillaLLM)GitHub 上听取你的意见。

引用

如果你想引用 Gorilla:

@inproceedings{berkeley-function-calling-leaderboard,
  title={Berkeley Function Calling Leaderboard},
  author={Fanjia Yan and Huanzhi Mao and Charlie Cheng-Jie Ji and Tianjun Zhang and Shishir G. Patil and Ion Stoica and Joseph E. Gonzalez},
  year={2024},
  howpublished={\\url{https://gorilla.cs.berkeley.edu/blogs/8_berkeley_function_calling_leaderboard.html}},
}

/Agent/ /AI/