Chamadas de função

Visão geral

É possível usar a chamada de função para definir funções personalizadas e fornecê-las a um modelo de IA generativa. Ao processar uma consulta, o modelo pode delegar determinadas tarefas de processamento de dados a essas funções. Ele não chama as funções. Em vez disso, ele fornece uma saída de dados estruturados que inclui o nome de uma função selecionada e os argumentos com os quais o modelo propõe a chamada a ser usada. É possível usar essa saída para invocar APIs externas. É possível então fornecer a saída da API de volta ao modelo, permitindo que ele conclua a resposta à consulta. Quando usada dessa maneira, a chamada de função permite que os LLMs acessem informações em tempo real e interajam com vários serviços, como bancos de dados SQL, sistemas de gestão de relacionamento com o cliente e repositórios de documentos.

O diagrama a seguir ilustra como funciona a chamada de função: Interação de chamada de função 

Para saber mais sobre os casos de uso de chamada de função, consulte Casos de uso de chamada de função. Para saber como criar um aplicativo de chamada de função, consulte este link. Para conferir as práticas recomendadas, consulte Práticas recomendadas.

Modelo Versão Estágio de inicialização da chamada de função Suporte à chamada de função paralela Compatibilidade com chamadas de função forçada
Gemini 1.0 Pro gemini-1.0-pro-001 Disponibilidade geral No No
Gemini 1.0 Pro gemini-1.0-pro-002 Disponibilidade geral No No
Gemini 1.5 Flash gemini-1.5-flash-001 Disponibilidade geral Sim No
Gemini 1.5 Pro gemini-1.5-pro-001 Disponibilidade geral Sim Sim

Casos de uso de chamada de funções

É possível usar a chamada de função para as seguintes tarefas:

Criar um aplicativo de chamada de função

Para permitir que um usuário interaja com o modelo e use a chamada de função, crie um código que execute as seguintes tarefas:

Crie um aplicativo que gerencie todas essas tarefas. Pode ser um chatbot de texto, um agente de voz, um fluxo de trabalho automatizado ou qualquer outro programa.

Definir e descrever um conjunto de funções disponíveis

O aplicativo precisa declarar um conjunto de funções que o modelo pode usar para processar a consulta. Cada declaração de função precisa incluir o nome da função e os parâmetros da função. É altamente recomendável incluir também a descrição da função em cada declaração de função.

Nome da função

O aplicativo e o modelo usam o nome da função para identificá-la.

Para conferir as práticas recomendadas relacionadas ao nome da função, consulte Práticas recomendadas: nome da função.

Parâmetros de função

Os parâmetros de função precisam ser fornecidos em um formato compatível com o esquema da OpenAPI.

A Vertex AI oferece suporte limitado ao esquema da OpenAPI. São aceitos os seguintes atributos: type, nullable, required, format, description, properties, items, enum. Não são aceitos os seguintes atributos: default, optional, maximum, oneOf.

Ao usar o curl, especifique o esquema usando JSON. Ao usar o SDK da Vertex AI para Python, especifique o esquema usando um dicionário Python.

Para práticas recomendadas relacionadas a parâmetros de função, consulte Práticas recomendadas: parâmetros de função.

Descrição da função

O modelo usa descrições de funções para entender a finalidade das funções e determinar se elas são úteis no processamento de consultas do usuário.

Para as práticas recomendadas relacionadas à descrição da função, consulte Práticas recomendadas: descrição da função.

Exemplo de uma declaração de função

Veja a seguir um exemplo de declaração de função simples em Python:

get_current_weather_func = FunctionDeclaration(
    name="get_current_weather",
    description="Get the current weather in a given location",
    parameters={
        "type": "object",
        "properties": {"location": {"type": "string", "description": "The city name of the location for which to get the weather."}},
    },
)

Este é um exemplo de declaração de função com uma matriz de itens:

extract_sale_records_func = FunctionDeclaration(
   name="extract_sale_records",
   description="Extract sale records from a document.",
   parameters={
       "type": "object",
       "properties": {
           "records": {
               "type": "array",
               "description": "A list of sale records",
               "items": {
                   "description": "Data for a sale record",
                   "type": "object",
                   "properties": {
                "id": {"type": "integer", "description": "The unique id of the sale."},
                       "date": {"type": "string", "description": "Date of the sale, in the format of MMDDYY, e.g., 031023"},
                       "total_amount": {"type": "number", "description": "The total amount of the sale."},
                       "customer_name": {"type": "string", "description": "The name of the customer, including first name and last name."},
                       "customer_contact": {"type": "string", "description": "The phone number of the customer, e.g., 650-123-4567."},
                   },
                   "required": ["id", "date", "total_amount"],
               },
           },
       },
       "required": ["records"],
   },
)

Enviar a consulta e as declarações de função ao modelo

Quando o usuário fornece um comando, o aplicativo precisa fornecer ao modelo o prompt do usuário e as declarações da função. Para configurar como o modelo gera resultados, o aplicativo pode fornecer ao modelo uma configuração de geração. Para configurar como o modelo usa as declarações de função, o aplicativo pode fornecer ao modelo uma configuração de ferramenta.

Comando do usuário

Este é um exemplo de comando do usuário: "Como está o clima em Boston?"

Para conferir as práticas recomendadas relacionadas à solicitação do usuário, consulte Práticas recomendadas: prompt do usuário.

Configuração de geração

O modelo pode gerar diferentes resultados para diferentes valores de parâmetros. O parâmetro de temperatura controla o grau de aleatoriedade nesta geração. Temperaturas mais baixas são boas para funções que exigem valores de parâmetro determinísticos, enquanto temperaturas mais altas são boas para funções com parâmetros que aceitam valores de parâmetros mais diversos ou criativos. Uma temperatura de 0 é determinista Nesse caso, as respostas para uma determinada solicitação são, na maioria, deterministas, mas uma pequena quantidade de variação ainda é possível. Para saber mais, consulte API Gemini.

Para definir esse parâmetro, envie uma configuração de geração (generation_config) com o prompt e as declarações da função. É possível atualizar o parâmetro temperature durante uma conversa por chat usando a API Vertex Generative AI e um generation_config atualizado. Para ver um exemplo de configuração do parâmetro temperature, consulte Como enviar o prompt e as declarações da função.

Para as práticas recomendadas relacionadas à configuração de geração, consulte Práticas recomendadas: configuração de geração.

Configuração da ferramenta

É possível impor algumas restrições sobre como o modelo precisa usar as declarações de função que você fornece. Por exemplo, em vez de permitir que o modelo escolha entre uma resposta de linguagem natural e uma chamada de função, é possível forçá-lo a prever apenas chamadas de função ("chamada de função forçada"). Também é possível fornecer ao modelo um conjunto completo de declarações de função, mas restringir as respostas a um subconjunto dessas funções.

Para colocar essas restrições, envie uma configuração de ferramenta (tool_config) com o comando e as declarações da função. Na configuração, é possível especificar um dos seguintes modos:

Modo Descrição
AUTOMÁTICO O comportamento padrão do modelo. O modelo decide se quer prever uma chamada de função ou uma resposta de linguagem natural.
QUALQUER UMA O modelo precisa prever apenas chamadas de função. Para limitar o modelo a um subconjunto de funções, defina os nomes das funções permitidas em allowed_function_names.
NENHUM O modelo não deve prever chamadas de função. Esse comportamento é equivalente a uma solicitação de modelo sem declarações de função associadas.

O modo ANY da configuração da ferramenta ("chamada de função forçada") é um recurso de Prévia. Ela é compatível apenas com modelos de Gemini 1.5 Pro.

Para saber mais, consulte API de chamada de função.

Como enviar o comando e as declarações de função

Veja a seguir um exemplo de como enviar a consulta e as declarações de função ao modelo e restringir o modelo para prever apenas chamadas de função get_current_weather.

# Initialize Vertex AI
from vertexai.preview.generative_models import ToolConfig

vertexai.init(project=project_id, location=location)

# Initialize Gemini model
model = GenerativeModel("Gemini 1.5 Pro")

# Define a tool that includes the function declaration get_current_weather_func
weather_tool = Tool(
    function_declarations=[get_current_weather_func],
)

# Define the user's prompt in a Content object that we can reuse in model calls
user_prompt_content = Content(
    role="user",
    parts=[
        Part.from_text(prompt),
    ],
)

# Send the prompt and instruct the model to generate content using the Tool object that you just created
response = model.generate_content(
    user_prompt_content,
    generation_config={"temperature": 0},
    tools=[weather_tool],
    tool_config=ToolConfig(
        function_calling_config=ToolConfig.FunctionCallingConfig(
            # ANY mode forces the model to predict a function call
            mode=ToolConfig.FunctionCallingConfig.Mode.ANY,
            # Allowed functions to call when the mode is ANY. If empty, any one of
            # the provided functions are called.
            allowed_function_names=["get_current_weather"],
    ))
)
response_function_call_content = response.candidates[0].content

Se o modelo determinar que precisa da saída de uma função específica, a resposta que o aplicativo recebe do modelo conterá o nome da função e os valores de parâmetro com os quais a função precisa ser chamada.

Veja a seguir um exemplo de resposta de modelo para o comando do usuário "Como está o clima em Boston?". O modelo propõe chamar a função get_current_weather com o parâmetro Boston, MA.

candidates {
  content {
    role: "model"
    parts {
      function_call {
        name: "get_current_weather"
        args {
          fields {
            key: "location"
            value {
              string_value: "Boston, MA"
            }
          }
        }
      }
    }
  }
  ...
}

Para comandos como "Receber detalhes do clima em Nova Délhi e São Francisco?", o modelo pode propor várias chamadas de função paralelas. A chamada de função paralela é um recurso de pré-lançamento. Ela é compatível com os modelos Gemini 1.5 Pro e Gemini 1.5 Flash. Para saber mais, consulte o Exemplo de chamada de função paralela.

Invocar uma API externa

Se o aplicativo receber o nome da função e os valores de parâmetro do modelo, ele precisará se conectar a uma API externa e chamar a função.

O exemplo a seguir usa dados sintéticos para simular um payload de resposta de uma API externa:

# Check the function name that the model responded with, and make an API call to an external system
if (
    response.candidates[0].content.parts[0].function_call.name
    == "get_current_weather"
):
    # Extract the arguments to use in your API call
    location = (
        response.candidates[0].content.parts[0].function_call.args["location"]
    )

    # Here you can use your preferred method to make an API request to fetch the current weather, for example:
    # api_response = requests.post(weather_api_url, data={"location": location})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = """{ "location": "Boston, MA", "temperature": 38, "description": "Partly Cloudy",
                    "icon": "partly-cloudy", "humidity": 65, "wind": { "speed": 10, "direction": "NW" } }"""

Para conferir as práticas recomendadas relacionadas à invocação de API, consulte Práticas recomendadas: invocação de API.

Fornecer a saída da função ao modelo

Depois que um aplicativo recebe uma resposta de uma API externa, ele precisa fornecer essa resposta ao modelo. Veja a seguir um exemplo de como fazer isso usando Python:

response = model.generate_content(
    [
        user_prompt_content,  # User prompt
        response_function_call_content,  # Function call response
        Content(
            parts=[
                Part.from_function_response(
                    name="get_current_weather",
                    response={
                        "content": api_response,  # Return the API response to Gemini
                    },
                )
            ],
        ),
    ],
    tools=[weather_tool],
)
# Get the model summary response
summary = response.candidates[0].content.parts[0].text

Se o modelo propôs várias chamadas de função paralelas, o aplicativo precisa fornecer todas as respostas de volta ao modelo. A chamada de função paralela é um recurso de pré-lançamento. Ela é compatível com os modelos Gemini 1.5 Pro e Gemini 1.5 Flash. Para saber mais, consulte o Exemplo de chamada de função paralela.

Os modelos gemini-1.0-pro-001 e gemini-1.0-pro-002 podem determinar que a saída de outra função é necessária para responder à consulta. Nesse caso, a resposta que o aplicativo recebe do modelo contém outro nome de função e outro conjunto de valores de parâmetro.

Se o modelo determinar que a resposta da API é suficiente para responder à consulta do usuário, ele criará uma resposta com linguagem natural e a retornará para o aplicativo. Nesse caso, o aplicativo precisa transmitir a resposta de volta ao usuário. Veja a seguir um exemplo de resposta de consulta: It is currently 38 degrees Fahrenheit in Boston, MA with partly cloudy skies. The humidity is 65% and the wind is blowing at 10 mph from the northwest.

Práticas recomendadas

Nome da função

Não use caracteres de ponto (.), traço (-) ou espaço no nome da função. Em vez disso, use o caractere de sublinhado (_) ou qualquer outro caractere.

Parâmetros de função

Escreva descrições claras e detalhadas dos parâmetros, incluindo detalhes como formato ou valores preferidos. Por exemplo, para uma função book_flight_ticket:

  • Veja a seguir um exemplo bom de uma descrição de parâmetro departure: Use the 3 char airport code to represent the airport. For example, SJC or SFO. Don't use the city name.
  • Veja a seguir um exemplo ruim de uma descrição de parâmetro departure: the departure airport

Se possível, use parâmetros fortemente tipados para reduzir as alucinações do modelo. Por exemplo, se os valores de parâmetro forem de um conjunto finito, adicione um campo enum em vez de colocar o conjunto de valores na descrição. Se o valor do parâmetro for sempre um número inteiro, defina o tipo como integer em vez de number.

Descrição da função

Escreva as descrições das funções de maneira clara e detalhada. Por exemplo, para uma função book_flight_ticket:

  • Veja a seguir um exemplo de uma descrição boa da função: book flight tickets after confirming users' specific requirements, such as time, departure, destination, party size and preferred airline
  • Veja a seguir um exemplo de uma descrição ruim da função: book flight ticket

Comando do usuário

Para melhores resultados, inclua os seguintes detalhes antes da consulta do usuário:

  • Contexto adicional para o modelo, por exemplo, You are a flight API assistant to help with searching flights based on user preferences..
  • Detalhes ou instruções sobre como e quando usar as funções, por exemplo, Don't make assumptions on the departure or destination airports. Always use a future date for the departure or destination time.
  • Instruções para fazer perguntas esclarecedoras se as consultas do usuário forem ambíguas, por exemplo, Ask clarifying questions if not enough information is available.

Configuração de geração

Para o parâmetro de temperatura, use 0 ou outro valor baixo. Isso instrui o modelo a gerar resultados mais confiáveis e reduz alucinações.

Invocação da API

Se o modelo propor a invocação de uma função que envia uma ordem, atualiza um banco de dados ou tem consequências significativas, valide a chamada de função com o usuário antes de executá-la.

Preços

Os preços da chamada de funções são baseados no número de caracteres nas entradas e saídas de texto. Para saber mais, consulte os preços da Vertex Generative AI.

Aqui, a entrada de texto (comando) se refere à consulta do usuário sobre o turno da conversa atual, as declarações de função para o turno da conversa atual e o histórico da conversa. O histórico da conversa inclui as consultas, as chamadas de função e as respostas de função das interações anteriores. A Vertex Generative AI trunca o histórico da conversa em 32.000 caracteres.

Saída de texto (resposta) refere-se às chamadas de função e às respostas de texto da rodada de conversa atual.

Amostras de chamada de função

É possível usar a chamada de função para gerar uma única resposta de texto ou para permitir uma sessão de chat. As respostas de texto ad hoc são úteis para tarefas específicas de negócio, incluindo a geração de código. As sessões de chat são úteis em cenários de conversa com formato livre, em que um usuário provavelmente fará perguntas complementares.

Se você usar a chamada de função para gerar uma única resposta, forneça ao modelo o contexto completo da interação. Por outro lado, se você usar a chamada da função no contexto de uma sessão de chat, ela armazenará o contexto por você e o incluirá em todas as solicitações do modelo. Em ambos os casos, a Vertex AI armazenará o histórico da interação no lado do cliente.

Para aprender a usar chamadas de função para gerar uma única resposta de texto, consulte exemplos de texto. Para saber como usar a chamada de função para permitir uma sessão de chat, consulte exemplos de chat. Para um exemplo que demonstra a chamada de função paralela, consulte Exemplo de chamada de função paralela.

Exemplos de texto

Python

Este exemplo demonstra um cenário de texto com uma só função e um só comando. Ele usa a classe GenerativeModel e os respectivos métodos. Para mais informações sobre como usar o SDK da Vertex AI para Python com os modelos multimodais do Gemini, consulte Introdução às classes multimodais no SDK da Vertex AI para Python.

Python

Para saber como instalar o SDK da Vertex AI para Python, consulte Instalar o SDK da Vertex AI para Python. Para mais informações, consulte a documentação de referência da API Python.

import vertexai
from vertexai.generative_models import (
    Content,
    FunctionDeclaration,
    GenerationConfig,
    GenerativeModel,
    Part,
    Tool,
)

# Initialize Vertex AI
# TODO(developer): Update and un-comment below lines
# project_id = "PROJECT_ID"
vertexai.init(project=project_id, location="us-central1")

# Initialize Gemini model
model = GenerativeModel(model_name="gemini-1.0-pro-001")

# Define the user's prompt in a Content object that we can reuse in model calls
user_prompt_content = Content(
    role="user",
    parts=[
        Part.from_text("What is the weather like in Boston?"),
    ],
)

# Specify a function declaration and parameters for an API request
function_name = "get_current_weather"
get_current_weather_func = FunctionDeclaration(
    name=function_name,
    description="Get the current weather in a given location",
    # Function parameters are specified in OpenAPI JSON schema format
    parameters={
        "type": "object",
        "properties": {"location": {"type": "string", "description": "Location"}},
    },
)

# Define a tool that includes the above get_current_weather_func
weather_tool = Tool(
    function_declarations=[get_current_weather_func],
)

# Send the prompt and instruct the model to generate content using the Tool that you just created
response = model.generate_content(
    user_prompt_content,
    generation_config=GenerationConfig(temperature=0),
    tools=[weather_tool],
)
function_call = response.candidates[0].function_calls[0]
print(function_call)

# Check the function name that the model responded with, and make an API call to an external system
if function_call.name == function_name:
    # Extract the arguments to use in your API call
    location = function_call.args["location"]  # noqa: F841

    # Here you can use your preferred method to make an API request to fetch the current weather, for example:
    # api_response = requests.post(weather_api_url, data={"location": location})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = """{ "location": "Boston, MA", "temperature": 38, "description": "Partly Cloudy",
                    "icon": "partly-cloudy", "humidity": 65, "wind": { "speed": 10, "direction": "NW" } }"""

# Return the API response to Gemini so it can generate a model response or request another function call
response = model.generate_content(
    [
        user_prompt_content,  # User prompt
        response.candidates[0].content,  # Function call response
        Content(
            parts=[
                Part.from_function_response(
                    name=function_name,
                    response={
                        "content": api_response,  # Return the API response to Gemini
                    },
                ),
            ],
        ),
    ],
    tools=[weather_tool],
)

# Get the model response
print(response.text)

Node.js

Este exemplo demonstra um cenário de texto com uma só função e um só comando.

REST

Este exemplo demonstra um cenário de texto com três funções e um só comando.

Neste exemplo, você chama o modelo de IA generativa duas vezes.

Primeira solicitação de modelo

A solicitação precisa definir uma consulta no parâmetro text. Esse exemplo define a seguinte consulta: "Quais cinemas em Mountain View exibem o filme da Barbie?".

A solicitação também precisa definir uma ferramenta (tools) com um conjunto de declarações de função (functionDeclarations). Essas declarações de função precisam ser especificadas em um formato compatível com o esquema da OpenAPI. Este exemplo define as seguintes funções:

  • find_movies encontra títulos de filmes em exibição nos cinemas.
  • find_theatres encontra cinemas com base na localização.
  • get_showtimes encontra os horários de início dos filmes em exibição em um cinema específico.

Para saber mais sobre os parâmetros da solicitação de modelo, consulte a API Gemini.

Substitua my-project pelo nome do projeto do Google Cloud.

Primeira solicitação de modelo

PROJECT_ID=my-project
MODEL_ID=gemini-1.0-pro
API=streamGenerateContent
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"  https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/us-central1/publishers/google/models/${MODEL_ID}:${API} -d '{
"contents": {
  "role": "user",
  "parts": {
    "text": "Which theaters in Mountain View show the Barbie movie?"
  }
},
"tools": [
  {
    "function_declarations": [
      {
        "name": "find_movies",
        "description": "find movie titles currently playing in theaters based on any description, genre, title words, etc.",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
            },
            "description": {
              "type": "string",
              "description": "Any kind of description including category or genre, title words, attributes, etc."
            }
          },
          "required": [
            "description"
          ]
        }
      },
      {
        "name": "find_theaters",
        "description": "find theaters based on location and optionally movie title which are is currently playing in theaters",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
            },
            "movie": {
              "type": "string",
              "description": "Any movie title"
            }
          },
          "required": [
            "location"
          ]
        }
      },
      {
        "name": "get_showtimes",
        "description": "Find the start times for movies playing in a specific theater",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
            },
            "movie": {
              "type": "string",
              "description": "Any movie title"
            },
            "theater": {
              "type": "string",
              "description": "Name of the theater"
            },
            "date": {
              "type": "string",
              "description": "Date for requested showtime"
            }
          },
          "required": [
            "location",
            "movie",
            "theater",
            "date"
          ]
        }
      }
    ]
  }
]
}'
  

Para o comando "Quais cinemas em Mountain View exibem o filme da Barbie?", o modelo pode retornar a função find_theatres com os parâmetros Barbie e Mountain View, CA.

Resposta à primeira solicitação de modelo

[{
"candidates": [
  {
    "content": {
      "parts": [
        {
          "functionCall": {
            "name": "find_theaters",
            "args": {
              "movie": "Barbie",
              "location": "Mountain View, CA"
            }
          }
        }
      ]
    },
    "finishReason": "STOP",
    "safetyRatings": [
      {
        "category": "HARM_CATEGORY_HARASSMENT",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_HATE_SPEECH",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
        "probability": "NEGLIGIBLE"
      },
      {
        "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
        "probability": "NEGLIGIBLE"
      }
    ]
  }
],
"usageMetadata": {
  "promptTokenCount": 9,
  "totalTokenCount": 9
}
}]
  

Segunda solicitação de modelo

Esse exemplo usa dados sintéticos em vez de chamar a API externa. Há dois resultados, cada um com dois parâmetros (name e address):

  1. name: AMC Mountain View 16, address: 2000 W El Camino Real, Mountain View, CA 94040
  2. name: Regal Edwards 14, address: 245 Castro St, Mountain View, CA 94040

Substitua my-project pelo nome do projeto do Google Cloud.

Segunda solicitação de modelo

PROJECT_ID=my-project
MODEL_ID=gemini-1.0-pro
API=streamGenerateContent
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"  https://us-central1-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/us-central1/publishers/google/models/${MODEL_ID}:${API} -d '{
"contents": [{
  "role": "user",
  "parts": [{
    "text": "Which theaters in Mountain View show the Barbie movie?"
  }]
}, {
  "role": "model",
  "parts": [{
    "functionCall": {
      "name": "find_theaters",
      "args": {
        "location": "Mountain View, CA",
        "movie": "Barbie"
      }
    }
  }]
}, {
  "parts": [{
    "functionResponse": {
      "name": "find_theaters",
      "response": {
        "name": "find_theaters",
        "content": {
          "movie": "Barbie",
          "theaters": [{
            "name": "AMC Mountain View 16",
            "address": "2000 W El Camino Real, Mountain View, CA 94040"
          }, {
            "name": "Regal Edwards 14",
            "address": "245 Castro St, Mountain View, CA 94040"
          }]
        }
      }
    }
  }]
}],
"tools": [{
  "functionDeclarations": [{
    "name": "find_movies",
    "description": "find movie titles currently playing in theaters based on any description, genre, title words, etc.",
    "parameters": {
      "type": "OBJECT",
      "properties": {
        "location": {
          "type": "STRING",
          "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
        },
        "description": {
          "type": "STRING",
          "description": "Any kind of description including category or genre, title words, attributes, etc."
        }
      },
      "required": ["description"]
    }
  }, {
    "name": "find_theaters",
    "description": "find theaters based on location and optionally movie title which are is currently playing in theaters",
    "parameters": {
      "type": "OBJECT",
      "properties": {
        "location": {
          "type": "STRING",
          "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
        },
        "movie": {
          "type": "STRING",
          "description": "Any movie title"
        }
      },
      "required": ["location"]
    }
  }, {
    "name": "get_showtimes",
    "description": "Find the start times for movies playing in a specific theater",
    "parameters": {
      "type": "OBJECT",
      "properties": {
        "location": {
          "type": "STRING",
          "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
        },
        "movie": {
          "type": "STRING",
          "description": "Any movie title"
        },
        "theater": {
          "type": "STRING",
          "description": "Name of the theater"
        },
        "date": {
          "type": "STRING",
          "description": "Date for requested showtime"
        }
      },
      "required": ["location", "movie", "theater", "date"]
    }
  }]
}]
}'
  

A resposta do modelo pode ser semelhante a esta:

Resposta à segunda solicitação de modelo

{
"candidates": [
  {
    "content": {
      "parts": [
        {
          "text": " OK. Barbie is showing in two theaters in Mountain View, CA: AMC Mountain View 16 and Regal Edwards 14."
        }
      ]
    }
  }
],
"usageMetadata": {
  "promptTokenCount": 9,
  "candidatesTokenCount": 27,
  "totalTokenCount": 36
}
}
  

Exemplos de chat

Python

Neste exemplo, demonstramos um cenário de chat com duas funções e dois comandos sequenciais. Ele usa a classe GenerativeModel e os respectivos métodos. Para mais informações sobre como usar o SDK da Vertex AI para Python com os modelos multimodais, consulte Introdução às classes multimodais no SDK da Vertex AI para Python.

Para saber como instalar ou atualizar o Python, consulte Instalar o SDK da Vertex AI para Python. Para mais informações, consulte a documentação de referência da API Python.

import vertexai
from vertexai.generative_models import (
    FunctionDeclaration,
    GenerationConfig,
    GenerativeModel,
    Part,
    Tool,
)

# Initialize Vertex AI
# project_id = "PROJECT_ID"
# TODO(developer): Update and un-comment below lines
vertexai.init(project=project_id, location="us-central1")

# Specify a function declaration and parameters for an API request
get_product_sku = "get_product_sku"
get_product_sku_func = FunctionDeclaration(
    name=get_product_sku,
    description="Get the SKU for a product",
    # Function parameters are specified in OpenAPI JSON schema format
    parameters={
        "type": "object",
        "properties": {
            "product_name": {"type": "string", "description": "Product name"}
        },
    },
)

# Specify another function declaration and parameters for an API request
get_store_location_func = FunctionDeclaration(
    name="get_store_location",
    description="Get the location of the closest store",
    # Function parameters are specified in OpenAPI JSON schema format
    parameters={
        "type": "object",
        "properties": {"location": {"type": "string", "description": "Location"}},
    },
)

# Define a tool that includes the above functions
retail_tool = Tool(
    function_declarations=[
        get_product_sku_func,
        get_store_location_func,
    ],
)

# Initialize Gemini model
model = GenerativeModel(
    model_name="gemini-1.0-pro-001",
    generation_config=GenerationConfig(temperature=0),
    tools=[retail_tool],
)

# Start a chat session
chat = model.start_chat()

# Send a prompt for the first conversation turn that should invoke the get_product_sku function
response = chat.send_message("Do you have the Pixel 8 Pro in stock?")

function_call = response.candidates[0].function_calls[0]
print(function_call)

# Check the function name that the model responded with, and make an API call to an external system
if function_call.name == get_product_sku:
    # Extract the arguments to use in your API call
    product_name = function_call.args["product_name"]  # noqa: F841

    # Here you can use your preferred method to make an API request to retrieve the product SKU, as in:
    # api_response = requests.post(product_api_url, data={"product_name": product_name})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = {"sku": "GA04834-US", "in_stock": "yes"}

# Return the API response to Gemini, so it can generate a model response or request another function call
response = chat.send_message(
    Part.from_function_response(
        name=get_product_sku,
        response={
            "content": api_response,
        },
    ),
)
# Extract the text from the model response
print(response.text)

# Send a prompt for the second conversation turn that should invoke the get_store_location function
response = chat.send_message(
    "Is there a store in Mountain View, CA that I can visit to try it out?"
)

function_call = response.candidates[0].function_calls[0]
print(function_call)

# Check the function name that the model responded with, and make an API call to an external system
if function_call.name == "get_store_location":
    # Extract the arguments to use in your API call
    location = function_call.args["location"]  # noqa: F841

    # Here you can use your preferred method to make an API request to retrieve store location closest to the user, as in:
    # api_response = requests.post(store_api_url, data={"location": location})

    # In this example, we'll use synthetic data to simulate a response payload from an external API
    api_response = {"store": "2000 N Shoreline Blvd, Mountain View, CA 94043, US"}

# Return the API response to Gemini, so it can generate a model response or request another function call
response = chat.send_message(
    Part.from_function_response(
        name="get_store_location",
        response={
            "content": api_response,
        },
    ),
)

# Extract the text from the model response
print(response.text)

Java

Antes de testar essa amostra, siga as instruções de configuração para Java Guia de início rápido da Vertex AI: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Vertex AI para Java.

Para autenticar na Vertex AI, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

import com.google.cloud.vertexai.VertexAI;
import com.google.cloud.vertexai.api.Content;
import com.google.cloud.vertexai.api.FunctionDeclaration;
import com.google.cloud.vertexai.api.GenerateContentResponse;
import com.google.cloud.vertexai.api.Schema;
import com.google.cloud.vertexai.api.Tool;
import com.google.cloud.vertexai.api.Type;
import com.google.cloud.vertexai.generativeai.ChatSession;
import com.google.cloud.vertexai.generativeai.ContentMaker;
import com.google.cloud.vertexai.generativeai.GenerativeModel;
import com.google.cloud.vertexai.generativeai.PartMaker;
import com.google.cloud.vertexai.generativeai.ResponseHandler;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;

public class FunctionCalling {
  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "your-google-cloud-project-id";
    String location = "us-central1";
    String modelName = "gemini-1.0-pro-002";

    String promptText = "What's the weather like in Paris?";

    whatsTheWeatherLike(projectId, location, modelName, promptText);
  }

  public static String whatsTheWeatherLike(String projectId, String location,
                                           String modelName, String promptText)
      throws IOException {

    try (VertexAI vertexAI = new VertexAI(projectId, location)) {

      FunctionDeclaration functionDeclaration = FunctionDeclaration.newBuilder()
          .setName("getCurrentWeather")
          .setDescription("Get the current weather in a given location")
          .setParameters(
              Schema.newBuilder()
                  .setType(Type.OBJECT)
                  .putProperties("location", Schema.newBuilder()
                      .setType(Type.STRING)
                      .setDescription("location")
                      .build()
                  )
                  .addRequired("location")
                  .build()
          )
          .build();

      System.out.println("Function declaration:");
      System.out.println(functionDeclaration);

      // Add the function to a "tool"
      Tool tool = Tool.newBuilder()
          .addFunctionDeclarations(functionDeclaration)
          .build();

      // Start a chat session from a model, with the use of the declared function.
      GenerativeModel model = new GenerativeModel(modelName, vertexAI)
          .withTools(Arrays.asList(tool));
      ChatSession chat = model.startChat();

      System.out.println(String.format("Ask the question: %s", promptText));
      GenerateContentResponse response = chat.sendMessage(promptText);

      // The model will most likely return a function call to the declared
      // function `getCurrentWeather` with "Paris" as the value for the
      // argument `location`.
      System.out.println("\nPrint response: ");
      System.out.println(ResponseHandler.getContent(response));

      // Provide an answer to the model so that it knows what the result
      // of a "function call" is.
      Content content =
          ContentMaker.fromMultiModalData(
              PartMaker.fromFunctionResponse(
                  "getCurrentWeather",
                  Collections.singletonMap("currentWeather", "sunny")));
      System.out.println("Provide the function response: ");
      System.out.println(content);
      response = chat.sendMessage(content);

      // See what the model replies now
      System.out.println("Print response: ");
      String finalAnswer = ResponseHandler.getText(response);
      System.out.println(finalAnswer);

      return finalAnswer;
    }
  }
}

Go

Antes de testar essa amostra, siga as instruções de configuração para Go Guia de início rápido da Vertex AI: como usar bibliotecas de cliente. Para mais informações, consulte a documentação de referência da API Vertex AI para Go.

Para autenticar na Vertex AI, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"

	"cloud.google.com/go/vertexai/genai"
)

// functionCallsChat opens a chat session and sends 4 messages to the model:
// - convert a first text question into a structured function call request
// - convert the first structured function call response into natural language
// - convert a second text question into a structured function call request
// - convert the second structured function call response into natural language
func functionCallsChat(w io.Writer, projectID, location, modelName string) error {
	// location := "us-central1"
	// modelName := "gemini-1.0-pro-002"
	ctx := context.Background()
	client, err := genai.NewClient(ctx, projectID, location)
	if err != nil {
		return fmt.Errorf("unable to create client: %v", err)
	}
	defer client.Close()

	model := client.GenerativeModel(modelName)

	// Build an OpenAPI schema, in memory
	paramsProduct := &genai.Schema{
		Type: genai.TypeObject,
		Properties: map[string]*genai.Schema{
			"productName": {
				Type:        genai.TypeString,
				Description: "Product name",
			},
		},
	}
	fundeclProductInfo := &genai.FunctionDeclaration{
		Name:        "getProductSku",
		Description: "Get the SKU for a product",
		Parameters:  paramsProduct,
	}
	paramsStore := &genai.Schema{
		Type: genai.TypeObject,
		Properties: map[string]*genai.Schema{
			"location": {
				Type:        genai.TypeString,
				Description: "Location",
			},
		},
	}
	fundeclStoreLocation := &genai.FunctionDeclaration{
		Name:        "getStoreLocation",
		Description: "Get the location of the closest store",
		Parameters:  paramsStore,
	}
	model.Tools = []*genai.Tool{
		{FunctionDeclarations: []*genai.FunctionDeclaration{
			fundeclProductInfo,
			fundeclStoreLocation,
		}},
	}
	model.SetTemperature(0.0)

	chat := model.StartChat()

	// Send a prompt for the first conversation turn that should invoke the getProductSku function
	prompt := "Do you have the Pixel 8 Pro in stock?"
	fmt.Fprintf(w, "Question: %s\n", prompt)
	resp, err := chat.SendMessage(ctx, genai.Text(prompt))
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has returned a function call to the declared function `getProductSku`
	// with a value for the argument `productName`.
	jsondata, err := json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.Marshal: %w", err)
	}
	fmt.Fprintf(w, "function call generated by the model:\n\t%s\n", string(jsondata))

	// Create a function call response, to simulate the result of a call to a
	// real service
	funresp := &genai.FunctionResponse{
		Name: "getProductSku",
		Response: map[string]any{
			"sku":      "GA04834-US",
			"in_stock": "yes",
		},
	}
	jsondata, err = json.MarshalIndent(funresp, "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.Marshal: %w", err)
	}
	fmt.Fprintf(w, "function call response sent to the model:\n\t%s\n\n", string(jsondata))

	// And provide the function call response to the model
	resp, err = chat.SendMessage(ctx, funresp)
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has taken the function call response as input, and has
	// reformulated the response to the user.
	jsondata, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.Marshal: %w", err)
	}
	fmt.Fprintf(w, "Answer generated by the model:\n\t%s\n\n", string(jsondata))

	// Send a prompt for the second conversation turn that should invoke the getStoreLocation function
	prompt2 := "Is there a store in Mountain View, CA that I can visit to try it out?"
	fmt.Fprintf(w, "Question: %s\n", prompt)

	resp, err = chat.SendMessage(ctx, genai.Text(prompt2))
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has returned a function call to the declared function `getStoreLocation`
	// with a value for the argument `store`.
	jsondata, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.Marshal: %w", err)
	}
	fmt.Fprintf(w, "function call generated by the model:\n\t%s\n", string(jsondata))

	// Create a function call response, to simulate the result of a call to a
	// real service
	funresp = &genai.FunctionResponse{
		Name: "getStoreLocation",
		Response: map[string]any{
			"store": "2000 N Shoreline Blvd, Mountain View, CA 94043, US",
		},
	}
	jsondata, err = json.MarshalIndent(funresp, "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.Marshal: %w", err)
	}
	fmt.Fprintf(w, "function call response sent to the model:\n\t%s\n\n", string(jsondata))

	// And provide the function call response to the model
	resp, err = chat.SendMessage(ctx, funresp)
	if err != nil {
		return err
	}
	if len(resp.Candidates) == 0 ||
		len(resp.Candidates[0].Content.Parts) == 0 {
		return errors.New("empty response from model")
	}

	// The model has taken the function call response as input, and has
	// reformulated the response to the user.
	jsondata, err = json.MarshalIndent(resp.Candidates[0].Content.Parts[0], "\t", "  ")
	if err != nil {
		return fmt.Errorf("json.Marshal: %w", err)
	}
	fmt.Fprintf(w, "Answer generated by the model:\n\t%s\n\n", string(jsondata))
	return nil
}

Exemplo de chamada de função paralela

REST

Este exemplo demonstra um cenário com uma função get_current_weather. O prompt do usuário é "Receber detalhes do clima em Nova Délhi e São Francisco?". O modelo propõe duas chamadas de função get_current_weather paralelas: uma com o parâmetro New Delhi e outra com o parâmetro San Francisco. A chamada de função paralela é um recurso de pré-lançamento. Ele é compatível com os modelos Gemini 1.5 Pro e Gemini 1.5 Flash.

Para saber mais sobre os parâmetros da solicitação de modelo, consulte a API Gemini.

candidates {
content {
  role: "model"
  parts: [
    {
      function_call {
        name: "get_current_weather"
        args {
          fields {
            key: "location"
            value {
              string_value: "New Delhi"
            }
          }
        }
      }
    },
    {
      function_call {
        name: "get_current_weather"
        args {
          fields {
            key: "location"
            value {
              string_value: "San Francisco"
            }
          }
        }
      }
    }
  ]
}
...
}

O comando a seguir demonstra como fornecer a saída da função para o modelo. Substitua my-project pelo nome do projeto do Google Cloud.

Solicitação de modelo

PROJECT_ID=my-project
MODEL_ID=gemini-1.5-pro-001
VERSION="v1"
LOCATION="us-central1"
ENDPOINT=${LOCATION}-aiplatform.googleapis.com
API="generateContent"
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"  https://${ENDPOINT}/${VERSION}/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:${API} -d '{
"contents": [
    {
        "role": "user",
        "parts": {
            "text": "What is difference in temperature in New Delhi and San Francisco?"
        }
    },
    {
        "role": "model",
        "parts": [
            {
                "functionCall": {
                    "name": "get_current_weather",
                    "args": {
                        "location": "New Delhi"
                    }
                }
            },
            {
                "functionCall": {
                    "name": "get_current_weather",
                    "args": {
                        "location": "San Francisco"
                    }
                }
            }
        ]
    },
    {
        "role": "user",
        "parts": [
            {
                "functionResponse": {
                    "name": "get_current_weather",
                    "response": {
                        "temperature": 30.5,
                        "unit": "C"
                    }
                }
            },
            {
                "functionResponse": {
                    "name": "get_current_weather",
                    "response": {
                        "temperature": 20,
                        "unit": "C"
                    }
                }
            }
        ]
    }
],
"tools": [
    {
        "function_declarations": [
            {
                "name": "get_current_weather",
                "description": "Get the current weather in a specific location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city and state, e.g. San Francisco, CA or a zip code e.g. 95616"
                        }
                    },
                    "required": [
                        "location"
                    ]
                }
            }
        ]
    }
]
}'
  

A resposta de linguagem natural criada pelo modelo é semelhante a esta:

Resposta do modelo

[
{
    "candidates": [
        {
            "content": {
                "parts": [
                    {
                        "text": "The temperature in New Delhi is 30.5C and the temperature in San Francisco is 20C. The difference is 10.5C. \n"
                    }
                ]
            },
            "finishReason": "STOP",
            ...
        }
    ]
    ...
}
]