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 de Android, lo que incluye configurar tu clave de API, agregar las dependencias del SDK a tu proyecto de Android y, luego, 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
currencyFrom cadena Moneda desde la que se convertirá
currencyTo cadena Moneda a la que se convertirá

Ejemplo de solicitud a la API

{
  "currencyFrom": "USD",
  "currencyTo": "SEK"
}

Ejemplo de respuesta de la API

{
  "base": "USD",
  "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.

suspend fun makeApiRequest(
    currencyFrom: String,
    currencyTo: String
): JSONObject {
    // This hypothetical API returns a JSON such as:
    // {"base":"USD","rates":{"SEK": 0.091}}
    return JSONObject().apply {
        put("base", currencyFrom)
        put("rates", hashMapOf(currencyTo to 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.

val getExchangeRate = defineFunction(
  name = "getExchangeRate",
  description = "Get the exchange rate for currencies between countries",
  Schema.str("currencyFrom", "The currency to convert from."),
  Schema.str("currencyTo", "The currency to convert to.")
) { from, to ->
    // Call the function that you declared above
    makeApiRequest(from, to)
}

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:

val generativeModel = GenerativeModel(
  // Use a model that supports function calling, like a Gemini 1.5 model
  modelName = "gemini-1.5-flash",
  // Access your API key as a Build Configuration variable (see "Set up your API key" above)
  apiKey = BuildConfig.apiKey,
  // Specify the function declaration.
  tools = listOf(Tool(listOf(getExchangeRate)))
)

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.

val chat = generativeModel.startChat()

val prompt = "How much is 50 US dollars worth in Swedish krona?"

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

// Check if the model responded with a function call
response.functionCall?.let { functionCall ->
  // Try to retrieve the stored lambda from the model's tools and
  // throw an exception if the returned function was not declared
  val matchedFunction = generativeModel.tools?.flatMap { it.functionDeclarations }
      ?.first { it.name == functionCall.name }
      ?: throw InvalidStateException("Function not found: ${functionCall.name}")

  // Call the lambda retrieved above
  val apiResponse: JSONObject = matchedFunction.execute(functionCall)

  // Send the API response back to the generative model
  // so that it generates a text response that can be displayed to the user
  response = chat.sendMessage(
    content(role = "function") {
        part(FunctionResponsePart(functionCall.name, apiResponse))
    }
  )
}

// Whenever the model responds with text, show it in the UI
response.text?.let { modelResponse ->
    println(modelResponse)
}