教程:函数调用

<ph type="x-smartling-placeholder"></ph>

函数调用可让您更轻松地从 Google Cloud 控制台获取结构化数据输出 生成模型。然后,您可以使用这些输出来调用其他 API 并返回 将相关的响应数据提供给模型。换句话说,函数调用有助于 将生成模型连接到外部系统, 可提供最新、最准确的信息。

您可以向 Gemini 模型提供函数说明。这些是 以应用语言编写的函数(也就是说,它们 Google Cloud Functions)。模型可能会要求您调用一个函数并返回 帮助模型处理您的查询。

如果您还没看过 函数调用简介(用于学习相关知识) 您也可以 不妨在 Google Colab 或查看 Gemini API Cookbook 代码库。

照明控制示例 API

假设您有一个基本的照明控制系统,其中包含一个应用编程接口, 并且希望让用户能够通过简单的 文本请求。您可以使用函数调用功能来解释光照 更改来自用户的请求,并将其转换为 API 调用,以设置光照 值。这个假设的照明控制系统可让您控制 即光的亮度和色温,两者定义为 参数:

参数 类型 必需 说明
brightness number 光级范围为 0 到 100。0 表示关闭,100 表示完整亮度。
colorTemperature 字符串 灯具的色温,可以是 daylightcoolwarm

为简单起见,这个虚构的照明系统只有一个光源,因此用户 不需要指定房间或地点。下面是一个 JSON 请求示例 您可以发送到照明控制 API,将亮度更改为 50% 使用日光色温:

{
  "brightness": "50",
  "colorTemperature": "daylight"
}

本教程介绍了如何为 Gemini API 设置函数调用, 解释用户的照明请求,并将其映射到 API 设置,以控制 亮度和色温值

准备工作:设置您的项目和 API 密钥

在调用 Gemini API 之前,您需要设置项目并配置 您的 API 密钥。

定义 API 函数

创建一个发出 API 请求的函数。该函数应定义 但可以在应用代码之外调用服务或 API 部署应用Gemini API 不会直接调用此函数,因此您需要 可以通过您的应用控制如何以及何时执行此函数 代码。为便于演示,本教程定义了一个模拟 API 函数, 仅返回请求的光照值:

def set_light_values(brightness, color_temp):
    """Set the brightness and color temperature of a room light. (mock API).

    Args:
        brightness: Light level from 0 to 100. Zero is off and 100 is full brightness
        color_temp: Color temperature of the light fixture, which can be `daylight`, `cool` or `warm`.

    Returns:
        A dictionary containing the set brightness and color temperature.
    """
    return {
        "brightness": brightness,
        "colorTemperature": color_temp
    }

创建供模型在函数调用中使用的函数时, 应在函数和参数中包含尽可能详细的信息。 描述。生成模型使用这些信息来确定 选择函数,以及如何为该函数中的形参提供值 调用。

在模型初始化期间声明函数

如果要对模型使用函数调用,您必须声明 函数。您可以通过将 模型的 tools 参数:

model = genai.GenerativeModel(model_name='gemini-1.5-flash',
                              tools=[set_light_values])

生成函数调用

使用函数声明初始化模型后,您可以 将模型与定义的函数相关联。您应该使用 聊天提示 (sendMessage()),因为函数调用通常受益于 了解之前提示和响应的上下文。

chat = model.start_chat()
response = chat.send_message('Dim the lights so the room feels cozy and warm.')
response.text

Python SDK 的 ChatSession 对象通过处理对话历史记录来简化聊天会话的管理 。您可以使用 enable_automatic_function_calling 获取 SDK 自动

# Create a chat session that automatically makes suggested function calls
chat = model.start_chat(enable_automatic_function_calling=True)

并行函数调用

除了上述基本函数调用外,您还可以在一次回合中调用多个函数。本部分举例说明了如何使用并行函数调用。

定义工具。

def power_disco_ball(power: bool) -> bool:
    """Powers the spinning disco ball."""
    print(f"Disco ball is {'spinning!' if power else 'stopped.'}")
    return True


def start_music(energetic: bool, loud: bool, bpm: int) -> str:
    """Play some music matching the specified parameters.

    Args:
      energetic: Whether the music is energetic or not.
      loud: Whether the music is loud or not.
      bpm: The beats per minute of the music.

    Returns: The name of the song being played.
    """
    print(f"Starting music! {energetic=} {loud=}, {bpm=}")
    return "Never gonna give you up."


def dim_lights(brightness: float) -> bool:
    """Dim the lights.

    Args:
      brightness: The brightness of the lights, 0.0 is off, 1.0 is full.
    """
    print(f"Lights are now set to {brightness:.0%}")
    return True

现在,使用一条指令来调用模型,该指令可以使用所有指定工具。

# Set the model up with tools.
house_fns = [power_disco_ball, start_music, dim_lights]

model = genai.GenerativeModel(model_name="gemini-1.5-flash", tools=house_fns)

# Call the API.
chat = model.start_chat()
response = chat.send_message("Turn this place into a party!")

# Print out each of the function calls requested from this single call.
for part in response.parts:
    if fn := part.function_call:
        args = ", ".join(f"{key}={val}" for key, val in fn.args.items())
        print(f"{fn.name}({args})")
power_disco_ball(power=True)
start_music(energetic=True, loud=True, bpm=120.0)
dim_lights(brightness=0.3)

输出的每条结果都反映了模型所请求的单个函数调用。要发回结果,请按请求的顺序包含响应。

# Simulate the responses from the specified tools.
responses = {
    "power_disco_ball": True,
    "start_music": "Never gonna give you up.",
    "dim_lights": True,
}

# Build the response parts.
response_parts = [
    genai.protos.Part(function_response=genai.protos.FunctionResponse(name=fn, response={"result": val}))
    for fn, val in responses.items()
]

response = chat.send_message(response_parts)
print(response.text)
Let's get this party started! I've turned on the disco ball, started playing some upbeat music, and dimmed the lights. 🎶✨  Get ready to dance! 🕺💃

函数调用数据类型映射

从 Python 函数中自动提取架构并非在所有情况下都有效。例如:它不处理您描述嵌套的字典对象字段的情况,但该 API 支持此操作。该 API 能够描述以下任意类型:

AllowedType = (int | float | bool | str | list['AllowedType'] | dict[str, AllowedType])

google.ai.generativelanguage 客户端库提供低级别类型的访问权限,让您可以完全控制。

首先了解一下模型的 _tools 属性,您可以看到它如何描述您将其传递给模型的函数:

def multiply(a:float, b:float):
    """returns a * b."""
    return a*b

model = genai.GenerativeModel(model_name='gemini-1.5-flash',
                             tools=[multiply])

model._tools.to_proto()
[function_declarations {
   name: "multiply"
   description: "returns a * b."
   parameters {
     type_: OBJECT
     properties {
       key: "b"
       value {
         type_: NUMBER
       }
     }
     properties {
       key: "a"
       value {
         type_: NUMBER
       }
     }
     required: "a"
     required: "b"
   }
 }]

这将返回 genai.protos.Tool 对象的列表,这些对象会发送到 API。如果您不熟悉这些印刷格式,那是因为 protobuf 类。每个 genai.protos.Tool(本例中为 1 个)都包含一个列表, genai.protos.FunctionDeclarations:描述函数及其 参数。

以下是使用 genai.protos 类。请注意,这些类仅描述 但它们不包含它的实现因此,使用此命令行不通 具有自动函数调用功能,但函数并不总是需要 实施。

calculator = genai.protos.Tool(
    function_declarations=[
      genai.protos.FunctionDeclaration(
        name='multiply',
        description="Returns the product of two numbers.",
        parameters=genai.protos.Schema(
            type=genai.protos.Type.OBJECT,
            properties={
                'a':genai.protos.Schema(type=genai.protos.Type.NUMBER),
                'b':genai.protos.Schema(type=genai.protos.Type.NUMBER)
            },
            required=['a','b']
        )
      )
    ])

同样,您也可以将其描述为一个与 JSON 兼容的对象:

calculator = {'function_declarations': [
      {'name': 'multiply',
       'description': 'Returns the product of two numbers.',
       'parameters': {'type_': 'OBJECT',
       'properties': {
         'a': {'type_': 'NUMBER'},
         'b': {'type_': 'NUMBER'} },
       'required': ['a', 'b']} }]}
genai.protos.Tool(calculator)
function_declarations {
  name: "multiply"
  description: "Returns the product of two numbers."
  parameters {
    type_: OBJECT
    properties {
      key: "b"
      value {
        type_: NUMBER
      }
    }
    properties {
      key: "a"
      value {
        type_: NUMBER
      }
    }
    required: "a"
    required: "b"
  }
}

无论采用哪种方式,您都需要将 genai.protos.Tool 的表示形式或工具列表传递给

model = genai.GenerativeModel('gemini-1.5-flash', tools=calculator)
chat = model.start_chat()

response = chat.send_message(
    f"What's 234551 X 325552 ?",
)

与之前一样,该模型会返回调用计算器的 multiply 函数的 genai.protos.FunctionCall

response.candidates
[index: 0
content {
  parts {
    function_call {
      name: "multiply"
      args {
        fields {
          key: "b"
          value {
            number_value: 325552
          }
        }
        fields {
          key: "a"
          value {
            number_value: 234551
          }
        }
      }
    }
  }
  role: "model"
}
finish_reason: STOP
]

自行执行函数:

fc = response.candidates[0].content.parts[0].function_call
assert fc.name == 'multiply'

result = fc.args['a'] * fc.args['b']
result
76358547152.0

将结果发送给模型以继续对话:

response = chat.send_message(
    genai.protos.Content(
    parts=[genai.protos.Part(
        function_response = genai.protos.FunctionResponse(
          name='multiply',
          response={'result': result}))]))