إدارة الجلسات والضغط (تعمّق تقني)¶
تشرح هذه الوثيقة كيف يدير OpenClaw الجلسات من البداية إلى النهاية:
- توجيه الجلسة (كيف تُطابِق الرسائل الواردة
sessionKey) - مخزن الجلسة (
sessions.json) وما الذي يتتبّعه - استمرارية السجل النصي (
*.jsonl) وبنيته - نظافة السجل النصي (تصحيحات خاصة بالموفّر قبل التشغيل)
- حدود السياق (نافذة السياق مقابل الرموز المتتبَّعة)
- الضغط (اليدوي + التلقائي) وأين يمكن ربط أعمال ما قبل الضغط
- الصيانة الصامتة (مثل كتابات الذاكرة التي لا ينبغي أن تُنتِج مخرجات مرئية للمستخدم)
إذا أردت نظرة عامة أعلى مستوى أولًا، ابدأ بـ:
مصدر الحقيقة: الـ Gateway¶
صُمّم OpenClaw حول عملية Gateway واحدة تمتلك حالة الجلسة.
- ينبغي لواجهات المستخدم (تطبيق macOS، واجهة التحكم على الويب، TUI) الاستعلام من الـ Gateway عن قوائم الجلسات وعدّادات الرموز.
- في الوضع البعيد، تكون ملفات الجلسة على المضيف البعيد؛ «فحص ملفات Mac المحلية» لن يعكس ما يستخدمه الـ Gateway.
طبقتان ثابتتان¶
يحفظ OpenClaw الجلسات في طبقتين:
-
مخزن الجلسة (
sessions.json) - خريطة مفتاح/قيمة:sessionKey -> SessionEntry- صغير، قابل للتغيير، وآمن للتحرير (أو حذف الإدخالات) - يتتبّع بيانات وصفية للجلسة (معرّف الجلسة الحالي، آخر نشاط، مفاتيح التبديل، عدّادات الرموز، إلخ) -
السجل النصي (
<sessionId>.jsonl) - سجل إلحاقي فقط ببنية شجرية (للإدخالاتid+parentId) - يخزّن المحادثة الفعلية + استدعاءات الأدوات + ملخّصات الضغط - يُستخدم لإعادة بناء سياق النموذج للأدوار اللاحقة
مواقع التخزين على القرص¶
لكل وكيل، على مضيف الـ Gateway:
- المخزن:
~/.openclaw/agents/<agentId>/sessions/sessions.json - السجلات النصية:
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl - جلسات مواضيع Telegram:
.../<sessionId>-topic-<threadId>.jsonl
يحلّ OpenClaw هذه المسارات عبر src/config/sessions.ts.
مفاتيح الجلسة (sessionKey)¶
يُحدِّد sessionKey «أي دلو محادثة» أنت فيه (توجيه + عزل).
أنماط شائعة:
- الدردشة الرئيسية/المباشرة (لكل وكيل):
agent:<agentId>:<mainKey>(الافتراضيmain) - مجموعة:
agent:<agentId>:<channel>:group:<id> - غرفة/قناة (Discord/Slack):
agent:<agentId>:<channel>:channel:<id>أو...:room:<id> - كرون:
cron:<job.id> - Webhook:
hook:<uuid>(ما لم يتم التجاوز)
القواعد المعتمدة موثّقة في /concepts/session.
معرّفات الجلسات (sessionId)¶
يشير كل sessionKey إلى sessionId الحالي (ملف السجل النصي الذي يواصل المحادثة).
قواعد عامة:
- إعادة الضبط (
/new،/reset) تُنشئsessionIdجديدًا لذلكsessionKey. - إعادة الضبط اليومية (الافتراضي 4:00 صباحًا بالتوقيت المحلي على مضيف الـ Gateway) تُنشئ
sessionIdجديدًا عند الرسالة التالية بعد حدّ إعادة الضبط. - انتهاء الخمول (
session.reset.idleMinutesأو القديمsession.idleMinutes) يُنشئsessionIdجديدًا عند وصول رسالة بعد نافذة الخمول. عند تفعيل اليومي + الخمول معًا، يفوز أيّهما ينتهي أولًا.
تفصيل تنفيذي: يحدث القرار في initSessionState() ضمن src/auto-reply/reply/session.ts.
مخطط مخزن الجلسة (sessions.json)¶
نوع قيمة المخزن هو SessionEntry في src/config/sessions.ts.
الحقول الرئيسية (غير حصرية):
sessionId: معرّف السجل النصي الحالي (يُشتق اسم الملف منه ما لم يتم تعيينsessionFile)updatedAt: طابع زمني لآخر نشاطsessionFile: تجاوز اختياري لمسار السجل النصيchatType:direct | group | room(يساعد واجهات المستخدم وسياسة الإرسال)provider،subject،room،space،displayName: بيانات وصفية لتوسيم المجموعة/القناة- مفاتيح التبديل:
thinkingLevel،verboseLevel،reasoningLevel،elevatedLevelsendPolicy(تجاوز لكل جلسة)- اختيار النموذج:
providerOverride،modelOverride،authProfileOverride- عدّادات الرموز (أفضل جهد/تعتمد على الموفّر):
inputTokens،outputTokens،totalTokens،contextTokenscompactionCount: عدد مرات اكتمال الضغط التلقائي لهذا مفتاح الجلسةmemoryFlushAt: الطابع الزمني لآخر تفريغ ذاكرة قبل الضغطmemoryFlushCompactionCount: عدد الضغط عند تشغيل آخر تفريغ
المخزن آمن للتحرير، لكن الـ Gateway هو المرجع: قد يعيد كتابة الإدخالات أو إعادة إحيائها أثناء تشغيل الجلسات.
بنية السجل النصي (*.jsonl)¶
تُدار السجلات النصية بواسطة @mariozechner/pi-coding-agent الخاص بـ SessionManager.
الملف بصيغة JSONL:
- السطر الأول: رأس الجلسة (
type: "session"، يتضمنid،cwd،timestamp، وparentSessionالاختياري) - ثم: إدخالات الجلسة مع
id+parentId(شجرة)
أنواع إدخالات ملحوظة:
message: رسائل المستخدم/المساعد/نتيجة الأداةcustom_message: رسائل محقونة بواسطة الامتداد تدخل سياق النموذج (يمكن إخفاؤها عن واجهة المستخدم)custom: حالة الامتداد التي لا تدخل سياق النموذجcompaction: ملخّص ضغط محفوظ معfirstKeptEntryIdوtokensBeforebranch_summary: ملخّص محفوظ عند التنقّل في فرع شجري
يتعمّد OpenClaw عدم «تصحيح» السجلات النصية؛ يستخدم الـ Gateway SessionManager لقراءتها وكتابتها.
نوافذ السياق مقابل الرموز المتتبَّعة¶
مفهومان مختلفان مهمّان:
- نافذة سياق النموذج: حدّ صارم لكل نموذج (الرموز المرئية للنموذج)
- عدّادات مخزن الجلسة: إحصاءات متحرّكة تُكتب في
sessions.json(تُستخدم لأوامر /status ولوحات المتابعة)
إذا كنت تضبط الحدود:
- تأتي نافذة السياق من كتالوج النماذج (ويمكن تجاوزها عبر التهيئة).
contextTokensفي المخزن هو قيمة تقدير/إبلاغ وقت التشغيل؛ لا تتعامل معه كضمان صارم.
للمزيد، راجع /token-use.
الضغط: ما هو¶
يلخّص الضغط المحادثات الأقدم في إدخال compaction محفوظ في السجل النصي، مع إبقاء الرسائل الحديثة سليمة.
بعد الضغط، ترى الأدوار اللاحقة:
- ملخص الدمج
- الرسائل بعد
firstKeptEntryId
الضغط مستمر (على عكس تقليم الجلسة). انظر /concepts/session-pruning.
متى يحدث الضغط التلقائي (تشغيل Pi)¶
في وكيل Pi المضمّن، يُفعَّل الضغط التلقائي في حالتين:
- استعادة من فيضان: يُرجع النموذج خطأ فيضان السياق → ضغط → إعادة المحاولة.
- صيانة العتبة: بعد دور ناجح، عندما:
contextTokens > contextWindow - reserveTokens
حيث:
contextWindowهي نافذة سياق النموذجreserveTokensهو الهامش المحجوز للمطالبات + مخرج النموذج التالي
هذه دلالات تشغيل Pi (يستهلك OpenClaw الأحداث، لكن Pi هو من يقرّر متى يضغط).
إعدادات الضغط (reserveTokens، keepRecentTokens)¶
توجد إعدادات الضغط الخاصة بـ Pi ضمن إعدادات Pi:
{
compaction: {
enabled: true,
reserveTokens: 16384,
keepRecentTokens: 20000,
},
}
يفرض OpenClaw أيضًا حدّ أمان أدنى للتشغيلات المضمّنة:
- إذا كان
compaction.reserveTokens < reserveTokensFloorأقل، يرفعه OpenClaw. - الحدّ الافتراضي الأدنى هو
20000رمزًا. - اضبط
agents.defaults.compaction.reserveTokensFloor: 0لتعطيل الحدّ الأدنى. - إذا كان أعلى بالفعل، يتركه OpenClaw كما هو.
السبب: ترك هامش كافٍ لأعمال «الصيانة» متعددة الأدوار (مثل كتابات الذاكرة) قبل أن يصبح الضغط حتميًا.
التنفيذ: ensurePiCompactionReserveTokens() في src/agents/pi-settings.ts
(يُستدعى من src/agents/pi-embedded-runner.ts).
الواجهات المرئية للمستخدم¶
يمكنك ملاحظة الضغط وحالة الجلسة عبر:
/status(في أي جلسة دردشة)openclaw status(CLI)openclaw sessions/sessions --json- الوضع المفصّل:
🧹 Auto-compaction complete+ عدد مرات الضغط
الصيانة الصامتة (NO_REPLY)¶
يدعم OpenClaw أدوارًا «صامتة» للمهام الخلفية حيث لا ينبغي للمستخدم رؤية مخرجات وسيطة.
الاتفاقية:
- يبدأ المساعد مخرجه بـ
NO_REPLYللإشارة إلى «عدم تسليم ردّ للمستخدم». - يقوم OpenClaw بإزالة/كبت ذلك في طبقة التسليم.
اعتبارًا من 2026.1.10، يقوم OpenClaw أيضًا بكبت بثّ المسودات/الكتابة عندما تبدأ قطعة جزئية بـ NO_REPLY، حتى لا تتسرّب مخرجات جزئية أثناء الدور.
«تفريغ الذاكرة» قبل الضغط (مُنفَّذ)¶
الهدف: قبل حدوث الضغط التلقائي، تشغيل دور وكيل صامت يكتب حالة دائمة إلى القرص
(مثل memory/YYYY-MM-DD.md في مساحة عمل الوكيل) بحيث لا يستطيع الضغط
محو السياق الحرج.
يستخدم OpenClaw نهج التفريغ قبل العتبة:
- مراقبة استخدام سياق الجلسة.
- عند تجاوز «عتبة لينة» (أدنى من عتبة الضغط في Pi)، تشغيل توجيه صامت «اكتب الذاكرة الآن» إلى الوكيل.
- استخدام
NO_REPLYبحيث لا يرى المستخدم شيئًا.
التهيئة (agents.defaults.compaction.memoryFlush):
enabled(الافتراضي:true)softThresholdTokens(الافتراضي:4000)prompt(رسالة المستخدم لدور التفريغ)systemPrompt(موجّه نظام إضافي يُلحق بدور التفريغ)
ملاحظات:
- تتضمن المطالبة/موجّه النظام الافتراضيان تلميح
NO_REPLYلكبت التسليم. - يعمل التفريغ مرة واحدة لكل دورة ضغط (يُتتبَّع في
sessions.json). - يعمل التفريغ فقط لجلسات Pi المضمّنة (تتجاوز الخلفيات عبر CLI ذلك).
- يُتجاوز التفريغ عندما تكون مساحة عمل الجلسة للقراءة فقط (
workspaceAccess: "ro"أو"none"). - راجع Memory لتخطيط ملفات مساحة العمل وأنماط الكتابة.
يُتيح Pi أيضًا خطّاف session_before_compact في واجهة برمجة الامتداد، لكن منطق التفريغ في OpenClaw
يعيش اليوم على جانب الـ Gateway.
قائمة التحقق لاستكشاف الأخطاء وإصلاحها¶
- خطأ في مفتاح الجلسة؟ مفتاح الجلسة خاطئ؟ ابدأ بـ /concepts/session وأكّد
sessionKeyفي/status. - تخزين ضد عدم تطابق النص ؟ عدم تطابق المخزن مع السجل النصي؟ أكّد مضيف الـ Gateway ومسار المخزن من
openclaw status. - البريد المزعج؟ تحقّق من:
- نافذة سياق النموذج (صغيرة جدًا)
- إعدادات الضغط (
reserveTokensالمرتفع جدًا مقارنة بنافذة النموذج قد يسبّب ضغطًا أبكر) - تضخّم نتائج الأدوات: فعّل/اضبط تقليم الجلسة
- الدوران الصامت للتسرب؟ تسرّب الأدوار الصامتة؟ أكّد أن الرد يبدأ بـ
NO_REPLY(الرمز الدقيق) وأنك على إصدار يتضمن إصلاح كبت البثّ.