كيف تقلل تكلفة AI API في Laravel؟ دليل شامل لخفض استهلاك Tokens وتكاليف الذكاء الاصطناعي
عند بناء أول ميزة تعتمد على الذكاء الاصطناعي داخل تطبيق Laravel، تكون البداية غالبًا بسيطة جدًا:
$response = (new SupportAgent)
->prompt($message);تعمل الميزة، تحصل على نتيجة جيدة، ثم تنتقل إلى Production.
لكن مع نمو التطبيق يبدأ عدد المستخدمين والطلبات بالارتفاع:
100 مستخدم
1,000 مستخدم
10,000 مستخدم
100,000 مستخدموهنا يظهر السؤال الذي يواجه تقريبًا كل تطبيق AI ناجح:
لماذا ترتفع فاتورة الـ AI بهذه السرعة، وكيف يمكن خفضها دون التضحية بجودة النتائج؟
في كثير من الحالات، المشكلة ليست أن خدمات الذكاء الاصطناعي غالية بطبيعتها، بل أن بنية التطبيق لم تُصمم منذ البداية للتفريق بين مهمة بسيطة يمكن تنفيذها بنموذج صغير، ومهمة تحتاج فعلًا إلى نموذج قوي.
قد تكتشف مثلًا أنك تستخدم أقوى Model لديك لمعرفة هل الرسالة:
positive
neutral
negativeأو أنك ترسل محادثة تحتوي على 150 رسالة في كل Request لكي تجيب عن سؤال بسيط مثل:
متى ينتهي اشتراكي؟أو تعيد إنشاء نفس Embedding عشرات أو آلاف المرات رغم أن النص لم يتغير.
أو تسمح للنموذج بإنتاج 4,000 Token بينما النتيجة المطلوبة لا تتجاوز:
hot
warm
coldلهذا فإن Cost Optimization الحقيقية لا تعني:
استخدم أرخص Model في كل مكان.
بل تعني:
استخدم أقل قدر من الـ Compute والـ Context والـ Tokens اللازم لإنجاز كل مهمة بالمستوى المطلوب من الجودة والموثوقية.
في هذا الدليل سنبني استراتيجية شاملة لتقليل تكلفة AI داخل Laravel تشمل:
- Model Routing.
- اختيار Model المناسبة لكل مهمة.
- Token Optimization.
- Context Reduction.
- Prompt Optimization.
- Structured Outputs.
- Result Caching.
- Embedding Caching.
- RAG Optimization.
- Conversation Summarization.
- Laravel Queues.
- منع Duplicate Jobs.
- Agent Step Limits.
- Usage Tracking.
- Cost Budgets.
- Adaptive Cost Control.
- Evaluation وقياس Cost per Useful Result.
أولًا: كيف تُحسب تكلفة AI API؟
لفهم كيفية تخفيض التكلفة، يجب أولًا معرفة من أين تأتي.
في معظم تطبيقات LLM يمكن تبسيط تكلفة العملية بالشكل التالي:
AI Cost =
Input Tokens
+
Output Tokens
+
Model Cost
+
Number of Requests
+
Tool / Search / Embedding Costs
+
Retries and Duplicate Workإذا كانت إحدى العمليات ترسل:
Input:
5,000 tokens
Output:
1,000 tokens
Total:
6,000 tokensوتنفذ العملية 100,000 مرة، فأنت تتعامل نظريًا مع:
6,000 × 100,000
=
600,000,000 tokensلهذا فإن تحسينًا صغيرًا جدًا على مستوى Request واحدة يمكن أن يتحول إلى توفير ضخم عند تكراره مئات الآلاف أو ملايين المرات.
القاعدة الأولى: لا تستخدم AI عندما يستطيع PHP أو SQL تنفيذ المهمة
هذه واحدة من أهم قواعد خفض التكلفة.
ليس كل شيء يحتاج إلى LLM.
إذا أردت حساب إجمالي فاتورة:
total = subtotal + taxفلا يوجد أي سبب منطقي لإرسال القيم إلى AI.
$total = $subtotal + $tax;PHP هنا:
- أسرع.
- أرخص.
- حتمي Deterministic.
- أسهل في الاختبار.
- أقل عرضة للأخطاء.
أمثلة على مهام لا تحتاج إلى AI
Calculate age
Check subscription expiration
Validate email
Find order by ID
Calculate discount
Sum invoice
Check account status
Compare numbers
Calculate percentages
Apply business rules
Check permissions
Validate database valuesهذه مهام يجب تنفيذها غالبًا باستخدام:
PHP
SQL
Laravel Validation
Business Logic
Database Queriesوليس LLM.
متى تصبح AI مناسبة؟
استخدم AI عندما تحتوي المهمة على معنى غير منظم أو تحتاج إلى فهم اللغة والسياق، مثل:
- فهم نية العميل.
- تحليل المشاعر.
- تلخيص محادثة.
- استخراج معلومات من نص غير منظم.
- تحليل عقد.
- اكتشاف اعتراضات العميل.
- Semantic Search.
- توليد نصوص.
- التعامل مع أسئلة بلغة طبيعية.
- تحليل حالات معقدة لا يمكن التعبير عنها بسهولة بقواعد ثابتة.
أكبر خطأ: استخدام Model واحدة لكل شيء
تخيل CRM يحتوي على الوظائف التالية:
Detect Sentiment
Classify Lead
Generate Tags
Summarize Message
Answer Customer
Analyze Sales Call
Extract Invoice
Analyze Contract
Build Sales Strategy
Complex Reasoningالخطأ الشائع هو إرسال كل هذه المهام إلى أقوى Model.
Everything
↓
Most Powerful Modelهذه Architecture سهلة برمجيًا، لكنها قد تكون مكلفة جدًا.
السؤال:
هل هذه الرسالة positive أم negative؟ليس بنفس صعوبة:
حلل هذا العقد المكون من 60 صفحة،
استخرج الالتزامات القانونية،
حدد التعارضات بين البنود،
ثم صنف المخاطر حسب شدتها.الحل: Model Routing
قسّم مهام AI حسب درجة التعقيد.
المستوى الأول: Simple Tasks
- Sentiment Classification.
- Intent Detection.
- Lead Classification.
- Tag Generation.
- Short Summaries.
- Simple Extraction.
المستوى الثاني: Medium Tasks
- Customer Support.
- Lead Analysis.
- Document Extraction.
- Call Summaries.
- Moderate RAG Questions.
- Email generation.
المستوى الثالث: Complex Tasks
- Contract Risk Analysis.
- Strategic Analysis.
- Multi-step Agents.
- Complex Reasoning.
- Large document synthesis.
- Tasks requiring several tools.
فتصبح Architecture:
Task
↓
Task Classification
↓
Complexity
↓
Model Router
↓
Cheap / Standard / Powerful Modelاستخدام UseCheapestModel في Laravel AI SDK
إذا كنت تستخدم Laravel AI SDK، فيمكن تحديد Agents المناسبة للمهام منخفضة التعقيد لكي تستخدم أرخص Text Model متاحة لدى Provider.
use Laravel\Ai\Attributes\UseCheapestModel;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Promptable;
#[UseCheapestModel]
class SentimentClassifier implements Agent
{
use Promptable;
// ...
}هذه الاستراتيجية مناسبة لمهام مثل:
- Sentiment Classification.
- Intent Detection.
- Simple Summaries.
- Simple Extraction.
- Tagging.
متى تستخدم UseSmartestModel؟
في الطرف الآخر، توجد مهام تكون فيها جودة الاستدلال أهم بكثير من تكلفة Request الواحدة.
use Laravel\Ai\Attributes\UseSmartestModel;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Promptable;
#[UseSmartestModel]
class ContractRiskAnalyzer implements Agent
{
use Promptable;
// ...
}الفكرة:
Simple Task
→ Cheapest acceptable model
Normal Task
→ Standard model
Complex Task
→ Smartest / powerful modelبدل:
Everything
→ Most expensive modelمتى يكون تثبيت Model أفضل؟
الاختيار التلقائي ممتاز عندما تريد الاستفادة من تطور الـ Providers والنماذج الجديدة.
لكن في Production توجد حالات تحتاج فيها إلى:
- تكلفة متوقعة.
- سلوك ثابت.
- نتائج قابلة للاختبار.
- منع تغيّر Model دون إجراء Evaluation جديد.
عندها يكون تثبيت Model محددة أكثر ملاءمة.
use Laravel\Ai\Attributes\Model;
#[Model('your-model-name')]
class SupportAgent
{
// ...
}Cost Optimization لا تعني اختيار Model الأرخص، بل اختيار أرخص Model تحقق مستوى الجودة المطلوب للمهمة.
استخدم Evaluation قبل تخفيض قوة Model
لا تغيّر Model لأن سعرها أرخص ثم تفترض أنها ستعمل بنفس الجودة.
أنشئ Dataset حقيقية من التطبيق.
مثلًا في Lead Classification:
100 real customer messages
Expected output:
Hot
Warm
Coldثم اختبر:
Cheap Model
Standard Model
Powerful Modelوقارن:
- Accuracy.
- Cost.
- Latency.
- Failure Rate.
- Retry Rate.
- JSON validity.
مثلًا:
Model A
Accuracy: 94%
Relative Cost: 1x
Model B
Accuracy: 95%
Relative Cost: 4xفي بعض المهام قد لا تكون زيادة Accuracy بنسبة 1% مبررًا لدفع أربعة أضعاف التكلفة.
لكن في مهام مالية أو قانونية أو عالية الحساسية، قد تكون الزيادة الصغيرة في الجودة مهمة جدًا.
لا تقيس Cost per Request فقط
Model منخفضة السعر ليست دائمًا الأرخص على مستوى النظام.
افترض أن Model رخيصة تفشل في 30% من الطلبات، فيضطر التطبيق إلى:
- إعادة Request.
- استدعاء Model ثانية.
- استهلاك المزيد من Tokens.
- تشغيل Validation إضافية.
لذلك:
Cheapest Model
≠
Lowest System Costالمقياس الأكثر أهمية هو:
Cost per Successful Result
أو
Cost per Useful Resultاستراتيجية أقوى: Model Escalation
لا تحتاج إلى إرسال كل Request إلى Model قوية من البداية.
يمكنك بدء المهمة بـ Model منخفضة التكلفة، وإذا كانت النتيجة غير مؤكدة فقط يتم تصعيد الحالة.
Cheap Model
↓
Confidence?
↙ ↘
YES NO
↓ ↓
Done Strong Modelمثلًا:
{
"classification": "hot",
"confidence": 0.96
}إذا كان:
confidence >= 0.85نعتمد النتيجة.
أما إذا كانت:
{
"classification": "warm",
"confidence": 0.48
}يمكن تصعيد الحالة إلى Model أقوى.
فتصبح التكلفة مثلًا:
80% of requests
→ Cheap Model
20% of requests
→ Strong Modelبدل:
100%
→ Strong Modelقلل Output Tokens
كل Token يقوم النموذج بإنشائها لها تكلفة.
إذا كانت UI تحتاج جملتين، فلا تطلب مقالًا.
على سبيل المثال:
Summarize this customer message.تعليمة مفتوحة مثل هذه قد تسمح للنموذج بإنتاج مئات الكلمات.
الأفضل:
Summarize the customer message in a maximum
of two short sentences.استخدام MaxTokens
Laravel AI SDK تسمح بتحديد أقصى عدد من Tokens التي يمكن للـ Agent توليدها.
use Laravel\Ai\Attributes\MaxTokens;
#[MaxTokens(200)]
class LeadClassifier implements Agent
{
use Promptable;
}إذا كانت المهمة عبارة عن:
- Lead Score.
- Classification.
- Short Summary.
فغالبًا لا تحتاج إلى السماح بإنتاج آلاف Tokens.
MaxTokens ليست بديلًا عن Prompt جيدة
إذا قلت للنموذج:
Write a detailed analysis of every possible
interpretation and provide 20 recommendations...ثم وضعت:
#[MaxTokens(100)]قد تحصل ببساطة على إجابة مقطوعة.
الأفضل الجمع بين:
Clear Task
+
Compact Prompt
+
Structured Output
+
Appropriate MaxTokensاستخدم Structured Output بدل المقالات الطويلة
إذا كان تطبيقك يحتاج إلى بيانات، فاطلب بيانات.
بدل:
Analyze this lead.استخدم Output واضحة مثل:
{
"score": 85,
"classification": "hot",
"summary": "Customer is highly interested in pricing.",
"next_action": "Call within 24 hours"
}هذه الطريقة تقلل:
- Output Tokens.
- الكلام غير المطلوب.
- Parsing complexity.
- احتمالات تغير شكل الإجابة.
Input Tokens قد تكون المشكلة الأكبر
المطورون يركزون كثيرًا على طول Output، لكن Input قد تكون أكبر منها بعشرات المرات.
تخيل Request يحتوي على:
System Prompt:
2,000 tokens
Conversation:
8,000 tokens
CRM Data:
5,000 tokens
Knowledge Base:
10,000 tokens
User Question:
50 tokens
Total:
25,050 tokensوكل ذلك للإجابة عن:
متى ينتهي اشتراكي؟هذه ليست مشكلة Model.
هذه مشكلة Architecture.
Context Reduction: لا ترسل كل شيء للنموذج
من أكبر فرص التوفير في تطبيقات AI تقليل Context.
تصميم سيئ:
$agent->prompt(
json_encode($customer->toArray())
);قد يؤدي ذلك إلى إرسال:
Name
Phone
Email
Orders
Invoices
Notes
Activities
Subscriptions
Messages
Logs
Metadata
Payments
Tickets
Relationshipsبينما السؤال:
ما حالة اشتراكي؟يحتاج ربما إلى:
Current Subscription
Expiration Date
Statusفقط.
استخدم Tools بدل إرسال قاعدة البيانات كاملة
أحد أفضل Designs للـ Agents هو منح Agent أدوات محددة للوصول إلى المعلومات عند الحاجة.
بدل:
Entire CRM Record
↓
LLMاستخدم:
User Question
↓
Agent
↓
Needs subscription data?
↓
GetSubscription Tool
↓
Only required fields
↓
LLM Responseهذا يحسن في الوقت نفسه:
- التكلفة.
- الخصوصية.
- الأمان.
- جودة Context.
- سهولة Debugging.
Conversation History قد تصبح قاتل التكلفة
تخيل Support Chat وصلت إلى 150 رسالة.
إذا كنت ترسل جميع الرسائل القديمة في كل Request:
Message #151
→ sends 150 old messages
Message #152
→ sends 151 old messages
Message #153
→ sends 152 old messagesأنت تعيد شراء نفس Context مرارًا وتكرارًا.
الحل: Rolling Summary
بدل إرسال:
Messages 1 → 150أرسل:
Conversation Summary
+
Last 10 Messagesمثال:
Conversation Summary:
- Customer subscribed to Premium.
- Payment completed.
- Activation is still pending.
- Ticket #1842 was created.
- Customer prefers WhatsApp.
Recent Context:
Last 10 messages.بهذه الطريقة تحافظ على أهم المعلومات دون إعادة إرسال تاريخ كامل للمحادثة.
Long-Term Memory يجب أن تكون Selective
إذا كان المستخدم يمتلك 500 Memory، فهذا لا يعني أن ترسل 500 Memory مع كل سؤال.
استخدم Semantic Retrieval لاسترجاع الأكثر ارتباطًا فقط.
Current Message
↓
Memory Search
↓
Top Relevant Memories
↓
Promptمثلًا:
500 memories stored
Retrieved:
Top 5 relevant memoriesوبذلك تحصل على Personalization دون تضخيم Context.
RAG ليست فقط لتحسين Accuracy
RAG يمكن أن تكون أيضًا أداة قوية لتقليل التكلفة.
بدل:
100 Documents
↓
All Document Text
↓
LLMاستخدم:
Question
↓
Embedding
↓
Vector Search
↓
Relevant Chunks
↓
LLMوبهذا ترسل أجزاء الوثائق المرتبطة بالسؤال بدل Knowledge Base كاملة.
لا تستخدم Top-K كبير بلا سبب
إذا كانت أفضل نتيجة لديك تتحقق باستخدام:
Top 3فإرسال:
Top 20قد يؤدي إلى:
- Input Tokens أكبر.
- Cost أعلى.
- Noise أكبر.
- احتمال تشتيت Model.
اختبر:
Top 3
Top 5
Top 8
Top 10ثم اختر أصغر قيمة تحافظ على Retrieval Quality المطلوبة.
Caching: لا تدفع مرتين مقابل نفس العمل
من أكثر التكاليف التي يمكن تجنبها:
Same Input
↓
Same AI Task
↓
New API Requestفي كل مرة.
مثلًا إذا كانت سياسة الاسترجاع ثابتة، وسأل 5,000 مستخدم أسئلة متشابهة عنها، فليس من الضروري دائمًا إنشاء إجابة جديدة بالكامل.
Result Caching في Laravel
مثال مبسط:
use Illuminate\Support\Facades\Cache;
$key = 'ai:refund-summary:v3';
$result = Cache::remember(
$key,
now()->addHours(24),
fn () => (new PolicySummarizer)
->prompt($refundPolicy)
);فتصبح العملية:
First Request
→ AI API
Next Requests
→ CacheCache Key يجب أن تحتوي Version
لا تستخدم Key عامة مثل:
ai:summaryلأنها لا تميز بين المحتوى أو Prompt أو Model.
صمم Key اعتمادًا على:
Task
+
Input Hash
+
Prompt Version
+
Model Versionمثال:
$key = sprintf(
'ai:summary:%s:%s:%s',
hash('sha256', $document->content),
'prompt-v4',
'model-v2'
);إذا تغير المحتوى:
New Content Hash
→ New Generationوإذا تغير Prompt:
New Prompt Version
→ New Generationلا تستخدم Cache للبيانات الحية بلا تفكير
السؤال:
What is order #9281 status?قد تكون إجابته الآن:
Shippedوبعد ساعة:
Deliveredإذا خزنت إجابة AI لمدة 24 ساعة، فستعيد معلومات قديمة.
لذلك:
Static Knowledge
→ Long Cache
Slow-changing Data
→ Short Cache
Live Transaction Data
→ Very Short Cache / No Result CacheEmbedding Caching
إذا كنت تستخدم Embeddings في RAG أو Semantic Search، فلا تعِد إنشاء Embedding لنفس المحتوى بلا سبب.
Laravel AI SDK توفر دعمًا مباشرًا لتخزين Embeddings مؤقتًا.
في ملف:
config/ai.phpيمكن تفعيلها مثلًا:
'caching' => [
'embeddings' => [
'cache' => true,
'store' => env('CACHE_STORE', 'database'),
],
],وعندما يكون المحتوى والـ Provider والـ Model وإعدادات Embedding متطابقة، يمكن إعادة استخدام النتيجة بدل تنفيذ API call جديدة.
Cache Embedding لطلب محدد
$response = Embeddings::for([
'Subscription payment issue',
])
->cache()
->generate();أو عند استخدام Helper مناسب:
$embedding = Str::of($content)
->toEmbeddings(cache: true);الأفضل من Cache: لا تعِد Indexing محتوى لم يتغير
Cache ممتازة، لكن التصميم الأفضل هو منع العمل أصلًا.
أنشئ Hash للمحتوى:
$hash = hash(
'sha256',
$article->content
);ثم قارنها بالنسخة السابقة:
if ($article->embedding_hash === $hash) {
return;
}فتصبح Architecture:
Content Updated?
↓
NO
→ Skip Embedding
YES
→ Generate Embedding
→ Store New Hashمنع العمل أفضل من تنفيذ العمل ثم الاعتماد على Cache لإلغائه.
Prompt Optimization
Prompt طويلة ليست بالضرورة Prompt أفضل.
من الأخطاء الشائعة كتابة System Prompt تحتوي على عشرات التعليمات العامة من نوع:
You are the world's greatest expert...
You must carefully think...
Always be accurate...
Always analyze every possible angle...
You should...ثم إضافة عشرات القواعد التي لا تؤثر فعليًا في المهمة.
المشكلة أن System Prompt قد يتم إرسالها مع كل Request.
إذا كان حجمها:
1,500 tokensوكان لديك:
1,000,000 requestsفأنت تتعامل مع:
1.5 billion repeated system-prompt tokensقبل حساب سؤال المستخدم أو Context الخاصة به.
اختصر التعليمات المتكررة
بدل:
You should under all circumstances carefully
analyze the user's customer message and determine
whether the sentiment expressed by the customer
is positive, neutral or negative...يمكن أن تكون:
Classify customer sentiment as:
positive, neutral, or negative.إذا كانت الاختبارات تثبت أن النسختين تحققان الجودة نفسها، فالثانية أفضل وأرخص.
لا تضع Documentation كاملة داخل System Prompt
تصميم مكلف:
System Prompt
[20 pages of company policies]
User:
Hiالتصميم الأفضل:
Short System Prompt
+
User Question
↓
RAG Search
↓
Relevant Policy Chunks
↓
LLMAgent Loops قد تستهلك ميزانيتك بسرعة
Agents التي تستطيع استخدام Tools قد تنفذ عدة Steps قبل الوصول إلى الإجابة.
مثلًا:
Agent
↓
Tool
↓
Model
↓
Tool
↓
Model
↓
Tool
↓
Modelكل Step قد تعني Request جديدة وTokens إضافية.
إذا لم يكن هناك حد واضح، يمكن أن تتحول مهمة واحدة إلى سلسلة مكلفة من العمليات.
استخدام MaxSteps
حدد عدد الخطوات المناسب لطبيعة Agent.
use Laravel\Ai\Attributes\MaxSteps;
#[MaxSteps(5)]
class SupportAgent implements Agent
{
use Promptable;
}لا تجعل:
MaxSteps = 20إذا كانت المهمة في الظروف الطبيعية تحتاج إلى خطوتين أو ثلاث فقط.
Laravel Queues لا تخفض سعر Token مباشرة، لكنها مهمة جدًا
Queue لا تجعل Model أرخص تلقائيًا.
لكنها تسمح لك بتنظيم العمليات المكلفة وإبعادها عن Request المستخدم المباشرة.
مهام مناسبة للـ Queue:
- تحليل مكالمات طويلة.
- إنشاء Embeddings.
- Document Indexing.
- Bulk Classification.
- Call Summarization.
- Large Import Processing.
- Offline AI Reports.
مثال:
AnalyzeSalesCall::dispatch($call->id);وبذلك يمكن التحكم في:
- Concurrency.
- Rate Limits.
- Retries.
- Timeouts.
- Priority.
- Batching.
انتبه إلى Retries
Retry غير منضبطة يمكن أن تضاعف التكلفة.
تخيل Job تكلف:
$0.10ويتم Retry خمس مرات بسبب Timeout غير صحيح.
قد تدفع عدة أضعاف التكلفة الفعلية للعملية.
حدد عدد المحاولات وBackoff بعناية، ولا تعِد تشغيل Generation ناجحة لمجرد أن جزءًا لاحقًا من Job فشل.
اجعل AI Operations قابلة لإعادة التشغيل بأمان
افصل:
Generate AI Resultعن:
Save Result
Send Notification
Update CRMإذا نجحت عملية AI وفشل إرسال Notification، فلا ينبغي أن تعيد Generation كاملة فقط لإعادة الإشعار.
امنع Duplicate AI Jobs
تخيل أن المستخدم ضغط زر التحليل ثلاث مرات.
بدون حماية:
Click
→ AI Job
Click
→ AI Job
Click
→ AI Jobوقد تدفع ثلاث مرات مقابل النتيجة نفسها.
في Laravel يمكن استخدام Unique Jobs عندما يناسب السيناريو.
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
class AnalyzeDocument implements ShouldQueue, ShouldBeUnique
{
public function __construct(
public int $documentId
) {}
public function uniqueId(): string
{
return (string) $this->documentId;
}
}استخدم Content Fingerprint لمنع العمل المكرر
في كثير من عمليات AI يمكن تعريف العملية باستخدام:
Task
+
Input
+
Prompt Version
+
Model
+
Configurationثم بناء Fingerprint:
$fingerprint = hash('sha256', json_encode([
'task' => 'document-summary',
'input' => $document->content,
'prompt_version' => 'v5',
'model' => $model,
]));قبل تنفيذ AI:
$existing = AiResult::where(
'fingerprint',
$fingerprint
)->first();
if ($existing) {
return $existing->result;
}هذه التقنية مفيدة جدًا في:
- Document Summaries.
- Classification.
- Embeddings.
- Reports.
- Product descriptions.
- Offline analysis.
Batch Processing
إذا كان لديك 10,000 Record تحتاج إلى Classification، لا تتعامل معها بالطريقة نفسها التي تتعامل بها مع Chat مباشر للمستخدم.
Interactive Request تحتاج Low Latency.
أما Offline Processing فيمكن أن تستخدم:
- Queues.
- Batches.
- أقل Priority.
- Provider Batch APIs عندما تكون متاحة ومناسبة.
- Models أقل تكلفة إذا كانت الجودة كافية.
اجمع عدة تصنيفات صغيرة عندما يكون ذلك منطقيًا
في بعض الحالات، إرسال 100 Request صغيرة بشكل منفصل قد يكون أقل كفاءة من معالجة مجموعة منظمة.
بدل:
Message 1 → API
Message 2 → API
Message 3 → API
...
Message 100 → APIيمكن في بعض السيناريوهات:
Messages 1-20
→ One structured classification taskلكن لا تطبق هذا بصورة عمياء.
Batch كبيرة جدًا قد تؤدي إلى:
- Context ضخمة.
- Parsing أصعب.
- فشل العملية كاملة بسبب عنصر واحد.
- Latency أعلى.
Usage Tracking ليس Feature اختيارية
لا يمكنك تحسين شيء لا تقيسه.
يجب أن تعرف على الأقل:
- كم Request AI يتم تنفيذها؟
- أي Features تستهلك أكثر؟
- أي Model تُستخدم؟
- ما متوسط Input Tokens؟
- ما متوسط Output Tokens؟
- كم تبلغ التكلفة لكل مستخدم؟
- كم تبلغ التكلفة لكل Feature؟
- كم تبلغ التكلفة لكل Tenant؟
- كم Retry تحدث؟
- كم Cache Hit لدينا؟
أنشئ جدول ai_usage
مثال على البيانات التي يمكنك تخزينها:
id
user_id
tenant_id
feature
provider
model
input_tokens
output_tokens
total_tokens
estimated_cost
latency_ms
cache_hit
success
created_atمثال Migration مبسط:
Schema::create('ai_usage', function ($table) {
$table->id();
$table->foreignId('user_id')
->nullable()
->index();
$table->string('feature')->index();
$table->string('provider')->nullable();
$table->string('model')->nullable();
$table->unsignedBigInteger('input_tokens')
->default(0);
$table->unsignedBigInteger('output_tokens')
->default(0);
$table->unsignedBigInteger('total_tokens')
->default(0);
$table->decimal('estimated_cost', 12, 6)
->default(0);
$table->unsignedInteger('latency_ms')
->nullable();
$table->boolean('cache_hit')
->default(false);
$table->boolean('success')
->default(true);
$table->timestamps();
});راقب Cost per User
قد تكتشف:
User #10
Monthly Revenue:
$100
AI Cost:
$4وهذا ممتاز.
لكن مستخدمًا آخر:
User #91
Monthly Revenue:
$19
AI Cost:
$38هنا لديك مشكلة تجارية حتى لو كانت Feature تعمل تقنيًا بشكل ممتاز.
راقب Cost per Feature
قد تكون التكلفة:
Support Chat
$500 / month
Lead Classification
$120 / month
Contract Analyzer
$3,800 / month
Daily AI Report
$7,200 / monthالآن أصبحت تعرف أين يجب أن تبدأ Optimization.
Budget Limits
لا تجعل استهلاك AI مفتوحًا بلا حدود، خصوصًا في SaaS.
يمكن بناء حدود حسب الخطة:
Basic
→ 100 AI actions / month
Pro
→ 1,000 AI actions / month
Enterprise
→ Customأو استخدم:
Monthly AI Credit Budgetبدل الاعتماد فقط على عدد Requests، لأن Request واحدة قد تكلف أكثر بكثير من أخرى.
Hard Limit وSoft Limit
Hard Limit
Budget exhausted
↓
AI disabledهذا بسيط لكنه قد يؤدي إلى تجربة سيئة.
Soft Limit
استراتيجية أكثر ذكاءً:
Budget 80%
↓
Switch non-critical tasks
to cheaper models
Budget 95%
↓
Disable optional bulk analysis
Budget 100%
↓
Keep only critical AI functionsAdaptive Cost Mode
يمكن أن تجعل النظام يعدل سلوكه تلقائيًا بناء على الاستهلاك.
Usage < 70%
→ Normal Mode
Usage 70%–90%
→ Cheapest acceptable models
Usage 90%–100%
→ Disable non-essential AI
Usage >= 100%
→ Critical AI onlyهذه Architecture أكثر مرونة من إغلاق AI بالكامل بمجرد الوصول إلى Limit.
راقب Cache Hit Rate
إذا كنت تستخدم Caching، يجب ألا تكتفي بتفعيلها.
راقب:
Cache Hits
Cache Misses
Hit Rateمثلًا:
10,000 AI-compatible operations
8,000 cache hits
2,000 API calls
Hit Rate:
80%هذا يعني أن Cache منعت 8,000 عملية محتملة.
راقب Token Distribution
المتوسط وحده قد يخدعك.
راقب:
Average Input Tokens
P50
P90
P95
P99قد تكتشف أن معظم Requests حجمها:
2,000 tokensلكن 1% منها تصل إلى:
80,000 tokensوهي التي ترفع الفاتورة بشكل كبير.
ضع Alerts للتكلفة غير الطبيعية
لا تنتظر نهاية الشهر حتى تكتشف المشكلة.
يمكن بناء Alerts مثل:
Daily AI cost > expected × 2
User cost > plan threshold
Feature cost spike > 50%
Token usage spike
Retry rate spike
Cache hit rate drops significantlyلا تعرض AI Feature مجانية بلا حماية
إذا كانت لديك Endpoint مثل:
POST /api/ai/generateمن دون:
- Authentication.
- Rate Limiting.
- Usage Quotas.
- Request Validation.
- Input Size Limits.
فأنت لا تواجه فقط خطر Abuse، بل أيضًا فاتورة غير محدودة.
ضع Input Size Limit قبل API
إذا كانت Feature مصممة لتحليل رسالة عميل، فلا تسمح للمستخدم بإرسال كتاب كامل.
$request->validate([
'message' => [
'required',
'string',
'max:10000',
],
]);حدد الحد بناءً على احتياجات Feature الحقيقية وليس رقمًا عشوائيًا.
Rate Limiting جزء من Cost Control
مثلًا:
RateLimiter::for('ai', function ($request) {
return Limit::perMinute(20)
->by($request->user()->id);
});يمكنك أيضًا وضع Limits مختلفة بناءً على خطة المستخدم.
لا ترسل أسرارًا وبيانات لا يحتاجها النموذج
Context Reduction لا تحسن التكلفة فقط، بل تقلل Data Exposure.
إذا كانت المهمة لا تحتاج:
- Password hashes.
- API keys.
- Internal metadata.
- Private notes.
- Full database records.
فلا ترسلها.
أفضل Token من ناحية التكلفة والأمان هو Token لم ترسلها أصلًا.
افصل AI Features حسب الغرض
بدل Agent ضخمة تحتوي على جميع تعليمات النظام:
MegaAgent
- Support
- Lead analysis
- Invoice extraction
- Contract analysis
- Sales strategy
- Classification
- Reports
- Everything elseيمكن تقسيمها إلى Agents صغيرة:
SentimentClassifier
LeadClassifier
SupportAgent
InvoiceExtractor
ContractAnalyzer
SalesCoachهذا يسمح لكل Agent بالحصول على:
- Prompt أقصر.
- Model مناسبة.
- MaxTokens مختلفة.
- MaxSteps مختلفة.
- Tools محددة.
مثال على Cost-Aware Architecture
User Request
│
▼
Laravel API
│
▼
Is AI Needed?
│ │
NO YES
│ │
▼ ▼
PHP / SQL Task Router
│
┌──────────────┼──────────────┐
▼ ▼ ▼
Simple Medium Complex
│ │ │
▼ ▼ ▼
Cheap Model Standard Model Strong Model
│ │ │
└──────────────┼──────────────┘
▼
Context Builder
│
┌─────────┼─────────┐
▼ ▼ ▼
RAG Memory Tools
│ │ │
└─────────┼─────────┘
▼
Cache Lookup
│ │
HIT MISS
│ │
▼ ▼
Result AI API
│
▼
Usage Tracking
│
▼
Result Cache
│
▼
UserProduction Strategy مقترحة
المرحلة 1: هل نحتاج AI؟
إذا كانت المهمة Deterministic، استخدم PHP أو SQL.
المرحلة 2: حدد نوع المهمة
classification
summary
support
extraction
reasoning
agent
RAGالمرحلة 3: اختر Model المناسبة
لا تستخدم Model واحدة لكل Tasks.
المرحلة 4: ابنِ Minimum Context
أرسل فقط المعلومات اللازمة.
المرحلة 5: افحص Cache
إذا كانت النتيجة متاحة وصالحة، لا تستدعِ API.
المرحلة 6: ضع Limits
MaxTokens
MaxSteps
Input Size
Timeout
Retriesالمرحلة 7: نفذ العملية
استخدم Queue إذا لم تكن النتيجة مطلوبة فورًا.
المرحلة 8: سجل Usage
احفظ Tokens والتكلفة وModel والـ Feature والـ User.
المرحلة 9: خزّن النتائج القابلة لإعادة الاستخدام
مع Cache Versioning واضح.
المرحلة 10: راقب الميزانية
استخدم Soft Limits قبل الوصول إلى Hard Limit.
Cost Optimization Checklist
قبل إطلاق أي AI Feature في Laravel، اسأل الأسئلة التالية:
- هل تحتاج المهمة إلى AI أصلًا؟
- هل يستطيع PHP أو SQL تنفيذها؟
- هل نستخدم Model أقوى من المطلوب؟
- هل توجد Model أرخص تحقق الجودة نفسها؟
- هل تم إجراء Evaluation بين Models؟
- هل يمكن استخدام Escalation؟
- هل يمكن Cache النتيجة؟
- هل Cache Key تحتوي Prompt Version؟
- هل Embedding نفسها موجودة مسبقًا؟
- هل المحتوى تغير أصلًا قبل Re-indexing؟
- هل نرسل بيانات أكثر مما تحتاجه المهمة؟
- هل Conversation History كبيرة؟
- هل يمكن استخدام Rolling Summary؟
- هل نسترجع Memories ذات صلة فقط؟
- هل Top-K في RAG أكبر من اللازم؟
- هل System Prompt أطول من اللازم؟
- هل Output أطول مما تحتاجه UI؟
- هل يمكن استخدام Structured Output؟
- هل MaxTokens محددة؟
- هل MaxSteps محددة؟
- هل Timeout مناسب؟
- هل Retry Policy مناسبة؟
- هل يمكن Queue العملية؟
- هل Job قد تُنفذ أكثر من مرة؟
- هل يمكن استخدام Unique Job؟
- هل نسجل Usage لكل Request؟
- هل نعرف Cost per User؟
- هل نعرف Cost per Feature؟
- هل لدينا Monthly Budget؟
- هل لدينا Alerts للارتفاع غير الطبيعي؟
- هل Endpoint محمية بـ Rate Limits؟
إذا لم تعرف إجابة عدد كبير من هذه الأسئلة، فهناك احتمال مرتفع لوجود Cost Waste داخل التطبيق.
ما الذي توفره Laravel نفسها لهذا النوع من Optimization؟
عند استخدام Laravel AI SDK وLaravel Framework، توجد عدة أدوات يمكن الاستفادة منها مباشرة.
UseCheapestModel
لاختيار Model منخفضة التكلفة للمهام التي لا تحتاج قدرات عالية.
UseSmartestModel
للمهام التي تستحق Model الأكثر قدرة.
Model
لتثبيت Model محددة عندما تحتاج Pricing وسلوكًا أكثر ثباتًا.
MaxTokens
للحد من حجم Generation.
MaxSteps
للحد من عدد خطوات Agent عند استخدام Tools.
Embedding Caching
لمنع إعادة طلب Embeddings المتطابقة.
Laravel Cache
لتخزين النتائج التي يمكن إعادة استخدامها.
Laravel Queues
لنقل العمليات الثقيلة أو غير الفورية إلى Background Workers.
Unique Jobs
لمنع بعض أنواع العمل المكرر.
Rate Limiting
للحد من Abuse والاستهلاك غير الطبيعي.
أين يبدأ أكبر توفير عادةً؟
ليس هناك Trick واحدة تخفض الفاتورة للجميع.
لكن في معظم المشاريع، يجب البحث أولًا عن هذه النقاط:
- إرسال Context أكبر من اللازم.
- استخدام Model قوية لمهام بسيطة.
- عدم استخدام Cache.
- إعادة إنشاء Embeddings بلا داعٍ.
- إرسال Conversation History كاملة.
- Outputs طويلة وغير ضرورية.
- AI Jobs مكررة.
- Retries غير منضبطة.
- Agent loops طويلة.
- عدم وجود Usage Tracking.
الخلاصة
تقليل تكلفة AI API داخل Laravel لا يعني البحث عن أرخص Model ثم استخدامها في كل شيء.
هذه الطريقة قد تقلل سعر Request الواحدة، لكنها قد تدمر الجودة وترفع عدد الإعادات والأخطاء، وبالتالي تصبح أغلى على مستوى النظام.
الاستراتيجية الصحيحة هي:
Right Task
↓
Is AI Really Needed?
↓
Right Model
↓
Minimum Required Context
↓
Minimum Useful Output
↓
Cache When Possible
↓
Avoid Duplicate Work
↓
Queue When Appropriate
↓
Track Usage
↓
Control Budgets
↓
Evaluate Quality vs Costتذكر أن الفاتورة الكبيرة نادرًا ما تأتي من Request واحدة مكلفة.
غالبًا تأتي من قرار صغير غير فعال يتكرر عشرات أو مئات الآلاف من المرات.
System Prompt أكبر من اللازم بمئات Tokens.
Conversation كاملة تُرسل في كل رسالة.
Embedding تُنشأ للمحتوى نفسه مرارًا.
Model قوية تُستخدم لمجرد Classification بسيطة.
Generation من 1,000 Token بينما التطبيق يحتاج 50 فقط.
Job واحدة يتم تنفيذها ثلاث مرات.
كل واحدة من هذه المشكلات قد تبدو صغيرة وحدها، لكن عند Scale تصبح تكلفة حقيقية.
أفضل نظام AI ليس النظام الذي يستخدم أقوى Model في كل Request، بل النظام الذي يعرف متى يحتاج إلى الذكاء، وكم يحتاج منه، ومتى لا يحتاج إليه أصلًا.
التعليقات (0)
لا توجد تعليقات بعد — كن أول من يشارك رأيه.
أضف تعليقك