Учебное пособие по вызову функций

Вызов функций упрощает получение структурированных выходных данных из генеративных моделей. Затем вы можете использовать эти выходные данные для вызова других API и возврата соответствующих данных ответа в модель. Другими словами, вызов функций помогает подключить генеративные модели к внешним системам, чтобы сгенерированный контент содержал самую актуальную и точную информацию.

Вы можете предоставить модели Gemini описания функций. Это функции, которые вы пишете на языке вашего приложения (то есть они не являются функциями Google Cloud). Модель может попросить вас вызвать функцию и отправить результат обратно, чтобы помочь модели обработать ваш запрос.

Если вы еще этого не сделали, ознакомьтесь с разделом «Введение в вызов функций», чтобы узнать больше.

Пример API для управления освещением

Представьте, что у вас есть базовая система управления освещением с интерфейсом прикладного программирования (API), и вы хотите, чтобы пользователи могли управлять освещением с помощью простых текстовых запросов. Вы можете использовать функцию вызова функций для интерпретации запросов на изменение освещения от пользователей и преобразования их в вызовы API для установки значений освещения. Эта гипотетическая система управления освещением позволяет вам контролировать яркость света и его цветовую температуру, определяемую как два отдельных параметра:

Параметр Тип Необходимый Описание
brightness число да Уровень освещенности от 0 до 100. Ноль выключен, 100 — полная яркость.
colorTemperature нить да Цветовая температура светильника может быть daylight , cool или warm .

Для простоты эта воображаемая система освещения имеет только один источник света, поэтому пользователю не нужно указывать комнату или местоположение. Вот пример запроса JSON, который вы можете отправить в API управления освещением, чтобы изменить уровень освещенности на 50%, используя цветовую температуру дневного света:

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

В этом руководстве показано, как настроить вызов функции для API Gemini, чтобы интерпретировать запросы пользователей на освещение и сопоставлять их с настройками API для управления значениями яркости и цветовой температуры источника света.

Прежде чем начать: настройте проект и ключ API.

Прежде чем вызывать API Gemini, вам необходимо настроить проект и ключ API.

Определить функцию API

Создайте функцию, которая выполняет запрос API. Эта функция должна быть определена в коде вашего приложения, но может вызывать службы или API за пределами вашего приложения. API Gemini не вызывает эту функцию напрямую, поэтому вы можете контролировать, как и когда эта функция выполняется, через код вашего приложения. В демонстрационных целях в этом руководстве определяется фиктивная функция API, которая просто возвращает запрошенные значения освещения:

func setLightValues(brightness: String,
                    colorTemp: String) -> JSONObject {
  // This mock API returns the requested lighting values
  return [
    "brightness": .string(brightness),
    "colorTemperature": .string(colorTemp)
  ]
}

Создание объявлений функций

Создайте объявление функции, которое вы передадите в генеративную модель. Когда вы объявляете функцию для использования моделью, вам следует включить как можно больше подробностей в описания функций и параметров. Генеративная модель использует эту информацию, чтобы определить, какую функцию выбрать и как предоставить значения параметров при вызове функции. Следующий код показывает, как объявить функцию управления освещением:

let controlLightFunctionDeclaration = FunctionDeclaration(
  name: "controlLight",
  description: "Set the brightness and color temperature of a room light.",
  parameters: [
    "brightness": Schema(
      type: .string,
      description: "Light level from 0 to 100. Zero is off and 100 is full brightness."
    ),
    "colorTemperature": Schema(
      type: .string,
      description: "Color temperature of the light fixture which can be `daylight`, `cool` or `warm`."
    ),
  ],
  requiredParameters: ["brightness", "colorTemperature"]
)

Объявляйте функции во время инициализации модели

Если вы хотите использовать вызов функций с моделью, вы должны предоставить объявления функций при инициализации объекта модели. Вы объявляете функции, устанавливая параметр tools модели:

// Use a model that supports function calling, like a Gemini 1.5 model
let generativeModel = GenerativeModel(
  name: "gemini-1.5-flash",
  apiKey: apiKey,
  // Specify the function declaration.
  tools: [Tool(functionDeclarations: [controlLightFunctionDeclaration])]
)

Создать вызов функции

После того как вы инициализировали модель с объявлениями функций, вы можете запросить модель с определенной функцией. Вам следует использовать вызов функций с использованием подсказок чата ( sendMessage() ), поскольку вызов функций обычно выигрывает от наличия контекста предыдущих запросов и ответов.

let chat = generativeModel.startChat()

let prompt = "Dim the lights so the room feels cozy and warm."

// Send the message to the generative model
let response1 = try await chat.sendMessage(prompt)

// Check if the model responded with a function call
guard let functionCall = response1.functionCalls.first else {
  fatalError("Model did not respond with a function call.")
}
// Print an error if the returned function was not declared
guard functionCall.name == "controlLight" else {
  fatalError("Unexpected function called: \(functionCall.name)")
}
// Verify that the names and types of the parameters match the declaration
guard case let .string(brightness) = functionCall.args["brightness"] else {
  fatalError("Missing argument: brightness")
}
guard case let .string(colorTemp) = functionCall.args["colorTemperature"] else {
  fatalError("Missing argument: colorTemperature")
}

// Call the hypothetical API
let apiResponse = setLightValues(brightness: brightness, colorTemperature: colorTemp)

// Send the API response back to the model so it can generate a text response that can be
// displayed to the user.
let response = try await chat.sendMessage([ModelContent(
  role: "function",
  parts: [.functionResponse(FunctionResponse(
    name: functionCall.name,
    response: apiResponse
  ))]
)])

// Log the text response.
guard let modelResponse = response.text else {
  fatalError("Model did not respond with text.")
}
print(modelResponse)
,

Вызов функций упрощает получение структурированных выходных данных из генеративных моделей. Затем вы можете использовать эти выходные данные для вызова других API и возврата соответствующих данных ответа в модель. Другими словами, вызов функций помогает подключить генеративные модели к внешним системам, чтобы сгенерированный контент содержал самую актуальную и точную информацию.

Вы можете предоставить модели Gemini описания функций. Это функции, которые вы пишете на языке вашего приложения (то есть они не являются функциями Google Cloud). Модель может попросить вас вызвать функцию и отправить результат обратно, чтобы помочь модели обработать ваш запрос.

Если вы еще этого не сделали, ознакомьтесь с разделом «Введение в вызов функций», чтобы узнать больше.

Пример API для управления освещением

Представьте, что у вас есть базовая система управления освещением с интерфейсом прикладного программирования (API), и вы хотите, чтобы пользователи могли управлять освещением с помощью простых текстовых запросов. Вы можете использовать функцию вызова функций для интерпретации запросов на изменение освещения от пользователей и преобразования их в вызовы API для установки значений освещения. Эта гипотетическая система управления освещением позволяет вам контролировать яркость света и его цветовую температуру, определяемую как два отдельных параметра:

Параметр Тип Необходимый Описание
brightness число да Уровень освещенности от 0 до 100. Ноль выключен, 100 — полная яркость.
colorTemperature нить да Цветовая температура светильника может быть daylight , cool или warm .

Для простоты эта воображаемая система освещения имеет только один источник света, поэтому пользователю не нужно указывать комнату или местоположение. Вот пример запроса JSON, который вы можете отправить в API управления освещением, чтобы изменить уровень освещенности на 50%, используя цветовую температуру дневного света:

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

В этом руководстве показано, как настроить вызов функции для API Gemini, чтобы интерпретировать запросы пользователей на освещение и сопоставлять их с настройками API для управления значениями яркости и цветовой температуры источника света.

Прежде чем начать: настроить свой проект и ключ API

Прежде чем вызывать API Gemini, вам необходимо настроить свой проект и настроить ключ API.

Определите функцию API

Создайте функцию, которая делает запрос API. Эта функция должна быть определена в коде вашего приложения, но может вызовать службы или API за пределами вашего приложения. API Gemini не вызывает этой функции напрямую, поэтому вы можете контролировать, как и когда эта функция выполняется через код вашего приложения. Для демонстрационных целей этот учебник определяет фиктивную функцию API, которая просто возвращает запрошенные значения освещения:

func setLightValues(brightness: String,
                    colorTemp: String) -> JSONObject {
  // This mock API returns the requested lighting values
  return [
    "brightness": .string(brightness),
    "colorTemperature": .string(colorTemp)
  ]
}

Создать объявления функции

Создайте объявление функции, которое вы передадите к генеративной модели. Когда вы объявляете функцию для использования моделью, вы должны включить как можно больше деталей в описания функции и параметров. Генеративная модель использует эту информацию, чтобы определить, какую функцию выбрать и как предоставить значения для параметров в вызове функции. Следующий код показывает, как объявить функцию управления освещением:

let controlLightFunctionDeclaration = FunctionDeclaration(
  name: "controlLight",
  description: "Set the brightness and color temperature of a room light.",
  parameters: [
    "brightness": Schema(
      type: .string,
      description: "Light level from 0 to 100. Zero is off and 100 is full brightness."
    ),
    "colorTemperature": Schema(
      type: .string,
      description: "Color temperature of the light fixture which can be `daylight`, `cool` or `warm`."
    ),
  ],
  requiredParameters: ["brightness", "colorTemperature"]
)

Объявить функции во время инициализации модели

Когда вы хотите использовать вызовы функций с помощью модели, вы должны предоставить ваши функции объявления при инициализации объекта модели. Вы объявляете функции, установив параметр tools модели:

// Use a model that supports function calling, like a Gemini 1.5 model
let generativeModel = GenerativeModel(
  name: "gemini-1.5-flash",
  apiKey: apiKey,
  // Specify the function declaration.
  tools: [Tool(functionDeclarations: [controlLightFunctionDeclaration])]
)

Генерировать вызов функции

После того, как вы инициализировали модель с объявлениями функции, вы можете предложить модель с определенной функцией. Вы должны использовать функции вызова, используя chat requent ( sendMessage() ), поскольку функциональные вызова, как правило, пользуются контекстом предыдущих подсказок и ответов.

let chat = generativeModel.startChat()

let prompt = "Dim the lights so the room feels cozy and warm."

// Send the message to the generative model
let response1 = try await chat.sendMessage(prompt)

// Check if the model responded with a function call
guard let functionCall = response1.functionCalls.first else {
  fatalError("Model did not respond with a function call.")
}
// Print an error if the returned function was not declared
guard functionCall.name == "controlLight" else {
  fatalError("Unexpected function called: \(functionCall.name)")
}
// Verify that the names and types of the parameters match the declaration
guard case let .string(brightness) = functionCall.args["brightness"] else {
  fatalError("Missing argument: brightness")
}
guard case let .string(colorTemp) = functionCall.args["colorTemperature"] else {
  fatalError("Missing argument: colorTemperature")
}

// Call the hypothetical API
let apiResponse = setLightValues(brightness: brightness, colorTemperature: colorTemp)

// Send the API response back to the model so it can generate a text response that can be
// displayed to the user.
let response = try await chat.sendMessage([ModelContent(
  role: "function",
  parts: [.functionResponse(FunctionResponse(
    name: functionCall.name,
    response: apiResponse
  ))]
)])

// Log the text response.
guard let modelResponse = response.text else {
  fatalError("Model did not respond with text.")
}
print(modelResponse)