POST /chat/completions اصلیترین endpoint وبسرویس گیسوست. فهرستی از پیامها میفرستید و مدل پیام بعدی گفتوگو را مینویسد.
مدلهای متنی کاتالوگ گیسو، از GPT و Claude تا Gemini و DeepSeek، همه از همین endpoint و با همین قالب صدا زده میشوند.
نمونهٔ کامل#
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
}'
import os
from openai import OpenAI
client = OpenAI(base_url="https://gisoo.pro/api/v1", api_key=os.environ["GISOO_API_KEY"])
reply = client.chat.completions.create(
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,
)
choice = reply.choices[0]
print(choice.message.content)
print(choice.finish_reason, reply.usage.total_tokens)
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://gisoo.pro/api/v1", apiKey: process.env.GISOO_API_KEY });
const reply = await client.chat.completions.create({
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,
});
console.log(reply.choices[0].message.content);
console.log(reply.choices[0].finish_reason, reply.usage.total_tokens);
<?php
$client = OpenAI::factory()
->withBaseUri('https://gisoo.pro/api/v1')
->withApiKey(getenv('GISOO_API_KEY'))
->make();
$reply = $client->chat()->create([
'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,
]);
echo $reply->choices[0]->message->content;
reply, err := client.Chat.Completions.New(context.TODO(), openai.ChatCompletionNewParams{
Model: "gpt-4o-mini",
Messages: []openai.ChatCompletionMessageParamUnion{
openai.SystemMessage("You are a support agent for an online bookshop. Reply in Persian, briefly and politely."),
openai.UserMessage("Can I return a book I bought last week?"),
},
Temperature: openai.Float(0.4),
MaxTokens: openai.Int(300),
})
if err != nil {
panic(err)
}
fmt.Println(reply.Choices[0].Message.Content)
ChatClient client = new(
model: "gpt-4o-mini",
credential: new ApiKeyCredential(Environment.GetEnvironmentVariable("GISOO_API_KEY")!),
options: new OpenAIClientOptions { Endpoint = new Uri("https://gisoo.pro/api/v1") });
ChatCompletion reply = client.CompleteChat(
[
new SystemChatMessage("You are a support agent for an online bookshop. Reply in Persian, briefly and politely."),
new UserChatMessage("Can I return a book I bought last week?"),
],
new ChatCompletionOptions { Temperature = 0.4f, MaxOutputTokenCount = 300 });
Console.WriteLine(reply.Content[0].Text);
پیامها و نقشها#
هر پیام یک role (نقش) و یک content (محتوا) دارد:
| نقش | کاربرد |
|---|---|
system | دستور کلی و لحن مدل؛ معمولاً پیام اول. اگر زبان پاسخ برایتان مهم است، همینجا بگویید. |
developer | معادل تازهتر system در مدلهای OpenAI. برای مدلهای سازندههای دیگر همان system را بفرستید. |
user | پیام کاربر. میتواند متن یا ترکیبی از متن و تصویر باشد (ورودی تصویر). |
assistant | پاسخهای قبلی مدل، برای ادامهٔ گفتوگو. |
tool | نتیجهٔ ابزاری که مدل خواسته بود (فراخوانی ابزار). |
حداکثر ۵۰۰ پیام در یک درخواست پذیرفته میشود و حجم کل درخواست تا ۲۰ مگابایت.
گفتوگوی چندمرحلهای#
وبسرویس چیزی از درخواست قبلی به یاد نمیآورد؛ هر درخواست مستقل است. برای ادامهٔ گفتوگو، پیامهای قبلی (هم پرسشها، هم پاسخهای مدل) را در هر درخواست دوباره بفرستید. هر پیامی که میفرستید توکن ورودی حساب میشود، پس گفتوگوی بلند گرانتر میشود؛ پیامهای خیلی قدیمی را خلاصه یا حذف کنید.
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."))
پارامترها#
GET /models.max_completion_tokens تبدیل میشود.minimal، low، medium یا high.پاسخ#
{
"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 مقدار فکر کردن را کم یا زیاد کنید و سقف خروجی را جوری بگذارید که برای فکر و پاسخ هر دو جا باشد.
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 هم 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) را با پرسشتان در تیکت بفرستید تا دقیق بررسی کنیم.