أيقونة H_AI: باب خزنة رمادي في نصه AI
لسه شغال عليه

بناء محرك AI شخصي

LLMs محلية، وتوليد صور وصوت على الجهاز نفسه، وvault خاص للملاحظات — كله شغّال على Mac Studio M4 Max وبوصله من أجهزتي، في البيت أو برّه

زهقت من إني أعتمد على الـ cloud APIs في كل حاجة. التأخير، والتكلفة، وقلق الخصوصية — كنت عايز AI بتاعي يشتغل محلي، ويرد فوراً، ويفضل private تماماً. فبنيت واحد. محرك AI شخصي شغّال على الـ Mac Studio M4 Max بتاعي، وبوصله من أجهزتي، في البيت أو برّه، عن طريق واجهة ويب عملتها بنفسي اسمها H_AI.

تحديث، أكتوبر 2026. لما كتبت المقال ده أول مرة في فبراير، كان H_AI شباك chat ومعاه شوية أدوات. من ساعتها اتعلم يشوف ويرسم ويسمع ويتكلم — كله على نفس الجهاز — وبيحتفظ بكل محادثة في vault في Obsidian يقدر يدوّر فيه. وكمان عدّى على سلسلة code reviews عملها فريق صغير من الـ AI agents، وده علّمني عن الفشل أكتر من أي feature. وعشان كده أعدت كتابة المقال.

تحديث، نوفمبر 2026. المقال ده بقى الجزء الأول: الحكاية من فبراير لأكتوبر. شوية معلومات تحت اتحدّثت (الـ model الافتراضي، والوصول من بعيد، وعدد الأدوات). اللي جه بعد كده — الـ hub، وشخص تاني في البيت، وأدوات بتتركّب كـ plug-ins — موجود في الجزء التاني: من شباك chat لـ hub للبيت.

الهدف دلوقتي مكتوب في أول الـ to‑do list بتاعة المشروع: مساعد AI محلي، لشخص واحد، كويس كفاية إنه يستبدل أدوات الـ AI الخارجية اللي بدفعلها فلوس وببعتلها بياناتي. كل تغيير بيتقاس على الجملة دي.

الـ hardware

Mac Studio M4 Max

🧠
M4 Max Apple Silicon
💾
64 GB Unified Memory
⚡
Ollama + MLX LLM Runtime
🌐
FastAPI server الويب

الـ M4 Max بـ 64 GB unified memory اختيار في الجون لتشغيل الـ LLMs المحلية. الـ GPU والـ CPU بيتشاركوا نفس الذاكرة — من غير نسخ بيانات بين الـ RAM والـ VRAM — فالـ models اللي على PC كانت هتحتاج graphics card 24 GB أو أكتر بتشتغل هنا عادي. Ollama هو اللي بيحمّل الـ models وبيعمل الـ inference، والـ MLX builds بتاعته معمولة مخصوص لـ Apple Silicon.

الـ models

التشكيلة اتغيرت تقريباً بالكامل من فبراير. المجموعة الحالية أحدث وأكبر وذاكرتها أطول بكتير:

الـ model الـ Context المستخدم أنسب لـ
Qwen 3.8 27B (MLX) ~49,000 token الـ default: الـ model المحلي الأساسي، والـ vision، والـ fallback لـ Claude
Qwen 3.6 35B-A3B ~32,000 token Mixture‑of‑experts — model كبير وتكلفة صغيرة لكل token؛ المساعد السريع
Gemma 4 26B / 31B ~32,000 token reasoning وكتابة بشكل عام
Gemma 4 (small) ~32,000 token أسئلة اليوم العادية السريعة
gpt-oss 20B ~32,000 token مهام قصيرة ومحددة
GLM-OCR — قراية النص من الـ scans والصور والمستندات
Claude (اختياري) أكبر بكتير بختاره بإيدي للأسئلة الصعبة، ومعاه fallback محلي automatic

لسه أقدر أبدّل الـ model في نص المحادثة من الـ header. لمدة شهر تقريباً من أول سبتمبر كان الـ default هو Claude، بوصله عن طريق الـ Claude Code CLI؛ ومن أكتوبر الـ default رجع محلي: Qwen 3.8، وClaude موجود بدوسة واحدة في الـ header (والـ default نفسه بيتغيّر من الـ dashboard). لما بختار Claude، الـ server بيتأكد منه قبل كل رد. لو الـ CLI مش موجود أو عامل logout أو وصل للـ rate limit، الرد بيتحوّل لـ Qwen 3.8 — بس عمره ما بيحصل من غير ما أعرف: الـ chat بيعرض تنبيه فيه رسالة الخطأ بتاعة Claude نفسه، لأن لو الـ model نزل لـ model أضعف من غير ما أعرف، هيبان كأن Claude هو اللي بيرد وحش. Claude مريّح، بس مش هو الأساس؛ الشغل الحقيقي هو إني أقفل الفجوة لحد ما الـ models المحلية ما تبقاش محتاجاه.

واجهة الويب

قلب المشروع لسه هو الـ webapp: FastAPI في الـ back end، وvanilla HTML/CSS/JS في الـ front end، ومتاح على HTTPS للابتوب والموبايل والتابلت. في مارس اتعمله redesign كامل، وفي سبتمبر لفّة تظبيط للموبايل: خانة الكتابة كانت 48% من عرض الموبايل وبقت 64%، وكل زرار بقى قد الحد الأدنى للـ touch target.

H_AI على الموبايل: إجابة مبنية على الـ README بتاع المشروع، مع خانة الكتابة الصغيرة
💬
chat بالـ Streaming بث الـ tokens لحظة بلحظة عن طريق Server‑Sent Events، مع حالة «⁦Thinking…⁩» للـ reasoning models
🗂️
المحادثات افتح أي محادثة قديمة من لوحة جانبية؛ والـ transcript بيفضل موجود بعد إعادة تحميل الصفحة وإعادة تشغيل الـ server
🧠
ضغط ذكي للمحادثة لما السياق يمتلي، المحادثة بتتلخّص عشان تفضل جوه حد الـ model
🎙️
صوت داخل وطالع سجّل سؤال على الموبايل، واسمع الإجابة بصوت عالي — تحويل الكلام لنص والنطق الاتنين بيشتغلوا محلي
🎨
توليد الصور اطلب صورة تظهرلك في الـ chat، وDraw Things بيرسمها على الـ Mac
🖼️
Vision والمستندات الصق صورة أو ارفع مستند واسأل عنه؛ والمسح الضوئي بيعدّي على model OCR مخصوص
🛠️
أكتر من 50 أداة جاهزة ملفات، وgit، وبحث على الويب، وتحميل صفحات ويب، وgrep، وآلة حاسبة، وصور، وصوت، وبحث في ملاحظاتي أنا — ومن أكتوبر كمان calendar، وshopping tracker، والبيت الذكي
📓
Obsidian Vault كل محادثة وصورة وتسجيل وblock code بيتحفظ كـ notes بصيغة Markdown مربوطة ببعض

أبعد من النص: يشوف ويرسم ويسمع

أكبر تغيير السنة دي إن H_AI مبقاش نصوص بس — من غير ما أي حاجة تخرج برّه البيت.

الصور. التوليد بيعدّي على أداة الـ command‑line بتاعة Draw Things، بتلات models لتلات مهام: model «⁦turbo⁩» سريع للـ drafts، وواحد جودته أعلى لما الموضوع يستاهل، وmodel تعديل بيغيّر في صورة موجودة. الصور اللي بتتولّد بتظهر في الـ chat مباشرة وبتتحفظ في الـ vault.

بطلب من H_AI فنار وقت المغرب: الصورة اترسمت محلي بـ Draw Things واتحفظت في الـ vault

الـ Vision والـ OCR. Qwen 3.8 يقدر يبص على صورة أو screenshot ملصوقة؛ وGLM‑OCR بيقرا النص من الـ scans والمستندات (والعربي بيرجع لـ Qwen 3.8، لأنه بيقراه أحسن). تقدر تولّد صورة وبعدين تطلب من الـ vision model يوصفها — لفّة رايح جاي بستخدمها كـ smoke test («⁦a single blue marble⁩» رجعت «⁦a glossy blue stone sphere⁩»).

الصوت. تحويل الكلام لنص والعكس بيعدّوا على Voicebox، شغّال محلي، والردود اللي بيقراها بصوت عالي بتطلع بصوتي أنا المستنسخ — نفس الـ setup اللي كتبت عنه في توليد الصوت من النص بـ models محلية. الإدخال الصوتي كان أول بند في قايمة «الخطوة الجاية» بتاعتي في فبراير. وخلصت.

ذاكرة بتفضل في البيت

كل محادثة دلوقتي بتتكتب في Obsidian vault كملاحظة Markdown: الكلام اللي اتقال، وأي code اتولّد، وروابط للصور والصوت اللي اتعملوا. المحادثات ممكن تتفرّع، والفرع بيحتفظ برابط لأصله، فالـ vault بيبان كـ graph لتفكيري مشي إزاي، مش مجرد كومة logs.

والأهم إن المساعد يقدر يدوّر في الـ vault ده. «⁦What did we decide about the database?⁩» أو «⁦Search my notes for the gold price⁩» بيعملوا بحث في ملاحظاتي أنا، والرد بيطلع من اللي موجود فيها. دي الحاجة الوحيدة اللي مفيش أداة خارجية تقدر تعملها زيها، لأن الملاحظات موجودة على الجهاز ده بس. ولما مفيش حاجة تطابق، بيقول كده — قبل ما أوصّل ده، لما كنت أسأل model محلي عن ملاحظاتي كان بيألّف واحدة بكل ثقة اسمها «⁦Gold Price History⁩».

نظام الـ Skills

الـ AI مش مجرد chatbot — يقدر يعمل حاجات بنفسه. لحد أكتوبر كان فيه 30 skill: قراية الملفات وكتابتها، والبحث في الـ code، وgit، وتحميل صفحات الويب، والبحث على الويب، والحسابات، وتوليد الصور والكلام، والتنقل بين المشاريع، والبحث في الـ vault. (دلوقتي بقوا أكتر من خمسين؛ والجزء التاني بيحكي عن الجداد.)

الـ model بيطلب أداة بإنه يكتب fenced block قصير. الـ server بيشغّله، وبعدين — وده كان الإصلاح الكبير في الصيف — بيدّي النتيجة للـ model تاني ويخليه يرد من الدليل ده. قبل كده الـ model كان بينده بحث على الويب وبعدين يرد من ذاكرته برضو؛ دلوقتي الإجابات مبنية على اللي الأداة رجّعته فعلاً.

الأدوات اللي للقراية بس بتشتغل فوراً. أي حاجة بتغيّر حاجة — كتابة ملف، أو commit، أو تشغيل صوت يطلع من السماعة — بيظهرلها card تأكيد الأول. لما أوافق، الأداة بتشتغل والـ model بيرد من ناتجها، زي ما بيعمل بالظبط مع الأدوات الـ automatic.

إجابة مبنية على الدليل: Qwen 3.8 بيقرا README.md بالـ skill اسمها read_file وبيلخّصه من محتوى الملف الفعلي

فشل شكله نجاح

أنفع درس في السنة مكانش feature. كان pattern، ودلوقتي مكتوب في أول خطة المشروع:

الفشل هنا بيقدّم نفسه على إنه نجاح. الإصلاح المفروض يخلّي الفشل باين، مش بس يقلّله.

العَرَض كان تقريباً دايماً واحد: فقاعة إجابة فاضية بتخلص بشكل عادي، كأن الـ model معندوش حاجة يقولها. ورا ده كانت أسباب مختلفة خالص:

«⁦What is 2+2?⁩» مرجّعتش أي إجابة. الـ pattern بتاع الآلة الحاسبة كان بيطابق مسافة واحدة، فحسب expression فاضي وفشل — والـ server اعتبر إن الأداة خلّصت السؤال، فالـ model ما اتسألش أصلاً.

typo في اسم model خلّى الـ stream فاضي. Ollama بيرد بخطأ «⁦model not found⁩»، بس الـ HTTP client مبيطلعش exception عليه، فالـ stream… خلص وخلاص. دلوقتي الخطأ بيظهر في الفقاعة.

Gemma كان بيسكت. دي فضلنا مختلفين عليها أسابيع: أنا كنت أقدر أعيدها 4 مرات من 9، والـ QA agent بتاعي مقدرش خالص. طلع إن Gemma 4 model thinking — كان بيولّد طول الوقت، بس في reasoning field مخفي، وسايب الإجابة الظاهرة فاضية. سؤال الاختبار بتاع الـ QA («⁦Paris⁩») ببساطة ماخلّاهوش يفكر. لما قفلت الـ thinking، الإجابات الفاضية نزلت من 4 من 9 لصفر من 6.

كل واحدة من دول اتصلّحت بإني خليت الفشل يقول هو إيه — خطأ في الفقاعة، أو تنبيه في الـ chat — مش بس بإني قلّلته.

فريق بيراجع الـ code

في سبتمبر إديت المشروع فريق ثابت من الـ AI agents في Claude Code، كل واحد له شغلة واحدة: CEO ماسك الهدف وبيقرر إيه اللي يستاهل، وQA lead بيجرّب بنفسه كل claim من أوله لآخره قبل ما يتقال على أي حاجة إنها خلصت، وsecurity reviewer، ومسؤولين عن الـ dashboard، والـ models، والـ tool calling، والميديا المحلية، والـ vault، والـ operations.

أول security review عملوه لقى سلسلة حقيقية: نص من صفحة ويب اتحمّلت ممكن يوصل للصفحة كـ HTML، وده ممكن بعدين يشغّل الأدوات — طريق من صفحة خبيثة لتشغيل أوامر على الـ Mac بتاعي. اتقفل في نفس اليوم. المراجعات اللي بعدها طلّعت عشرات الـ bugs اللي مش باينة أوي، منها feature تاريخ المحادثات بتاعها عمره ما اشتغل لأن خطأ كان بيتبلع في السكوت. القاعدة اللي طلعت من ده: كل finding لازم يتعمله reproduce قبل ما يتصلّح، ومحدش بيمضي على شغله بنفسه.

الأمان

H_AI بدأ للـ LAN بس، عن قصد. في أكتوبر بقى فيه سبب أوصل أبعد، ودلوقتي كمان أجهزتي أنا (وبس) تقدر توصله من أي مكان، عن طريق Tailscale — شبكة خاصة بين أجهزتي، HTTPS بس، وعمرها ما بتتفتح على الإنترنت العام. جوه الحدود دي:

الوصول: HTTPS في كل مكان بشهادة self‑signed، ومفاتيح الـ API بتتقارن كـ hashes في constant time، وpasswords الـ dashboard متخزّنة بـ bcrypt، وrate limits على الـ API وصفحة تسجيل الدخول الاتنين. الصور والصوت بيستخدموا signed links عمرها قصير بدل ما المفتاح يبان. وصفحة الـ dashboard مبقتش تشيل مفتاح الـ API خالص — المتصفح بيعمل authentication بالـ login session بتاعته بدل كده، ومن صفحات الـ server نفسه بس.

المحتوى اللي مش موثوق: أي حاجة جاية من برّه — صفحة ويب، أو مستند مرفوع، أو ملاحظة قديمة — بتتحاط في fence كـ data قبل ما توصل للـ model، بـ marker عشوائي المحتوى ميقدرش يزوّره. ملف PDF مكتوب فيه «⁦ignore all previous instructions⁩» بيتبلّغ عنه، مش بيتنفّذ. والـ web fetch مينفعش يتوجّه للخدمات الشغّالة على الـ Mac نفسه.

العمليات: أي حاجة بتغيّر في النظام محتاجة تأكيد، ووضع الـ agent التجريبي — اللي ممكن يشغّل أوامر shell الـ model كاتبها — مقفول إلا لما أنا أفتحه.

الـ Architecture

الـ stack لسه بسيط عن قصد:

الـ Backend: FastAPI مع async streaming وPydantic validation. مفيش database — الجلسات والـ logs ملفات JSON على الـ disk، والذاكرة طويلة المدى هي الـ vault بتاع Markdown.

الـ Frontend: Vanilla HTML وCSS وJavaScript، مع Marked.js وHighlight.js. مفيش React ومفيش build step. وهو PWA، فبيتثبّت على الشاشة الرئيسية.

الـ Runtimes بتاعة الـ AI والميديا: Ollama للـ models المحلية، والـ Claude Code CLI لـ Claude، وDraw Things للصور، وVoicebox للكلام. كل واحد خدمة محلية لوحدها؛ لو واحدة وقعت، الـ features بتاعتها بس هي اللي بتقف، ولوحة الخدمات بتوريني أنهي واحدة.

لوحة الخدمات المحلية: Ollama وVoicebox وDraw Things والـ Claude CLI والـ vault، وقدام كل واحدة الـ skills اللي بتشغّلها
أحسن setup للـ AI هو اللي بتستخدمه فعلاً كل يوم. لما خليته متاح من كل أجهزتي، بقى جزء طبيعي من الـ workflow بتاعي.

الخطوة الجاية

الصوت خلص. وكمان الصور والرؤية والذاكرة طويلة المدى. اللي فاضل:

قفل الفجوة مع Claude — إني أخلّي الـ models المحلية كويسة كفاية في استخدام الأدوات لدرجة إن Claude يبقى اختياري. Claude لسه أحسن بشكل واضح في إنه يعرف إمتى يستخدم أداة. الوصول من بعيد كان الخطوة الجاية في القايمة دي، وخلص: Tailscale، ومن أجهزتي بس. وكمان أكتر من الشغل اللي طلع هو الأهم: إني ألاقي الأماكن اللي بيفشل فيها من غير صوت، وأخليها تتكلم.

باقي الحكاية — hub، وشخص تاني في البيت، والإيصالات، والـ calendars، وأدوات بتتركّب كـ plug-ins — موجودة في الجزء التاني: من شباك chat لـ hub للبيت.

مفيش اشتراك للـ models المحلية. ومفيش بيانات بتخرج من الشبكة بتاعتي إلا لو اخترت الـ cloud. بس الـ hardware بتاعي، وsoftware كويس، وكل حاجة ملكي أنا.