1. بررسی اجمالی
فراخوانی تابع در Gemini چیست؟
Vertex AI Gemini API خانوادهای از مدلهای هوش مصنوعی تولید شده توسط Google DeepMind است که برای موارد استفاده چندوجهی طراحی شده است. فراخوانی تابع یکی از ویژگیهای مدلهای Gemini است که دریافت خروجی دادههای ساختاریافته از مدلهای تولیدی را برای توسعهدهندگان آسانتر میکند.
سپس توسعهدهندگان میتوانند از این خروجیها برای فراخوانی سایر APIها و برگرداندن دادههای پاسخ مربوطه به مدل استفاده کنند. به عبارت دیگر، فراخوانی تابع به شما کمک می کند تا مدل های تولیدی خود را به سیستم های خارجی متصل کنید تا محتوای تولید شده شامل به روزترین و دقیق ترین اطلاعات باشد.
فراخوانی تابع چگونه کار می کند
توابع با استفاده از اعلان های تابع توصیف می شوند، که به مدل مولد کمک می کند تا هدف و پارامترهای یک تابع را درک کند. پس از اینکه اعلانهای تابع در یک پرس و جو را به یک مدل تولیدی منتقل کردید، مدل یک شی ساختاریافته را برمیگرداند که شامل نام توابع مرتبط و آرگومانهای آنها بر اساس کوئری کاربر است. توجه داشته باشید که با فراخوانی تابع، مدل در واقع تابع را فراخوانی نمی کند. در عوض، میتوانید از تابع و پارامترهای بازگشتی برای فراخوانی تابع در هر زبان، کتابخانه یا چارچوبی که میخواهید استفاده کنید!
چیزی که خواهی ساخت
در این کد لبه، شما یک خط لوله AI مولد با Vertex AI Gemini API و Python خواهید ساخت. با استفاده از برنامه شما، کاربران می توانند در مورد نرخ ارز سوال کنند و سیستم آخرین داده ها را از یک API خارجی دریافت می کند و با پاسخ به کاربر پاسخ می دهد.
چیزی که یاد خواهید گرفت
- نحوه تعامل با مدل Gemini با استفاده از کتابخانه مشتری پایتون
- نحوه تعریف یک اعلان تابع و ثبت آن به عنوان یک ابزار
- چگونه Gemini را فراخوانی کنیم و پاسخ فراخوانی تابع را دریافت کنیم
- چگونه پاسخ تابع را به Gemini برگردانیم و به کاربر پاسخ دهیم
آنچه شما نیاز دارید
- یک پروژه Google Cloud
- مرورگری مانند کروم
- یک محیط توسعه پایتون مانند Colab یا Colab Enterprise
2. راه اندازی و الزامات
قبل از اینکه بتوانید از فراخوانی تابع در Gemini استفاده کنید، باید Vertex AI API را فعال کنید و آخرین نسخه کتابخانه کلاینت Vertex AI Python را نصب کنید.
Vertex AI API را فعال کنید
برای فعال کردن Vertex AI API، مراحل زیر را دنبال کنید:
- در مرورگر خود، به صفحه جزئیات خدمات Vertex AI API بروید.
- روی دکمه Enable کلیک کنید تا Vertex AI API در پروژه Google Cloud شما فعال شود.
کتابخانه کلاینت پایتون را برای Vertex AI نصب کنید
برای نصب کتابخانه های کلاینت پایتون برای Vertex AI، مراحل زیر را دنبال کنید:
- یک ترمینال در محیط توسعه خود باز کنید.
- بررسی کنید که یک محیط توسعه پایتون معتبر دارید و در صورت نیاز به این دستورالعمل ها مراجعه کنید.
- دستور زیر را برای نصب کتابخانه کلاینت پایتون برای Vertex AI اجرا کنید:
pip install --upgrade google-cloud-aiplatform
- اگر در یک محیط نوت بوک در حال اجرا هستید، ممکن است لازم باشد زمان اجرا/هسته خود را مجددا راه اندازی کنید تا از بسته های تازه نصب شده استفاده کنید.
اکنون آماده استفاده از Vertex AI API هستید!
3. مشکل را درک کنید
آیا تا به حال با یک مدل زبان بزرگ یا مدل هوش مصنوعی مولد تعامل داشتهاید و از آن در مورد اطلاعات لحظهای یا فعلی سؤال کردهاید، فقط برای اینکه پاسخی با اطلاعات قدیمی یا اطلاعات نادرست دریافت کنید؟
بیایید آن را امتحان کنیم! ابتدا بسته های پایتون مربوطه را وارد کرده و مدل Gemini را مقداردهی اولیه می کنیم. می توانید کد زیر را در یک محیط توسعه پایتون مانند Colab یا Colab Enterprise و با نصب آخرین نسخه Vertex AI SDK برای پایتون اجرا کنید:
import vertexai
from vertexai.generative_models import GenerativeModel
model = GenerativeModel("gemini-1.5-pro-001")
حالا بیایید یک سوال در مورد نرخ ارزهای مختلف امروز بپرسیم:
response = model.generate_content(
"What's the exchange rate for euros to dollars today?"
)
print(response.text)
این مدل باید یک پاسخ محدود یا قدیمی مشابه برای شما ایجاد کند:
As an AI language model, I don't have access to real-time currency exchange rates. However, as of my last update in September 2021, the approximate exchange rate between euros (EUR) and US dollars (USD) was: 1 EUR ≈ 1.18 USD Please note that currency exchange rates constantly fluctuate and can vary depending on various factors such as economic conditions, supply and demand, political events, and more. To obtain the most up-to-date and accurate exchange rate, I recommend using a reliable currency converter or financial website that provides live rates. [...]
اگر یک کاربر نهایی این نوع پاسخ را دریافت میکرد، باید زمینهها را تغییر دهد تا ارزهای مورد علاقه خود را جستجو کند، آخرین نرخ ارز را دریافت کند و هر تبدیلی را به تنهایی انجام دهد.
در حالت ایده آل، یک خط لوله مدل مولد می تواند برخی یا همه این وظایف را برای کاربر انجام دهد. در بخش بعدی، راهحلهای رایج برای دریافت پاسخهای ساختاریافته از مدلهای تولیدی را امتحان خواهید کرد تا بتوانید سیستمهای خارجی را فراخوانی کنید.
4. راه حل های رایج را امتحان کنید
هنگام کار با مدلهای مولد در سناریوهایی که به اطلاعات یا دادههای بهروز از منابع خارجی نیاز دارید، میتوانید یک API خارجی را فراخوانی کنید و سپس نتایج را به مدل مولد برگردانید تا در پاسخ به آن استفاده کند.
قبل از فراخوانی یک سیستم خارجی، باید تابع مناسب برای استفاده را تعیین کنید، پارامترهای مربوطه را از کاربر استخراج کنید، و پارامترها را در یک شی داده ساخت یافته قرار دهید. این معمولاً شامل مهندسی سریع جامع برای وادار کردن مدل مولد به خروجی داده های ساخت یافته معتبر است.
بیایید دوباره سوالی را که در بخش قبل پرسیدیم بررسی کنیم و چند دستورالعمل اضافی برای مدل اضافه کنیم. درخواست زیر را به مدل Gemini ارسال کنید:
user_prompt = "What's the exchange rate from euros to US dollars today?"
response = model.generate_content("""
Your task is to extract parameters from the user's input and return it as a
structured JSON payload. The user will ask about the exchange rate and which
currency they are converting from and converting to.
User input: {user_prompt}
Please extract the currencies as parameters and put them in a JSON object.
""".format(user_prompt=user_prompt))
print(response.text)
این نتایج پاسخ متنی زیر است که JSON معتبر نیست و کار با آن برای ما دشوار خواهد بود:
```json { "currency_from": "euros", "currency_to": "US dollars" } ```
به طور خاص، اولین و آخرین خطوط پاسخ متنی شامل بکتیکهایی برای محدود کردن بلوک کد است، خط اول شامل یک مشخصکننده زبان است، و مقادیر موجود در شی JSON اختصارات ارز سه حرفی استاندارد نیستند که یک API تبادل ارز میتواند انجام دهد. به عنوان پارامترهای ورودی انتظار می رود.
میتوانیم سعی کنیم از Python برای پردازش این متن به JSON معتبر و یک فرهنگ لغت استفاده کنیم، دستورالعملهای بیشتری را به دستور اضافه کنیم، یک یا چند نمونه از خروجی مورد نظر را ارائه دهیم، مدل را تنظیم دقیق کنیم، یا یک تماس دیگر با مدل مولد درخواست کنیم. آن را برای پاک کردن JSON.
اما راه قطعی تری وجود دارد! بیایید یاد بگیریم که چگونه از فراخوانی تابع در Gemini برای جستجوی اطلاعات در سرویسهای خارجی و بازگرداندن پاسخهای مرتبط به کاربران نهایی استفاده کنیم.
5. فراخوانی تابع چگونه کار می کند
قبل از اینکه استخراج پارامتر و فراخوانی تابع را شروع کنیم، بیایید مراحل فراخوانی تابع و اینکه کدام مؤلفه ها در زمان اجرا استفاده می شوند را مرور کنیم.
ورودی کاربر به Gemini API
درخواست کاربر به Gemini API ارسال میشود و در آن فراخوانی API به مدل Gemini، توسعهدهنده یک یا چند اعلان تابع را در یک ابزار تعریف کرده است تا مدل Gemini بداند کدام توابع را میتواند فراخوانی کند و چگونه آنها را فراخوانی کند. .
Gemini API یک تماس تابع را برمیگرداند
بر اساس محتوای ورودی و درخواست کاربر، Gemini یک پاسخ فراخوانی تابع را با دادههای ساختاریافته که شامل نام تابع مورد نظر و پارامترهای مربوطه برای استفاده است، برمیگرداند.
یک درخواست API ایجاد کنید
سپس، از نام تابع و پارامترها برای درخواست API برای بازیابی اطلاعات از یک سیستم خارجی یا API استفاده خواهید کرد. این درخواست و پاسخ API توسط توسعه دهنده در کد برنامه پیاده سازی می شود و خارج از محدوده Gemini API و SDK اتفاق می افتد. برای مثال، ممکن است از کتابخانه requests
در پایتون برای فراخوانی REST API و دریافت پاسخ JSON استفاده کنید. یا می توانید تابع را با استفاده از رویکرد دلخواه و کتابخانه مشتری فراخوانی کنید.
پاسخ API را به Gemini برگردانید
در نهایت، پاسخ API را به مدل Gemini برمیگردانید تا بتواند پاسخی به درخواست اولیه کاربر نهایی ایجاد کند یا اگر مدل Gemini تشخیص دهد که به اطلاعات اضافی نیاز دارد، پاسخ دیگری را فراخوانی کند.
6. API خود را انتخاب کنید
اکنون که جریان کلی و مراحل خاص فراخوانی تابع را درک کرده اید، یک خط لوله هوش مصنوعی مولد برای دریافت آخرین نرخ های مبادله ارز ایجاد خواهید کرد. ابتدا باید API را که می خواهیم به عنوان منبع اطلاعات استفاده کنیم، انتخاب کنیم.
برای برنامه مبادله ارز خود، از REST API در https://www.frankfurter.app/ استفاده می کنیم تا آخرین اطلاعات را در مورد نرخ ارز جهانی دریافت کنیم.
برای تعامل با این API REST، ممکن است یک تماس REST API با requests
در Python به صورت زیر برقرار کنیم:
import requests
url = "https://api.frankfurter.app/latest"
response = requests.get(url)
response.text
یا یک درخواست cURL
مانند:
curl https://api.frankfurter.app/latest
که پاسخی شبیه به:
{ "amount": 1, "base": "EUR", "date": "2023-12-20", "rates": { "AUD": 1.6186, "BGN": 1.9558, "BRL": 5.3287, "CAD": 1.4609, "CHF": 0.946, "CNY": 7.8121, "CZK": 24.538, "DKK": 7.4565, "GBP": 0.86555, "HKD": 8.5439, "HUF": 385.23, "IDR": 16994, "ILS": 3.9983, "INR": 91.06, "ISK": 150.3, "JPY": 157.12, "KRW": 1425.62, "MXN": 18.6867, "MYR": 5.0977, "NOK": 11.2895, "NZD": 1.7421, "PHP": 60.991, "PLN": 4.3413, "RON": 4.9699, "SEK": 11.129, "SGD": 1.4562, "THB": 38.252, "TRY": 31.883, "USD": 1.0944, "ZAR": 20.111 } }
از آنجایی که فراخوانی تابع در Gemini در واقع API خارجی را برای شما فراخوانی نمی کند، چنین محدودیتی در مورد نوع API که استفاده می کنید وجود ندارد! می توانید از یک سرویس Cloud Run، یک تابع Cloud، یک درخواست API به یک سرویس Google Cloud یا هر API خارجی REST استفاده کنید.
7. یک تابع و ابزار را تعریف کنید
اکنون که یک REST API را برای استفاده انتخاب کرده اید، اکنون می توانیم مشخصات API را تعریف کرده و عملکرد را در یک ابزار ثبت کنیم.
مطمئن شوید که آخرین نسخه Vertex AI SDK برای پایتون را نصب کرده اید.
سپس، ماژول های لازم را از Python SDK وارد کرده و مدل Gemini را مقداردهی اولیه کنید:
from vertexai.generative_models import (
Content,
FunctionDeclaration,
GenerativeModel,
Part,
Tool,
)
model = GenerativeModel("gemini-1.5-pro-001")
با مراجعه به REST API در https://api.frankfurter.app/ ، می بینیم که پارامترهای ورودی زیر را می پذیرد:
پارامتر | تایپ کنید | توضیحات |
| رشته | ارز برای تبدیل |
| رشته | ارز برای تبدیل |
| رشته | تاریخ دریافت نرخ ارز |
با استفاده از این پارامترها، مشخصات جزئی OpenAPI برای این API REST در قالب YAML به نظر می رسد:
openapi: 3.0.0
info:
title: Frankfurter Exchange Rate API
description: This API provides current and historical exchange rates
version: 1.0.0
servers:
- url: https://api.frankfurter.app
paths:
/{date}:
get:
summary: Get the latest currency exchange rates.
parameters:
- name: date
in: path
description: Get currency rates for a specific date or 'latest' if a date is not specified
required: true
schema:
type: string
- name: from
in: query
description: The currency to convert from.
required: true
schema:
type: string
- name: to
in: query
description: The currency to convert to.
schema:
type: string
اکنون، اجازه دهید این را به عنوان یک FunctionDeclaration
با استفاده از Python SDK برای Gemini ثبت کنیم:
get_exchange_rate_func = FunctionDeclaration(
name="get_exchange_rate",
description="Get the exchange rate for currencies between countries",
parameters={
"type": "object",
"properties": {
"currency_date": {
"type": "string",
"description": "A date that must always be in YYYY-MM-DD format or the value 'latest' if a time period is not specified"
},
"currency_from": {
"type": "string",
"description": "The currency to convert from in ISO 4217 format"
},
"currency_to": {
"type": "string",
"description": "The currency to convert to in ISO 4217 format"
}
},
"required": [
"currency_from",
"currency_date",
]
},
)
مطمئن شوید که تا حد امکان از جزئیات در توضیحات تابع و پارامتر استفاده کنید زیرا مدل تولیدی از این اطلاعات برای تعیین اینکه کدام تابع را انتخاب کند و چگونه پارامترها را در فراخوانی تابع پر کند استفاده می کند.
در نهایت، Tool
تعریف میکنید که شامل اعلان تابع است:
exchange_rate_tool = Tool(
function_declarations=[get_exchange_rate_func],
)
در اینجا، شما از یک اعلان تابع در یک ابزار استفاده می کنید، اما توجه داشته باشید که می توانید یک یا چند اعلان تابع را در یک ابزار ثبت کنید، و مدل تابع مناسب را برای استفاده در زمان اجرا انتخاب می کند. برای جزئیات بیشتر درباره FunctionDeclaration
، Tool
و کلاس های مرتبط در Gemini SDK برای Python، به مستندات مربوط به فراخوانی تابع در Gemini API مراجعه کنید.
شما پیکربندی تعاریف عملکرد و ابزار خود را تکمیل کرده اید. در بخش بعدی، مدل مولد را با این ابزار فراخوانی میکنیم و یک تابع فراخوانی میکنیم که میتوانیم از آن برای فراخوانی REST API استفاده کنیم.
8. یک فراخوانی تابع ایجاد کنید
اکنون می توانید مدل مولد را درخواست کنید و tool
را که تعریف کرده اید در آن قرار دهید:
prompt = """What is the exchange rate from Australian dollars to Swedish krona?
How much is 500 Australian dollars worth in Swedish krona?"""
response = model.generate_content(
prompt,
tools=[exchange_rate_tool],
)
بیایید نگاهی به شی پاسخ بیندازیم:
print(response.candidates[0].content) role: "model" parts { function_call { name: "get_exchange_rate" args { fields { key: "currency_to" value { string_value: "SEK" } } fields { key: "currency_from" value { string_value: "AUD" } } fields { key: "currency_date" value { string_value: "latest" } } } } }
به نظر می رسد که مدل یک تابع موجود را انتخاب کرده و یک تابع را برای تابع get_exchange_rate
همراه با پارامترها برمی گرداند. و پارامترها در فرمت صحیحی هستند که ما می خواستیم. هورا برای دریافت پاسخ های ساختاریافته از مدل های مولد!
در بخش بعدی، از اطلاعات موجود در پاسخ برای درخواست API استفاده خواهید کرد.
9. درخواست API داشته باشید
به یاد داشته باشید که فراخوانی تابع در Gemini در واقع فراخوانی API خارجی را برای شما انجام نمی دهد. در عوض، شما آزاد هستید که از هر زبان، کتابخانه یا چارچوبی که می خواهید استفاده کنید!
در اینجا از کتابخانه requests
در پایتون برای فراخوانی نرخ ارز REST API استفاده خواهید کرد.
بیایید پاسخ را در یک فرهنگ لغت پایتون باز کنیم:
params = {}
for key, value in response.candidates[0].content.parts[0].function_call.args.items():
params[key[9:]] = value
params
اکنون می توانیم requests
یا هر روش دیگری را فراخوانی کنیم:
import requests
url = f"https://api.frankfurter.app/{params['date']}"
api_response = requests.get(url, params=params)
api_response.text
که منجر به پاسخی مشابه می شود:
'{"amount":1.0,"base":"AUD","date":"2024-01-16","rates":{"SEK":6.8682}}'
و ما پاسخ خود را از REST API، با آخرین اطلاعات نرخ ارز از امروز داریم. در بخش بعدی، این اطلاعات را به مدل برمیگردانیم تا بتواند پاسخ مناسبی را برای کاربر ایجاد کند.
10. پاسخ ایجاد کنید
در نهایت، اجازه دهید با بازگرداندن پاسخ تابع به مدل در نوبت مکالمه بعدی، یک پاسخ برای کاربر ایجاد کنیم:
response = model.generate_content(
[
Content(role="user", parts=[
Part.from_text(prompt + """Give your answer in steps with lots of detail
and context, including the exchange rate and date."""),
]),
Content(role="function", parts=[
Part.from_dict({
"function_call": {
"name": "get_exchange_rate",
}
})
]),
Content(role="function", parts=[
Part.from_function_response(
name="get_exchange_rate",
response={
"content": api_response.text,
}
)
]),
],
tools=[exchange_rate_tool],
)
response.candidates[0].content.parts[0].text
هنگامی که پاسخ تابع را به مدل برگردانیم، به درخواست کاربر به همراه اطلاعات مربوطه از پاسخ API پاسخ خواهد داد.
The exchange rate from Australian dollars to Swedish krona on January 16, 2024, is 1 Australian dollar is equal to 6.8663 Swedish krona. So, 500 Australian dollars would be worth 500 * 6.8663 = 3,433.15 Swedish krona.
11. نمونه کد کامل را مشاهده کنید
در این مرحله، میتوانید کد پایتون خود را با استفاده از یک سرویس Cloud Run، یک تابع Cloud یا سرویس Cloud دیگری در یک API پشتیبان قرار دهید و یک برنامه frontend را مستقر کنید که از این API backend برای انجام کوئریهای مدل و فراخوانیهای API استفاده میکند.
در اینجا نمونه کد کامل برای راه حل نهایی ما آمده است:
import requests
from vertexai.generative_models import (
Content,
FunctionDeclaration,
GenerativeModel,
Part,
Tool,
)
model = GenerativeModel("gemini-1.5-pro-001")
get_exchange_rate_func = FunctionDeclaration(
name="get_exchange_rate",
description="Get the exchange rate for currencies between countries",
parameters={
"type": "object",
"properties": {
"currency_date": {
"type": "string",
"description": "A date that must always be in YYYY-MM-DD format or the value 'latest' if a time period is not specified"
},
"currency_from": {
"type": "string",
"description": "The currency to convert from in ISO 4217 format"
},
"currency_to": {
"type": "string",
"description": "The currency to convert to in ISO 4217 format"
}
},
"required": [
"currency_from",
"currency_date",
]
},
)
exchange_rate_tool = Tool(
function_declarations=[get_exchange_rate_func],
)
prompt = """What is the exchange rate from Australian dollars to Swedish krona?
How much is 500 Australian dollars worth in Swedish krona?"""
response = model.generate_content(
prompt,
tools=[exchange_rate_tool],
)
response.candidates[0].content
params = {}
for key, value in response.candidates[0].content.parts[0].function_call.args.items():
params[key[9:]] = value
params
import requests
url = f"https://api.frankfurter.app/{params['date']}"
api_response = requests.get(url, params=params)
api_response.text
response = model.generate_content(
[
Content(role="user", parts=[
Part.from_text(prompt + """Give your answer in steps with lots of detail
and context, including the exchange rate and date."""),
]),
Content(role="function", parts=[
Part.from_dict({
"function_call": {
"name": "get_exchange_rate",
}
})
]),
Content(role="function", parts=[
Part.from_function_response(
name="get_exchange_rate",
response={
"content": api_response.text,
}
)
]),
],
tools=[exchange_rate_tool],
)
response.candidates[0].content.parts[0].text
در این پیاده سازی، ما از دو درخواست برای مدل مولد استفاده کردیم: یک درخواست برای ایجاد فراخوانی تابع و درخواست دیگر برای برگرداندن پاسخ تابع. توجه داشته باشید که این تنها یکی از روشهای مدیریت فراخوانی تابع و پاسخهای تابع با Gemini است. همچنین میتوانید برای دریافت اطلاعات بیشتر برای درخواست خود، فراخوانیهای تابع اضافی انجام دهید یا از فراخوانی تابع با روشهای چت و ناهمزمان استفاده کنید.
برای نمونه کدهای اضافی، به دفترچه نمونه برای فراخوانی تابع در Gemini مراجعه کنید.
12. تبریک می گویم
با استفاده از فراخوانی تابع در Gemini، شما با موفقیت یک خط لوله هوش مصنوعی مولد ساخته اید که با Vertex AI Gemini API و Python استفاده می کند! کاربران می توانند در مورد نرخ ارز بپرسند و سیستم آخرین داده ها را از یک API خارجی دریافت می کند و با پاسخ پاسخ می دهد.
با توجه به درخواست کاربر نهایی، تابعی که در Gemini فراخوانی میکند، از انتخاب تابع مناسب، استخراج پارامترها از اعلان و برگرداندن یک شی داده ساختاریافته برای شما برای برقراری تماس API خارجی مراقبت میکند.
طراحی فراخوانی تابع در Gemini در نظر گرفته شده است تا بهترین های هر دو جهان را برای استخراج قطعی پارامترها به شما ارائه دهد، در حالی که خلاصه سازی و ایجاد محتوا را به مدل تولیدی واگذار می کند. به راحتی می توانید سایر API ها و درخواست های موجود در خط لوله خود را امتحان کنید و سایر عملکردهای موجود مربوط به Vertex AI Gemini API را بررسی کنید.
پاک کردن
برای جلوگیری از تحمیل هزینه به حساب Google Cloud خود برای منابع استفاده شده در این کد لبه، می توانید پاکسازی زیر را انجام دهید:
- برای جلوگیری از هزینه های غیر ضروری Google Cloud، از کنسول Google Cloud برای حذف پروژه خود در صورت عدم نیاز استفاده کنید.
- اگر میخواهید APIهای Vertex AI را غیرفعال کنید، به صفحه جزئیات خدمات Vertex AI API بروید و روی Disable API کلیک کنید و تأیید کنید.
بیشتر بدانید
با این راهنماها و منابع به یادگیری در مورد هوش مصنوعی مکالمه و هوش مصنوعی مولد ادامه دهید:
- مروری بر مدل های جمینی
- اسناد فراخوانی تابع در Gemini
- نمونه نوت بوک برای فراخوانی تابع در Gemini
- نمونه دفترچه یادداشت برای Gemini
- هوش مصنوعی مولد در Google Cloud
مجوز
این اثر تحت مجوز Creative Commons Attribution 2.0 Generic مجوز دارد.