6.5 KiB
SovereignAI Starter
مشروع تعليمي لبناء مساعد ذكاء اصطناعي محلي قابل للتوسع. النموذج الافتراضي qwen2.5:1.5b-instruct-q4_K_M (نحو 986 ميغابايت)، ونموذج gemma4:e2b (نحو 7.16 غيغابايت) مثبت للتجربة والمقارنة.
مكونات النسخة الأولى
- FastAPI كواجهة HTTP محلية.
- وكيل تجريبي بأداة حساب آمنة ومحدودة.
- واجهة
/docsلاستكشاف الـ API من المتصفح. - يمكن توصيلها بخادم نموذج محلي يوفّر واجهة OpenAI مثل Ollama.
- دون إعداد عنوان خادم نموذج، تعمل الواجهة في وضع العرض التجريبي.
التشغيل على Windows
- ثبّت Python 3.11 أو أحدث.
- افتح PowerShell داخل المجلد. إذا كانت
.venvموجودة، تخطَّ خطوة إنشائها وثبّت الاعتماديات فقط عند الحاجة. - أنشئ بيئة افتراضية وثبت الاعتماديات:
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
- (اختياري على جهاز جديد فقط) شغّل Ollama واسحب النموذج:
ollama pull qwen2.5:1.5b-instruct-q4_K_M
الخادم الحالي مضبوط افتراضيًا على Ollama المحلي واسم النموذج أعلاه. لتغييرهما عرّف المتغيرات في نافذة PowerShell نفسها:
$env:LOCAL_LLM_BASE_URL = "http://127.0.0.1:11434/v1"
$env:LOCAL_MODEL = "qwen2.5:1.5b-instruct-q4_K_M"
لتشغيل API على Gemma 4 بدل النموذج الافتراضي في نافذة PowerShell الحالية:
$env:LOCAL_MODEL = "gemma4:e2b"
.\start-api.ps1
يمكن أيضًا اختيار النموذج لكل طلب من POST /v1/chat/completions بإرسال model، أو من POST /v1/agent/run بإرسال model مع task. يبقى النموذج الافتراضي Qwen ما لم تغيّره من البيئة. على جهاز الاختبار، Gemma 4 E2B اشتغلت محليًا على CPU، لكنها استخدمت قرابة 3.5 غيغابايت من الذاكرة أثناء التحميل؛ قد تختلف السرعة حسب الجهاز.
راجع رخصة النموذج المختار وشروطه الحالية قبل الاستخدام التجاري. تنزيل النموذج يحتاج اتصال إنترنت ومساحة تخزين.
- شغل الـ API على جهازك فقط (أو شغل
start-api.ps1):
python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
- افتح
http://127.0.0.1:8000/docs.
نقاط التجربة
GET /healthللتأكد من أن الخدمة تعمل.POST /v1/chat/completionsلإرسال رسالة.POST /v1/agent/runلتجربة الوكيل والأداة الحسابية.POST /v1/chat/completionsيمرر الطلب إلى الخادم المحلي عند ضبط المتغيرين أعلاه.- يمكن التبديل في Swagger بين النموذجين بإضافة
modelإلى جسم الطلب، مثلgemma4:e2b.
الخدمة مربوطة بـ 127.0.0.1 عمدًا، فلا تعرضها على الشبكة أو الإنترنت الآن. الوكيل الحالي يمرر السؤال النصي للنموذج، وينفذ الحسابات البسيطة بأداة حساب محلية محدودة. لا يقرأ ملفات ولا ينفذ أوامر النظام.
واجهة Flutter
يوجد تطبيق Flutter متعدد المنصات في flutter_app، ويبدأ كواجهة محادثة ويب عربية متصلة بهذا الـ API. راجع flutter_app/README.md للتشغيل. عنوان الاتصال الافتراضي http://127.0.0.1:8000؛ التطبيق يسمح بتغييره من الإعدادات.
المحادثات والصوت
- تحفظ FastAPI المحادثات والرسائل في SQLite محليًا. على Windows يوجد الملف في
%LOCALAPPDATA%\SovereignAI\data\sovereign_ai.sqlite3، وخارج مجلد المشروع لتجنب مزامنة قاعدة البيانات مع OneDrive. - لكل سجل محادثة
user_id، وتُفلتر عمليات القراءة والتعديل والحذف على أساسه. في النسخة المحلية يوفّر FastAPI ملف مستخدم تطوير ثابتًا، وترسل الواجهة معرّفه في ترويسةX-User-ID؛ هذا ليس تسجيل دخول أو عزلًا أمنيًا صالحًا للاستضافة العامة. - جدول
user_identitiesمهيأ لربط المستخدم مستقبلًا بمعرّف مزود مثل Google أو البريد/الهاتف، لكن تدفق تسجيل الدخول لم يُنفذ بعد. عند إضافة مستخدمين حقيقيين يجب استبدال الترويسة بهوية موثقة من جلسة/JWT. - رسائل الدردشة ترسل إلى Ollama المحلي. التسجيل الصوتي يحوّل إلى نص عبر Groq Whisper؛ لذلك يُرسل الصوت إلى Groq عند الضغط على إيقاف التسجيل.
- مفتاح Groq يجب أن يبقى في متغير البيئة
GROQ_API_KEYالخاص بخادم FastAPI، ولا يوضع في Flutter أو في ملفات المشروع. - على جهاز التطوير الحالي حُفظ المتغير في بيئة Windows الخاصة بالمستخدم، وليس في ملف
.env. يقرأهstart-api.ps1عند تشغيل الخادم، ويظهر/healthحالة الإعداد فقط دون إظهار المفتاح. عند استضافة الخادم لاحقًا، أضف المفتاح إلى إعدادات البيئة السرية في خدمة الاستضافة.
عنوان الشبكة
عنوان Wi-Fi الحالي لهذا الجهاز 192.168.100.20 والبوابة 192.168.100.1، والعنوان موزع عبر DHCP. لتثبيته، احجز العنوان الحالي من صفحة الراوتر ضمن DHCP Reservation / Address Reservation للجهاز DESKTOP-13T75A5، مستخدمًا MAC واجهة Wi-Fi الظاهر في ipconfig /all. لا تغيّر إعداد IPv4 يدويًا في Windows بالتزامن مع حجز DHCP. هذا يثبت العنوان داخل الشبكة المنزلية فقط؛ لا يفتح وصولًا من الإنترنت. الخوادم ما زالت مربوطة بـ 127.0.0.1.