Khaled Ahmed
الرئيسية المدوّنة الخلفيه والمعماريه
الخلفيه والمعماريه

دمج OpenAI مع Laravel: البث المباشر وضبط التكلفة وأخطاء الإنتاج

Khaled Ahmed 16 min read

إذا كنت تضيف ميزة ذكاء اصطناعي إلى تطبيق Laravel في عام 2026، فابدأ بحزمة laravel/ai الرسمية ما لم يكن لديك سبب تقني واضح لغير ذلك، وتعامل مع مفتاح OpenAI باعتباره وسيلة دفع لا مجرد متغير في ملف الإعدادات. أنا خالد أحمد، مطوّر Full Stack من القاهرة، بخبرة تتجاوز خمس سنوات وأكثر من 39 مشروعًا إنتاجيًا في ثماني دول. هذا المقال هو القائمة التي أطبّقها فعليًا: اختيار الحزمة، والبث المباشر، والطوابير، وحدود الاستدعاء، وضبط التكلفة قبل أن تتحوّل التجربة إلى فاتورة.

1. الخلاصة أولًا: أي حزمة تستخدم في بيئة الإنتاج؟

الإجابة المختصرة حتى أغسطس 2026: استخدم laravel/ai. هي الحزمة الرسمية من فريق Laravel نفسه، وقد تحوّل إليها ثقل المنظومة كلها خلال أشهر قليلة.

أما التحفّظ الذي لن يذكره لك من يبيعك ميزة ذكاء اصطناعي، فهو أن الحزمة ما زالت في الإصدار 0.x. الإصدار المنشور على Packagist وقت كتابة هذا المقال هو v0.10.3 بتاريخ 6 أغسطس 2026، ويتطلب PHP بإصدار ^8.3 وLaravel ^12.0 أو ^13.0. صدر منها ستة وأربعون إصدارًا حتى الآن، أي أن وتيرة التغيير سريعة جدًا. ثبّت الإصدار في ملف composer.json بقيد محدد، واقرأ ملاحظات الإصدار قبل أي ترقية، ولا تبنِ نظامًا لن تلمسه لعامين فوق اعتمادية ما زالت في مرحلة ما قبل الاستقرار.

هذا مقارنة صريحة بين الخيارات الأربعة الواقعية، وقد استخدمتها جميعًا:

الخيار الإصدار وتاريخ التحقق يناسب الثمن الذي تدفعه
laravel/ai الرسمية v0.10.3 — 6 أغسطس 2026 · PHP ‎^8.3‎ · Laravel 12/13 المشاريع الجديدة. تدعم الوكلاء والأدوات والمخرجات المهيكلة والبث والطوابير والبث اللحظي والتضمينات ومخازن المتجهات والتحويل التلقائي بين المزوّدين. ما زالت 0.x بإصدارات شبه أسبوعية، والتغييرات الكاسرة أمر متوقع. طبقة التجريد قد تتأخر أحيانًا عن مزايا خاصة بمزوّد بعينه.
openai-php/laravel v0.20.0 — 15 يونيو 2026 · PHP ‎^8.2‎ · Laravel 11.29/12.12/13 من يريد غلافًا رفيعًا وأمينًا فوق واجهة OpenAI نفسها، بما فيها Responses API، دون طبقة وسيطة. أيضًا 0.x، ومصمّمة لمزوّد واحد فقط. لا تحويل تلقائي ولا تجريد، وستبني بنفسك منطق إعادة المحاولة وتتبّع التكلفة.
prism-php/prism v0.100.1 — 20 مارس 2026 التطبيقات القائمة عليها بالفعل. كانت أفضل خيار متعدد المزوّدين قبل صدور الحزمة الرسمية. تباطأت وتيرة إصداراتها بوضوح بعد ظهور laravel/ai. راجع حالة المستودع بنفسك قبل بدء أي مشروع جديد عليها.
استدعاء مباشر عبر Http:: عميل HTTP المدمج في Laravel ميزة واحدة، ونقطة نهاية واحدة، ونموذج واحد. زر «لخّص لي هذا النص» مثلًا. ستعيد كتابة تحليل البث وإعادة المحاولة والمهل وتسجيل الاستهلاك يدويًا. مقبول لاستدعاء واحد، مرهق لعشرة.

قاعدة عملية: استدعاء واحد فقط في التطبيق كله؟ استخدم Http:: وانتهِ. استدعاءان أو أكثر، أو احتمال إضافة مزوّد ثانٍ لاحقًا؟ استخدم laravel/ai. ولا تثبّت حزمتين للذكاء الاصطناعي جنبًا إلى جنب أبدًا، وإلا انتهيت بسياستَي إعادة محاولة، ومهلتين مختلفتين، ولا مكان واحد يخبرك كم أنفقت.

لماذا غيّرت الحزمة الرسمية المعادلة فعلًا

ليست المسألة أنها «رسمية» فحسب. المسألة أن أربعة أشياء كنت أبنيها يدويًا في كل مشروع صارت جزءًا من إطار العمل: بثّ Server-Sent Events يمكن إرجاعه مباشرة من الـ route، ودالة queue() مصحوبة بـ then وcatch، وتحويل تلقائي بين المزوّدين بمجرد تمرير مصفوفة، ومجموعة أحداث جاهزة مثل PromptingAgent وAgentPrompted وInvokingTool وToolInvoked وStreamingAgent وAgentStreamed تمنحك نقطة تعليق نظيفة لتسجيل التكلفة. هذا أسبوع عمل كامل لم أعد أحاسب عليه أحدًا.

2. التثبيت والقرارات التي تُتخذ مرة واحدة

التثبيت ثلاثة أوامر:

composer require laravel/ai

php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"

php artisan migrate

يُنشئ الترحيل جدولَي agent_conversations وagent_conversation_messages. افتح هذين الجدولين وتأمّلهما قبل تشغيل الترحيل على تطبيق متعدد المستأجرين، لأنك تحتاج إلى تحديد أين تعيش سجلات المحادثة إذا كنت تفرض عزل المستأجرين على مستوى قاعدة البيانات. تناولت هذا الحد الفاصل بتفصيل أكبر في دليل بناء SaaS متعدد المستأجرين على Laravel، والقاعدة نفسها تنطبق هنا: المحادثة بيانات مستأجر، وستحتوي على كل ما لصقه المستخدمون بداخلها.

تُوضع بيانات الاعتماد في config/ai.php أو في .env. تتعرّف الحزمة على مفاتيح OpenAI وAnthropic وGemini وMistral وCohere وxAI وGroq وDeepSeek وOpenRouter وAzure OpenAI وElevenLabs وJina وVoyageAI وOllama، إضافة إلى مزوّد عام متوافق مع واجهة OpenAI يغطي أي نموذج تستضيفه بنفسك أو تشغّله خلف Bedrock. هذا الاتساع وحده يوضّح مدى جدية طبقة التجريد.

ثلاثة قرارات إعداد يخطئ فيها أغلب الفرق:

  • حدّد عنوان قاعدة مخصصًا إذا احتجت نقطة تحكم مركزية. يسمح لك المعامل url داخل إعدادات المزوّد بتمرير الطلبات عبر LiteLLM أو نقطة نهاية vLLM تستضيفها بنفسك أو وسيط خاص بك. (أمّا Azure OpenAI فلا يحتاج إلى هذه الحيلة، لأنه مزوّد معتمد داخل الحزمة أصلًا.) هكذا تركّز إدارة المفاتيح، وتفرض سقف إنفاق خارج شيفرة التطبيق، وتسجّل كل طلب حتى لو تجاوز أحد المطورين طبقة الخدمة لديك. في المشاريع المنظَّمة — البنوك والقطاع الصحي وأي مشروع في السعودية يمسّ بيانات شخصية — يكون هذا شرطًا لا خيارًا.
  • اضبط المهلة عن قصد. المهلة الافتراضية في الحزمة ستون ثانية، ونموذج استدلالي يستدعي أدوات قد يتجاوزها. استخدم السمة #[Timeout(120)] على الوكلاء البطيئة تحديدًا بدل رفع القيمة العامة وإخفاء التعليقات الحقيقية.
  • لا تضع المفتاح في حزمة الواجهة الأمامية إطلاقًا. بديهي، ومع ذلك ورثت مشروعين كان فيهما VITE_OPENAI_API_KEY ظاهرًا في ملف JavaScript عام. غيّر المفتاح فورًا، ثم راجع قائمة فحص أمان الموقع قبل إطلاق أي شيء آخر.

3. الوكلاء: وحدة التجريد الصحيحة

الفكرة المركزية في الحزمة هي الوكيل (Agent): صنف PHP يملك التعليمات وسياق المحادثة والأدوات ومخطط المخرجات. تنشئه بأمر php artisan make:agent SupportTriage، أو تضيف --structured للحصول على نسخة بمخطط JSON.

namespace App\Ai\Agents;

use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Attributes\MaxTokens;
use Laravel\Ai\Attributes\Model;
use Laravel\Ai\Attributes\Provider;
use Laravel\Ai\Attributes\Temperature;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasStructuredOutput;
use Laravel\Ai\Enums\Lab;
use Laravel\Ai\Promptable;
use Stringable;

#[Provider(Lab::OpenAI)]
#[Model('gpt-5.6-luna')]
#[MaxTokens(600)]
#[Temperature(0.2)]
class SupportTriage implements Agent, HasStructuredOutput
{
    use Promptable;

    public function instructions(): Stringable|string
    {
        return 'صنّف تذكرة الدعم. لا تخترع رقم طلب غير موجود.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'category' => $schema->string()->required(),
            'urgency'  => $schema->integer()->min(1)->max(5)->required(),
            'reply'    => $schema->string()->required(),
        ];
    }
}

سطران في هذا المثال ليسا مسألة ذوق، بل أداتا ضبط تكلفة. السمة #[MaxTokens(600)] سقف صارم على الشطر الأغلى من الفاتورة، والسمة #[Temperature(0.2)] في مهمة تصنيف تقلّص الإسهاب الذي يضخّم رموز المخرجات. أما المخطط المهيكل فيمنحك JSON قابلًا للتحليل بدل فقرة نصية تلاحقها بالتعبيرات النمطية، وهو الانضباط ذاته الذي أدافع عنه في أفضل ممارسات تصميم واجهات API: عرّف العقد أولًا، ثم أجبر النظام على احترامه.

تقدّم الحزمة أيضًا السمتين #[UseCheapestModel] و#[UseSmartestModel]. مريحتان، لكنني أتجنّبهما في الإنتاج. تعريف «الأرخص» تحدده الحزمة لا أنت، وقد يتبدّل تحت قدميك مع ترقية صغيرة. سمِّ النموذج صراحةً، وغيّره عن قصد.

4. كيف تبثّ الرموز إلى المتصفح من Laravel؟

البث المباشر هو أكبر مكسب في جودة التجربة المدركة. من واقع مراقبتي لاستخدام هذه المزايا، زمن الانتظار نفسه يُقرأ سريعًا حين يرى المستخدم النص يتوالى أمامه، ويُقرأ عطلًا حين يرى مؤشر تحميل صامتًا: يصبر الناس على توليد طويل يرونه، ويغادرون بسرعة أمام شاشة لا تتحرك.

مع الحزمة الرسمية، المسار السعيد سطر واحد فعلًا، لأن الكائن المُعاد StreamableAgentResponse صالح كاستجابة route ويرسل أحداث Server-Sent Events تلقائيًا:

use App\Ai\Agents\SupportTriage;
use Laravel\Ai\Responses\StreamedAgentResponse;

Route::post('/ai/triage', function (Request $request) {
    return SupportTriage::make()
        ->stream($request->string('ticket'))
        ->then(function (StreamedAgentResponse $response) {
            // $response->text و $response->usage
            // خزّن الرسالة وعدّاد الرموز هنا تحديدًا
        });
})->middleware(['auth', 'throttle:ai']);

إذا كانت واجهتك مبنية على React أو Next.js وتستخدم بالفعل Vercel AI SDK في المتصفح، فاستدعِ ->usingVercelDataProtocol() على الاستجابة، فيتطابق تنسيق البث مع ما يتوقعه useChat دون أن تكتب محلّلًا خاصًا. هذا يوفّر وقتًا حقيقيًا في المعمارية التي أشرحها في بناء نسخة SaaS أولى بـ Laravel وReact.

أربعة أسباب تُفشل البث على الخادم رغم نجاحه محليًا

الشيفرة سهلة، والبنية التحتية هي التي تُضيّع يومين من عمر المشروع.

  1. تخزين Nginx المؤقت. افتراضيًا يخزّن Nginx استجابة الخادم الخلفي ويسلّمها دفعة واحدة في النهاية، فيصلك «بثّ» ليس بثًا. تحتاج إلى proxy_buffering off; وإلى ترويسة X-Accel-Buffering: no على مسار البث. هذا السبب الأول لعبارة «يعمل عندي ولا يعمل على الـ server».
  2. Cloudflare وشبكات التوزيع. قد تُخزَّن استجابة SSE مؤقتًا أو تُقطع عند حافة عدوانية. استثنِ مسار البث من التمرير عبر الوكيل، أو تحقّق منه من طرف إلى طرف قبل أن تَعِد العميل به. وإذا كنت ما زلت تختار البنية، فمقالي عن اختيار الاستضافة المناسبة يوضّح أي إعداد يجعل هذا الأمر بلا وجع.
  3. عدد عمّال PHP-FPM. كل اتصال بث مفتوح يحجز عاملًا كاملًا طوال عمره. بقيمة pm.max_children = 20 تكفي عشرون محادثة متزامنة لتجميد الموقع بأكمله. إمّا أن تنتقل إلى Octane، أو تستخدم مسار البث اللحظي أدناه، أو ترفع عدد العمّال وأنت مدرك للتكلفة. هنا تحديدًا يتوقف نقاش Laravel مقابل Node.js عن كونه نظريًا: حلقة أحداث Node تتعامل مع اتصالات طويلة خاملة بتكلفة أقل، وPHP يحتاج إلى Octane أو طابور لمجاراتها.
  4. مهلة الخمول في موازن الحمل. موازن حمل أو وكيل عكسي بمهلة خمول ستين ثانية سيقطع توليدًا طويلًا في منتصف الجملة. ارفع المهلة على مسار البث وحده.

البديل: البث عبر WebSockets بدل HTTP

إذا كان حجز عمّال HTTP غير مقبول لديك، فادفع عملية التوليد إلى طابور وابثّ الأجزاء لحظيًا. الحزمة تدعم ذلك مباشرة:

use Illuminate\Broadcasting\PrivateChannel;

SupportTriage::make()->broadcastOnQueue(
    $request->string('ticket'),
    new PrivateChannel('conversations.'.$conversation->id),
);

يعود طلب HTTP فورًا، ويتولى عامل الطابور التوليد، ويوصل Reverb أو Pusher الرموز إلى المتصفح. الثمن طبقة WebSocket إضافية وأجزاء متحركة أكثر، لكنه النمط الذي يتوسّع فعلًا فوق بضع عشرات من المستخدمين المتزامنين على استضافة PHP اعتيادية.

اختر بحسب التزامن: أقل من ثلاثين عملية توليد متزامنة تقريبًا؟ SSE مع Octane أبسط وكافٍ. أكثر من ذلك؟ طابور مع بث لحظي. ولا تبنِ طبقة WebSocket في اليوم الأول لمنتج لديه أربعون مستخدمًا.

5. أين توضع استدعاءات الذكاء الاصطناعي: في المتحكّم أم في الطابور؟

القاعدة التي أطبّقها في كل مشروع:

  • في المتحكّم مع بث: عندما يكون المستخدم ينتظر أمام الشاشة والمخرج نفسه هو المنتج. المحادثة، الصياغة، «اشرح لي هذا». ابثّها.
  • في مهمة طابور: كل ما عدا ذلك. التصنيف، والتلخيص عند الرفع، وتوليد التضمينات، وإثراء البيانات، والترجمة الجماعية، وأي شيء يبدأ من webhook.
  • ولا تستدعِ النموذج تزامنيًا في متحكّم بلا بث إطلاقًا. هذا طلب يستغرق من ثلاث إلى أربعين ثانية، ويحجز عاملًا، ويموت على خطأ 502، ولا يمكن إعادة تنفيذه. إنه أسوأ الخيارين معًا، وهو أكثر خطأ أصادفه في الشيفرات الموروثة.

الطابور في الحزمة مباشر ومملّ بالمعنى الجيد:

SupportTriage::make()
    ->queue($ticket->body)
    ->then(fn ($response) => $ticket->applyTriage($response))
    ->catch(fn (Throwable $e) => report($e));

وأربع قواعد تشغيلية تعلّمتها بالطريقة المكلفة:

  1. ضع مهام الذكاء الاصطناعي في طابور مستقل وتحت مشرف Horizon خاص بها. نموذج بطيء يجب ألا يعطّل رسائل إعادة تعيين كلمة المرور.
  2. اجعل $tries منخفضًا و$backoff صريحًا. أستخدم public $tries = 3; وpublic $backoff = [10, 60, 300];. حلقة إعادة محاولة افتراضية أمام واجهة مدفوعة تعني الدفع ثلاث مرات مقابل الفشل نفسه.
  3. اجعل المهمة عديمة الأثر عند التكرار. خزّن بصمة للمدخل واخرج مبكرًا إذا كانت النتيجة محفوظة. عمّال الطوابير يُقتلون في منتصف التنفيذ أثناء النشر، وبدون هذه الخطوة تعيد التوليد وتعيد الدفع.
  4. احفظ الاستهلاك داخل المعاملة نفسها التي تحفظ النتيجة. إن حفظت الإجابة وضاع عدد الرموز، فلوحة التكلفة عندك مجرد تخمين.

6. كيف تمنع ميزة الذكاء الاصطناعي من التهام ميزانيتك؟

هذا هو القسم الذي يهتم به العميل بعد الأسبوع الثاني. فيما يلي أسعار OpenAI المعلنة لكل مليون رمز، تحققت منها في أغسطس 2026. راجعها بنفسك قبل أن تعطي عرض سعر لأي أحد، لأن هذا الجدول تغيّر أكثر من مرة سنويًا منذ 2023. التشكيلة الحالية على صفحة الأسعار هي عائلة GPT-5.6: نموذج Sol الرائد، وTerra للفئة المتوازنة اليومية، وLuna للفئة الاقتصادية. وقد خُفّض سعر Terra بنسبة 20% وسعر Luna بنسبة 80% في 30 يوليو 2026، بينما بقي Sol على حاله. وما زالت أجيال GPT-5 وGPT-4.1 متاحة وتستحق المعرفة، لأن كثيرًا من التطبيقات الإنتاجية مثبّتة عليها:

النموذج المدخلات / مليون المدخلات المخزّنة / مليون المخرجات / مليون
GPT-5.6 Sol (الرائد)5.00 USD0.50 USD30.00 USD
GPT-5.6 Terra2.00 USD0.20 USD12.00 USD
GPT-5.6 Luna0.20 USD0.02 USD1.20 USD
GPT-5 / GPT-5.11.25 USD0.125 USD10.00 USD
GPT-5-mini0.25 USD0.025 USD2.00 USD
GPT-5-nano0.05 USD0.005 USD0.40 USD
GPT-4.12.00 USD0.50 USD8.00 USD
GPT-4.1-mini0.40 USD0.10 USD1.60 USD
o4-mini1.10 USD0.275 USD4.40 USD

وهامشان يؤلمان في الإنتاج. في فئات GPT-5.6، الطلبات التي تتجاوز نحو 272 ألف رمز في المدخلات تنتقل إلى شريحة سعر أعلى للسياق الطويل، أي أن ميزة بحث دلالي يتضخّم سياقها تدريجيًا قد تغيّر شريحة سعرها دون أن يعدّل أحد سطرًا واحدًا. وفي GPT-5.6 وما بعده، تُحاسَب كتابة المخزون المؤقت بمعدل 1.25 ضعف سعر المدخلات غير المخزّنة؛ رخيصة لكنها ليست مجانية، فتخزين مقدمة تستخدمها مرة واحدة خسارة صغيرة لا مكسبًا صغيرًا.

اقرأ شكل الجدول لا أرقامه. المخرجات تكلّف من ستة إلى ثمانية أضعاف المدخلات عبر التشكيلة كلها — ستة أضعاف في Sol وثمانية في GPT-5. المدخلات المخزّنة مؤقتًا تكلّف عُشر المدخلات الجديدة. الفئة الاقتصادية أرخص من الرائد بخمسة وعشرين ضعفًا في المدخلات — Luna بـ 0.20 دولار مقابل Sol بـ 5.00 دولارات. كل أدوات ضبط التكلفة الحقيقية تتفرّع من هذه الحقائق الثلاث.

سبع أدوات، بترتيب تطبيقي

  1. ضع سقفًا لرموز المخرجات. #[MaxTokens] على كل وكيل بلا استثناء. توليد بلا سقف يعني فاتورة بلا سقف.
  2. وجّه الطلبات بحسب صعوبتها. معظم حركة الإنتاج الحقيقية تصنيف واستخراج وردود قصيرة، وهذه تعمل على gpt-5.6-luna، أو على gpt-5-mini وgpt-5-nano إن كنت مثبّتًا على الجيل السابق. احتفظ بـ Sol، أو بأي نموذج رائد وقت قراءتك، لخمسة إلى عشرة بالمئة من الطلبات التي تحتاجه فعلًا. في خبرتي، هذه الخطوة وحدها تزيل عادةً الجزء الأكبر من الفاتورة، لأن الفرق تضبط الميزة كلها افتراضيًا على أضخم نموذج ثم لا تعود إليها.
  3. استفد من التخزين المؤقت للتعليمات. المدخلات المخزّنة أرخص بنسبة تسعين بالمئة، لكن اقرأ العبارة بدقة: الخصم يسري على رموز المقدمة المخزّنة عند تحقق التطابق، لا على فاتورة المدخلات كلها. وشرطان يحكمان ذلك. الأول أن تكون بداية التعليمات ثابتة: ضع التعليمات الطويلة والمخطط والأمثلة في المقدمة، وضع محتوى المستخدم المتغيّر في النهاية. والثاني أن التخزين التلقائي في OpenAI لا يبدأ إلا عند مقدمة بطول ألف وأربعة وعشرين رمزًا تقريبًا، ثم يتقدّم بخطوات من 128 رمزًا، أي أن التعليمات القصيرة لا تُخزَّن أصلًا، والمخزون يسقط بعد دقائق قليلة من عدم الاستخدام. اضبط الشرطين فينخفض الجزء الثابت من مدخلاتك بنسبة تسعين بالمئة، وأخطئ في الترتيب فتدفع السعر الكامل في كل استدعاء. ومعظم الفرق لا تنظر في هذا إطلاقًا.
  4. استخدم Batch API لكل ما ليس أمام المستخدم. الخصم خمسون بالمئة من السعر القياسي. الإثراء الليلي، ومعالجة البيانات التاريخية، وإعادة توليد تضمينات كتالوج المنتجات — كلها تنتمي إلى Batch.
  5. فكّر في flex processing للأعمال غير المتزامنة. خيار service_tier بقيمة flex يُسعَّر بأسعار Batch مقابل استجابة أبطأ. وفق التوثيق الذي راجعته في أغسطس 2026 ما زال موصوفًا بأنه تجريبي وبتوافر محدود للنماذج، وقد يعيد خطأ 429 «resource unavailable»، ولا تُحاسَب عليه صراحةً. والمهلة الافتراضية في حِزم OpenAI الرسمية عشر دقائق على طلبات flex، وقد تحتاج المهام المعقّدة إلى أكثر منها: ارفع المهلة عن قصد، وتراجع تدريجيًا عند 429، واسقط إلى service_tier: auto إن كان للعمل موعد نهائي أصلًا. مفيد، لكن لا تضع مستخدمًا ينتظر أمامه.
  6. خزّن نتائجك أنت مؤقتًا. احسب بصمة للمدخل المُطبَّع مع اسم النموذج ورقم نسخة التعليمات، واحفظ الاستجابة. في أدوات الرد على الدعم أو توليد أوصاف المنتجات تكون نسبة معتبرة من الطلبات شبه مكررة. هذا تخزين مؤقت تطبيقي عادي وهو ربح مجاني، والمبدأ نفسه الذي أشرحه في لماذا يفتح موقعك ببطء.
  7. قِس الاستهلاك لكل مستخدم ولكل مستأجر. خزّن prompt_tokens وcompletion_tokens واسم النموذج والتكلفة المحسوبة مع معرّف المستخدم في كل استدعاء، ثم افرض حصة. بدون ذلك يكفي مستخدم واحد متحمّس أو خطأ في حلقة برمجية ليفتح الصنبور على آخره. صمّم هذا الجدول جيدًا من المرة الأولى، وملاحظاتي في تصميم قواعد البيانات لتطبيقات الويب تنطبق حرفيًا.

الحزمة تمنحك خطاف الأداة السابعة مجانًا: استمع لحدثَي AgentPrompted وAgentStreamed واكتب سجل الاستهلاك من داخل المستمع. مستمع واحد يغطي كل الاستدعاءات، بلا صنف خدمة يتذكّر الجميع المرور عبره.

اضبط حدًا صارمًا للفوترة في لوحة OpenAI من اليوم الأول. ليس تنبيهًا عند تجاوز مبلغ، بل سقفًا صارمًا يوقف الاستدعاءات. هذا هو الضابط الوحيد الذي يعمل وأنت نائم، وقد أنقذ أكثر من عميل من حلقة خارجة عن السيطرة اكتُشفت صباح الاثنين.

7. كيف تتعامل مع حدود الاستدعاء وإعادة المحاولة بأمان؟

تُعيد OpenAI رمز الحالة 429 عند تجاوز الحد، وترسل ترويسات يجب أن تقرأها فعلًا: Retry-After وx-ratelimit-limit-requests وx-ratelimit-remaining-requests وx-ratelimit-limit-tokens وx-ratelimit-remaining-tokens وترويسات reset المقابلة. الحدود مرتبطة بمستوى الاستخدام الذي يرتفع مع الإنفاق التراكمي، ولذلك يكون مفتاح جديد في المستوى الأول مقيَّدًا بدرجة أكبر بكثير من مفتاح في المستوى الرابع. هذا يفسّر الظاهرة الشائعة: ميزة عملت في بيئة الاختبار على المفتاح الشخصي للمؤسس، ثم انهارت على حساب الشركة.

أربع قواعد:

  1. احترم Retry-After ثم أضف عشوائية. تراجع ثابت عبر عدة عمّال ينتج عاصفة إعادة محاولة متزامنة تُعيد تفعيل الحد نفسه. أضف jitter.
  2. اخنق الطلبات قبل الإرسال لا بعد الفشل. استخدم Redis::throttle() أو وسيط المهام RateLimited لتبقى تحت السقف بدل أن تكتشفه. أرخص وأهدأ من إعادة المحاولة التفاعلية.
  3. فرّق بين أصناف الأخطاء. خطأ 429 بسبب معدل الاستدعاء يُعاد بتراجع تدريجي. خطأ 429 بسبب نفاد الرصيد لا يُعاد إطلاقًا، لأن البطاقة فشلت وإعادة المحاولة تملأ جدول المهام الفاشلة فحسب. خطأ 400 بسبب طول السياق لا يُعاد بل يُقتطع المدخل. أخطاء 500 و503 تُعاد بضع مرات. إعادة المحاولة العمياء على أي استثناء هي كيف تتحوّل طلبيّة سيئة واحدة إلى ثلاثمئة.
  4. حوّل ولا تسقط. تقبل الحزمة مصفوفة مزوّدين: provider: [Lab::OpenAI, Lab::Anthropic]. لميزة يجب أن تبقى حيّة أثناء عطل مزوّد، هذا المعامل الواحد هو خطة التعافي بأكملها — بشرط ألا تكون تعليماتك ومخططاتك مرتبطة بـ OpenAI ارتباطًا يجعل البديل ينتج نصًا رديئًا. اختبر مسار البديل عمدًا مرة واحدة على الأقل.

8. أخطاء إنتاج لا يحذّرك منها أحد

البث يُصعّب مراجعة المحتوى

توثيق OpenAI نفسه يشير إلى هذه النقطة: تقييم المخرجات الجزئية أصعب، وإشارات مراجعة المحتوى تصل بعد اكتمال التوليد. إذا كنت تبثّ نصًا إلى مستخدمين نهائيين في منتج استهلاكي، فأنت تعرض النص قبل أن تحكم عليه. إمّا أن تقبل هذه المخاطرة صراحةً، أو ألا تبثّ في المزايا القريبة من المحتوى الذي ينشئه المستخدمون.

الأدوات سطح هجوم

في اللحظة التي تمنح فيها الوكيل أداة تقرأ من قاعدة بياناتك، يصبح بإمكان تعليمة المستخدم أن تحاول توجيه تلك الأداة. قيّد كل أداة بالمستخدم المصادَق عليه على مستوى الاستعلام نفسه، ولا تثق أبدًا بمعرّف خرج من نموذج، وتحقّق من وسائط الأداة بالصرامة ذاتها التي تتحقق بها من طلب نموذج. عامل النموذج كعميل غير موثوق يستدعي واجهتك الداخلية.

تسجيل التعليمات قرار يمسّ حماية البيانات

تسجيل التعليمات كاملة مفيد جدًا في التنقيح، ويتحول إلى مسؤولية قانونية في اليوم الذي يلصق فيه مستخدم رقم هوية أو تفصيلًا طبيًا. سجّل افتراضيًا عدد الرموز واسم النموذج وزمن الاستجابة وبصمة التعليمة ومقتطفًا مقتطعًا منها فقط. أمّا التسجيل الكامل فليكن خلف مفتاح تشغيل، وبمدة احتفاظ محددة، ومذكورًا في سياسة الخصوصية — خصوصًا لعملاء السعودية والإمارات حيث تشتدّ قواعد حماية البيانات الشخصية عامًا بعد عام.

مجموعات التقييم هي اختبارات الانحدار عندك

لا يمكنك كتابة اختبار وحدة يقيس «هل هذا الرد جيد»، لكن يمكنك بناء مجموعة من ثلاثين مدخلًا حقيقيًا مع التصنيف المتوقع لكل منها والتحقق منها. الحزمة تجعل هذا رخيصًا عبر SupportTriage::fake()، التي تقبل استجابة ثابتة أو مصفوفة استجابات أو دالة تفحص كائن AgentPrompt الوارد. استخدم التزييف في CI حتى لا تكلفك الاختبارات شيئًا، وشغّل مجموعة التقييم الحقيقية يدويًا قبل تغيير أي نموذج أو تعليمة.

رقّم نسخ التعليمات

خزّن رقم نسخة التعليمة مع كل استدعاء مسجَّل. حين تنخفض الجودة في الربع القادم، أول سؤال سيكون «ما الذي تغيّر»، وجملة «عدّلنا التعليمات في مارس» لا يمكن الإجابة بها إلا إذا كنت قد كتبتها.

9. كم تكلّف هذه الميزة؟

نطاقات صادقة، لا عرض سعر. هذه هي الشرائح التي أنطلق منها كمطوّر مستقل يعمل عن بُعد من القاهرة، وشركات التطوير في لندن أو دبي تطلب عادةً ضعفين إلى أربعة أضعاف للنطاق نفسه، وقد فصّلت ذلك في مطوّر مستقل أم شركة تطوير.

النطاق ما يشمله تكلفة التنفيذ المعتادة الإنفاق الشهري المتوقع على الواجهة
ميزة واحدة وكيل واحد عبر طابور، تسجيل استهلاك، لوحة متابعة للمشرف. بلا بث. 900 – 2,000 USD 20 – 150 USD
مساعد محادثة ببث مباشر واجهة محادثة، SSE أو Reverb، تخزين المحادثات، حصص لكل مستخدم، خنق للطلبات. 2,500 – 6,000 USD 100 – 800 USD
بحث دلالي على مستنداتك استيعاب المستندات، التقطيع، التضمينات، مخزن المتجهات، ضبط الاسترجاع، الاستشهادات. 5,000 – 12,000 USD 150 – 1,500 USD
سير عمل وكيل بأدوات أدوات متعددة تستدعي واجهاتك الداخلية، موافقات بشرية، سجل تدقيق، مزوّد احتياطي. 8,000 – 20,000+ USD متغيّر بشدة

الافتراضات خلف هذه الأرقام: قاعدة شيفرة Laravel 12 أو 13 قائمة وبحالة معقولة، وحساب الواجهة باسمك أنت، وعمود الإنفاق الشهري مبني على توجيه ذكي للنماذج لا على تشغيل كل شيء على النموذج الرائد. عملاء مصر والخليج يطلبون غالبًا الأرقام نفسها بالجنيه المصري أو الريال السعودي أو الدرهم الإماراتي، وأنا أسعّر بالعملة التي تفضّلها. أمّا تكلفة استهلاك الواجهة فتُحاسب دائمًا على حسابك مباشرة في OpenAI، ولا تمرّ عبري بأي هامش.

العامل الأكبر في تكلفة التنفيذ ليس الذكاء الاصطناعي، بل حالة الشيفرة المحيطة به. إضافة وكيل إلى تطبيق Laravel نظيف ومختبَر تستغرق أسبوعًا. إضافته إلى تطبيق عمره خمس سنوات بلا عمّال طوابير، وبلا Horizon، ومنطق أعماله ساكن داخل المتحكّمات، تستغرق شهرًا، لأنك ستبني الأساس أولًا.

10. قائمة فحص قبل الإطلاق

  • سقف فوترة صارم مضبوط في لوحة المزوّد، لا مجرد تنبيه.
  • #[MaxTokens] على كل وكيل، ونموذج مسمّى صراحةً لا مُختار تلقائيًا.
  • النموذج الرخيص هو الافتراضي، والرائد على المسارات التي تحتاجه فقط.
  • مقدمة تعليمات ثابتة وطويلة بما يكفي لتجاوز الحد الأدنى للتخزين المؤقت، حتى يعمل فعلًا.
  • قياس رموز لكل مستخدم يُكتب من مستمع أحداث، مع حصة مفروضة.
  • مهام الذكاء الاصطناعي في طابور مستقل بـ $tries و$backoff صريحين، مع بصمة مدخل تمنع التكرار.
  • معالجة 429 تقرأ Retry-After وتضيف عشوائية، وبلا إعادة محاولة على 400 أو نفاد الرصيد.
  • مسار البث مستثنى من التخزين المؤقت للوكيل العكسي، وبمهلة خمول مرفوعة، ومختبَر على الخادم الحقيقي لا محليًا.
  • كل أداة مقيّدة بالمستخدم المصادَق عليه على مستوى الاستعلام.
  • بصمات التعليمات ونسخها مسجّلة، والتعليمات الكاملة خلف مفتاح تشغيل بمدة احتفاظ.
  • مجموعة تقييم ثابتة، وfake() في CI حتى لا تكلّف الاختبارات شيئًا.
  • خطة بديلة موثّقة: ماذا تفعل الميزة حين يتعطّل المزوّد؟

إذا أنجزت إحدى عشرة نقطة من اثنتي عشرة، فالميزة جاهزة للإنتاج. وإذا أنجزت أقل من ست، فما لديك عرض تجريبي — والعروض التجريبية هي بالضبط ما يُطلق للمستخدمين الحقيقيين ثم يُغلق بهدوء بعد ستة أسابيع حين تصل الفاتورة.

11. إذا أردت تنفيذ هذا معك

أنا أبني هذه المزايا لكسب عيشي، وغالبًا لفرق لديها منتج Laravel يعمل بالفعل وتريد جزء الذكاء الاصطناعي منفَّذًا بشكل صحيح لا ملصوقًا من الخارج. إن أردت رأيًا ثانيًا في معمارية، أو تنفيذًا بسعر ثابت، أو إنقاذ ميزة تتصرف بشكل سيئ في الإنتاج بالفعل، فيمكنك الاطلاع على صفحة الخدمات أو التعاقد معي كمطوّر Laravel مباشرة.

أرسل لي وصف الميزة عبر صفحة التواصل، واذكر إصدار Laravel لديك وإعداد الطوابير الحالي وما يُفترض أن تفعله الميزة. سأرد خلال 24 ساعة باستشارة مجانية وعرض سعر ثابت. وإن كان رأيي الصادق أنك لا تحتاج إلى ذكاء اصطناعي في هذه الحالة تحديدًا، فسأقول لك ذلك بدل أن أبيعك شيئًا.

أسئله شائعه

أي حزمة OpenAI أستخدم مع Laravel في الإنتاج؟
حتى أغسطس 2026، استخدم الحزمة الرسمية laravel/ai في المشاريع الجديدة، فهي تقدّم الوكلاء والأدوات والمخرجات المهيكلة وبثّ SSE والطوابير والتحويل بين المزوّدين بشكل مدمج. لكنها ما زالت 0.x (الإصدار v0.10.3 بتاريخ 6 أغسطس 2026، ويتطلب PHP ‎^8.3‎ وLaravel 12 أو 13)، لذا ثبّت الإصدار واقرأ ملاحظات كل ترقية. أما البديل كغلاف رفيع لمزوّد واحد فهو openai-php/laravel v0.20.0.
كيف أبثّ الرموز إلى المتصفح من Laravel؟
مع laravel/ai، أرجِع استجابة stream() مباشرة من الـ route، فهي ترسل أحداث Server-Sent Events تلقائيًا، ودالة usingVercelDataProtocol() تطابق تنسيق Vercel AI SDK لواجهات React. الجزء الصعب هو البنية التحتية: عطّل proxy_buffering في Nginx، وأرسل ترويسة X-Accel-Buffering: no، واستثنِ المسار من التمرير عبر CDN عدواني، وارفع مهلة الخمول في موازن الحمل.
كيف أمنع ميزة الذكاء الاصطناعي من التهام ميزانيتي؟
اضبط سقف فوترة صارمًا في لوحة OpenAI من اليوم الأول، وضع #[MaxTokens] على كل وكيل، ووجّه معظم الحركة إلى الفئة الاقتصادية — gpt-5.6-luna اليوم، أو gpt-5-mini وgpt-5-nano إن كنت مثبّتًا على الجيل السابق — بدل النموذج الرائد Sol. ثم ضع التعليمات الثابتة في مقدمة الطلب حتى يعمل التخزين المؤقت (المدخلات المخزّنة أرخص بتسعين بالمئة، لكن فقط فوق مقدمة بطول ألف وأربعة وعشرين رمزًا تقريبًا)، واستخدم Batch API بخصم خمسين بالمئة للأعمال الخلفية، وقِس الرموز لكل مستخدم مع فرض حصة.
هل توضع استدعاءات الذكاء الاصطناعي في الطوابير أم في المتحكّمات؟
ابثّ من المتحكّم فقط حين يكون المستخدم ينتظر أمام الشاشة والنص نفسه هو المنتج: المحادثة والصياغة والشرح. ما عدا ذلك مكانه مهمة طابور: التصنيف، والتلخيص عند الرفع، والتضمينات، وإثراء البيانات، وأي عمل يبدأ من webhook. ولا تستدعِ النموذج تزامنيًا في متحكّم بلا بثّ، فذلك يحجز عاملًا حتى أربعين ثانية، ويموت على خطأ 502، ولا يمكن إعادة تنفيذه.
كيف أتعامل مع حدود الاستدعاء وإعادة المحاولة بأمان؟
تُعيد OpenAI رمز 429 مع ترويسة Retry-After وترويسات x-ratelimit-*؛ احترم Retry-After ثم أضف عشوائية حتى لا يعيد العمّال المحاولة في وقت واحد. اخنق الطلبات قبل الإرسال عبر Redis::throttle أو وسيط المهام RateLimited. وفرّق بين الأخطاء: أعد المحاولة على 429 الخاص بالمعدل وعلى أخطاء 5xx، ولا تعدها أبدًا على 429 بسبب نفاد الرصيد ولا على خطأ 400 بسبب طول السياق. وللاستمرارية، مرّر مصفوفة مزوّدين للتحويل التلقائي.
كم تكلّف ميزة ذكاء اصطناعي في Laravel؟
نطاقات صادقة لا عرض سعر: ميزة واحدة عبر طابور مع تسجيل الاستهلاك تكلّف عادةً 900 إلى 2000 دولار للتنفيذ، و20 إلى 150 دولارًا شهريًا على الواجهة. مساعد محادثة ببثّ وحصص يتراوح بين 2500 و6000 دولار، والبحث الدلالي على مستنداتك بين 5000 و12000 دولار. والعامل الأكبر في التكلفة هو حالة الشيفرة المحيطة لا الذكاء الاصطناعي نفسه. وأسعّر بالجنيه المصري أو الريال السعودي أو الدرهم عند الطلب.
هل حزمة laravel/ai مستقرة بما يكفي للإنتاج؟
نعم يمكن استخدامها في الإنتاج اليوم، مع تحفّظ يجب التخطيط له: ما زالت في الإصدار 0.x بوتيرة إصدارات شبه أسبوعية، إذ صدر منها ستة وأربعون إصدارًا حتى أغسطس 2026. التغييرات الكاسرة بين الإصدارات الصغيرة أمر متوقع. ثبّت الإصدار، واحتفظ بمجموعة تقييم ثابتة لاكتشاف تغيّر السلوك، وخصّص وقت صيانة بسيطًا كل ربع سنة للترقيات.
كلمات مفتاحية: LaravelOpenAIAI IntegrationStreamingAPI Cost OptimizationPHPQueues

مستعد لتطبيق ما قرأته؟

استشاره مجانية 30 دقيقة، رد خلال 24 ساعة، وعرض سعر مكتوب.

تواصل واتساب