VeilLLM: بروكسي DLP محلي لمنصة الذكاء الاصطناعي الخاصة بك

قبل بضعة أسابيع كنت أجهز منصة الذكاء الاصطناعي الخاصة بي. Hermes agent، و DeepSeek API. الإعداد المعتاد.

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

هذا الشعور لم يختف.

The Moment

ما كنت أبحث عنه

What I Was Looking For

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

كان يجب أن يكون محلياً. لا خدمات سحابية، ولا اشتراكات DLP خارجية. كان يجب أن يعمل على المعالج CPU لأنني لا أملك GPU للتشغيل. وكان يجب أن يكون سريعاً. إذا أضاف نصف ثانية لكل طلب، لن أستخدمه.

بحثت. لم أجد شيئاً مناسباً.

فبنيته بنفسي.

كيف يعمل VeilLLM

How VeilLLM Works

VeilLLM هو بروكسي عكسي يتحدث لغة OpenAI API. توجه منصتك إلى http://127.0.0.1:4000/v1 بدلاً من مزود النموذج. هذا كل شيء.

عندما يصل طلب، يمر عبر خط أنابيب للكشف. نموذج Presidio من Microsoft يتعرف على البيانات الشخصية: الأسماء، الإيميلات، أرقام الهواتف، بطاقات الائتمان، أرقام IBAN، عناوين IP، المواقع، أرقام الضمان الاجتماعي. وفوق ذلك، طبقة من التعابير النمطية تلتقط مفاتيح API: مفاتيح OpenAI، ومفاتيح Anthropic، ومفاتيح AWS، ورموز GitHub، ومفاتيح Google API، ورموز JWT، وكتل المفاتيح الخاصة.

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

الطلب المُخفي يذهب إلى مزود النموذج. النموذج يرد بشكل طبيعي. VeilLLM يعيد استبدال العناصر النائبة بالقيم الأصلية قبل أن يصل الرد إلى منصتك.

منصتك لا تعرف حتى أنه موجود.

تغيير إعداد واحد

One Config Change

هذا هو الجزء المهم. VeilLLM يتحدث OpenAI API، فأي شيء يمكن توجيهه إلى base URL مخصص يعمل مباشرة.

Hermes. Cline. Continue. Aider. OpenHands. سكربتاتك الخاصة. سطر واحد يتغير.

# Before
base_url: https://api.openai.com/v1

# After
base_url: http://127.0.0.1:4000/v1

رأس التفويض Authorization يمر دون تغيير. البروكسي يعمل على المنفذ 4000 افتراضياً. يمكنك تغييره بمتغير بيئة.

التثبيت أمر واحد.

pip install veil-llm

عند التشغيل الأول، ينشئ ملف إعدادات بقيم افتراضية مناسبة ويُنزل نموذج spaCy. يستغرق حوالي 30 ثانية.

الأجزاء الصعبة

The Hard Parts

الـ streams كانت أصعب مما توقعت.

عندما يبث النموذج الرموز، يصل الرد في أجزاء. لا يمكنك إخفاء واستعادة العناصر النائبة بنفس الطريقة لأن العنصر النائب قد ينقسم عبر جزأين. VeilLLM لا يتعامل مع البث حالياً. إذا كانت منصتك تستخدم stream: true، أطفئه.

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

الوقت المستغرق يضيف 20 إلى 50 ميلي ثانية لكل طلب فوق الوقت الطبيعي. معظم هذا من نموذج Presidio وهو يفحص الـ prompt. لطلب محادثة عادي يأخذ 500ms إلى ثانيتين، 20 إلى 50ms تختفي. لطلب تحت 100ms، ستلاحظها.

الكشف عبر اللغات نقطة أخرى. Presidio يدعم عدة لغات، لكن جودة التعرف على الكيانات تتفاوت. الإنجليزية ممتازة. كل شيء آخر قيد التطوير.

ما زلت أحاول فهمه

What I'm Still Figuring Out

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

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

جربه

Try It

المستودع على github.com/h-f-fares/VeilLLM. رخصة Apache 2.0. هناك واجهة Gradio تجريبية في المستودع تظهر بالضبط ما يتم إخفاؤه، مباشرة، بدون الحاجة لمفتاح API. إذا أردت أن تراه يعمل قبل توصيله بأي شيء، ابدأ من هناك.

pip install veil-llm

أسئلة، اقتراحات، مشاكل: افتح issue على GitHub أو جدني هنا. أبني هذا بشكل مفتوح وأفضل أن أسمع ما هو معطوب على أن أكتشفه لاحقاً.