Visualizza su ai.google.dev | Esegui in Google Colab | Visualizza il codice sorgente su GitHub |
Puoi fornire ai modelli Gemini le descrizioni delle funzioni. Il modello potrebbe chiederti di chiamare una funzione e inviare il risultato per aiutarlo a gestire la query.
Configurazione
Installa l'SDK Python
L'SDK Python per l'API Gemini è contenuto nel pacchetto google-generativeai
. Installa la dipendenza utilizzando pip:
pip install -U -q google-generativeai
Importa pacchetti
Importa i pacchetti necessari.
import pathlib
import textwrap
import time
import google.generativeai as genai
from IPython import display
from IPython.display import Markdown
def to_markdown(text):
text = text.replace('•', ' *')
return Markdown(textwrap.indent(text, '> ', predicate=lambda _: True))
Configura la chiave API
Prima di poter utilizzare l'API Gemini, devi ottenere una chiave API. Se non ne hai già una, crea una chiave con un clic in Google AI Studio.
In Colab, aggiungi la chiave al gestore dei secret nella sezione "☁" del riquadro a sinistra. Assegna il nome API_KEY
.
Una volta ottenuta la chiave API, passala all'SDK. A tale scopo, puoi procedere in uno dei due seguenti modi:
- Inserisci la chiave nella variabile di ambiente
GOOGLE_API_KEY
(l'SDK la acquisirà automaticamente da lì). - Passa la chiave a
genai.configure(api_key=...)
try:
# Used to securely store your API key
from google.colab import userdata
# Or use `os.getenv('API_KEY')` to fetch an environment variable.
GOOGLE_API_KEY=userdata.get('GOOGLE_API_KEY')
except ImportError:
import os
GOOGLE_API_KEY = os.environ['GOOGLE_API_KEY']
genai.configure(api_key=GOOGLE_API_KEY)
Nozioni di base sulle funzioni
Puoi passare un elenco di funzioni all'argomento tools
durante la creazione di un genai.GenerativeModel
.
def multiply(a:float, b:float):
"""returns a * b."""
return a*b
model = genai.GenerativeModel(model_name='gemini-1.0-pro',
tools=[multiply])
model
genai.GenerativeModel( model_name='models/gemini-1.0-pro', generation_config={}, safety_settings={}, tools=<google.generativeai.types.content_types.FunctionLibrary object at 0x10e73fe90>, )
Il modo consigliato per utilizzare le chiamate di funzione è tramite l'interfaccia di chat. Il motivo principale è che FunctionCalls
si adatta perfettamente alla struttura multi-turno della chat.
chat = model.start_chat(enable_automatic_function_calling=True)
Quando le chiamate di funzione automatiche sono attivate, chat.send_message
chiama automaticamente la tua funzione se il modello lo richiede.
Sembra che restituisca semplicemente un messaggio di risposta contenente la risposta corretta:
response = chat.send_message('I have 57 cats, each owns 44 mittens, how many mittens is that in total?')
response.text
'The total number of mittens is 2508.'
57*44
2508
Se guardi nella ChatSession.history
puoi vedere la sequenza di eventi:
- Hai inviato la domanda.
- Il modello ha risposto con
glm.FunctionCall
. genai.ChatSession
ha eseguito la funzione localmente e ha inviato al modello unglm.FunctionResponse
.- Il modello ha utilizzato l'output della funzione nella risposta.
for content in chat.history:
part = content.parts[0]
print(content.role, "->", type(part).to_dict(part))
print('-'*80)
user -> {'text': 'I have 57 cats, each owns 44 mittens, how many mittens is that in total?'} -------------------------------------------------------------------------------- model -> {'function_call': {'name': 'multiply', 'args': {'a': 57.0, 'b': 44.0} } } -------------------------------------------------------------------------------- user -> {'function_response': {'name': 'multiply', 'response': {'result': 2508.0} } } -------------------------------------------------------------------------------- model -> {'text': 'The total number of mittens is 2508.'} --------------------------------------------------------------------------------
In generale, il diagramma di stato è:
Il modello può rispondere con più chiamate di funzione prima di restituire una risposta testuale, e le chiamate di funzione precedeno la risposta testuale.
Sebbene il tutto sia stato gestito automaticamente, se hai bisogno di un maggiore controllo puoi:
- Lascia il valore predefinito
enable_automatic_function_calling=False
ed elabora autonomamente le risposteglm.FunctionCall
. - In alternativa, utilizza
GenerativeModel.generate_content
, dove devi gestire anche la cronologia chat.
[Facoltativo] Accesso di basso livello
L'estrazione automatica dello schema dalle funzioni Python non funziona in tutti i casi. Ad esempio, non gestisce i casi in cui descrivi i campi di un oggetto dizionario nidificato, ma l'API supporta questa operazione. L'API è in grado di descrivere tutti i seguenti tipi:
AllowedType = (int | float | bool | str | list['AllowedType'] | dict[str, AllowedType]
La libreria client di google.ai.generativelanguage
consente di accedere ai tipi di basso livello, dandoti il pieno controllo.
import google.ai.generativelanguage as glm
Prima di tutto all'interno dell'attributo _tools
del modello, puoi vedere come descrive la funzione o le funzioni che hai trasmesso al modello:
def multiply(a:float, b:float):
"""returns a * b."""
return a*b
model = genai.GenerativeModel(model_name='gemini-1.0-pro',
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" } }]
Questo restituisce l'elenco di glm.Tool
oggetti che verranno inviati all'API. Se il formato stampato non conosce il formato, si tratta di classi protobuf di Google. Ogni glm.Tool
(1 in questo caso) contiene un elenco di glm.FunctionDeclarations
, che descrivono una funzione e i relativi argomenti.
Ecco una dichiarazione per la stessa funzione di moltiplicazione scritta utilizzando le classi glm
.
Tieni presente che queste classi descrivono solo la funzione per l'API e non ne includono un'implementazione. Quindi, l'utilizzo di questa funzione non funziona con le chiamate di funzione automatiche, ma non sempre le funzioni richiedono un'implementazione.
calculator = glm.Tool(
function_declarations=[
glm.FunctionDeclaration(
name='multiply',
description="Returns the product of two numbers.",
parameters=glm.Schema(
type=glm.Type.OBJECT,
properties={
'a':glm.Schema(type=glm.Type.NUMBER),
'b':glm.Schema(type=glm.Type.NUMBER)
},
required=['a','b']
)
)
])
In modo equivalente, puoi descrivere questo oggetto come un oggetto compatibile con 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']} }]}
glm.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" } }
In ogni caso, passi una rappresentazione di glm.Tool
o di un elenco di strumenti a
model = genai.GenerativeModel('gemini-pro', tools=calculator)
chat = model.start_chat()
response = chat.send_message(
f"What's 234551 X 325552 ?",
)
Come prima che il modello restituisca un glm.FunctionCall
che richiama la funzione multiply
della calcolatrice:
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 ]
Esegui la funzione autonomamente:
fc = response.candidates[0].content.parts[0].function_call
assert fc.name == 'multiply'
result = fc.args['a'] * fc.args['b']
result
76358547152.0
Invia il risultato al modello per continuare la conversazione:
response = chat.send_message(
glm.Content(
parts=[glm.Part(
function_response = glm.FunctionResponse(
name='multiply',
response={'result': result}))]))
Riepilogo
Le chiamate di funzione di base sono supportate nell'SDK. Ricorda che è più facile da gestire con la modalità chat, a causa della naturale struttura degli scambi. Sta a te chiamare le funzioni e inviare i risultati al modello in modo che possa produrre una risposta testuale.