Instructivo: Llama a funciones con la API de Gemini


La llamada a funciones facilita la obtención de resultados de datos estructurados de modelos generativos. Luego, puedes usar estos resultados para llamar a otras APIs y mostrar los datos de respuesta relevantes al modelo. En otras palabras, la llamada a funciones te ayuda a conectar modelos generativos a sistemas externos para que el contenido generado incluya la información más actualizada y precisa.

Puedes proporcionar descripciones de funciones a los modelos de Gemini. Son funciones que escribes en el lenguaje de tu app (es decir, no son Google Cloud Functions). El modelo puede pedirte que llames a una función y envíes el resultado para ayudar al modelo a controlar tu consulta.

Si aún no lo has hecho, consulta la Introducción a las llamadas a funciones para obtener más información.

Configura tu proyecto

Antes de llamar a la API de Gemini, debes configurar tu proyecto, lo que incluye configurar tu clave de API, agregar el SDK a tus dependencias de Pub e inicializar el modelo.

Cómo configurar una llamada a función

En este instructivo, harás que el modelo interactúe con una API hipotética de intercambio de monedas que admita los siguientes parámetros:

Parámetro Tipo Obligatorio Descripción
currencyDate cadena Fecha para recuperar el tipo de cambio de
(que siempre debe estar en formato AAAA-MM-DD o el valor latest si no se especifica un período)
currencyFrom cadena Moneda desde la que se convertirá
currencyTo cadena no Moneda a la que se convertirá

Ejemplo de solicitud a la API

{
  "currencyDate": "2024-04-17",
  "currencyFrom": "USD",
  "currencyTo": "SEK"
}

Ejemplo de respuesta de la API

{
  "base": "USD",
  "date": "2024-04-17",
  "rates": {"SEK": 0.091}
}

Paso 1: Crea la función que realiza la solicitud a la API

Si aún no lo has hecho, comienza por crear la función que realiza una solicitud a la API.

Para la demostración de este instructivo, en lugar de enviar una solicitud a la API real, mostrarás valores codificados en el mismo formato que mostraría una API real.

Future<Map<String, Object?>> findExchangeRate(
  Map<String, Object?> arguments,
) async =>
    // This hypothetical API returns a JSON such as:
    // {"base":"USD","date":"2024-04-17","rates":{"SEK": 0.091}}
    {
      'date': arguments['currencyDate'],
      'base': arguments['currencyFrom'],
      'rates': <String, Object?>{arguments['currencyTo'] as String: 0.091}
    };

Paso 2: Crea una declaración de función

Crea la declaración de función que pasarás al modelo generativo (siguiente paso de este instructivo).

Incluye tantos detalles como sea posible en las descripciones de funciones y parámetros. El modelo generativo usa esta información para determinar qué función seleccionar y cómo proporcionar valores para los parámetros en la llamada a función.

final exchangeRateTool = FunctionDeclaration(
    'findExchangeRate',
    'Returns the exchange rate between currencies on given date.',
    Schema(SchemaType.object, properties: {
      'currencyDate': Schema(SchemaType.string,
          description: 'A date in YYYY-MM-DD format or '
              'the exact value "latest" if a time period is not specified.'),
      'currencyFrom': Schema(SchemaType.string,
          description: 'The currency code of the currency to convert from, '
              'such as "USD".'),
      'currencyTo': Schema(SchemaType.string,
          description: 'The currency code of the currency to convert to, '
              'such as "USD".')
    }, requiredProperties: [
      'currencyDate',
      'currencyFrom'
    ]));

Paso 3: Especifica la declaración de la función durante la inicialización del modelo

Para especificar la declaración de función cuando inicialices el modelo generativo, pásalo al parámetro tools del modelo:

final model = GenerativeModel(
  // Use a model that supports function calling, like a Gemini 1.5 model
  model: 'gemini-1.5-flash',
  apiKey: apiKey,

  // Specify the function declaration.
  tools: [
    Tool(functionDeclarations: [exchangeRateTool])
  ],
);

Paso 4: Genera una llamada a función

Ahora puedes indicarle al modelo con la función definida.

La forma recomendada de usar la llamada a funciones es a través de la interfaz de chat, ya que las llamadas a funciones se ajustan perfectamente a la estructura de varios turnos del chat.

final chat = model.startChat();
final prompt = 'How much is 50 US dollars worth in Swedish krona?';

// Send the message to the generative model.
var response = await chat.sendMessage(Content.text(prompt));

final functionCalls = response.functionCalls.toList();
// When the model response with a function call, invoke the function.
if (functionCalls.isNotEmpty) {
  final functionCall = functionCalls.first;
  final result = switch (functionCall.name) {
    // Forward arguments to the hypothetical API.
    'findExchangeRate' => await findExchangeRate(functionCall.args),
    // Throw an exception if the model attempted to call a function that was
    // not declared.
    _ => throw UnimplementedError(
        'Function not implemented: ${functionCall.name}')
  };
  // Send the response to the model so that it can use the result to generate
  // text for the user.
  response = await chat
      .sendMessage(Content.functionResponse(functionCall.name, result));
}
// When the model responds with non-null text content, print it.
if (response.text case final text?) {
  print(text);
}