Eğitim: Gemini API ile işlev çağrısı


ai.google.dev'de görüntüleyin Google Colab'de çalıştır Kaynağı GitHub'da görüntüleyin

Özel işlevleri tanımlamak ve Gemini'a iletmek için işlev çağrısını kullanın. Model, bu işlevleri doğrudan çağırmaz. Bunun yerine, işlev adını ve önerilen bağımsız değişkenleri belirten yapılandırılmış veri çıkışı oluşturur. Bu çıkış, harici API'lerin çağrılmasını sağlar ve elde edilen API çıkışı daha sonra modele tekrar dahil edilebilir. Böylece daha kapsamlı sorgu yanıtları elde edilebilir. İşlev çağrısı, LLM'lerin gerçek zamanlı bilgilerle ve veritabanları, müşteri ilişkileri yönetimi sistemleri ve belge depoları gibi çeşitli hizmetlerle etkileşim kurmasını sağlayarak alakalı ve bağlamsal yanıtlar sağlama becerilerini geliştirir. Gemini modellerine işlevlerin açıklamalarını sağlayabilirsiniz. Model, bir işlev çağırmanızı ve modelin sorgunuzu işlemesine yardımcı olmak için sonucu geri göndermenizi isteyebilir.

Henüz yapmadıysanız daha fazla bilgi edinmek için İşlev çağrısına giriş bölümüne göz atın.

Kurulum

Python SDK'yı yükleme

Gemini API için Python SDK, google-generativeai paketinde yer alır. Pip kullanarak bağımlılığı yükleyin:

pip install -U -q google-generativeai

Paketleri içe aktar

Gerekli paketleri içe aktarın.

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

API anahtarınızı oluşturma

Gemini API'yi kullanabilmek için önce bir API anahtarı edinmeniz gerekir. Anahtarınız yoksa Google AI Studio'da tek tıklamayla oluşturun.

API anahtarı alma

Colab'de, anahtarı sol paneldeki "🔑" simgesinin altında gizli anahtar yöneticisine ekleyin. API_KEY adını verin.

API anahtarınızı aldıktan sonra SDK'ya iletin. Bunu iki şekilde yapabilirsiniz:

  • Anahtarı, GOOGLE_API_KEY ortam değişkenine yerleştirin (SDK otomatik olarak oradan alır).
  • Anahtarı genai.configure(api_key=...) adlı cihaza verin
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)

İşlev çağrısıyla ilgili temel bilgiler

İşlev çağrısını kullanmak için GenerativeModel oluştururken tools parametresine bir işlev listesi iletin. Model, bir istemi en iyi şekilde yanıtlamak için işleve ihtiyaç duyup duymadığına karar vermek üzere işlev adını, docstring'i, parametreleri ve parametre türü ek açıklamalarını kullanır.

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

Sohbet arayüzü üzerinden işlev çağrılarını kullanmanız önerilir. Bunun nedeni, işlev çağrılarının kullanıcı ile model arasındaki iki yönlü etkileşimi yakalarken doğal olarak çok dönüşlü sohbetlere uymasıdır. Python SDK'sı ChatSession, sohbet geçmişini sizin yerinize işlediğinden sohbetler için harika bir arayüzdür. enable_automatic_function_calling parametresini kullanmak, işlev çağrısını daha da basitleştirir:

chat = model.start_chat(enable_automatic_function_calling=True)

Otomatik işlev çağrısı etkin durumdayken chat.send_message, model tarafından isterse işlevinizi otomatik olarak çağırır.

Görünüşe göre, doğru yanıtı içeren bir metin yanıtı döndürülmüştür:

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

Görüşmenin akışını ve işlev çağrılarının bunlara nasıl entegre edildiğini görmek için sohbet geçmişini inceleyin.

ChatSession.history özelliği, kullanıcı ile Gemini modeli arasındaki görüşmenin kronolojik kaydını depolar. İleti dizisindeki her dönüş, aşağıdaki bilgileri içeren bir glm.Content nesnesiyle temsil edilir:

  • Rol: İçeriğin "kullanıcı"dan mı yoksa "modelden" mi kaynaklandığını tanımlar.
  • Parçalar: İletinin ayrı bileşenlerini temsil eden glm.Part nesnelerinin listesi. Yalnızca metin içeren modelde bu bölümler şunlar olabilir:
    • Metin: Düz kısa mesajlar.
    • İşlev Çağrısı (glm.FunctionCall): Sağlanan bağımsız değişkenlerle belirli bir işlevi yürütmek için modelden gelen istek.
    • İşlev Yanıtı (glm.FunctionResponse): İstenen işlevi yürüttükten sonra kullanıcı tarafından döndürülen sonuç.

Eldiven hesaplamasıyla ilgili önceki örnekte, geçmiş aşağıdaki sırayı gösterir:

  1. Kullanıcı: Toplam eldiven sayısıyla ilgili soruyu sorar.
  2. Model: Çarpma işlevinin faydalı olduğunu belirler ve kullanıcıya bir FunctionCall isteği gönderir.
  3. Kullanıcı: ChatSession, işlevi (ayarlanan enable_automatic_function_calling nedeniyle) otomatik olarak yürütür ve hesaplanan sonucuyla birlikte bir FunctionResponse gönderir.
  4. Model: Nihai yanıtı formüle etmek için işlevin çıkışını kullanır ve bunu bir metin yanıtı olarak sunar.
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.'}
--------------------------------------------------------------------------------

Genel olarak durum diyagramı şöyledir:

Model her zaman metin veya bir FunctionCall ile yanıt verebilir. Model bir FunctionCall gönderirse kullanıcı bir FunctionResponse ile yanıt vermelidir

Model, metin yanıtı döndürmeden önce birden çok işlev çağrısıyla yanıt verebilir ve işlev çağrıları, metin yanıtından önce gelir.

Bu işlemlerin tümü otomatik olarak gerçekleştiriliyor olsa da daha fazla denetime ihtiyacınız varsa şunları yapabilirsiniz:

  • Varsayılan enable_automatic_function_calling=False ayarını değiştirmeyin ve glm.FunctionCall yanıtlarını kendiniz işleyin.
  • Alternatif olarak, sohbet geçmişini yönetmeniz gereken GenerativeModel.generate_content hizmetini de kullanabilirsiniz.

Paralel işlev çağrısı

Yukarıda açıklanan temel işlev çağrısına ek olarak, tek bir turda birden çok işlevi de çağırabilirsiniz. Bu bölümde, paralel işlev çağrısını nasıl kullanabileceğinize dair bir örnek gösterilmektedir.

Araçları tanımlama.

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

Şimdi, belirtilen tüm araçları kullanabilecek bir talimatla modeli çağırın.

# Set the model up with tools.
house_fns = [power_disco_ball, start_music, dim_lights]

model = genai.GenerativeModel(model_name="gemini-1.5-pro-latest", 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)

Yazdırılan sonuçların her biri, modelin istediği tek bir işlev çağrısını yansıtır. Sonuçları geri göndermek için yanıtları istendiği sırayla ekleyin.

# 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 = [
    glm.Part(function_response=glm.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! 🕺💃

(İsteğe bağlı) Düşük düzey erişim

Şemanın python işlevlerinden otomatik olarak ayıklanması her durumda çalışmaz. Örneğin: İç içe yerleştirilmiş bir sözlük nesnesinin alanlarını açıkladığınız durumları işlemez, ancak API bunu destekler. API aşağıdaki türlerin herhangi birini tanımlayabilir:

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

google.ai.generativelanguage istemci kitaplığı, alt düzey türlere erişim sunarak size tam denetim sağlar.

import google.ai.generativelanguage as glm

İlk olarak modelin _tools özelliğine göz atarak modele aktardığınız işlevleri nasıl tanımladığını görebilirsiniz:

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

Bu, API'ye gönderilecek glm.Tool nesnelerin listesini döndürür. Basılı biçim tanıdık değilse, bunun nedeni bunların Google protobuf sınıfları olmasıdır. Her glm.Tool (bu örnekte 1) bir işlevi ve bağımsız değişkenlerini açıklayan bir glm.FunctionDeclarations listesi içerir.

Burada, glm sınıfları kullanılarak yazılmış aynı çarpma işlevine ilişkin bir bildirim bulunmaktadır.

Bu sınıfların yalnızca API'nın işlevini açıkladığını, API'nin bir uygulamasını içermediğini unutmayın. Bu nedenle otomatik işlev çağrısında bu işlev işe yaramaz ancak işlevlerin her zaman uygulanması gerekmez.

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

Aynı şekilde, bunu JSON uyumlu bir nesne olarak tanımlayabilirsiniz:

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

Her iki durumda da bir glm.Tool temsilini veya araç listesini iletirsiniz

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

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

Model, hesap makinesinin multiply işlevini çağıran bir glm.FunctionCall döndürmesinden önce olduğu gibi:

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
]

İşlevi kendiniz yürütün:

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

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

Görüşmeye devam etmek için sonucu modele gönderin:

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

Özet

SDK'da temel işlev çağrısı desteklenir. Sohbet modunun kullanımı, karşılıklı iletişimin doğal yapısı nedeniyle daha kolay olduğunu unutmayın. İşlevleri çağırmaktan ve modelin metin yanıtı üretebilmesi için sonuçları modele geri göndermekten siz sorumlusunuz.