מדריך להפעלת פונקציות

הפעלת פונקציות מאפשרת לקבל פלט של נתונים מובְנים בקלות רבה יותר גנרטיביים. לאחר מכן תוכלו להשתמש בפלט הזה כדי לקרוא לממשקי API אחרים ולהחזיר את נתוני התגובה הרלוונטיים למודל. במילים אחרות, קריאה לפונקציות לחבר מודלים גנרטיביים למערכות חיצוניות, כדי שהתוכן שנוצר כוללת את המידע העדכני והמדויק ביותר.

אתם יכולים להוסיף למודלים של Gemini תיאורים של פונקציות. אלה פונקציות שכותבים בשפת האפליקציה (כלומר, הן לא Google Cloud Functions). יכול להיות שהמודל יבקש מכם להפעיל פונקציה ולשלוח חזרה התוצאה כדי לעזור למודל לטפל בשאילתה.

אם עדיין לא עשיתם זאת, כדאי לעיין מבוא לקריאת פונקציות כדי ללמוד נוספים. אפשר גם כדאי לנסות את התכונה הזאת Google Colab או לקרוא את הקוד לדוגמה מאגר Gemini API Cookbook.

דוגמה לממשק API לבקרת תאורה

נניח שיש לכם מערכת בסיסית לבקרת תאורה עם תוכנת אפליקציה ממשק API ורוצים לאפשר למשתמשים לשלוט באורות באמצעות בקשות טקסט. אפשר להשתמש בתכונה 'קריאת פונקציות' כדי לפרש תאורה לשנות בקשות ממשתמשים ולתרגם אותן לקריאות ל-API כדי להגדיר את התאורה ערכים. מערכת הבקרה ההיפותטית הזו מאפשרת לשלוט בהירות של התאורה ובטמפרטורת הצבע שלה, שמוגדרות כשני פרמטרים נפרדים:

פרמטר סוג נדרש תיאור
brightness number כן רמת התאורה מ-0 עד 100. אפס כבוי ו-100 מציג בהירות מלאה.
colorTemperature מחרוזת כן טמפרטורת הצבע של גוף התאורה. הערכים האפשריים הם daylight,‏ cool או warm.

כדי לפשט את העניין, מערכת התאורה הדמיונית הזו כוללת רק נורית אחת, כך שהמשתמש לא צריך לציין חדר או מיקום. הנה דוגמה לבקשת JSON אפשר לשלוח לממשק ה-API של בקרת התאורה כדי לשנות את עוצמת התאורה ל-50% באמצעות טמפרטורת הצבע של אור היום:

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

במדריך הזה תלמדו איך להגדיר קריאה לפונקציה של Gemini API כדי לפרש בקשות של משתמשים לגבי התאורה ולמפות אותן להגדרות API, כדי לשלוט בערכי הבהירות וטמפרטורת הצבע של התאורה.

לפני שמתחילים: מגדירים את הפרויקט ואת מפתח ה-API

לפני שמפעילים את Gemini API, צריך להגדיר את הפרויקט ולהגדיר את מפתח ה-API.

הגדרה של פונקציית API

יוצרים פונקציה ששולחת בקשת API. צריך להגדיר את הפונקציה הזו בקוד של האפליקציה, אבל היא יכולה להפעיל שירותים או ממשקי API מחוץ לאפליקציה. ממשק ה-API של Gemini לא קורא לפונקציה הזו ישירות, כך שתוכלו לקבוע איך ומתי הפונקציה הזו תתבצע באמצעות קוד האפליקציה. לצורך הדגמה, המדריך הזה מגדיר פונקציית API מדומה מחזירה רק את ערכי התאורה המבוקשים:

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
    }

כשיוצרים פונקציה לשימוש בקריאה לפונקציה על ידי המודל, צריך לכלול כמה שיותר פרטים בפונקציה ובפרמטר תיאורים. המודל הגנרטיבי משתמש במידע הזה כדי לקבוע איזו פונקציה לבחור ואיך לספק ערכים לפרמטרים בקריאה לפונקציה.

הכרזה על פונקציות במהלך האינטוליזציה של המודל

אם רוצים להשתמש בקריאות לפונקציות במודל, צריך להצהיר על כאשר מאתחלים את אובייקט המודל. כדי להצהיר על פונקציות, מגדירים את הפרמטר tools של המודל:

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

יצירת בקשה להפעלת פונקציה

אחרי שמאתחלים את המודל עם הצהרות הפונקציה, אפשר להציג את המודל עם הפונקציה המוגדרת. צריך להשתמש בקריאה לפונקציות באמצעות הנחיות בצ'אט (sendMessage()), מפני ששיחות עם פונקציות בדרך כלל מניבות תועלת באמצעות ההקשר של ההנחיות והתשובות הקודמות.

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

ערכת ה-SDK של Python ChatSession אובייקט שמפשט את ניהול השיחות בצ'אט על ידי טיפול בהיסטוריית השיחות עבורך. אפשר להשתמש ב-enable_automatic_function_calling כדי לקבל את ה-SDK לקרוא באופן אוטומטי לפונקציה.

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

קריאה לפונקציה מקבילה

בנוסף לפונקציות הבסיסיות שמתוארות למעלה, אפשר גם להפעיל מספר פונקציות בפנייה אחת. בקטע הזה מוצגת דוגמה לשימוש בקריאה מקבילה לפונקציות.

להגדיר את הכלים.

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

עכשיו קוראים למודל הוראה שיכולה להשתמש בכל הכלים שצוינו.

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

כל אחת מהתוצאות המודפסות משקפת קריאה לפונקציה אחת שהמודל ביקש. כדי לשלוח את התוצאות בחזרה, צריך לכלול את התשובות באותו סדר שבו הן התבקשו.

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

מיפוי סוגי הנתונים של הקריאה לפונקציה

חילוץ אוטומטי של סכימה מפונקציות Python לא פועל בכל המקרים. לדוגמה: הוא לא מטפל במקרים שבהם מתארים את השדות של אובייקט מילון בתצוגת עץ, אבל ה-API כן תומך בכך. ה-API יכול לתאר כל אחד מהסוגים הבאים:

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

ספריית הלקוח google.ai.generativelanguage מספקת גישה לסוגים ברמה הנמוכה שמספקים שליטה מלאה.

קודם נעיף מבט במאפיין _tools של המודל, כדי לראות איך הוא מתאר את הפונקציות שהעברתם למודל:

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

הפונקציה מחזירה את רשימת האובייקטים מסוג genai.protos.Tool שיישלחו ל-API. אם הפורמט המודפס לא מוכר לכם, הסיבה לכך היא שהתוויות Google לסוגים שונים של אב-טיפוס. כל genai.protos.Tool (1 במקרה הזה) מכיל רשימה של genai.protos.FunctionDeclarations, שמתארים פונקציה ואת הארגומנטים שלה.

זוהי הצהרה לגבי אותה פונקציית הכפלה שנכתבו באמצעות הפונקציה genai.protos כיתות. חשוב לזכור שהכיתות האלה מתארות רק את הפונקציה של ה-API, הן לא כוללות הטמעה שלו. לכן, השימוש באפשרות הזו לא עובד עם קריאה אוטומטית לפונקציות, אבל לא תמיד צריך להטמיע פונקציות.

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

אפשר גם לתאר את זה כאובייקט תואם ל-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"
  }
}

בכל מקרה, עליך להעביר ייצוג של genai.protos.Tool או רשימת כלים כדי

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

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

כמו קודם, המודל מחזיר genai.protos.FunctionCall שמפעיל את הפונקציה multiply של המחשבון:

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
]

מפעילים את הפונקציה בעצמכם:

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

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

כדי להמשיך בשיחה, שולחים את התוצאה למודל:

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