المدونةالمقال 12
const agent = router.route(task)
if (risk === "HIGH") await approve()
memory.store("decision", context)
للمطورين6 دقائق
البنية

للمطورين: كيف بنينا وصول

لن نشارك كل التفاصيل — بعضها ملكية فكرية وبعضها استراتيجي. لكن ما نشاركه حقيقي ويعكس قراراتنا المعمارية الفعلية. ## المشكلة التقنية الحقيقية

للمطورينمطورون + مهندسون + تقنيون6 دقائق

لن نشارك كل التفاصيل — بعضها ملكية فكرية وبعضها استراتيجي. لكن ما نشاركه حقيقي ويعكس قراراتنا المعمارية الفعلية. ## المشكلة التقنية الحقيقية

الجمهور
مطورون + مهندسون + تقنيون
الهدف
مصداقية تقنية + استقطاب مواهب

نبدأ بالصدق

لن نشارك كل التفاصيل — بعضها ملكية فكرية وبعضها استراتيجي. لكن ما نشاركه حقيقي ويعكس قراراتنا المعمارية الفعلية.

المشكلة التقنية الحقيقية

بناء نظام يرد على أسئلة = سهل نسبياً.
بناء نظام ينفّذ مهام بشكل موثوق في بيئة حقيقية غير متوقعة = تحدي حقيقي.

تحديات واجهناها في الإنتاج:

التحديوش يعني ببساطة
Idempotency — الرسالة تصل مرتينالعميل يرسل رسالة وبسبب الشبكة توصل مرتين — لازم النظام ما ينفذ الأمر مرتين
واتساب ينقطع وسط معالجة طلبمثل ما الكهرباء تفصل وأنت تشتغل — لازم يكمل من حيث وقف
سلة تتأخر في الردأحياناً API سلة يكون بطيء — لازم النظام ينتظر بذكاء ولا يتعطل
النموذج اللغوي (LLM) يرجع نتيجة غير متوقعةأحياناً الذكاء الاصطناعي يرد بشكل مو مطابق — لازم نتعامل مع هالحالات
Long-running workflows — موافقة المالك تأتي بعد ساعاتمهام تستمر ساعات أو أيام — ما تنفع في HTTP request واحد

القرارات المعمارية الكبرى

### 1. نهج ReAct (التفكير ثم التنفيذ)

وش هو: ReAct = Reason + Act. بدل ما النظام يتبع خطوات ثابتة (مثل وصفة طبخ)، يفكر في كل خطوة ويقرر الخطوة اللي بعدها بناءً على اللي شافه.

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

التحدي: ReAct بطيء لو ما تتحكم فيه. حلينا هذا بتخزين مؤقت ذكي (Caching) — يعني لو وصول فكر في مشكلة قبل كذا، ما يفكر فيها من جديد. وحطينا سقوف واضحة لعدد خطوات التفكير عشان ما يدخل في حلقة ما تنتهي.

### 2. نماذج لغوية متعددة حسب المهمة

وصول ما يستخدم نموذج ذكاء اصطناعي واحد لكل شي. يستخدم النموذج المناسب لكل نوع مهمة:

نوع المهمةالنموذجليش
ردود فورية (أقل من 500 مللي ثانية)نموذج سريع ومُحسَّن للسرعةالعميل ما يقدر ينتظر
تحليل وتقاريرنموذج أعمق وأقوىالتحليل يحتاج دقة مو سرعة
مهام حرجة (استرداد مبالغ مثلاً)نموذج مع تحقق إضافيالخطأ هنا تكلفته عالية

كيف: نستخدم LiteLLM Router يوجه كل طلب للنموذج المناسب. لو النموذج الأساسي فشل أو تعطل، يتحول تلقائياً لنموذج بديل (Fallback) بدون ما العميل يحس.

### 3. نظام ذاكرة متعدد المستويات

أربع مستويات ذاكرة، كل واحدة لغرض مختلف:

المستوىالتقنيةالاستخداممثال بسيط
المحادثة الحاليةRedis (في الذاكرة المؤقتة)سياق المحادثة الجارية — سريع ومؤقت"العميل قال قبل شوي إنه يبي مقاس L"
المهامMongoDB مع حذف تلقائي بعد فترةمهام قيد التنفيذ"ننتظر موافقة المالك على الاسترداد"
القراراتMongoDB مفهرس وقابل للبحثسجل القرارات والإجراءات"المالك وافق على استرداد لهذا العميل قبل"
معرفة المتجربيانات منظمة + بحث دلاليكل شي عن المتجر ومنتجاته"سياسة الإرجاع ٧ أيام، الشحن مجاني فوق ٢٠٠ ريال"

التحدي: الحفاظ على تناسق البيانات بين المستويات. القرار: Eventual Consistency (التناسق النهائي) مقبول في معظم الحالات — يعني ممكن يكون فيه تأخير بسيط. لكن في المهام الحرجة (مثل العمليات المالية) نستخدم Strict Consistency — تناسق فوري بدون أي تأخير.

### 4. نظام الموافقات وتصنيف المخاطر

كل إجراء يمر بمحرك تصنيف قبل التنفيذ. هذا هو الكود المبسط:

class RiskLevel:
 LOW = "auto_execute" # ينفذ تلقائياً (رد على سؤال)
 MEDIUM = "execute_notify" # ينفذ ويبلغ المالك
 HIGH = "approval_needed" # ينتظر موافقة المالك
 CRITICAL = "blocked" # ممنوع تماماً

التصنيف يعتمد على أربعة عوامل:

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

### 5. نظام المهام طويلة الأمد (Workflow Orchestration)

بعض المهام تستغرق ساعات أو أيام. مثال: عميل يطلب استرداد - وصول يسأل المالك - المالك يرد بعد ٣ ساعات - وصول يكمل التنفيذ.

هذا ما ينفع في HTTP request واحد. نستخدم نظام Workflow Orchestration (تنسيق المهام) يضمن:

  • Exactly-once semantics (تنفيذ مرة واحدة بالضبط) — كل خطوة تنفذ مرة واحدة حتى لو النظام أعاد التشغيل
  • استمرارية بعد أي فشل — لو السيرفر وقع ورجع، يكمل من حيث وقف
  • تتبع حالة كل مهمة — تقدر تعرف أي مهمة وين وصلت في أي وقت
  • إمكانية الإلغاء والتعديل — لو المالك غير رأيه

### 6. عزل بيانات المتاجر (Multi-tenancy)

كل متجر في بيئة معزولة تماماً:

  • Logical isolation — قاعدة بيانات منفصلة منطقياً لكل متجر
  • Redis namespace منفصل — الذاكرة المؤقتة لكل متجر ما تختلط بغيرها
  • Rate limiting لكل متجر — حدود استخدام مستقلة عشان متجر مشغول ما يأثر على الباقي
  • Zero data leakage — ما في أي طريقة بيانات متجر توصل لمتجر ثاني

البنية التقنية (اللي نقدر نشاركه)

الواجهة: Next.js 14 (App Router)
الخادم: Node.js / Express
المنسق: Python
قاعدة البيانات: MongoDB (أساسي) + Redis (مؤقت) + PostgreSQL (صلاحيات)
واتساب: Evolution API (واجهة واتساب للأعمال)
توجيه الذكاء: LiteLLM
البحث الدلالي: ChromaDB
الملفات: MinIO (متوافق مع S3)
المصادقة: Keycloak
الاستضافة: Docker على Hetzner (ألمانيا)
النشر: GitHub Actions - Docker Hub

ليش هالاختيارات؟

القرارالبديلليش اخترنا كذا
MongoDB كقاعدة أساسيةPostgreSQLمرونة المستندات مهمة لبيانات المتاجر اللي تختلف من متجر لمتجر
Python للمنسقNode.jsالمكتبات الأقوى في الذكاء الاصطناعي كلها في Python
Hetzner (ألمانيا)خدمات سحابية أمريكيةسعر أفضل + قوانين حماية بيانات أوروبية صارمة
LiteLLMمباشرة مع مزود واحدمرونة التبديل بين النماذج بدون تغيير الكود

وش ما نشاركه

بعض المكونات الاستراتيجية تبقى خاصة. شاركنا الـ "وش نستخدم" — لكن "كيف" نستخدمه بالتفصيل في بعض الأجزاء هو اللي يشكل ميزتنا التنافسية.

للمطورين المهتمين بالانضمام

نبحث عن مهندسين يفهمون:

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

نحن فريق صغير يبني شي كبير. إذا كنت من هالنوع من المهندسين — كلمنا.