پرش به محتوا

گفت‌وگو (Chat Completions)

اصلی‌ترین endpoint وب‌سرویس گیسو: ساختار پیام‌ها، نقش system و user، پارامترهای دما و طول پاسخ، مدل‌های استدلالی و نمونه‌کد در شش زبان.

بازبینی: ۸ مهر ۱۴۰۵ ۹ دقیقه مطالعه

POST /chat/completions اصلی‌ترین endpoint وب‌سرویس گیسوست. فهرستی از پیام‌ها می‌فرستید و مدل پیام بعدی گفت‌وگو را می‌نویسد. مدل‌های متنی کاتالوگ گیسو، از GPT و Claude تا Gemini و DeepSeek، همه از همین endpoint و با همین قالب صدا زده می‌شوند.

POSThttps://gisoo.pro/api/v1/chat/completions

نمونهٔ کامل#

curl https://gisoo.pro/api/v1/chat/completions \
  -H "Authorization: Bearer $GISOO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [
      {"role": "system", "content": "You are a support agent for an online bookshop. Reply in Persian, briefly and politely."},
      {"role": "user", "content": "Can I return a book I bought last week?"}
    ],
    "temperature": 0.4,
    "max_tokens": 300
  }'

پیام‌ها و نقش‌ها#

هر پیام یک role (نقش) و یک content (محتوا) دارد:

نقشکاربرد
systemدستور کلی و لحن مدل؛ معمولاً پیام اول. اگر زبان پاسخ برایتان مهم است، همین‌جا بگویید.
developerمعادل تازه‌تر system در مدل‌های OpenAI. برای مدل‌های سازنده‌های دیگر همان system را بفرستید.
userپیام کاربر. می‌تواند متن یا ترکیبی از متن و تصویر باشد (ورودی تصویر).
assistantپاسخ‌های قبلی مدل، برای ادامهٔ گفت‌وگو.
toolنتیجهٔ ابزاری که مدل خواسته بود (فراخوانی ابزار).

حداکثر ۵۰۰ پیام در یک درخواست پذیرفته می‌شود و حجم کل درخواست تا ۲۰ مگابایت.

گفت‌وگوی چندمرحله‌ای#

وب‌سرویس چیزی از درخواست قبلی به یاد نمی‌آورد؛ هر درخواست مستقل است. برای ادامهٔ گفت‌وگو، پیام‌های قبلی (هم پرسش‌ها، هم پاسخ‌های مدل) را در هر درخواست دوباره بفرستید. هر پیامی که می‌فرستید توکن ورودی حساب می‌شود، پس گفت‌وگوی بلند گران‌تر می‌شود؛ پیام‌های خیلی قدیمی را خلاصه یا حذف کنید.

Python نگه داشتن تاریخچه
history = [{"role": "system", "content": "You are a friendly Persian tutor for English learners."}]

def ask(text: str) -> str:
    history.append({"role": "user", "content": text})
    reply = client.chat.completions.create(model="gpt-4o-mini", messages=history, max_tokens=400)
    answer = reply.choices[0].message.content
    history.append({"role": "assistant", "content": answer})  # the model only remembers what you send back
    return answer

print(ask("What does 'take off' mean?"))
print(ask("Give me two example sentences with it."))

پارامترها#

model string الزامی
شناسهٔ مدل؛ از GET /models.
messages array الزامی
پیام‌های گفت‌وگو، به ترتیب.
max_tokens integer
سقف توکن خروجی. پیش از هر درخواست مبلغی از اعتبار کنار گذاشته می‌شود و این عدد اندازهٔ آن را تعیین می‌کند؛ اگر نفرستید، ۴۰۹۶ توکن فرض می‌شود. برای مدل‌های استدلالی OpenAI خودکار به max_completion_tokens تبدیل می‌شود.
max_completion_tokens integer
نام تازه‌تر همان سقف در OpenAI؛ هر کدام را بفرستید پذیرفته می‌شود.
temperature number
میزان خلاقیت؛ ۰ یعنی پاسخ‌های ثابت‌تر، عدد بالاتر یعنی متنوع‌تر. Gemini حداکثر ۱ می‌پذیرد و مدل‌های استدلالی OpenAI فقط مقدار پیش‌فرض را می‌پذیرند؛ برای آن‌ها نفرستید.
top_p number
جایگزین temperature برای کنترل تنوع؛ معمولاً یکی از این دو را عوض کنید.
stop string | array
رشته‌هایی که با رسیدن به آن‌ها تولید متن می‌ایستد.
n integer
تعداد پاسخ جدا برای یک درخواست؛ حداکثر ۴. هزینه تقریباً n برابر می‌شود.
stream boolean
پاسخ تکه‌تکه، همان لحظه که ساخته می‌شود (پاسخ جریانی).
response_format object
tools / tool_choice array / string
ابزارهایی که مدل می‌تواند صدا بزند (فراخوانی ابزار).
reasoning_effort string
برای مدل‌های استدلالی: minimal، low، medium یا high.
seed، presence_penalty، frequency_penalty number
به سرویس‌دهنده فرستاده می‌شوند. Gemini این‌ها را نمی‌پذیرد و خطای ۴۰۰ می‌دهد؛ برای Gemini نفرستید.
user string
پذیرفته می‌شود، ولی گیسو شناسهٔ خودش را به سرویس‌دهنده می‌فرستد و شناسهٔ کاربران شما به بیرون نمی‌رود.

پاسخ#

JSON chat.completion
{
  "id": "req_7d2e19c0a4b6f8e1d3c5a7b9",
  "object": "chat.completion",
  "created": 1790000000,
  "model": "gpt-4o-mini",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "…" },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 48,
    "completion_tokens": 72,
    "total_tokens": 120,
    "prompt_tokens_details": { "cached_tokens": 0 },
    "completion_tokens_details": { "reasoning_tokens": 0 }
  }
}

finish_reason می‌گوید چرا تولید متن تمام شد:

  • stop: پاسخ کامل شد.
  • length: به سقف max_tokens رسید و پاسخ نیمه‌تمام است. سقف را بالاتر ببرید. در مدل‌های استدلالی ممکن است همهٔ سقف صرف فکر کردن شده باشد و content خالی بماند.
  • tool_calls: مدل می‌خواهد ابزاری را صدا بزند.
  • content_filter: سرویس‌دهنده بخشی از پاسخ را برای سیاست محتوایی‌اش نگه داشت.

id پاسخ و هدر X-Request-Id شناسهٔ همین درخواست در گیسو است. آن را در لاگ خودتان نگه دارید؛ با آن هزینهٔ دقیق درخواست را از GET /requests/{id} می‌گیرید و پشتیبانی هم با همین شناسه پیگیری می‌کند.

مدل‌های استدلالی#

مدل‌های استدلالی (مثل gpt-5-mini) پیش از پاسخ «فکر می‌کنند». توکن‌های فکر کردن به شما نشان داده نمی‌شوند، ولی جزو توکن خروجی حساب می‌شوند و در usage.completion_tokens_details.reasoning_tokens می‌آیند. با reasoning_effort مقدار فکر کردن را کم یا زیاد کنید و سقف خروجی را جوری بگذارید که برای فکر و پاسخ هر دو جا باشد.

Python reasoning_effort
reply = client.chat.completions.create(
    model="gpt-5-mini",
    reasoning_effort="low",          # minimal | low | medium | high
    max_completion_tokens=2000,      # thinking tokens count towards this too
    messages=[{"role": "user", "content": "A train leaves at 14:35 and arrives at 19:10. How long is the trip?"}],
)
print(reply.choices[0].message.content)
print(reply.usage.completion_tokens_details)  # reasoning_tokens is inside
Gemini و DeepSeek

Gemini هم reasoning_effort را می‌پذیرد و توکن فکر کردن را جزو خروجی حساب می‌کند؛ گیسو آن را در reasoning_tokens جدا نشان می‌دهد تا بدانید هزینه از کجا آمده است. اگر سقف خروجی Gemini خیلی کم باشد، ممکن است پاسخ با finish_reason: length و متن خالی برگردد. بعضی مدل‌ها، مثل DeepSeek، متن فکر کردن را در فیلد reasoning_content یا reasoning پیام هم می‌فرستند.

فایل صوتی در گفت‌وگو (Gemini)#

مدل‌های Gemini فایل صوتی را داخل پیام می‌پذیرند: بخشی از نوع input_audio با دادهٔ base64 و قالب mp3 یا wav. این راه برای خلاصه کردن یا پیاده کردن متن جلسه با توضیحات شما کار می‌کند. حجم کل درخواست تا ۲۰ مگابایت است؛ فایل بلند را با ffmpeg به صدای تک‌کاناله با نرخ ۳۲ کیلوبیت و تکه‌های ۱۵ دقیقه‌ای تبدیل کنید. جزئیات در صفحهٔ صدا.

چند نکتهٔ کاربردی#

  • زبان پاسخ را صریح بگویید. «Reply in Persian» در پیام system جلوی پاسخ انگلیسی را می‌گیرد.
  • max_tokens را واقعی بگذارید. سقف کمتر یعنی مبلغ کمتری پیش از درخواست کنار گذاشته می‌شود و پاسخ بی‌جهت طولانی نمی‌شود.
  • بخش ثابت پرامپت را اول بگذارید. OpenAI و چند سرویس‌دهندهٔ دیگر ابتدای تکراری درخواست‌ها را کش می‌کنند و توکن کش‌شده ارزان‌تر حساب می‌شود (cached_tokens در usage).
  • برای پاسخ‌های بلند stream را روشن کنید. کاربر شروع پاسخ را زود می‌بیند و تا آخرش منتظر نمی‌ماند.

پاسخ پرسشتان را پیدا نکردید؟

شناسهٔ درخواست (هدر X-Request-Id) را با پرسشتان در تیکت بفرستید تا دقیق بررسی کنیم.

تیکت پشتیبانی