Gemini API: فراخوانی تابع با پایتون

مشاهده در ai.google.dev در Google Colab اجرا شود مشاهده منبع در GitHub

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

برپایی

Python SDK را نصب کنید

Python SDK برای Gemini API در بسته google-generativeai موجود است. وابستگی را با استفاده از pip نصب کنید:

pip install -U -q google-generativeai

بسته های وارداتی

بسته های لازم را وارد کنید.

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 خود را تنظیم کنید

قبل از اینکه بتوانید از Gemini API استفاده کنید، ابتدا باید یک کلید API دریافت کنید. اگر قبلاً یکی ندارید، با یک کلیک در Google AI Studio یک کلید ایجاد کنید.

یک کلید API دریافت کنید

در Colab، کلید را به مدیر مخفی زیر "🔑" در پانل سمت چپ اضافه کنید. نام API_KEY را به آن بدهید.

هنگامی که کلید API را دارید، آن را به SDK منتقل کنید. شما می توانید این کار را به دو صورت انجام دهید:

  • کلید را در متغیر محیطی GOOGLE_API_KEY قرار دهید (SDK به طور خودکار آن را از آنجا دریافت می کند).
  • کلید را به genai.configure(api_key=...) بدهید
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)

مبانی تابع

هنگام ایجاد یک genai.GenerativeModel می توانید لیستی از توابع را به آرگومان tools ارسال کنید.

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

روش پیشنهادی برای استفاده از فراخوانی تابع از طریق رابط چت است. دلیل اصلی این است که FunctionCalls به خوبی در ساختار چند نوبتی چت قرار می گیرد.

chat = model.start_chat(enable_automatic_function_calling=True)

با فعال کردن فراخوانی عملکرد خودکار chat.send_message به طور خودکار تابع شما را در صورت درخواست مدل، فراخوانی می کند.

به نظر می رسد که به سادگی یک پاسخ متنی حاوی پاسخ صحیح را برمی گرداند:

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.'
l10n
57*44
2508

اگر به ChatSession.history نگاه کنید، می توانید توالی رویدادها را ببینید:

  1. شما سوال را ارسال کردید
  2. مدل با glm.FunctionCall پاسخ داد.
  3. genai.ChatSession تابع را به صورت محلی اجرا کرد و مدل را یک glm.FunctionResponse برگرداند.
  4. مدل در پاسخ خود از خروجی تابع استفاده کرد.
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.'}
--------------------------------------------------------------------------------

به طور کلی نمودار حالت به صورت زیر است:

مدل همیشه می تواند با متن یا FunctionCall پاسخ دهد. اگر مدل یک FunctionCall ارسال کند، کاربر باید با یک FunctionResponse پاسخ دهد

این مدل می‌تواند قبل از بازگرداندن یک پاسخ متنی با چندین فراخوانی تابع پاسخ دهد و فراخوانی‌های تابع قبل از پاسخ متنی می‌آیند.

در حالی که همه اینها به صورت خودکار انجام می شد، اگر به کنترل بیشتری نیاز دارید، می توانید:

  • enable_automatic_function_calling=False پیش‌فرض بگذارید و پاسخ‌های glm.FunctionCall را خودتان پردازش کنید.
  • یا از GenerativeModel.generate_content استفاده کنید، جایی که باید سابقه چت را نیز مدیریت کنید.

[اختیاری] دسترسی سطح پایین

استخراج خودکار طرحواره از توابع پایتون در همه موارد کار نمی کند. به عنوان مثال: مواردی را که شما فیلدهای یک دیکشنری-شیء تودرتو را توصیف می‌کنید کنترل نمی‌کند، اما API از این پشتیبانی می‌کند. API قادر است هر یک از انواع زیر را توصیف کند:

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

کتابخانه مشتری google.ai.generativelanguage دسترسی به انواع سطح پایین را فراهم می کند و به شما کنترل کامل می دهد.

import google.ai.generativelanguage as glm

ابتدا به داخل ویژگی _tools مدل نگاه کنید، می توانید ببینید که چگونه تابع(هایی) را که به مدل ارسال کرده اید، توصیف می کند:

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

این لیستی از اشیاء glm.Tool را که به API ارسال می شوند، برمی گرداند. اگر قالب چاپ شده آشنا نیست، به این دلیل است که این کلاس‌های پروتوباف گوگل هستند. هر glm.Tool (در این مورد 1) حاوی لیستی از glm.FunctionDeclarations است که یک تابع و آرگومان های آن را توصیف می کند.

در اینجا یک اعلان برای همان تابع ضرب نوشته شده با استفاده از کلاس های glm است.

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

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

به طور معادل، می توانید این را به عنوان یک شی سازگار با 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']} }]}
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"
  }
}

در هر صورت، شما نمایشی از glm.Tool یا لیستی از ابزارها را به آن ارسال می کنید

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

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

مانند قبل از اینکه مدل یک glm.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(
    glm.Content(
    parts=[glm.Part(
        function_response = glm.FunctionResponse(
          name='multiply',
          response={'result': result}))]))

خلاصه

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