A chamada de função facilita a geração de saídas de dados estruturados de modelos generativos. Você pode usar essas saídas para chamar outras APIs e retornar os dados de resposta relevantes ao modelo. Em outras palavras, a chamada de função ajuda você conecta modelos generativos a sistemas externos para que o conteúdo gerado inclui as informações mais atualizadas e precisas.
É possível fornecer descrições de funções aos modelos do Gemini. Essas são funções que você escreve no idioma do seu app, ou seja, elas não são funções do Google Cloud. O modelo pode pedir que você chame uma função e retorne o resultado para ajudar o modelo a lidar com sua consulta.
Confira a Introdução à chamada de função para aprender mais. Você também pode testar esse recurso Google Colab ou confira o exemplo de código Repositório do Manual da API Gemini (em inglês).
Exemplo de API para controle de iluminação
Imagine que você tem um sistema básico de controle de iluminação com um aplicativo de programação interface de usuário (API) e quer permitir que os usuários controlem as luzes por meio de interfaces solicitações de texto. Você pode usar o recurso de chamada de função para interpretar solicitações de mudança de iluminação dos usuários e traduzi-las em chamadas de API para definir os valores de iluminação. Esse sistema hipotético de controle de iluminação permite controlar o brilho da luz e a temperatura de cor, definidos como dois parâmetros separados:
Parâmetro | Tipo | Obrigatório | Descrição |
---|---|---|---|
brightness |
number | sim | Nível de luz de 0 a 100. Zero é desativado e 100 é brilho total. |
colorTemperature |
string | sim | Temperatura de cor do dispositivo de iluminação, que pode ser daylight , cool ou warm . |
Para simplificar, esse sistema de iluminação imaginário tem apenas uma luz, para que o usuário não precise especificar um cômodo ou local. Este é um exemplo de solicitação JSON você pode enviar à API de controle de iluminação para mudar o nível de iluminação para 50% usando a temperatura da cor da luz do dia:
{
"brightness": "50",
"colorTemperature": "daylight"
}
Neste tutorial, mostramos como configurar uma chamada de função para a API Gemini para interpretar solicitações de iluminação dos usuários e mapeá-las para as configurações da API para controlar uma os valores de brilho e temperatura da cor da luz.
Antes de começar: configurar o projeto e a chave de API
Antes de chamar a API Gemini, você precisa definir seu projeto e configurar sua chave de API.
Definir uma função de API
Crie uma função que faça uma solicitação de API. Essa função precisa ser definida no código do seu aplicativo, mas pode chamar serviços ou APIs fora dele. A API Gemini não chama essa função diretamente, então você pode controlar como e quando essa função é executada por meio do seu aplicativo o código-fonte. Para fins de demonstração, este tutorial define uma função de API simulada que retorna apenas os valores de iluminação solicitados:
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
}
Ao criar uma função para ser usada em uma chamada de função pelo modelo, inclua o máximo de detalhes possível nas descrições da função e do parâmetro. O modelo generativo usa essas informações para determinar quais função a ser selecionada e como fornecer valores para os parâmetros na função a chamada.
Declarar funções durante a inicialização do modelo
Quando você quer usar a chamada de função com um modelo, declare suas
funções ao inicializar o objeto do modelo. Você declara funções definindo
o parâmetro tools
do modelo:
model = genai.GenerativeModel(model_name='gemini-1.5-flash',
tools=[set_light_values])
Gerar uma chamada de função
Depois de inicializar o modelo com as declarações de função, você pode solicitar
a função definida. Use a chamada de função com
comandos de chat (sendMessage()
), já que a chamada de função geralmente se beneficia da
ter o contexto de comandos e respostas anteriores.
chat = model.start_chat()
response = chat.send_message('Dim the lights so the room feels cozy and warm.')
response.text
O SDK do Python
ChatSession
simplifica o gerenciamento de sessões de chat ao lidar com o histórico de conversas
para você. Você pode usar o enable_automatic_function_calling
para que o SDK
chame a função automaticamente.
# Create a chat session that automatically makes suggested function calls
chat = model.start_chat(enable_automatic_function_calling=True)
Chamada de função paralela
Além da chamada de função básica descrita acima, você também pode chamar várias funções em um único turno. Nesta seção, mostramos um exemplo de como usar a chamada de função paralela.
Definir as ferramentas.
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
Agora chame o modelo com uma instrução que possa usar todas as ferramentas especificadas.
# 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)
Cada um dos resultados impressos reflete uma única chamada de função solicitada pelo modelo. Para enviar os resultados de volta, inclua as respostas na mesma ordem em que foram solicitadas.
# 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! 🕺💃
Mapeamento de tipo de dados de chamada de função
A extração automática de esquemas de funções do Python não funciona em todos os casos. Por exemplo, ele não processa casos em que você descreve os campos de um objeto-dicionário aninhado, mas a API oferece suporte a isso. A API pode descrever qualquer um dos seguintes tipos:
AllowedType = (int | float | bool | str | list['AllowedType'] | dict[str, AllowedType])
A biblioteca de cliente google.ai.generativelanguage fornece acesso aos tipos de nível inferior, oferecendo controle total para você.
Primeiro, confira o atributo _tools
do modelo e veja como ele descreve as funções que você transmitiu a ele:
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" } }]
Isso retorna a lista de objetos genai.protos.Tool
que seriam enviados ao
API. Se você não conhece o formato impresso, é porque esses documentos
protobuf. Cada genai.protos.Tool
(um neste caso) contém uma lista de
genai.protos.FunctionDeclarations
, que descrevem uma função e os
.
Veja aqui uma declaração para a mesma função de multiplicação escrita usando o
genai.protos
de turmas. Essas classes apenas descrevem a função da API, não incluindo uma implementação dela. Portanto, usá-lo não funciona
com a chamada de função automática, mas as funções nem sempre precisam de uma
implementação.
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']
)
)
])
Da mesma forma, você pode descrever isso como um objeto compatível com 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" } }
De qualquer forma, você transmite uma representação de um genai.protos.Tool
ou uma lista de ferramentas para
model = genai.GenerativeModel('gemini-1.5-flash', tools=calculator)
chat = model.start_chat()
response = chat.send_message(
f"What's 234551 X 325552 ?",
)
Como antes, o modelo retorna um genai.protos.FunctionCall
que invoca a função multiply
da calculadora:
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 ]
Execute a função:
fc = response.candidates[0].content.parts[0].function_call
assert fc.name == 'multiply'
result = fc.args['a'] * fc.args['b']
result
76358547152.0
Envie o resultado ao modelo para continuar a conversa:
response = chat.send_message(
genai.protos.Content(
parts=[genai.protos.Part(
function_response = genai.protos.FunctionResponse(
name='multiply',
response={'result': result}))]))