DeepSeek Harness: عزل الخدمات والنطاق
آخر تحديث: 2026-08-31
في بيئات الوكلاء المتعددين والجلسات المتعددة، الخدمات المشتركة نعمة ونقمة — الخدمات العامة مريحة لكنها عرضة للتعارض، الخدمات المعزولة آمنة لكن تكلفة الاتصال أعلى. نظام النطاق في Cordis يوازن بينهما: مشتركة افتراضياً، معزولة عند الطلب.
📋 المتطلبات المسبقة: أكمل 19-service.md، تفهم صنف Service الأساسي
1. ما ستتعلمه
- النطاق العام (Global Scope)
- نطاق الجلسة (Session Scope)
- نطاق الطلب (Request Scope)
- إعدادات isolate realm
- النطاق وإعدادات الوكيل المسبقة
- عزل الخدمات متعدد الوكلاء
2. النطاق العام
(1) السلوك الافتراضي
افتراضياً، جميع الخدمات عامة — هناك نسخة واحدة فقط عبر نسخة DSH بالكامل:
export default class CacheService extends Service {
constructor(ctx: Context) {
super(ctx, 'cache') // فريد عالمياً
}
}
(2) خصائص الخدمة العامة
| الخاصية | الوصف |
|---|---|
| أحادية | نسخة واحدة فقط لكل عملية |
| مشتركة | جميع الجلسات والطلبات تتشارك نفس الحالة |
| بدون عزل | البيانات المُعدّلة بالجلسة A مرئية للجلسة B |
(3) السيناريوهات المُطبقة
- إدارة الإعدادات (إعدادات عامة واحدة فقط مطلوبة)
- تجمعات الاتصال (الاتصالات المشتركة أكثر كفاءة)
- خدمات السجلات (السجلات يجب جمعها مركزياً)
- محولات النماذج (استدعاءات API يمكن إعادة استخدامها عبر الجلسات)
(4) ▶ مثال 4
// ❌ الذاكرة المؤقتة العامة تُسبب تسرب بيانات عبر الجلسات
export default class CacheService extends Service {
private data = new Map<string, any>()
set(key: string, value: any) {
this.data.set(key, value)
}
}
// الجلسة A: ctx.cache.set('temp', 'secret-data')
// الجلسة B: ctx.cache.get('temp') → 'secret-data' (تسرب!)
3. نطاق الجلسة
(1) المفهوم
نطاق الجلسة يُنشئ نسخة خدمة مستقلة لكل جلسة:
export default class SessionCacheService extends Service {
static scope = 'session'
constructor(ctx: Context) {
super(ctx, 'session-cache')
}
}
(2) ▶ مثال 2
graph LR
S1[الجلسة A أُنشئت] --> C1[نسخة CacheService A]
S2[الجلسة B أُنشئت] --> C2[نسخة CacheService B]
S1 --> D1[الجلسة A دُمرت → CacheService A دُمر]
S2 --> D2[الجلسة B دُمرت → CacheService B دُمر]
(3) تصريح النطاق
export default class SessionCacheService extends Service {
static scope = 'session'
// أو
// static scope = Symbol('session')
}
(4) السيناريوهات المُطبقة
- ذاكرة مؤقتة بمستوى الجلسة
- تجاوزات إعدادات بمستوى الجلسة
- تخصيص مجموعة أدوات بمستوى الجلسة
- تاريخ الجلسة
(5) تأثير العزل عبر الجلسات
الجلسة A:
ctx.sessionCache.set('key', 'value-A')
الجلسة B:
ctx.sessionCache.get('key') → undefined (معزول)
الجلسة A:
ctx.sessionCache.get('key') → 'value-A' (متاح داخل الجلسة)
4. نطاق الطلب
(1) المفهوم
نطاق الطلب يُنشئ نسخة مستقلة لكل استدعاء أداة أو طلب LLM:
export default class RequestContextService extends Service {
static scope = 'request'
constructor(ctx: Context) {
super(ctx, 'request-context')
}
}
(2) دورة حياة نطاق الطلب
graph LR
R1[الطلب 1 يبدأ] --> S1[نسخة الخدمة 1]
R2[الطلب 2 يبدأ] --> S2[نسخة الخدمة 2]
R1 --> E1[الطلب 1 يكتمل → النسخة 1 تُدمّر]
R2 --> E2[الطلب 2 يكتمل → النسخة 2 تُدمّر]
(3) السيناريوهات المُطبقة
- معلومات سياق بمستوى الطلب (IP المستخدم، مُعرّف الطلب)
- فحوصات صلاحيات بمستوى الطلب
- توقيت أداء بمستوى الطلب
- تجميع سجلات بمستوى الطلب
(4) مقارنة مستويات النطاق الثلاثة
| البُعد | عام | الجلسة | الطلب |
|---|---|---|---|
| النسخ | 1 | 1 لكل جلسة | 1 لكل طلب |
| دورة الحياة | عمر العملية | عمر الجلسة | عمر الطلب |
| مشاركة الحالة | مشتركة عالمياً | داخل الجلسة | داخل الطلب فقط |
| الذاكرة | منخفضة | متوسطة | عالية |
| الأفضل لـ | إعدادات/تجمعات اتصال | ذاكرة مؤقتة/تاريخ | صلاحيات/توقيت |
5. إعدادات isolate realm
(1) مفهوم Realm
Realm هو نطاق العزل في Cordis — إنشاء مساحات إضافات مستقلة داخل نفس نسخة DSH:
# cordis.yml
realms:
agent-a:
isolate: ['cache', 'tools']
plugins:
my-tool-a:
$insert: ./plugins/tool-a
agent-b:
isolate: ['cache', 'tools']
plugins:
my-tool-b:
$insert: ./plugins/tool-b
(2) حقل isolate
قائمة isolate تُحدد أي خدمات تحصل على نسخ مستقلة داخل الـ realm:
realms:
my-realm:
isolate:
- cache # خدمة cache تحصل على نسخة مستقلة
- tools # خدمة tools تحصل على نسخة مستقلة
# الخدمات غير المُدرجة تبقى مشتركة عالمياً
(3) نسخ الخدمات داخل Realm
عام: llm (مشترك)
realm-a: cache (مستقل)، tools (مستقل)
realm-b: cache (مستقل)، tools (مستقل)
الإضافات في realm-a → ctx.cache = cache الخاص بـ realm-a
الإضافات في realm-b → ctx.cache = cache الخاص بـ realm-b
لا يؤثران على بعضهما
(4) حالات استخدام Realm
| السيناريو | الوصف |
|---|---|
| وكلاء متعددون | وكلاء مختلفون لديهم مجموعات أدوات وذاكرات مؤقتة مختلفة |
| متعددو المستأجرين | خدمات مستأجرين مختلفين معزولة mutually |
| الاختبار | realm الاختبار لا يؤثر على realm الإنتاج |
| اختبار A/B | realmان يستخدمان تطبيقات خدمة مختلفة |
(5) التواصل عبر Realms
Realms معزولة افتراضياً لكن يمكنها التواصل عبر الخدمات العامة:
// خدمة عامة (غير متأثرة بـ isolate)
export default class EventBusService extends Service {
constructor(ctx: Context) {
super(ctx, 'event-bus') // ليس في قائمة isolate → مشترك عالمياً
}
emit(event: string, data: any) { /* ... */ }
on(event: string, handler: Function) { /* ... */ }
}
// إضافة في realm-a
ctx.eventBus.emit('data-updated', { source: 'realm-a' })
// إضافة في realm-b
ctx.eventBus.on('data-updated', (data) => {
ctx.logger.info(`received from ${data.source}`)
})
6. النطاق وإعدادات الوكيل المسبقة
(1) مفهوم الإعداد المسبق للوكيل
الإعداد المسبق للوكيل هو تهيئة مُعرّفة مسبقاً تشمل مجموعة الأدوات ومُعاملات النموذج وإعدادات النطاق:
presets:
coder:
model: deepseek-coder
tools: [file_edit, shell, search]
mode: standard
reviewer:
model: deepseek-chat
tools: [file_edit, search]
mode: minimal
isolate: [cache]
(2) علاقة الإعداد المسبق والنطاق
كل إعداد مسبق يمكنه تحديد قائمة isolate، مُنشئاً نسخ خدمات مستقلة لذلك الوكيل:
وكيل coder: cache مشترك، tools مستقل
وكيل reviewer: cache مستقل، tools مشترك
(3) سيناريو الوكلاء المتعددين
# cordis.yml
agents:
coder:
preset: coder
isolate: [tools]
reviewer:
preset: reviewer
isolate: [tools, cache]
(4) تعاون الوكلاء البيني
graph TB
subgraph Global
LLM[llm Service]
EVENT[event-bus Service]
end
subgraph Agent-Coder
CT[tools Service]
CC[cache Service]
end
subgraph Agent-Reviewer
RT[tools Service]
RC[cache Service]
end
CT --> LLM
RT --> LLM
CT --> EVENT
RT --> EVENT
7. عزل الخدمات متعدد الوكلاء
(1) اختيار استراتيجية العزل
مشترك بالكامل: جميع الخدمات عامة → بسيط لكن تعارضات محتملة
معزول بالكامل: جميع الخدمات مستقلة → آمن لكن هدر موارد
عزل مختلط: خدمات أساسية مشتركة + خدمات أعمال معزولة → نهج متوازن
العزل المختلط المُوصى به:
| نوع الخدمة | استراتيجية العزل | السبب |
|---|---|---|
| llm | مشترك | استدعاءات API يمكن إعادة استخدامها |
| sessions | مشترك | إدارة جلسات موحدة |
| tools | معزول | كل وكيل له مجموعة أدوات مختلفة |
| cache | معزول | كل وكيل له ذاكرة مؤقتة مستقلة |
| fs | مشترك | نظام ملفات واحد فقط |
(2) ▶ مثال 2
agents:
frontend-dev:
preset: coder
isolate: [tools, cache]
tools:
- file_edit
- shell
- search
config:
cache:
maxSize: 100
backend-dev:
preset: coder
isolate: [tools, cache]
tools:
- file_edit
- shell
- search
- database
config:
cache:
maxSize: 200
(3) تقدير استهلاك الموارد
| مستوى العزل | الذاكرة | CPU | الاتصالات |
|---|---|---|---|
| مشترك عالمياً | 1x | 1x | 1x |
| وكلاء 2 معزول | ~2x | ~1.5x | ~2x |
| وكلاء 5 معزول | ~5x | ~3x | ~5x |
(4) كشف تسرب العزل
// مراقبة عدّاد نسخ الخدمات
ctx.on('service/created', (name, instance) => {
ctx.logger.info(`service created: ${name}, total instances: ${countInstances(name)}`)
})
// إذا كان عدد نسخ خدمة يتجاوز عدد الوكلاء بكثير، قد يكون هناك تسرب
❓ أسئلة شائعة
static scope هي أحادية عامة افتراضياً.typescript constructor(ctx: Context) { super(ctx, 'cache') console.log(`cache instance created: ${this.id}, scope: ${this.scope}`) } 📖 ملخص
- ثلاثة مستويات نطاق: عام (افتراضي)، جلسة (مستقل لكل جلسة)، طلب (مستقل لكل طلب)
- الخدمات العامة تناسب إعدادات/تجمعات اتصال، خدمات الجلسة تناسب ذاكرة مؤقتة/تاريخ، خدمات الطلب تناسب صلاحيات/توقيت
- إعدادات isolate realm تُنشئ نسخ خدمات مستقلة لمساحات مُحددة
- إعدادات الوكيل المسبقة مُقترنة بالنطاق تُفعّل عزل مجموعة أدوات وذاكرة مؤقتة متعدد الوكلاء
- استراتيجية العزل المختلط المُوصى بها: خدمات أساسية مشتركة + خدمات أعمال معزولة
- اختيار النطاق يؤثر على الذاكرة والأداء؛ اعزل عند الحاجة، لا تُفرط
📝 تمارين
1. ⭐ أساسي: اكتب SessionStateService بنطاق جلسة يُحافظ على تخزين مفتاح-قيمة مستقل لكل جلسة. ابدأ جلستين وتحقق من عزل البيانات.
2. ⭐⭐ متوسط: هيّئ realm يعزل خدمات cache و tools. ادخل cache داخل وخارج realm، وتحقق أنك تحصل على نسخ مختلفة.
3. ⭐⭐⭐ تحدٍ: صمّم نظام وكلاء مزدوج: coder و reviewer. Coder لديه أدوات file_edit/shell، reviewer لديه أدوات file_edit/search فقط. كلاهما يشارك llm و sessions، لكن cache ومجموعات الأدوات معزولة بشكل مستقل. تحقق: أداة shell الخاصة بـ coder غير مرئية لـ reviewer، وذاكرتيهما المؤقتتين لا تؤثران على بعضهما.