Samouczek wywoływania funkcji

Wywołanie funkcji ułatwia pobieranie danych wyjściowych z uporządkowanych danych modeli generatywnych. Następnie możesz używać tych danych do wywoływania innych interfejsów API i zwracania odpowiednich danych odpowiedzi do modelu. Innymi słowy, wywołanie funkcji pomaga Łączysz modele generatywne z systemami zewnętrznymi, aby wygenerowane treści zawiera najbardziej aktualne i dokładne informacje.

Możesz przekazywać modelom Gemini opisy funkcji. Są to funkcje napisane w języku aplikacji (czyli nie są to funkcje Google Cloud Functions). Model może poprosić o wywołanie funkcji i odesłanie wyniku, aby pomóc w obróbce zapytania.

Zapoznaj się z Wprowadzenie do wywoływania funkcji więcej. Możesz też wypróbuj tę funkcję w Google Colab lub wyświetl przykładowy kod w Repozytorium Gemini API Cookbook.

Przykładowy interfejs API do sterowania oświetleniem

Wyobraź sobie, że masz podstawowy system sterowania oświetleniem i programowanie interfejsu (API) i chcesz umożliwić użytkownikom sterowanie oświetleniem za pomocą prostego żądań tekstowych. Możesz skorzystać z funkcji wywoływania funkcji, aby interpretować oświetlenie zmieniać żądania użytkowników i przekształcać je w wywołania interfejsu API w celu ustawienia oświetlenia . Ten hipotetyczny system sterowania oświetleniem umożliwia kontrolowanie jasności światła i jego temperatury barwowej, zdefiniowanych jako dwa oddzielne parametry:

Parametr Typ Wymagane Opis
brightness liczba tak Poziom światła od 0 do 100. Zero oznacza wyłączone, a 100 – pełną jasność.
colorTemperature ciąg znaków tak Temperatura kolorów oświetlenia, która może wynosić daylight, cool lub warm.

Dla uproszczenia ten wymyślony system oświetleniowy ma tylko jedno światło, dzięki czemu użytkownik nie musi określać pomieszczenia ani lokalizacji. Oto przykład żądania JSON, które możesz wysłać do interfejsu Lighting Control API, aby zmienić poziom światła do 50% przy użyciu temperatury barwowej światła dziennego:

{
  "brightness": "50",
  "colorTemperature": "daylight"
}

W tym samouczku pokazujemy, jak skonfigurować wywołanie funkcji dla interfejsu Gemini API, aby interpretować żądania dotyczące oświetlenia użytkowników i mapować je na ustawienia interfejsu API w celu sterowania wartościami jasności i temperatury barwowej światła.

Zanim zaczniesz: skonfiguruj projekt i klucz interfejsu API

Zanim wywołasz Gemini API, musisz skonfigurować projekt klucz interfejsu API.

Zdefiniuj funkcję interfejsu API

utworzyć funkcję, która wysyła żądanie do interfejsu API; Funkcję tę należy zdefiniować w kodzie aplikacji, ale może ona wywoływać usługi lub interfejsy API spoza aplikacji. Gemini API nie wywołuje tej funkcji bezpośrednio, więc może kontrolować sposób i czas wykonywania tej funkcji w aplikacji w kodzie. Na potrzeby demonstracji ten samouczek definiuje fikcyjną funkcję interfejsu API, która zwraca tylko żądane wartości oświetlenia:

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
    }

Podczas tworzenia funkcji, która ma być używana w wywołaniu funkcji przez model, należy podać w opisie funkcji i parametrów jak najwięcej szczegółów. Model generatywny wykorzystuje te informacje do określenia, do wyboru funkcji i sposobu podania wartości parametrów w funkcji .

Deklarowanie funkcji podczas inicjowania modelu

Jeśli chcesz używać wywołania funkcji w modelu, musisz zadeklarować funkcje podczas inicjowania obiektu modelu. Funkcje deklarujesz, ustawiając parametr tools modelu:

model = genai.GenerativeModel(model_name='gemini-1.5-flash',
                              tools=[set_light_values])

Generowanie wywołania funkcji

Po zainicjowaniu modelu za pomocą deklaracji funkcji możesz wywołać model za pomocą zdefiniowanej funkcji. Wywoływania funkcji należy używać za pomocą promptów na czacie (sendMessage()), ponieważ wywołanie funkcji zazwyczaj przynosi korzyści w kontekście poprzednich promptów i odpowiedzi.

chat = model.start_chat()
response = chat.send_message('Dim the lights so the room feels cozy and warm.')
response.text

Pakiet SDK Pythona ChatSession upraszcza zarządzanie sesjami czatu przez obsługę historii rozmowy dla Ciebie. Możesz użyć tagu enable_automatic_function_calling, aby pakiet SDK automatycznie wywoływał funkcję.

# Create a chat session that automatically makes suggested function calls
chat = model.start_chat(enable_automatic_function_calling=True)

Wywoływanie funkcji równoległej

Oprócz opisanego powyżej podstawowego wywoływania funkcji możesz też wywoływać wiele funkcji naraz. W tej sekcji pokazujemy, jak korzystać z równoległego wywoływania funkcji.

Zdefiniuj narzędzia.

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

Teraz wywołaj model z instrukcją, która może używać wszystkich określonych narzędzi.

# 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)

Każdy z wyświetlanych wyników odzwierciedla jedno wywołanie funkcji, którego zażądał model. Aby otrzymać wyniki z powrotem, dodaj odpowiedzi w takiej kolejności, w jakiej zostały wymagane.

# 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! 🕺💃

Mapowanie typu danych wywołania funkcji

Automatyczne wyodrębnianie schematu z funkcji Pythona nie we wszystkich przypadkach działa. Na przykład: nie obsługuje przypadków, w których opisuje się pola zagnieżdżonego obiektu słownika, ale interfejs API obsługuje tę funkcję. Interfejs API może opisywać te typy:

AllowedType = (int | float | bool | str | list['AllowedType'] | dict[str, AllowedType])

Biblioteka klienta google.ai.generativelanguage zapewnia dostęp do typów niskich poziomów, dając Ci pełną kontrolę.

Najpierw przyjrzyj się atrybutowi _tools modelu. Możesz zobaczyć, jak opisuje on funkcje przekazane do modelu:

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"
   }
 }]

Zwraca listę obiektów genai.protos.Tool, które zostałyby wysłane do funkcji API. Jeśli format wydruku nie jest Ci znajomy, to dlatego, że są to klasy Google protobuf. Każdy element genai.protos.Tool (w tym przypadku 1) zawiera listę elementów genai.protos.FunctionDeclarations, które opisują funkcję i jej argumenty.

Oto deklaracja tej samej funkcji mnożenia napisanej przy użyciu klas genai.protos. Pamiętaj, że te klasy tylko opisują funkcję interfejsu API, ale nie zawierają jej implementacji. Korzystanie z tej funkcji nie działa, z automatycznym wywoływaniem funkcji, ale funkcje nie zawsze wymagają implementacji.

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']
        )
      )
    ])

Możesz też opisać ten obiekt jako obiekt zgodny z 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"
  }
}

W obu przypadkach przekazujesz reprezentację elementu genai.protos.Tool lub listy narzędzi, aby

model = genai.GenerativeModel('gemini-1.5-flash', tools=calculator)
chat = model.start_chat()

response = chat.send_message(
    f"What's 234551 X 325552 ?",
)

Tak jak przed tym modelem, który zwraca funkcję genai.protos.FunctionCall wywołującą funkcję multiply kalkulatora:

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
]

Wykonaj funkcję samodzielnie:

fc = response.candidates[0].content.parts[0].function_call
assert fc.name == 'multiply'

result = fc.args['a'] * fc.args['b']
result
76358547152.0

Aby kontynuować rozmowę, wyślij wynik do modelu:

response = chat.send_message(
    genai.protos.Content(
    parts=[genai.protos.Part(
        function_response = genai.protos.FunctionResponse(
          name='multiply',
          response={'result': result}))]))