استفاده از یک مدل زبانی از طریق API در عمل، صرفاً ارسال یک پیام و دریافت پاسخ آن است. با این حال، آشنایی با چند مفهوم پایه به شما کمک میکند تا از همان اولین فراخوانی، تسلط کافی بر کار داشته باشید. در ادامه این مفاهیم را با هم مرور میکنیم.
ساختار یک فراخوانی
هر فراخوانی از سه بخش تشکیل میشود: نشانی مقصد (کجا ارسال کنیم)، کلید API (برای احراز هویت) و بار پیام (محتوای مدنظر ما). پاسخ دریافتی نیز شامل یک کد وضعیت (مانند 200 برای موفقیت، 401 برای خطای احراز هویت و 429 برای محدودیت نرخ درخواست) و یک بدنه است که پاسخ مدل در آن قرار دارد.
نقشها: system، user، assistant
مهمترین نکته این است که مدل حافظهای ندارد. بنابراین هر بار باید کل تاریخچه لازم را خودتان ارسال کنید. این تاریخچه در قالب فهرستی از پیامها با سه نقش متفاوت تعریف میشود:
- system: دستورالعملی کلی که رفتار، چارچوب و قواعد بازی را در همان ابتدا مشخص میکند.
- user: پیام ارسالی از سوی کاربر.
- assistant: پاسخهای قبلی مدل که برای حفظ پیوستگی گفتوگو، آنها را دوباره ارسال میکنید.
messages = [
{"role": "system", "content": "تو یک معلمِ ریاضی هستی. صبور باش."},
{"role": "user", "content": "۲ بهعلاوهٔ ۲ چند میشود؟"},
{"role": "assistant", "content": "۲ بهعلاوهٔ ۲ میشود ۴."},
{"role": "user", "content": "حالا آن را در ۳ ضرب کن."},
]
به دلیل وجود پیام assistant در تاریخچه، مدل متوجه میشود که منظور از «آن» همان عدد ۴ است.
توکنها و هزینه
مدل متنهای ورودی را به واحدهایی کوچکتر به نام توکن تجزیه میکند. به عنوان یک قاعدهی سرانگشتی، در زبان انگلیسی هر توکن معادل حدوداً سه چهارم یک کلمه است، اما زبان فارسی توکنهای بیشتری مصرف میکند (تقریباً به ازای هر دو نویسه، یک توکن). هزینه استفاده از خدمات بر اساس تعداد توکنها محاسبه میشود و ورودی و خروجی قیمتگذاری متفاوتی دارند. پنجره زمینه نشاندهنده حداکثر تعداد توکنی است که مدل میتواند در یک زمان پردازش کند؛ این ظرفیت در مدلهای امروزی از حدود صدهزار تا بیش از یک میلیون توکن متغیر است.
در گفتوگوهای طولانی که حجم آنها از پنجره زمینه فراتر میرود، دو راهکار پیش رو دارید: پنجره کشویی (نگهداری آخرین پیامها و حذف موارد قدیمی) یا خلاصهسازی (فشردهکردن پیامهای قدیمی در قالب یک خلاصه کوتاه).
دما و چند پارامتر کلیدی
دما (temperature) میزان تصادفیبودن خروجی را کنترل میکند که معمولاً عددی بین 0 تا 2 است. مقدار 0 باعث میشود مدل همواره محتملترین پاسخ را انتخاب کند (که برای کارهایی مثل کدنویسی و استخراج داده مناسب است)؛ مقدار ۱ حالتی متعادل ایجاد میکند و مقادیر بالاتر برای کارهای خلاقانه کاربرد دارند. یک قاعدهی کلیدی: برای تنظیم دقیق خروجی، همواره یکی از دو پارامتر دما یا top_p را تغییر دهید و هرگز هر دو را به صورت همزمان دستکاری نکنید.
پارامتر کلیدی دیگر، حداکثر توکن خروجی است. این مشخصه طول پاسخ مدل را محدود میکند؛ به این معنا که اگر مدل به سقف تعیینشده برسد، خروجی را در همان نقطه قطع میکند و پاسخی نیمهکاره تحویل میدهد، نه اینکه آن را خلاصهسازی کند. بنابراین، این مقدار را باید متناسب با نیاز خود تنظیم کنید.
خروجی ساختارمند
در بسیاری از مواقع ترجیح میدهید پاسخ دریافتی را به عنوان دادهای ساختاریافته پردازش کنید، نه یک متن ساده و آزاد. برای این کار دو راهکار وجود دارد.
نخست، حالت JSON: در این روش از مدل درخواست میکنید که پاسخ خود را صرفاً در قالب ساختار JSON ارائه دهد. نکتهی مهم این است که حتماً باید کلمهی JSON را در متن دستور (پرامپت) خود بگنجانید.
response = client.chat.completions.create(
model="...",
messages=[
{"role": "system", "content": "خروجی را فقط بهصورت JSON بده."},
{"role": "user", "content": "استخراج کن: آیفون ۱۵، قیمت ۹۹۹ دلار"},
],
response_format={"type": "json_object"},
)
data = json.loads(response.choices[0].message.content)
این روش تولید یک سند JSON معتبر را تضمین میکند، اما صحت ساختار داخلی آن (مانند حضور قطعی تمامی فیلدهای مدنظر شما) را تضمین نخواهد کرد. روش دوم، فراخوانی تابع (function calling) است: در این حالت، مشخصات و ورودیهای یک تابع را برای مدل تعریف میکنید و مدل ملزم میشود خروجی خود را دقیقاً بر اساس همان ساختار ارائه دهد؛ روشی که برای دریافت دادههای ساختاریافته بسیار دقیقتر و قابلاعتمادتر است.
جمعبندی
اولین قدم برای تعامل موفق با یک API، تسلط بر همین مفاهیم پایه است: پیامهای نقشمحور، مدیریت توکنها و هزینهها، تنظیم پارامترهای رفتاری و پیادهسازی سازوکارهای خروجی ساختارمند. با درک عمیق این اصول اساسی، یادگیری سایر قابلیتها و ابزارهای پیشرفته کار بسیار سادهای خواهد بود.