Voir sur ai.google.dev | Exécuter dans Google Colab | Afficher la source sur GitHub |
Vous pouvez fournir aux modèles Gemini des descriptions de fonctions. Le modèle peut vous demander d'appeler une fonction et de renvoyer le résultat pour l'aider à gérer votre requête.
Préparation
Installer le SDK Python
Le SDK Python pour l'API Gemini est contenu dans le package google-generativeai
. Installez la dépendance à l'aide de pip:
pip install -U -q google-generativeai
Importer des packages
Importez les packages nécessaires.
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))
Configurer votre clé API
Pour pouvoir utiliser l'API Gemini, vous devez d'abord obtenir une clé API. Si vous ne possédez pas encore de clé, créez-en une en un clic dans Google AI Studio.
Dans Colab, ajoutez la clé au gestionnaire de secrets sous le bouton "EIDR" du panneau de gauche. Donnez-lui le nom API_KEY
.
Une fois la clé API obtenue, transmettez-la au SDK. Pour cela, vous avez le choix entre deux méthodes :
- Placez la clé dans la variable d'environnement
GOOGLE_API_KEY
(le SDK la récupérera automatiquement à partir de là). - Transmettre la clé à
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)
Principes de base des fonctions
Vous pouvez transmettre une liste de fonctions à l'argument tools
lorsque vous créez 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 est recommandé d'utiliser les appels de fonction via l'interface de chat. La raison principale est que FunctionCalls
s'intègre parfaitement à la structure multitours du chat.
chat = model.start_chat(enable_automatic_function_calling=True)
Lorsque l'appel de fonction automatique est activé, chat.send_message
appelle automatiquement votre fonction si le modèle le demande.
Il semble simplement renvoyer une réponse textuelle contenant la bonne réponse:
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
Si vous regardez dans la ChatSession.history
, vous pouvez voir la séquence d'événements:
- Vous avez envoyé la question.
- Le modèle a renvoyé une réponse
glm.FunctionCall
. genai.ChatSession
a exécuté la fonction localement et renvoyé au modèle uneglm.FunctionResponse
.- Le modèle a utilisé la sortie de la fonction dans sa réponse.
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.'} --------------------------------------------------------------------------------
En général, le diagramme d'état est le suivant:
Le modèle peut répondre avec plusieurs appels de fonction avant de renvoyer une réponse textuelle, et les appels de fonction avant la réponse textuelle.
Bien que tout ait été géré automatiquement, si vous avez besoin de plus de contrôle, vous pouvez:
- Conservez la valeur par défaut
enable_automatic_function_calling=False
et traitez vous-même les réponsesglm.FunctionCall
. - Vous pouvez également utiliser
GenerativeModel.generate_content
, qui vous permet également de gérer l'historique des discussions.
[Facultatif] Accès de bas niveau
L'extraction automatique du schéma à partir des fonctions Python ne fonctionne pas dans tous les cas. Par exemple, elle ne gère pas les cas où vous décrivez les champs d'un objet de dictionnaire imbriqué, mais l'API le permet. L'API est capable de décrire les différents types suivants:
AllowedType = (int | float | bool | str | list['AllowedType'] | dict[str, AllowedType]
La bibliothèque cliente google.ai.generativelanguage
donne accès aux types de niveau inférieur, ce qui vous offre un contrôle total.
import google.ai.generativelanguage as glm
Tout d'abord, dans l'attribut _tools
du modèle, vous pouvez voir comment il décrit la ou les fonctions que vous lui avez transmises:
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" } }]
Cela renvoie la liste des objets glm.Tool
qui seraient envoyés à l'API. Si le format imprimé ne vous est pas familier, il s'agit de classes de tampons de protocole Google. Chaque glm.Tool
(1 dans ce cas) contient une liste de glm.FunctionDeclarations
, qui décrivent une fonction et ses arguments.
Voici une déclaration pour la même fonction de multiplication écrite à l'aide des classes glm
.
Notez que ces classes ne font que décrire la fonction de l'API, elles n'incluent pas d'implémentation. L'utilisation de cette option ne fonctionne donc pas avec l'appel automatique de fonctions, mais les fonctions n'ont pas toujours besoin d'être implémentées.
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']
)
)
])
De manière équivalente, vous pouvez décrire cela comme un objet compatible 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" } }
Dans tous les cas, vous transmettez une représentation d'un glm.Tool
ou d'une liste d'outils à
model = genai.GenerativeModel('gemini-pro', tools=calculator)
chat = model.start_chat()
response = chat.send_message(
f"What's 234551 X 325552 ?",
)
Comme avant que le modèle ne renvoie un glm.FunctionCall
en appelant la fonction multiply
du calculateur:
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 ]
Exécutez la fonction vous-même:
fc = response.candidates[0].content.parts[0].function_call
assert fc.name == 'multiply'
result = fc.args['a'] * fc.args['b']
result
76358547152.0
Envoyez le résultat au modèle pour poursuivre la conversation:
response = chat.send_message(
glm.Content(
parts=[glm.Part(
function_response = glm.FunctionResponse(
name='multiply',
response={'result': result}))]))
Résumé
Le SDK prend en charge les appels de fonctions de base. N'oubliez pas qu'il est plus facile à gérer en mode chat, en raison de la structure naturelle des échanges. Vous êtes en charge d'appeler les fonctions et de renvoyer les résultats au modèle afin qu'il puisse générer une réponse textuelle.