آموزش فراخوانی توابع

فراخوانی تابع، دریافت خروجی داده های ساختاریافته از مدل های تولیدی را برای شما آسان تر می کند. سپس می توانید از این خروجی ها برای فراخوانی API های دیگر و برگرداندن داده های پاسخ مربوطه به مدل استفاده کنید. به عبارت دیگر، فراخوانی تابع به شما کمک می کند تا مدل های تولیدی را به سیستم های خارجی متصل کنید تا محتوای تولید شده شامل به روزترین و دقیق ترین اطلاعات باشد.

می توانید مدل های Gemini را با توضیحاتی در مورد عملکردها ارائه دهید. اینها توابعی هستند که شما به زبان برنامه خود می نویسید (یعنی توابع Google Cloud نیستند). مدل ممکن است از شما بخواهد که یک تابع را فراخوانی کنید و نتیجه را برای کمک به مدل در رسیدگی به درخواست شما ارسال کنید.

اگر قبلاً این کار را نکرده‌اید، برای کسب اطلاعات بیشتر ، مقدمه فراخوانی تابع را بررسی کنید. همچنین می توانید این ویژگی را در Google Colab امتحان کنید یا کد نمونه را در مخزن Gemini API Cookbook مشاهده کنید.

API مثال برای کنترل روشنایی

تصور کنید یک سیستم کنترل روشنایی اولیه با یک رابط برنامه نویسی کاربردی (API) دارید و می خواهید به کاربران اجازه دهید تا از طریق درخواست های متنی ساده، چراغ ها را کنترل کنند. می‌توانید از ویژگی فراخوانی تابع برای تفسیر درخواست‌های تغییر نور از سوی کاربران و ترجمه آنها به فراخوان‌های API برای تنظیم مقادیر نور استفاده کنید. این سیستم کنترل روشنایی فرضی به شما امکان می دهد روشنایی نور و دمای رنگ آن را کنترل کنید که به عنوان دو پارامتر جداگانه تعریف می شود:

پارامتر تایپ کنید مورد نیاز توضیحات
brightness شماره بله سطح نور از 0 تا 100. صفر خاموش است و 100 روشنایی کامل است.
colorTemperature رشته بله دمای رنگ دستگاه نور که می تواند daylight ، cool یا warm باشد.

برای سادگی، این سیستم نورپردازی خیالی تنها یک نور دارد، بنابراین کاربر مجبور نیست اتاق یا مکان را مشخص کند. در اینجا نمونه ای از درخواست JSON است که می توانید برای تغییر سطح نور با استفاده از دمای رنگ نور روز به API کنترل روشنایی ارسال کنید:

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

این آموزش به شما نشان می‌دهد که چگونه یک Function Call را برای Gemini API تنظیم کنید تا درخواست‌های روشنایی کاربران را تفسیر کند و آنها را به تنظیمات API برای کنترل مقدار روشنایی و دمای رنگ نور تنظیم کنید.

قبل از شروع: پروژه و کلید API خود را تنظیم کنید

قبل از فراخوانی Gemini API، باید پروژه خود را راه اندازی کرده و کلید API خود را پیکربندی کنید.

یک تابع API را تعریف کنید

تابعی بسازید که درخواست API می دهد. این تابع باید در کد برنامه شما تعریف شود، اما می تواند خدمات یا API های خارج از برنامه شما را فراخوانی کند. Gemini API این تابع را مستقیماً فراخوانی نمی کند، بنابراین می توانید نحوه و زمان اجرای این تابع را از طریق کد برنامه خود کنترل کنید. برای اهداف نمایشی، این آموزش یک تابع 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

شی ChatSession Python SDK مدیریت جلسات چت را با مدیریت تاریخچه مکالمه برای شما ساده می کند. می توانید از 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! 🕺💃

نگاشت نوع داده فراخوانی تابع

استخراج خودکار طرحواره از توابع پایتون در همه موارد کار نمی کند. به عنوان مثال: مواردی را که شما فیلدهای یک دیکشنری-شیء تودرتو را توصیف می‌کنید کنترل نمی‌کند، اما 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 ارسال می شوند، برمی گرداند. اگر قالب چاپ شده آشنا نیست، به این دلیل است که این کلاس‌های پروتوباف گوگل هستند. هر 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}))]))