تحويل البيانات الخام إلى معرفة منظمة قابلة للاستخدام

لم أعد أستخدم ما بنيته منذ عام. استبدلته بقواعد المعرفة

16 سبتمبر 2026قراءة 12 دقيقةالعودة للرئيسية

عندما أصبح الذكاء الاصطناعي جزءًا من بيئة العمل

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

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

بقيت مشكلة واحدة: في كل مرة تريد تنفيذ مهمة حقيقية، تحتاج إلى شرحها من البداية. حتى لو كنت تستخدم ChatGPT أو Claude أو غيرهما، هناك دائمًا حد لما يعرفه الـModel عنك وعن طريقة عملك. لا يعرف لماذا تستخدم Template معينًا، أو لماذا يُعامل عميل معين بطريقة مختلفة، أو لماذا يجب تعديل رقم معين قبل استخدامه، أو لماذا نأخذ أحيانًا قيمة مباشرة من الملف ونحتاج أحيانًا أخرى إلى ربطها مع Dataset أخرى لعمل Mapping. يمكنك طبعًا كتابة كل هذا في الـPrompt، لكن ماذا لو كانت المهمة تحتوي على عشرات أو مئات القواعد؟ وماذا لو كانت هذه القواعد تتغير مع الوقت؟

النظام الذي بنيته في 2025

واحدة من المهام التي أقوم بها بشكل شبه يومي في عملي هي معالجة كمية ضخمة من البيانات القادمة من أكثر من 70 مصدرًا مختلفًا، وكل مصدر منها يرسل البيانات بطريقة مختلفة. أحد المصادر قد يرسل Excel بأسماء Columns معينة، ومصدر آخر يستخدم أسماء مختلفة تمامًا لنفس البيانات، ومصدر يستخدم الريال وآخر الدينار. بعض المصادر تحتاج إلى Mapping مع بيانات أخرى، ومصادر ثانية تحتوي على أرقام تحتاج إلى تغيير الـStructure الخاص بها قبل استخدامها.

لو أردت اختصار النظام الذي بنيته للتعامل مع كل هذا، فهو عبارة عن Python Script مخصص تقريبًا لكل مصدر. يأخذ الـScript البيانات بالشكل الذي جاءت فيه ويحولها إلى Template موحد يمكن استخدامه لاحقًا، لكن داخل هذه الـScripts شروط كثيرة جدًا: إذا كانت القيمة بهذا الشكل فافعل كذا، وإذا كانت العملة مختلفة فطبّق Conversion معينًا، وإذا لم نجد ID معينًا فابحث عنه داخل Dataset أخرى، وإذا كان رقم معين يتبع Structure محددًا فأعد بناءه، وإذا وُجدت حالة معينة فطبّق Rule إضافية قبل إخراج الملف.

بنيت هذا المشروع في منتصف 2025، وفي ذلك الوقت كان الحل منطقيًا جدًا. بدل أن أعيد عملية المعالجة نفسها يدويًا كل يوم، كتبت القواعد مرة واحدة داخل Python وأصبحت العملية التي كانت تحتاج وقتًا طويلًا تحدث بشكل شبه تلقائي. إذا أُضيف مصدر جديد، أبني له Script جديدًا. إذا تغيرت قاعدة معينة، أعدّل الـScript. وإذا ظهر Exception جديد، أضيف Condition جديدة.

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

المشكلة لم تعد في تنفيذ القواعد، بل في أن معرفة العمل نفسها أصبحت مدفونة داخل الكود.

لماذا تغيّر الحل الآن

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

اليوم لا يجب أن أستخدم الـModel كمحادثة فقط. أستطيع إعطاءه Tools، والسماح له بقراءة الملفات وتشغيل Python وإنشاء Script مؤقت وتجربة النتيجة وقراءة الـError إذا حدث، ثم تعديل الـCode وإعادة التشغيل. وهنا بدأت أسأل نفسي: إذا كان الـAI قادرًا على كتابة الـPython التي أحتاجها في كل مرة، فلماذا ما زلت أحافظ يدويًا على عشرات الـScripts؟

المشكلة طبعًا ليست بهذه البساطة. يمكنني إعطاء الـModel ملفًا والقول: حوّل هذا الملف إلى الـTemplate الذي أستخدمه. لكن كيف سيعرف الـModel القواعد؟ كيف سيعرف أن هذا المصدر يحتاج إلى Mapping مع ملف آخر؟ وكيف سيعرف أن هذه المجموعة من المصادر تستخدم طريقة الحساب نفسها لقيمة معينة، أو أن Rule ما تغيرت الأسبوع الماضي؟

يمكنني كتابة Prompt ضخم يحتوي على كل هذه المعلومات، لكن عندها لم أحل المشكلة؛ لقد استبدلت Python Script ضخمًا بـPrompt ضخم.

المعرفة على شكل شجرة

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

مثلًا، يجب أن تنتهي جميع المصادر في الـTemplate نفسه، وهناك Validation Rules عامة تنطبق على الجميع، وطريقة موحدة لتسجيل الأخطاء والتعامل مع البيانات الناقصة. بعد ذلك قد تكون هناك مجموعة من المصادر تستخدم العملة نفسها، ومجموعة ثانية تحتاج إلى نوع الـMapping نفسه، ومجموعة ثالثة تأتي من النوع نفسه من الأنظمة ولذلك يتشابه الـStructure الخاص بها. كلما نزلنا أكثر، أصبحت القواعد أكثر تخصصًا، إلى أن نصل إلى Source واحد لديه Exception خاص به.

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

بالتوازي مع ذلك، كنت أعمل على واجهة AI خاصة أستخدمها على جهازي. بداخلها أستطيع تشغيل Local Models أو استخدام Models مثل ChatGPT وClaude عندما لا تكون حساسية البيانات مشكلة، وبإمكاني التنقل بينها حسب المهمة. الـModel نفسه ليس هو المشروع؛ هو مجرد جزء منه ويمكن تغييره في أي وقت. حوله توجد Tools تسمح له بالوصول إلى الملفات، وتشغيل Code، وقراءة مجلدات معينة، أو الربط مع تطبيقات خارجية حسب الصلاحيات التي أعطيها له.

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

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

تخيل أن لدي محادثة رئيسية تعرف القواعد التي تنطبق على جميع مصادر البيانات. تعرف شكل الـOutput النهائي، والـValidation Rules، وأين توجد الملفات، وما الذي يحدث عندما تكون البيانات ناقصة، وتعرف أن الـRaw Data لا يجب تعديلها مباشرة.

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

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

هرم معرفة الوكلاء الفرعيين وكيف يرث كل مستوى القواعد الموجودة فوقه

إذا كانت هناك قاعدة تنطبق على جميع المصادر، أكتبها مرة واحدة في الأعلى. وإذا كان لدي 18 مصدرًا يستخدمون طريقة التعامل نفسها مع العملة، أضع القاعدة في المكان الذي يجمعهم. وإذا كان ثلاثة فقط من هذه المصادر يحتاجون إلى Mapping إضافي، أضع الـMapping في المستوى الذي يجمع الثلاثة. وإذا كان Source واحد فقط لديه Exception في Column معين، أضع هذا الـException في آخر مستوى.

بالتالي، عندما يصل ملف إلى الـAgent الخاص بهذا المصدر، فهو لا يعرف فقط الـException الصغير الخاص به، بل يعرف أيضًا الـMapping الموجود في المستوى الأعلى، وقواعد العملة الموجودة فوقه، والقواعد العامة لمعالجة البيانات الموجودة في بداية الشجرة.

يمكن أن تبدو عملية بناء الـContext الخاص بكل مصدر في الكود بهذا الشكل:

Pythonknowledge_context.py
def build_context(source):    rules = []    rules += knowledge["general"]    if source.currency == "SAR":        rules += knowledge["currency"]["SAR"]    if source.mapping_group:        rules += knowledge["mapping"][source.mapping_group]    rules += knowledge["sources"][source.id]    return rules

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

وهنا أصبح الأمر بالنسبة لي أكثر من مجرد طريقة لتنظيم المحادثات. أصبحت المعرفة نفسها تأخذ شكل المشكلة الحقيقية.

وكلاء متخصصون وسياق أصغر

الـSub Agent بالنسبة إليّ ليس Chatbot صغيرًا يتحدث مع Chatbot آخر. أراه كمحادثة متخصصة جدًا لها Context محدد ودور محدد. قيمتها ليست في أنها تعرف كل شيء؛ بل، على العكس، في أنها تعرف فقط الجزء الذي تحتاجه بالإضافة إلى المعرفة الموجودة فوقها. وهذا يحل مشكلة أخرى، هي حجم الـContext، لأنني لا أحتاج إلى إعطاء الـModel جميع القواعد الخاصة بالـ70 مصدرًا في كل مرة أعمل فيها على Source واحد.

إذا كنت أعمل على Source رقم 32 مثلًا، فما يحتاجه الـModel هو القواعد العامة، ثم قواعد المجموعة التي ينتمي إليها هذا المصدر، ثم القواعد الأكثر تخصصًا، وفي النهاية الـExceptions الخاصة به. أما بقية قواعد المصادر فلا تهمه أصلًا.

لكن أكثر ما جعلني أحب هذه الطريقة هو موضوع التغييرات.

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

Pythonupdate_shared_rule.py
knowledge.update(    path="currency.SAR.conversion",    value={        "target": "JOD",        "rate": 0.189,    },)

يمكن تطبيق الفكرة نفسها على Mapping أو Validation Rule أو طريقة بناء رقم معين أو مكان Dataset مرجعية أو أي Business Logic آخر مشترك بين أكثر من مصدر.

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

Python لم تختف، لكن دورها تغيّر

هذا لا يعني أن Python اختفت من النظام؛ بالعكس، ما تغير فقط هو دورها.

في النظام الذي بنيته في 2025، كان الـScript هو النظام نفسه. كانت الـBusiness Rules والتنفيذ موجودين داخله، وبالتالي كان أي تغيير في العمل يعني غالبًا تغييرًا في الـCode. الآن أحاول جعل القواعد والمعرفة منفصلة عن طريقة التنفيذ. يقرأ الـAgent القواعد ويفهم شكل البيانات، ثم يستطيع كتابة Python المناسبة للمهمة وتشغيلها واختبارها.

إذا كان الـScript الناتج مفيدًا لإعادة الاستخدام، فيمكن الاحتفاظ به. وإذا تغيرت القواعد بعد أسبوع، يمكن للـAgent تعديل الـScript أو حتى إعادة بنائه بناءً على المعرفة الجديدة. بهذه الطريقة، ما زال الـCode مهمًا جدًا، لكنه لم يعد المكان الذي تعيش فيه معرفة العمل.

Pythontemporary_execution.py
context = knowledge.for_source("source_32")script = agent.generate_python(    input_file="source_32.xlsx",    rules=context,    output_schema=STANDARD_TEMPLATE,)result = run(script)validate(result)

ما زالت Python موجودة، لكنها تُولّد من المعرفة المطلوبة للمهمة بدل أن تكون المكان الذي تعيش فيه هذه المعرفة بشكل دائم.

وطبعًا، هذا لا يعني أنني سأعطي LLM ملفًا يحتوي على نصف مليون Row وأقول له عالجه ثم أثق بالنتيجة. بالعكس، في كثير من الحالات لا يحتاج الـModel إلى قراءة البيانات كاملة أصلًا. دوره هو فهم الـSchema، وقراءة Samples كافية، وتحديد القواعد التي يجب تطبيقها، ثم كتابة أو اختيار الأداة التي ستتعامل مع الملف كاملًا بطريقة Deterministic.

بعد ذلك يمكنه عمل Validation على النتيجة. هل عدد الـRows قبل المعالجة وبعدها منطقي؟ هل جميع الـColumns المطلوبة موجودة؟ هل توجد Values لم نستطع عمل Mapping لها؟ هل ظهرت Duplicates؟ هل تغير Total معين بطريقة غير متوقعة؟ وإذا فشل أحد هذه الاختبارات، يستطيع الـAgent العودة إلى المشكلة ومعرفة السبب.

بهذه الطريقة لا أتعامل مع الـAI كأنه Magic Box يأخذ ملفًا ويرجع ملفًا آخر، بل كأنه يدير عملية المعالجة ويستخدم Python والأدوات الأخرى لتنفيذها.

المعرفة، الـModel، والتنفيذ

أكثر ما تغير عندي في النهاية هو أنني بدأت أفصل بين ثلاثة أشياء كنت أخلطها سابقًا: المعرفة، والـModel، والتنفيذ. المعرفة تشرح ماذا نعرف وكيف يجب أن يتم العمل، والـModel يقرأ هذه المعرفة ويفهم ما يحتاجه منها، والـTools تنفذ العمل الحقيقي.

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

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

قبل سنة، كنت أحاول تحويل كل ما أعرفه عن معالجة البيانات إلى Code. إذا ظهرت قاعدة جديدة أكتبها، وإذا تغير مصدر أعدّل الـScript، وإذا ظهر Exception جديد أضيف Condition جديدة. اليوم أحاول تحويل ما أعرفه إلى Knowledge يستطيع الذكاء الاصطناعي فهمها، وبعدها أترك طريقة التنفيذ تتغير حسب المهمة.

أنا لا أريد أن أبني Script لكل مشكلة إذا كان بإمكاني بناء عقل يعرف لماذا يجب معالجة البيانات بهذه الطريقة، ثم أعطيه الأدوات التي يحتاجها حتى ينفذها.

ربما هذا أكثر ما تغير في طريقة استخدامي للذكاء الاصطناعي خلال السنة الماضية. لفترة طويلة كنت أستخدم الـAI ليساعدني على بناء الأنظمة: أطلب منه Function، أو أصلح معه Error، أو أجعله يكتب Script. لكن المعرفة الحقيقية عن طريقة العمل كانت ما زالت في رأسي أو داخل الـCode.

اليوم أحاول أن أجعل هذه المعرفة نفسها جزءًا من النظام.

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

لذلك يمكن القول إنني استبدلت عشرات الـScripts بأسطول من الذكاء الاصطناعي، لكن الفكرة ليست في عدد الـAgents ولا في الـModel الذي يشغّلهم. ستتغير الـModels، وستصبح الأجهزة أقوى، وستتغير طريقة تشغيل الذكاء الاصطناعي نفسها.

أما الجزء الذي أريد الاحتفاظ به فعلًا فهو المعرفة.

لأنني قبل عام كنت أبني النظام الذي ينفذ القواعد، أما اليوم فأحاول بناء النظام الذي يفهم القواعد، والتنفيذ يأتي بعد ذلك.

اقرأ المزيد من المقالات

العودة للرئيسية