Über Funktionsaufrufe in Gemini mit APIs interagieren

1. Übersicht

Was sind Funktionsaufrufe in Gemini?

Die Vertex AI Gemini API ist eine Familie von generativen KI-Modellen, die von Google DeepMind entwickelt wurden und für multimodale Anwendungsfälle entwickelt wurden. Funktionsaufrufe sind eine Funktion der Gemini-Modelle, die es Entwicklern erleichtert, strukturierte Datenausgaben aus generativen Modellen zu erhalten.

Entwickler können diese Ausgaben dann verwenden, um andere APIs aufzurufen und die relevanten Antwortdaten an das Modell zurückzugeben. Mit anderen Worten: Funktionsaufrufe helfen Ihnen, Ihre generativen Modelle mit externen Systemen zu verbinden, damit die generierten Inhalte die neuesten und genauesten Informationen enthalten.

Funktionsweise von Funktionsaufrufen

Funktionen werden mithilfe von Funktionsdeklarationen beschrieben, wodurch das generative Modell den Zweck und die Parameter innerhalb einer Funktion versteht. Nachdem Sie Funktionsdeklarationen in einer Abfrage an ein generatives Modell übergeben haben, gibt das Modell ein strukturiertes Objekt zurück, das die Namen relevanter Funktionen und deren Argumente basierend auf der Suchanfrage des Nutzers enthält. Beachten Sie, dass das Modell die Funktion bei Funktionsaufrufen nicht tatsächlich aufruft. Stattdessen können Sie die zurückgegebene Funktion und die Parameter verwenden, um die Funktion in einer beliebigen Sprache, Bibliothek oder jedem Framework aufzurufen.

API-Schnittstelle

Aufgaben

In diesem Codelab erstellen Sie mit der Vertex AI Gemini API und Python eine Generative AI-Pipeline. Wenn du deine App verwendest, können Nutzer nach Wechselkursen fragen. Das System ruft dann die neuesten Daten von einer externen API ab und schickt dem Nutzer die Antwort.

Lerninhalte

  • Über die Python-Clientbibliothek mit dem Gemini-Modell interagieren
  • Funktionsdeklaration definieren und als Tool registrieren
  • Gemini aufrufen und eine Antwort auf einen Funktionsaufruf erhalten
  • So geben Sie die Funktionsantwort an Gemini zurück und reagieren an den Nutzer

Voraussetzungen

2. Einrichtung und Anforderungen

Bevor Sie Funktionsaufrufe in Gemini verwenden können, müssen Sie die Vertex AI API aktivieren und die neueste Version der Vertex AI Python-Clientbibliothek installieren.

Vertex AI API aktivieren

So aktivieren Sie die Vertex AI API:

  1. Rufen Sie in Ihrem Browser die Seite Vertex AI API-Dienstdetails auf.
  2. Klicken Sie auf die Schaltfläche Aktivieren, um die Vertex AI API in Ihrem Google Cloud-Projekt zu aktivieren.

Python-Clientbibliothek für Vertex AI installieren

So installieren Sie die Python-Clientbibliotheken für Vertex AI:

  1. Öffnen Sie ein Terminal in Ihrer Entwicklungsumgebung.
  2. Prüfen Sie, ob Sie eine gültige Python-Entwicklungsumgebung haben, und lesen Sie bei Bedarf diese Richtlinien.
  3. Führen Sie den folgenden Befehl aus, um die Python-Clientbibliothek für Vertex AI zu installieren:
    pip install --upgrade google-cloud-aiplatform
    
  4. Wenn Sie in einer Notebook-Umgebung arbeiten, müssen Sie möglicherweise die Laufzeit bzw. den Kernel neu starten, um die neu installierten Pakete zu verwenden.

Jetzt können Sie die Vertex AI API verwenden.

3. Das Problem verstehen

Haben Sie schon einmal mit einem Large Language Model oder Generative-AI-Modell interagiert und es nach Echtzeit- oder aktuellen Informationen gefragt, nur um eine Antwort mit veralteten oder fehlerhaften Informationen zu erhalten?

Probieren wir es jetzt aus! Zuerst importieren wir die relevanten Python-Pakete und initialisieren das Gemini-Modell. Sie können den folgenden Code in einer Python-Entwicklungsumgebung wie Colab oder Colab Enterprise ausführen und die neueste Version des Vertex AI SDK für Python installieren:

import vertexai
from vertexai.generative_models import GenerativeModel
model = GenerativeModel("gemini-1.5-pro-001")

Stellen wir nun eine Frage zum heutigen Wechselkurs für verschiedene Währungen:

response = model.generate_content(
    "What's the exchange rate for euros to dollars today?"
)
print(response.text)

Das Modell sollte in etwa folgende eingeschränkte oder veraltete Antwort für Sie generieren:

As an AI language model, I don't have access to real-time currency exchange
rates. However, as of my last update in September 2021, the approximate exchange
rate between euros (EUR) and US dollars (USD) was:

1 EUR ≈ 1.18 USD

Please note that currency exchange rates constantly fluctuate and can vary
depending on various factors such as economic conditions, supply and demand,
political events, and more. To obtain the most up-to-date and accurate exchange
rate, I recommend using a reliable currency converter or financial website that
provides live rates.

[...]

Wenn ein Endnutzer diese Art von Antwort erhält, muss er den Kontext wechseln, um die für ihn interessanten Währungen nachzuschlagen, den aktuellen Wechselkurs abzurufen und selbst Conversions durchzuführen.

Im Idealfall könnte eine Pipeline für ein generatives Modell einige oder alle dieser Aufgaben für den Nutzer erledigen. Im nächsten Abschnitt lernen Sie einige gängige Problemumgehungen kennen, um strukturierte Antworten von generativen Modellen zu erhalten, damit Sie externe Systeme aufrufen können.

4. Gängige Problemumgehungen ausprobieren

Wenn Sie mit generativen Modellen in Szenarien arbeiten, in denen Sie aktuelle Informationen oder Daten aus externen Quellen benötigen, können Sie eine externe API aufrufen und die Ergebnisse dann an das generative Modell zurückgeben, damit es in seiner Antwort verwendet wird.

Bevor Sie ein externes System aufrufen, müssen Sie die richtige Funktion bestimmen, die relevanten Parameter vom Nutzer extrahieren und die Parameter in ein strukturiertes Datenobjekt einfügen. Dazu ist in der Regel ein umfangreiches Prompt-Engineering erforderlich, um das generative Modell zur Ausgabe gültiger strukturierter Daten zu zwingen.

Lassen Sie uns die Frage aus dem vorherigen Abschnitt noch einmal durchgehen und einige zusätzliche Anweisungen für das Modell hinzufügen. Senden Sie die folgende Anfrage an das Gemini-Modell:

user_prompt = "What's the exchange rate from euros to US dollars today?"

response = model.generate_content("""
Your task is to extract parameters from the user's input and return it as a
structured JSON payload. The user will ask about the exchange rate and which
currency they are converting from and converting to.

User input: {user_prompt}

Please extract the currencies as parameters and put them in a JSON object.
""".format(user_prompt=user_prompt))
print(response.text)

Das Ergebnis ist die folgende Textantwort, die kein gültiges JSON-Format hat und für uns schwierig zu arbeiten ist:

```json
{
  "currency_from": "euros",
  "currency_to": "US dollars"
}
```

Insbesondere die erste und letzte Zeile der Textantwort enthalten Graviszeichen zur Begrenzung des Codeblocks, die erste Zeile enthält einen Sprachbezeichner und die Werte im JSON-Objekt sind keine standardmäßigen Währungsabkürzungen aus drei Buchstaben, die eine Währungstausch-API als Eingabeparameter erwarten würde.

Wir könnten versuchen, diesen Text mit Python in gültige JSON-Dateien und ein Wörterbuch nachzuverarbeiten, dem Prompt weitere Anweisungen hinzuzufügen, ein oder mehrere Beispiele für die gewünschte Ausgabe bereitzustellen, das Modell zu optimieren oder das generative Modell noch einmal aufzurufen, um den JSON-Code zu bereinigen.

Aber es gibt einen deterministischen Weg! Sehen wir uns an, wie Sie Funktionsaufrufe in Gemini verwenden, um Informationen in externen Diensten abzufragen und relevante Antworten an Endnutzer zurückzugeben.

5. Funktionsweise von Funktionsaufrufen

Bevor wir mit der Parameterextraktion und Funktionsaufrufen beginnen, sehen wir uns die Schritte des Funktionsaufrufs an und welche Komponenten zur Laufzeit verwendet werden.

Funktionsaufrufe in Gemini

Nutzereingabe in die Gemini API

Der Prompt des Nutzers wird an die Gemini API gesendet. Bei diesem API-Aufruf an das Gemini-Modell hat der Entwickler eine oder mehrere Funktionsdeklarationen innerhalb eines Tools definiert, damit das Gemini-Modell weiß, welche Funktionen es aufrufen kann und wie es aufgerufen werden kann.

Die Gemini API gibt einen Funktionsaufruf zurück

Basierend auf dem Inhalt der Nutzereingabe und des Prompts gibt Gemini eine Funktionsaufruf-Antwort mit strukturierten Daten zurück, die den Namen der aufzurufenden Funktion und die entsprechenden zu verwendenden Parameter enthalten.

API-Anfrage stellen

Anschließend verwenden Sie den Funktionsnamen und die Parameter, um eine API-Anfrage zum Abrufen von Informationen aus einem externen System oder einer externen API zu senden. Diese API-Anfrage und -Antwort wird vom Entwickler im Anwendungscode implementiert und liegt außerhalb des Geltungsbereichs der Gemini API und des Gemini SDK. Sie können beispielsweise die requests-Bibliothek in Python verwenden, um eine REST API aufzurufen und eine JSON-Antwort zu erhalten. Alternativ können Sie die Funktion mit Ihrem bevorzugten Ansatz und Ihrer bevorzugten Clientbibliothek aufrufen.

API-Antwort an Gemini zurückgeben

Schließlich übergeben Sie die API-Antwort wieder an das Gemini-Modell, damit es eine Antwort auf den anfänglichen Prompt des Endnutzers generieren oder eine andere Antwort auf einen Funktionsaufruf aufrufen kann, wenn das Gemini-Modell feststellt, dass es zusätzliche Informationen benötigt.

6. API auswählen

Sie kennen jetzt den gesamten Ablauf und die einzelnen Schritte beim Funktionsaufruf. Als Nächstes erstellen Sie eine Generative-AI-Pipeline, um die neuesten Währungskurse abzurufen. Zunächst müssen wir auswählen, welche API als Informationsquelle verwendet werden soll.

Für unsere Währungs-App verwenden wir die REST API unter https://www.frankfurter.app/, um die neuesten Informationen zu globalen Wechselkursen abzurufen.

Um mit dieser REST API zu interagieren, können wir einen REST API-Aufruf mit requests in Python so ausführen:

import requests
url = "https://api.frankfurter.app/latest"
response = requests.get(url)
response.text

oder eine cURL-Anfrage wie:

curl https://api.frankfurter.app/latest

Dadurch wird eine Antwort wie diese zurückgegeben:

{
  "amount": 1,
  "base": "EUR",
  "date": "2023-12-20",
  "rates": {
    "AUD": 1.6186, "BGN": 1.9558, "BRL": 5.3287,
    "CAD": 1.4609, "CHF": 0.946, "CNY": 7.8121,
    "CZK": 24.538, "DKK": 7.4565, "GBP": 0.86555,
    "HKD": 8.5439, "HUF": 385.23, "IDR": 16994,
    "ILS": 3.9983, "INR": 91.06, "ISK": 150.3,
    "JPY": 157.12, "KRW": 1425.62, "MXN": 18.6867,
    "MYR": 5.0977, "NOK": 11.2895, "NZD": 1.7421,
    "PHP": 60.991, "PLN": 4.3413, "RON": 4.9699,
    "SEK": 11.129, "SGD": 1.4562, "THB": 38.252,
    "TRY": 31.883, "USD": 1.0944, "ZAR": 20.111
  }
}

Da Funktionsaufrufe in Gemini den externen API-Aufruf nicht für Sie ausführen, gibt es keine solchen Einschränkungen im Hinblick auf den verwendeten API-Typ. Sie können einen Cloud Run-Dienst, eine Cloud Functions-Funktion, eine API-Anfrage an einen Google Cloud-Dienst oder eine beliebige externe REST API verwenden.

7. Funktion und Tool definieren

Nachdem Sie eine REST API ausgewählt haben, können Sie nun eine API-Spezifikation definieren und die Funktion in einem Tool registrieren.

Prüfen Sie, ob Sie die neueste Version des Vertex AI SDK für Python installiert haben.

Importieren Sie dann die erforderlichen Module aus dem Python SDK und initialisieren Sie das Gemini-Modell:

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

model = GenerativeModel("gemini-1.5-pro-001")

Die REST API unter https://api.frankfurter.app/ akzeptiert die folgenden Eingabeparameter:

Parameter

Typ

Beschreibung

from

String

Währung, aus der umgerechnet werden soll

to

String

Währung, in die umgerechnet werden soll

date

String

Datum, für das der Wechselkurs abgerufen werden soll

Mit diesen Parametern sieht eine partielle OpenAPI-Spezifikation für diese REST API im YAML-Format so aus:

openapi: 3.0.0
info:
  title: Frankfurter Exchange Rate API
  description: This API provides current and historical exchange rates
  version: 1.0.0
servers:
  - url: https://api.frankfurter.app
paths:
  /{date}:
    get:
      summary: Get the latest currency exchange rates.
      parameters:
        - name: date
          in: path
          description: Get currency rates for a specific date or 'latest' if a date is not specified
          required: true
          schema:
            type: string
        - name: from
          in: query
          description: The currency to convert from.
          required: true
          schema:
            type: string
        - name: to
          in: query
          description: The currency to convert to.
          schema:
            type: string

Registrieren wir es jetzt mit dem Python SDK für Gemini als FunctionDeclaration:

get_exchange_rate_func = FunctionDeclaration(
    name="get_exchange_rate",
    description="Get the exchange rate for currencies between countries",
    parameters={
    "type": "object",
    "properties": {
        "currency_date": {
            "type": "string",
            "description": "A date that must always be in YYYY-MM-DD format or the value 'latest' if a time period is not specified"
        },
        "currency_from": {
            "type": "string",
            "description": "The currency to convert from in ISO 4217 format"
        },
        "currency_to": {
            "type": "string",
            "description": "The currency to convert to in ISO 4217 format"
        }
    },
         "required": [
            "currency_from",
            "currency_date",
      ]
  },
)

Achten Sie darauf, in den Beschreibungen der Funktionen und Parameter so viele Details wie möglich zu verwenden, da das generative Modell anhand dieser Informationen bestimmt, welche Funktion ausgewählt und wie die Parameter im Funktionsaufruf ausgefüllt werden sollen.

Zum Schluss definieren Sie eine Tool, die die Funktionsdeklaration enthält:

exchange_rate_tool = Tool(
    function_declarations=[get_exchange_rate_func],
)

Hier verwenden Sie eine Funktionsdeklaration in einem Tool. Beachten Sie jedoch, dass Sie eine oder mehrere Funktionsdeklarationen in einem Tool registrieren können. Das Modell wählt dann die passende Funktion aus, die zur Laufzeit verwendet werden soll. Weitere Informationen zu FunctionDeclaration, Tool und verwandten Klassen im Gemini SDK für Python finden Sie in der Dokumentation zu Funktionsaufrufen in der Gemini API.

Sie haben die Konfiguration der Funktion und der Tooldefinitionen abgeschlossen. Im nächsten Abschnitt rufen wir das generative Modell mit diesem Tool auf und erhalten einen Funktionsaufruf zurück, mit dem wir die REST API aufrufen können.

8. Funktionsaufruf generieren

Jetzt können Sie das generative Modell auffordern und die von Ihnen definierte tool einfügen:

prompt = """What is the exchange rate from Australian dollars to Swedish krona?
How much is 500 Australian dollars worth in Swedish krona?"""

response = model.generate_content(
    prompt,
    tools=[exchange_rate_tool],
)

Sehen wir uns das Antwortobjekt an:

print(response.candidates[0].content)

role: "model"
parts {
  function_call {
    name: "get_exchange_rate"
    args {
      fields {
        key: "currency_to"
        value {
          string_value: "SEK"
        }
      }
      fields {
        key: "currency_from"
        value {
          string_value: "AUD"
        }
      }
      fields {
        key: "currency_date"
        value {
          string_value: "latest"
        }
      }
    }
  }
}

Anscheinend hat das Modell die eine verfügbare Funktion ausgewählt und zusammen mit den Parametern einen Funktionsaufruf für die Funktion get_exchange_rate zurückgegeben. Und die Parameter haben das gewünschte Format. Glückwunsch, du hast strukturierte Antworten von generativen Modellen erhalten!

Im nächsten Abschnitt verwenden Sie die Informationen in der Antwort, um eine API-Anfrage zu stellen.

9. API-Anfrage stellen

Denken Sie daran, dass Funktionsaufrufe in Gemini den externen API-Aufruf nicht für Sie ausführen. Vielmehr können Sie jede beliebige Sprache, Bibliothek oder jedes beliebige Framework verwenden.

Hier verwenden Sie die requests-Bibliothek in Python, um die REST API für Wechselkurse aufzurufen.

Entpacken wir die Antwort in ein Python-Wörterbuch:

params = {}
for key, value in response.candidates[0].content.parts[0].function_call.args.items():
    params[key[9:]] = value
params

Jetzt können wir requests oder eine beliebige andere Methode aufrufen:

import requests
url = f"https://api.frankfurter.app/{params['date']}"
api_response = requests.get(url, params=params)
api_response.text

Das führt zu einer Antwort, die in etwa so aussieht:

'{"amount":1.0,"base":"AUD","date":"2024-01-16","rates":{"SEK":6.8682}}'

Und wir haben unsere Antwort von der REST API mit den neuesten Wechselkursinformationen von heute. Im nächsten Abschnitt geben wir diese Informationen an das Modell zurück, damit es eine relevante Antwort für den Nutzer generieren kann.

10. Antwort generieren

Generieren wir abschließend eine Antwort für den Nutzer, indem wir die Funktionsantwort in der nächsten Unterhaltungsrunde an das Modell zurückgeben:

response = model.generate_content(
    [
    Content(role="user", parts=[
        Part.from_text(prompt + """Give your answer in steps with lots of detail
            and context, including the exchange rate and date."""),
    ]),
    Content(role="function", parts=[
        Part.from_dict({
            "function_call": {
                "name": "get_exchange_rate",
            }
        })
    ]),
    Content(role="function", parts=[
        Part.from_function_response(
            name="get_exchange_rate",
            response={
                "content": api_response.text,
            }
        )
    ]),
    ],
    tools=[exchange_rate_tool],
)


response.candidates[0].content.parts[0].text

Sobald die Funktionsantwort an das Modell zurückgesendet wird, reagiert dieses auf den Prompt des Nutzers zusammen mit relevanten Informationen aus der API-Antwort.

The exchange rate from Australian dollars to Swedish krona on January 16, 2024,
is 1 Australian dollar is equal to 6.8663 Swedish krona.

So, 500 Australian dollars would be worth 500 * 6.8663 = 3,433.15 Swedish krona.

11. Vollständiges Codebeispiel ansehen

An dieser Stelle können Sie Ihren Python-Code mithilfe eines Cloud Run-Dienstes, einer Cloud Functions-Funktion oder eines anderen Cloud-Dienstes in eine Backend-API einfügen und eine Frontend-App bereitstellen, die diese Backend API für Modellabfragen und API-Aufrufe verwendet.

Hier ist das vollständige Codebeispiel für unsere endgültige Lösung:

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

model = GenerativeModel("gemini-1.5-pro-001")

get_exchange_rate_func = FunctionDeclaration(
    name="get_exchange_rate",
    description="Get the exchange rate for currencies between countries",
    parameters={
    "type": "object",
    "properties": {
        "currency_date": {
            "type": "string",
            "description": "A date that must always be in YYYY-MM-DD format or the value 'latest' if a time period is not specified"
        },
        "currency_from": {
            "type": "string",
            "description": "The currency to convert from in ISO 4217 format"
        },
        "currency_to": {
            "type": "string",
            "description": "The currency to convert to in ISO 4217 format"
        }
    },
         "required": [
            "currency_from",
            "currency_date",
      ]
  },
)

exchange_rate_tool = Tool(
    function_declarations=[get_exchange_rate_func],
)

prompt = """What is the exchange rate from Australian dollars to Swedish krona?
How much is 500 Australian dollars worth in Swedish krona?"""

response = model.generate_content(
    prompt,
    tools=[exchange_rate_tool],
)

response.candidates[0].content

params = {}
for key, value in response.candidates[0].content.parts[0].function_call.args.items():
    params[key[9:]] = value
params

import requests
url = f"https://api.frankfurter.app/{params['date']}"
api_response = requests.get(url, params=params)
api_response.text

response = model.generate_content(
    [
    Content(role="user", parts=[
        Part.from_text(prompt + """Give your answer in steps with lots of detail
            and context, including the exchange rate and date."""),
    ]),
    Content(role="function", parts=[
        Part.from_dict({
            "function_call": {
                "name": "get_exchange_rate",
            }
        })
    ]),
    Content(role="function", parts=[
        Part.from_function_response(
            name="get_exchange_rate",
            response={
                "content": api_response.text,
            }
        )
    ]),
    ],
    tools=[exchange_rate_tool],
)


response.candidates[0].content.parts[0].text

Bei dieser Implementierung wurden zwei Anfragen an das generative Modell verwendet: eine Anfrage zum Generieren eines Funktionsaufrufs und eine weitere Anfrage zum Zurückgeben der Funktionsantwort. Beachten Sie, dass dies nur eine Methode zur Verarbeitung von Funktionsaufrufen und Funktionsantworten mit Gemini ist. Sie können auch zusätzliche Funktionsaufrufe durchführen, um weitere Informationen für Ihre Abfrage zu erhalten, oder Funktionsaufrufe mit Chat- und asynchronen Methoden verwenden.

Weitere Codebeispiele finden Sie im Beispielnotebook für Funktionsaufrufe in Gemini.

12. Glückwunsch

Mit Funktionsaufrufen in Gemini haben Sie erfolgreich eine Generative AI-Pipeline erstellt, die mit der Vertex AI Gemini API und Python verwendet wird. Nutzer können nach Wechselkursen fragen. Das System ruft dann die neuesten Daten von einer externen API ab und antwortet mit einer Antwort.

Bei einem Prompt eines Endnutzers wird durch Funktionsaufrufe in Gemini die entsprechende Funktion ausgewählt, Parameter aus dem Prompt extrahiert und ein strukturiertes Datenobjekt zurückgegeben, damit Sie einen externen API-Aufruf ausführen können.

Das Design von Funktionsaufrufen in Gemini soll Ihnen das Beste aus beiden Welten zum deterministischen Extrahieren von Parametern bieten, während die Zusammenfassung und Inhaltserstellung dem generativen Modell überlassen wird. Sie können auch andere APIs und Prompts in Ihrer Pipeline ausprobieren und die anderen Funktionen der Gemini API von Vertex AI kennenlernen.

API-Schnittstelle

Bereinigen

Mit der folgenden Bereinigung können Sie vermeiden, dass Ihrem Google Cloud-Konto die in diesem Codelab verwendeten Ressourcen in Rechnung gestellt werden:

  • Löschen Sie Ihr Projekt mit der Google Cloud Console, wenn Sie es nicht benötigen, um unnötige Google Cloud-Gebühren zu vermeiden.
  • Wenn Sie die APIs für Vertex AI deaktivieren möchten, rufen Sie die Seite Vertex AI API Service Details auf, klicken Sie auf Disable API (API deaktivieren) und bestätigen Sie den Vorgang.

Weitere Informationen

In diesen Leitfäden und Ressourcen erfahren Sie mehr über konversationelle und generative KI:

Lizenz

Dieser Text ist mit einer Creative Commons Attribution 2.0 Generic License lizenziert.