بهینهسازی هزینه
بهینهسازی هزینه در AvalAI بیشتر یعنی کاهش توکنها، حذف درخواستهای غیرضروری، انتخاب مدل مناسب و هدایت کارهای غیر فوری به سطح سرویس ارزانتر. راهنمای هزینه OpenAI این ایدهها را کنار Batch API و flex processing توضیح میدهد؛ در AvalAI همین اصول را به کار ببرید، اما هر مدل، endpoint و قابلیت حساب را با مستندات AvalAI بررسی کنید.
اهرمهای هزینه
| اهرم | چگونه هزینه را کم میکند | مستندات AvalAI |
|---|---|---|
| درخواستهای کمتر | stepها را ترکیب کنید، خروجی deterministic را cache کنید و برای منطق ثابت UI از LLM استفاده نکنید. | بهترین شیوههای استقرار |
| توکن ورودی کمتر | chunkهای retrieval را کوتاه کنید، context قدیمی را فشرده کنید و prompt را cache-friendly نگه دارید. | شمارش توکن، فشردهسازی Context |
| توکن خروجی کمتر | بودجه پاسخ را صریح کنید و max_output_tokens / max_completion_tokens بگذارید. | بهینهسازی تاخیر |
| مدل کوچکتر | taskهای ساده را به مدلهای mini/flash/nano بدهید و مدلهای frontier را برای کارهای سخت نگه دارید. | انتخاب مدل، قیمتگذاری |
| بودجه reasoning | وقتی evalها نشان میدهند کیفیت با توکن reasoning پنهان کمتر حفظ میشود، reasoning.effort را کاهش دهید. | استدلال، انتخاب مدل |
| توکنهای cacheشده | instructionها و schemaهای ثابت را در ابتدای prompt نگه دارید. | کش کردن پرامپت |
| کار async یا flex | کارهای غیر فوری را با پردازش ارزانتر یا queueشده اجرا کنید. | سطوح سرویس، پردازش دستهای |
هر درخواست را ارزانتر کنید
برای /v1/responses پاسخ را محدود کنید و دادهای را که بعدا لازم ندارید ذخیره نکنید:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AVALAI_API_KEY"],
base_url="https://api.avalai.ir/v1",
)
response = client.responses.create(
model="gpt-5.4-mini",
instructions="Answer in at most 5 bullets. Do not include background explanations.",
input="Summarize the operational risks in this incident note: ...",
reasoning={"effort": "low"},
text={"verbosity": "low"},
max_output_tokens=300,
store=False,
)
print(response.output_text)import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AVALAI_API_KEY,
baseURL: "https://api.avalai.ir/v1",
});
const response = await client.responses.create({
model: "gpt-5.4-mini",
instructions: "Answer in at most 5 bullets. Do not include background explanations.",
input: "Summarize the operational risks in this incident note: ...",
reasoning: { effort: "low" },
text: { verbosity: "low" },
max_output_tokens: 300,
store: false,
});
console.log(response.output_text);برای /v1/chat/completions از max_completion_tokens استفاده کنید و context بازیابیشده را compact نگه دارید.
برای baselineهای GPT-5.5، reasoning سطح medium نقطه شروع خوبی برای کیفیت است. وقتی workflow evalها را پاس کرد، روی همان dataset مقدار low برای reasoning و verbosity را مقایسه کنید. در تصمیمهای compliance، safety، مالی، migration کد یا high-impact فقط وقتی reasoning را پایین بیاورید که eval و human review نشان دهد تنظیم ارزانتر همچنان قابلاعتماد است.
سقف توکن را با بودجه پاسخ قابل مشاهده اشتباه نگیرید
در مدلهای دارای reasoning، پارامترهای max_output_tokens در Responses، max_completion_tokens در Chat Completions و پارامتر قدیمی max_tokens میتوانند هم reasoning پنهان و هم پاسخ قابل مشاهده را پوشش دهند. این پارامترها کل generation را محدود میکنند و بخشی از بودجه را برای متن قابل مشاهده کاربر رزرو نمیکنند.
این رفتار میتواند به یک تله هزینه تبدیل شود: درخواست ممکن است توکن خروجی قابل پرداخت مصرف کند اما پاسخ متنی خالی برگرداند. برای مثال، اگر سقف درخواست ۱٬۵۰۰ توکن باشد و usage.output_tokens_details.reasoning_tokens نشان دهد تقریبا همه ۱٬۵۰۰ توکن صرف reasoning شدهاند، ممکن است هیچ بودجهای برای متن نهایی باقی نماند. instruction کوتاهی مانند «پاسخ حداکثر ۲۰۰ کاراکتر باشد» فقط طول پاسخ مورد انتظار را محدود میکند و لزوما reasoning داخلی مدل را محدود نمیکند.
پیش از retry، تمام شدن بودجه را تشخیص دهید
نشانههای زیر را تمام شدن بودجه توکن بدانید، نه اینکه خودکار آن را اختلال provider، شکست content filter یا پاسخ موفق خالی تلقی کنید:
- Responses API: مقدار
status: "incomplete"همراه باincomplete_details.reason: "max_output_tokens"؛ ممکن استresponse.outputفقط آیتم reasoning داشته باشد وresponse.output_textخالی باشد. - Chat Completions: مقدار
finish_reason: "length"؛ محتوای قابل مشاهده ممکن است خالی یا بریده باشد. - شواهد usage: مقدار
output_tokens_details.reasoning_tokensبهoutput_tokensنزدیک است و متن قابل مشاهده کم یا خالی است.
پاسخ ناقص را مانند پاسخ موفق parse، cache، نمایش یا در billing داخلی بهعنوان جواب قابل استفاده ثبت نکنید. status، دلیل incomplete یا finish، سقف توکن تنظیمشده، طول متن قابل مشاهده، reasoning tokenها، مدل، reasoning effort، نسخه prompt و x-request-id را log کنید.
هزینه را بر اساس پاسخ موفق بهینه کنید
سقف توکن پایینتر وقتی باعث شکست قابل پرداخت و retry شود، ارزانتر نیست. هر دو metric زیر را track کنید:
cost_per_successful_answer =
total_cost_of_initial_attempts_and_retries
/ number_of_usable_answers
wasted_reasoning_rate =
reasoning_tokens_from_incomplete_no-text_responses
/ total_reasoning_tokensبرای هر دسته prompt ارزیابیشده، بهجای یک سقف عمومی، envelope مبتنی بر اندازهگیری بسازید:
- مقدارهای P50، P95 و P99 مصرف reasoning token و طول پاسخ قابل مشاهده را برای درخواستهای موفق اندازه بگیرید.
- کمترین
reasoning.effortرا انتخاب کنید که evalهای کیفیت و safety را پاس میکند. - سقف generation را در محدوده حداکثر پشتیبانیشده مدل بهاندازه reasoning مورد انتظار بهاضافه حاشیه پاسخ نهایی تنظیم کنید.
- برای نرخ پاسخ incomplete/بدون متن و تکرار تمام شدن بودجه به تفکیک مدل و نسخه prompt alert بگذارید.
- پس از تغییر snapshot مدل، ابزارها، context بازیابیشده، schema یا prompt دوباره eval کنید؛ همه این موارد میتوانند نیاز reasoning را تغییر دهند.
سیاست بازیابی محدود داشته باشید
هنگام تمام شدن بودجه، فقط مطابق policy صریح برنامه retry کنید. بر اساس ریسک task و قابلیت مدل، یک تغییر کنترلشده اعمال کنید: سقف توکن را افزایش دهید، reasoning.effort را روی low یا none بگذارید، task را ساده یا تقسیم کنید، context نامرتبط را کم کنید یا درخواست را به مدل مناسبتری route کنید. درخواست را بدون تغییر retry نکنید، زیرا ممکن است همان شکست قابل پرداخت تکرار شود؛ تعداد retryها را نیز محدود کنید تا یک action کاربر هزینه را چند برابر نکند.
در کارهای high-impact فقط برای کاهش هزینه reasoning را خودکار کم نکنید؛ بودجه بزرگتر، تقسیم task یا human review را ترجیح دهید. بخشهای بودجه توکن reasoning و بهترین شیوههای استقرار را ببینید.
بر اساس ارزش Task مسیریابی کنید
بهجای یک مدل پیشفرض برای همه چیز، policy مسیریابی داشته باشید:
- Taskهای سطح ۱: classification، extraction، summary کوتاه و formatting معمولا میتوانند با مدلهای کوچکتر یا ارزانتر اجرا شوند.
- Taskهای سطح ۲: پاسخهای کاربرمحور و workflowهای چندمرحلهای ابزار، مدل پیشفرض قویتر و بودجه خروجی سختگیرانه میخواهند.
- Taskهای سطح ۳: reasoning پرارزش، migration کد یا بررسی compliance میتواند مدل reasoning بزرگتر، پردازش پسزمینه و verification اضافه را توجیه کند.
دقت، هزینه و تاخیر را جداگانه track کنید. مدلی ارزانتر که دو retry لازم دارد ممکن است از مدل قویتری که یکبار موفق میشود گرانتر تمام شود.
Guardrail بودجه اضافه کنید
بهینهسازی هزینه باید قبل از خرج شدن هزینه هم امن fail کند، نه فقط بعدا dashboard نشان دهد. guardrailها را در سه سطح اضافه کنید:
- هر درخواست: درخواستهایی را که از بودجه token-count شما بیشترند قبل از فراخوانی مدل reject یا به مسیر ارزانتر منتقل کنید.
- هر workflow: retryها، loopهای ابزار و fan-out موازی را محدود کنید تا یک action کاربر نتواند فراخوانی نامحدود بسازد.
- هر حساب یا reseller: با User API و رکوردهای billing خودتان بودجه روزانه، ماهانه یا مخصوص مشتری را enforce کنید.
وقتی یک درخواست از بودجه عبور کرد، fallback را صریح انتخاب کنید: ابتدا context را خلاصه کنید، به مدل کوچکتر بروید، به flex route کنید، آن را به پردازش پسزمینه منتقل کنید، یا از کاربر تأیید action پرهزینهتر را بگیرید. context حساس compliance، safety، finance یا migration را بیصدا truncate نکنید.
از Flex برای کارهای غیر فوری استفاده کنید
سطوح سرویس عمومی مستندشده AvalAI مقدارهای default و flex هستند. فقط وقتی مدل پشتیبانی میکند و job کندی یا unavailable شدن موقت ظرفیت را تحمل میکند، service_tier: "flex" بفرستید.
response = client.responses.create(
model="gpt-5.4-mini",
input="Generate 50 synthetic support-ticket examples for evaluation.",
service_tier="flex",
store=False,
)const response = await client.responses.create({
model: "gpt-5.4-mini",
input: "Generate 50 synthetic support-ticket examples for evaluation.",
service_tier: "flex",
store: false,
});curl https://api.avalai.ir/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AVALAI_API_KEY" \
-d '{
"model": "gpt-5.4-mini",
"input": "Generate 50 synthetic support-ticket examples for evaluation.",
"service_tier": "flex",
"store": false
}'راهنمای Flex در OpenAI هزینه کمتر را با پاسخ کندتر و احتمال خطای 429 Resource Unavailable معاوضه میکند. در AvalAI، Flex را ظرفیت best-effort بدانید مگر اینکه قرارداد حساب شما چیز دیگری بگوید:
- برای jobهای طولانی Flex، timeout کلاینت را افزایش دهید و به timeout پیشفرض SDK تکیه نکنید.
- برای کارهایی که میتوانند منتظر بمانند، پاسخهای
429یا resource unavailable را با exponential backoff retry کنید. - فقط وقتی تکمیل شدن از مسیر کمهزینه مهمتر است، به
service_tier: "default"fallback کنید. - برای checkout تعاملی، تغییر حساب، moderation ایمنیمحور یا هر مسیری که تأخیر ظرفیت تجربه کاربر را خراب میکند، Flex را استفاده نکنید.
اگر یک نمونه OpenAI را منتقل میکنید که service_tier: "priority" دارد، در AvalAI از default استفاده کنید مگر اینکه priority processing برای حساب و route شما صریحا فعال شده باشد.
کار Batch و Background
برای تعداد زیادی ردیف مستقل، از الگوی پردازش دستهای یا worker سازگار با rate limit خودتان استفاده کنید تا زمانی که Batch میزبانیشده برای route شما فعال شود. برای یک پاسخ طولانی، از پردازش پسزمینه یا job table مدیریتشده در برنامه استفاده کنید.
Batch برای throughput آفلاین است، نه کاهش latency مسیر کاربر. Batch API مرجع OpenAI از pool ظرفیت جدا، پنجره تکمیل ۲۴ ساعته، ورودیهای .jsonl، مقدارهای custom_id یکتا و فایل نتیجهای استفاده میکند که ترتیب خروجی آن ممکن است با ترتیب ورودی یکی نباشد. هنگام تطبیق این الگو با AvalAI، فعال بودن Batch میزبانیشده را برای همان endpoint و مدل بررسی کنید، custom_id را برای join کردن نتیجهها نگه دارید و ردیفهای expired یا failed را work unit قابل retry در job system خودتان بدانید.
نمونههای مناسب برای async:
- اجرای eval و مقایسه prompt؛
- data enrichment شبانه؛
- گزارشهای طولانی که UI را block نمیکنند؛
- تولید داده synthetic؛
- backfill و تحلیل migration.
هزینه واقعی را اندازهگیری کنید
فقط به estimate تکیه نکنید. این موارد را ثبت کنید:
- مدل، endpoint، سطح سرویس، نسخه prompt و reasoning effort؛
- مقدار تنظیمشده
max_output_tokens،max_completion_tokensیاmax_tokensقدیمی؛ - status پاسخ،
incomplete_details.reason، مقدارfinish_reasonدر Chat Completions و طول متن قابل مشاهده؛ - تعداد توکن ورودی، خروجی، reasoning و cached وقتی برگردانده میشود؛
x-request-idاز headerهای پاسخ؛- estimated cost برای feedback سریع UI؛
- داده billing نهایی از User API.
قبل از تغییر مدل، برای همه routeهای نامزد از یک فرمول unit-cost یکسان استفاده کنید. در همه ارائهدهندگان و مدلها، توکنهای reasoning پنهان با نرخ توکن خروجی مدل انتخابی محاسبه میشوند. ابتدا semantics فیلد usage در endpoint را بررسی کنید: وقتی output_tokens از قبل reasoning را شامل میشود و output_tokens_details.reasoning_tokens تفکیک آن است، افزودن دوباره reasoning_tokens باعث دوبارهشماری هزینه میشود.
وقتی خروجی کل از قبل reasoning را شامل میشود:
expected_cost =
uncached_input_tokens * input_price
+ cached_input_tokens * cached_input_price
+ output_tokens * output_price
+ retry_rate * average_retry_costوقتی route خروجی قابل مشاهده و reasoning را بهصورت دو مقدار جدا و بدون همپوشانی گزارش میکند، برای هر دو از همان قیمت خروجی استفاده کنید:
expected_cost =
uncached_input_tokens * input_price
+ cached_input_tokens * cached_input_price
+ visible_output_tokens * output_price
+ reasoning_tokens * output_price
+ retry_rate * average_retry_costقیمتها را در کد symbolic نگه دارید و از منبع pricing فعلی خودتان بارگذاری کنید. estimate را با billing واقعی AvalAI تطبیق دهید، چون providerها ممکن است usage مربوط به reasoning را متفاوت نمایش دهند، هرچند توکنهای reasoning با نرخ توکن خروجی محاسبه میشوند. مقایسه مهم «ارزانترین مدل به ازای هر توکن» نیست؛ بلکه «کمترین هزینه موردانتظار برای هر پاسخ قابل استفاده با کیفیت، نرخ retry و latency موردنیاز workflow» است.
اول ۱۰٪ workflowهای گرانتر را در dashboard پیدا کنید. قبل از دنبال کردن صرفهجوییهای کوچک، prompt و انتخاب مدل را همانجا بهینه کنید.