ذاكرة وكيل الذكاء الاصطناعي بين الجلسات: ملف التقدم وسجل القرارات وgit وسكربت التهيئة
لا تملك وكلاء الذكاء الاصطناعي ذاكرة بين الجلسات: كل ما لم يُكتب في ملفات المستودع لا تعرفه الجلسة الجديدة. تُبنى ذاكرة الوكيل من أدوات واضحة: PROGRESS.md (أين نحن الآن)، وDECISIONS.md (لماذا هذا الخيار وما الذي رُفض)، وcommits في git تشرح المقصود، وبروتوكول تسليم في AGENTS.md يأمر بقراءتها في البداية وتحديثها في النهاية، وسكربت init يتحقق من البيئة ويطبع الحالة الحالية.
لماذا لا يتذكر الوكيل شيئاً؟
النموذج لا يحفظ حالته بين عمليات التشغيل. كل ما يعرفه الوكيل عن مهمتك موجود في نافذة السياق للجلسة الحالية: الملفات التي قرأها، ومخرجات الأوامر، وحوار معك. تنتهي الجلسة أو يمتلئ السياق، فتبدأ الجلسة الجديدة من الصفر، ولا ترى إلا ما هو مكتوب على القرص.
تشبيه مفيد: مهندس عبقري يأتي إلى العمل كل صباح وقد مُسحت ذاكرته تماماً. سيفهم الشيفرة بسرعة، لكنه لن يتذكر أي بنية اختير البارحة، ولماذا رُفضت البدائل، وفي أي حالة كانت الاختبارات. ومن دون ملاحظات سيقضي 15 إلى 20 دقيقة في الاستطلاع، وغالباً سيعيد تصميم ما رفضتَه عن قصد.
لذلك فإن ذاكرة وكيل الذكاء الاصطناعي ليست خاصية في النموذج، بل جزء من الهارنس: مجموعة ملفات وقواعد تصممها أنت. والخبر الجيد أنك لا تحتاج قواعد بيانات متجهية ولا خدمات خاصة. تكفي بضعة ملفات Markdown وgit وقليل من الانضباط.
لماذا لا يحل نافذة السياق الكبيرة المشكلة؟
قد يبدو أن الانتظار لنموذج بنافذة أكبر كافٍ. لكن المهمة المعقدة تملأ أي نافذة: الوكيل يقرأ قاعدة الشيفرة، ويراكم تاريخ القرارات، ويستقبل مخرجات اختبارات مطولة، ويحتفظ بالحوار كله. ومع اتساع النافذة تكبر الحاجات معها. المشكلة معمارية لا مسألة حجم.
وهناك أثر ثانٍ: قرب حدود النافذة تميل كثير من النماذج إلى الاستعجال في إنهاء العمل، فتتخطى الفحص أو تختار الحل البسيط بدل الصحيح. وقد وصفت Anthropic هذه الملاحظة لنماذجها، ويختلف مقدار الأثر من نموذج إلى آخر. فالجلسة الطويلة عند حد السياق ليست خطر فقدان المعلومات فحسب، بل خطر تراجع جودة العمل.
الضغط (compaction): ما الذي يُحفظ وما الذي يضيع؟
الضغط هو تكثيف الجزء المبكر من الحوار في ملخص قصير لتفريغ مساحة داخل الجلسة نفسها. في Claude Code تقوم بذلك الأداة /compact، ويحدث الضغط تلقائياً عند الاقتراب من الحد. أما الأمر /clear فيمسح التاريخ ويبدأ الحديث من جديد.
مشكلة الضغط أن الملخص يحفظ عادة «ماذا» ويفقد «لماذا». الشيفرة الجاهزة تبقى في الملفات، لكن الاستدلال — لماذا اختير الخيار ب، ولماذا لم تُستخدم مكتبة، ولماذا أُهمل التحسين عمداً — يُكثَّف إلى كلمتين أو يختفي. فتقوم الخطوة التالية للوكيل بـ«تحسين» قرار مقصود لأنها لم تعد ترى أسبابه.
| الضغط | إعادة الضبط (جلسة جديدة) | |
|---|---|---|
| ما الذي يحدث | يُستبدل الجزء المبكر من الحوار بملخص | تُغلق الجلسة وتقرأ الجديدة ملفات الحالة |
| ما الذي يُحفظ | ما رأى النموذج أنه مهم أثناء الضغط | بالضبط ما كتبته في الملفات |
| الاستعجال قرب الحد | قد يبقى | يُصفَّر |
| متى يكون مناسباً | المهمة ستتسع للجلسة الحالية بالتأكيد | أفق المهمة طويل أو غير واضح |
قاعدة عملية بلا مقاييس معقدة: حين تشغل المهمة نحو 60% من النافذة، توقف عن كتابة الشيفرة وجهّز تسليم العمل. أما إذا كان السياق مشغولاً بنحو 40% وكانت نهاية المهمة قريبة فيكفي الضغط.
أربعة عناصر تتكون منها ذاكرة الوكيل
بدلاً من الاعتماد على ذاكرة النموذج، أنشئ دفتر سفينة. يتكون من أربعة أجزاء، ولكل منها دور محدد.
- PROGRESS.md — أين نحن الآن.
- DECISIONS.md — لماذا تم الأمر على هذا النحو لا غيره.
- commits في Git — نقاط حفظ مجانية لحالة العمل.
- بروتوكول التسليم في AGENTS.md — ما يُفعل عند الاستلام وعند الانصراف.
PROGRESS.md: ملف التقدم
يجيب عن سؤال واحد: في أي حالة يوجد المشروع الآن؟ يقرؤه الوكيل أولاً في بداية الجلسة، ويحدّثه آخراً قبل الانصراف. الملف قصير، ويُعاد كتابته ولا يُلحق به إلى ما لا نهاية، فالتاريخ يعيش في git.
# PROGRESS.md
## الهدف الحالي
البحث في كتالوج المنتجات (الميزة search-01)
## الحالة
- HEAD: 4f2a9c1
- make check: أخضر، 142/142 اختباراً
- المنجز: فهرس في PostgreSQL (tsvector)، ونقطة GET /search
- المتحقق منه: اختبارات الوحدة + طلب curl يدوي بثلاثة استعلامات
## العوائق
- لا توجد بيانات عن الصرف المورفولوجي للغة الكازاخية — ننتظر القرار
## الخطوة التالية
إضافة الترقيم الصفحي إلى GET /search، المعيار: اختبار للصفحة الثانية
لاحظ الحقول الأربعة التي تكفي لتسليم العمل: hash الـ commit، ونسبة الاختبارات الناجحة، والعوائق، والخطوة التالية. فإذا لم تستطع جلسة جديدة أن تواصل العمل بيقين اعتماداً على هذا الملف، فهذا يعني أن القالب ينقصه حقل.
DECISIONS.md: سجل القرارات
يحفظ «اللماذا» نفسه الذي يضيع عند الضغط. صيغة القيد: القرار، والسبب، وما الذي رُفض ولماذا، والقيود.
## 2026-03-14 — تخزين مؤقت لإعدادات المستخدم في Redis
- القرار: Redis مع TTL خمس دقائق، وإبطال فوري عند الكتابة.
- السبب: تُقرأ في كل طلب، والبيانات صغيرة جداً.
- رُفض: materialized view في PostgreSQL — التغييرات متكررة جداً، والصيانة لا تستحق.
- القيد: لا تُخزَّن إعدادات الدفع مؤقتاً.
أثمن سطر هنا هو «رُفض». فهو يمنع الجلسة اللاحقة من «تحسين» القرار بالعودة إلى خيار سبق بحثه ونُبذ. وسجل القرارات، خلافاً لملف التقدم، لا يُختصر بل يُضاف إليه فقط: لا تُحذف القيود القديمة، بل تُعلَّم بأنها استُبدلت بقيود جديدة.
تاريخ git كنقاط حفظ
الـ commits هي لقطات مُنسَّخة لحالة العمل مدمجة في العمل أصلاً. يستطيع الوكيل قراءة git log وgit diff ليستعيد ما الذي تغيّر. ولكي يعمل التاريخ كذاكرة يجب أن تشرح رسالة الـ commit المقصود، لا أن تعيد سرد الـ diff.
# سيئ
git commit -m "update search.py"
# جيد
git commit -m "search: فهرس tsvector بدلاً من LIKE
LIKE '%q%' لا يستخدم الفهرس، وعلى 200 ألف منتج يستغرق الاستعلام 1.8 ثانية.
الترقيم الصفحي لم يُنجز بعد، انظر PROGRESS.md."
الـ commits الصغيرة المتكررة بعد كل تشغيل اختبارات أخضر تمنحك نقطة تراجع إضافية. إذا انحرفت الجلسة عن المسار فالعودة إلى آخر حالة متحقق منها أسهل بكثير من فك تشابك تعديلات نصف منجزة.
بروتوكول التسليم في AGENTS.md
ملفات الحالة لا تنفع إذا لم يكن الوكيل يعرف بوجودها. لذلك يُكتب في ملف التعليمات (AGENTS.md أو CLAUDE.md) بروتوكول قصير: ماذا يفعل عند الاستلام وعند الانصراف.
## الاستلام
1. اقرأ PROGRESS.md وDECISIONS.md.
2. حدد المهمة النشطة في .agent/feature_list.json.
3. شغّل make check للتأكد من تناسق المستودع.
4. واصل من «الخطوة التالية» دون إعادة فتح ما تم حسمه.
## الانصراف
1. شغّل make check وثبّت الحالة الخضراء بـ commit.
2. حدّث PROGRESS.md: HEAD والاختبارات والعوائق والخطوة التالية.
3. أضف القرارات الجديدة إلى DECISIONS.md.
4. لا تترك عملاً نصف منجز في شجرة العمل.
يُفضَّل أن يبقى البروتوكول قصيراً: بضعة أسطر في ملف التعليمات، لا صفحات.
سكربت init: تسريع بداية الجلسة
لكي لا يجمع الوكيل الصورة يدوياً، أعطه سكربتاً واحداً يتحقق من البيئة ويطبع الحالة. ينبغي أن يكون السكربت idempotent، أي يمكن تشغيله مراراً دون ضرر، وأن ينتهي برسالة واضحة عن الجاهزية.
#!/usr/bin/env bash
set -euo pipefail
echo "== 1. البيئة =="
command -v uv >/dev/null || { echo "FAIL: uv غير مثبت"; exit 1; }
uv sync --frozen
echo "== 2. المستودع =="
if [ -n "$(git status --porcelain)" ]; then
echo "WARN: شجرة العمل غير نظيفة"
else
echo "OK: نظيفة"
fi
echo "HEAD: $(git log -1 --oneline)"
echo "== 3. الفحص =="
make check
echo "== 4. الحالة =="
cat PROGRESS.md
echo "جاهز للعمل"
بعد ذلك يكفي في بروتوكول الاستلام سطر واحد: «شغّل scripts/init.sh». وفي Claude Code يمكن أتمتة هذا التشغيل عبر hook عند بداية الجلسة (حدث SessionStart)، ولكن حتى بدونه سينفذ الوكيل السكربت بتعليمات من الملف.
ما الذي يُوضع في ذاكرة الوكيل وما الذي لا يُوضع؟
الخطأ الأكبر أن تتحول الذاكرة إلى مكب نفايات. كل سطر يقرؤه الوكيل عند البداية يشغل مكاناً في السياق، والزائد يطغى على المهم.
| يُوضع | لا يُوضع |
|---|---|
| الهدف الحالي والخطوة التالية | إعادة سرد الشيفرة التي سيقرؤها الوكيل بنفسه |
| القرارات مع أسبابها والبدائل المرفوضة | السجل الكامل للحوار ومخرجات الأوامر |
| hash الـ commit وحالة الاختبارات | قائمة التبعيات، فهي موجودة في ملف الحزم |
| العوائق والأسئلة المفتوحة | «عملت بشكل رائع، وكل شيء يعمل» دون ذكر طريقة التحقق |
| الطرق المسدودة: ما جُرّب ولماذا لم ينجح | الأسرار والرموز والكلمات السرية |
| المهام مع معايير القبول | ملاحظات قديمة عن مهام مغلقة |
افصل أيضاً حسب عمر المعلومة. قواعد المشروع تتغير نادراً وتخص كل المهام، ومكانها ملف التعليمات. أما الحالة فتتغير في كل جلسة، ومكانها ملف التقدم. وإذا خلطتهما تضخم ملف التعليمات سريعاً بملاحظات قديمة.
الجلسة الأولى: التهيئة مرحلة مستقلة
لا تنفع الذاكرة بين الجلسات إذا انزلقت الجلسة الأولى إلى الفوضى. الصورة النموذجية: تكتب على مستودع فارغ «أضف البحث»، وبعد نصف ساعة يتبين أن إطار الاختبارات مُعدّ بشكل خاطئ وصيغة الهجرات غير مناسبة. ظهر البحث، لكن الأساس معوج.
السبب أن التنفيذ والتهيئة يحسّنان أشياء مختلفة: الأول يحسّن عدد الميزات المنجزة في هذه الجلسة، والثانية تحسّن سرعة وموثوقية كل الجلسات اللاحقة. ويميل الوكيل إلى النتيجة المرئية، أي الشيفرة. لذلك يُفصل التهيئة في جلسة مستقلة لها معيار إنجاز من أربعة شروط.
- أن يعمل التشغيل:
make setupوmake devيعملان من نسخة نظيفة. - أن يكون هناك تحقق: يوجد
make testومعه اختبار حقيقي واحد على الأقل ينجح. - أن يُرى التقدم: ملف الحالة موجود ويمكن قراءته.
- أن يُستأنف العمل: توجد قائمة مهام مع معايير قبول.
إذا كنت تبدأ مشاريع جديدة كثيراً فأنشئ قالب مستودع فيه Makefile وإطار الاختبارات وهيكل AGENTS.md ومجلد .agent/ وscripts/init.sh والمدقق اللغوي وCI. حينها تقتصر التهيئة على خصوصية المشروع المحدد.
كيف تتحقق من عمل الذاكرة؟
أصدق مقياس هو الزمن من بداية الجلسة الجديدة حتى أول تعديل ذي معنى في الشيفرة. دون أثر مكتوب يكون عادة 15 إلى 20 دقيقة من الاستطلاع، ومع تسليم جيد للعمل يكون دقيقتين أو ثلاثاً. قِس ذلك مرة قبل التغيير ومرة بعده، وسترى إن كان الانضباط يستحق العناء.
الطريقة الثانية هي اختبار البداية الباردة. افتح جلسة جديدة واكتب «تابع»، ثم اطرح خمسة أسئلة: ما الهدف الحالي؟ في أي حالة الاختبارات؟ ما القرار المتخذ في الموضوع الرئيسي ولماذا؟ ما الذي يعيق العمل؟ ما الخطوة التالية؟ إذا أجاب الوكيل عن الأسئلة الخمسة من الملفات دون تخمين، فالذاكرة مبنية بشكل صحيح. وكل إجابة غير واثقة تعني حقلاً ناقصاً في القالب.
أخطاء شائعة
- ملف التقدم لا يتوقف عن النمو. بعد شهر يحتوي على مئات الأسطر من التاريخ. أعد كتابته ليعكس الحالة الحالية، والتاريخ في git.
- لا يوجد سطر «رُفض». سجل القرارات بلا البدائل المرفوضة لا يحمي من النقاشات المتكررة.
- الوكيل يحدّث الحالة «بالتقدير». اكتب كيف جرى التحقق: الأمر والنتيجة، لا «كل شيء يعمل».
- تسليم العمل عند حد النافذة. عند الحد يكون الوكيل مستعجلاً بالفعل؛ ابدأ التسليم مبكراً، عند نحو 60%.
- شجرة عمل غير نظيفة عند الانصراف. التعديلات نصف المنجزة دون commit تربك الجلسة التالية.
خلاصة
ذاكرة وكيل الذكاء الاصطناعي بين الجلسات لا تُبنى على النموذج، بل على الملفات: PROGRESS.md يحفظ الحالة الحالية، وDECISIONS.md يحفظ الأسباب والبدائل المرفوضة، وcommits في git نقاط حفظ تشرح المقصود، وبروتوكول التسليم في AGENTS.md يجعل الوكيل يقرأ هذا كله ويحدّثه. وسكربت init يختصر البداية إلى أمر واحد، واختبار البداية الباردة يبيّن إن كانت السجلات كافية. ويُشرح دفتر السفينة الخاص بالوكيل وعقد التهيئة بالتطبيق العملي في دورة هندسة الهارنس.
الأسئلة الشائعة
هل يمكن أن أطلب من الوكيل أن يتذكر شيئاً للمستقبل؟
لن يتذكره الوكيل إلا إذا كتبه في ملف ستقرؤه الجلسة التالية. يوجد في Claude Code ملفات ذاكرة وCLAUDE.md، لكن لحالة مهمة محددة يكون ملف تقدم صريح في المستودع أضمن.
ما الفرق بين PROGRESS.md وCHANGELOG؟
الـ CHANGELOG يصف التغييرات للمستخدمين حسب الإصدارات. أما PROGRESS.md فيصف حالة العمل الجارية للجلسة التالية، ويُعاد كتابته كلما تغيّرت الحالة.
هل أحتاج قاعدة بيانات متجهية لذاكرة وكيل البرمجة؟
عادة لا في عمل داخل مستودع واحد: حالة المهمة تتسع لبضعة ملفات قصيرة، والوكيل يقرأ الشيفرة مباشرة. يكون البحث المتجهي مفيداً عندما تحتاج البحث في كم كبير من الوثائق الخارجية.
هل أضع ملفات الحالة في git؟
نعم، فتكون الحالة متاحة لأي جلسة ولكل أعضاء الفريق، ويُحفظ تاريخ تغيراتها. الاستثناء الملاحظات الشخصية وكل ما يحتوي أسراراً.
ماذا لو نسي الوكيل تحديث PROGRESS.md في النهاية؟
اجعل التحديث جزءاً من معيار الإنجاز في بروتوكول الانصراف، وتحقق منه آلياً، مثلاً بـ hook أو سكربت يقارن HEAD المكتوب في الملف مع الـ commit الحالي.
يُشرح هذا الموضوع بالتفصيل مع التطبيق العملي في دورة «Harness Engineering: инженерия надёжности AI-агентов».
الانتقال إلى الدورة