教程:函数调用

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

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

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

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

照明控制示例 API

假设您有一个带有应用编程接口 (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"
   }
 }]

这会返回要发送到 API 的 genai.protos.Tool 对象列表。如果您不熟悉这些印刷格式,这是因为这些是 Google 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}))]))