SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-28

كيفية استضافة SandBase Harness على خادمك

شغّل SandBase Harness v0.3.2 على VPS تملكه، مع تثبيت الإصدار المحدد وملف الوكيل YAML وخوادم MCP وأنماط العزل وتوجيه Anthropic SDK إلى خادمك.

ما تحصل عليه عند الاستضافة الذاتية لبيئة تشغيل وكلاء SandBase

تعني الاستضافة الذاتية لبيئة تشغيل وكلاء SandBase تشغيل SandBase Harness على خادم تملكه، بحيث تبقى الجلسات وبيانات الاعتماد والذاكرة ومسارات التدقيق على قرصك بدلاً من قرص جهة أخرى. وهي خدمة Node. تستمع على 127.0.0.1:3000، وتوفّر واجهة HTTP API من النوع /v1 ووحدة تحكم ويب، وتحفظ حالتها في SQLite بجوار ملفات الوكيل.

تتبع واجهة /v1 API بنية Claude Managed Agents (CMA)، وهي واجهة API المستضافة للوكلاء المُدارين. وهذا ما يجعل بيئة التشغيل هذه مهمة في الاتجاهين: يمكنك كتابة التعليمات البرمجية باستخدام Anthropic SDK وتوجيه baseURL فيها إلى خادمك، ثم نقل التعليمات البرمجية نفسها لاحقاً إلى نشر مستضاف.

لا تأتي SandBase Harness مع نموذج. بل تستدعي نموذجاً. اعتباراً من August 2026، تدعم OpenAI وAnthropic ونقاط النهاية المتوافقة مع OpenAI، وهذا يشمل البوابات المستضافة ذاتياً وموفّرين مثل DeepSeek V4. ولا يزال عليك توفير مفتاح API، أو خادم محلي يتحدث OpenAI API.

ما تحتاج إليه قبل البدء

  • VPS يعمل بنظام Ubuntu 24.04 ويحتوي على 2 GB من ذاكرة RAM على الأقل. يُعد بناء TypeScript أثقل خطوة في عملية التثبيت.
  • Node.js بإصدار 22 أو أحدث، وnpm بإصدار 10 أو أحدث. هذان الحدّان الأدنى إلزاميان وفقاً لما يحدده المشروع.
  • git، إضافةً إلى مفتاح API لمزوّد النماذج الذي تخطط لاستخدامه.
  • Docker، ولكن فقط إذا كنت تريد بيئات sandbox للحاويات لكل جلسة.

يأتي Ubuntu 24.04 مع Node 18.19 في مستودعه الخاص، وهذا أقل من الحد الأدنى المطلوب. لذلك ثبّت Node من NodeSource بدلاً من ذلك.

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs git
node -v
npm -v

يجب أن يعرض node -v القيمة v22 أو قيمة أعلى، ويجب أن يعرض npm -v القيمة 10 أو قيمة أعلى. إذا كان node -v لا يزال يعرض v18.19.1، فهذا يعني أن حزمة التوزيعة لا تزال مثبتة وتظهر أولاً في PATH. أزلها قبل المتابعة، لأن عملية البناء تستخدم إصدار node الذي يعثر عليه shell.

تثبيت SandBase من الوسم v0.3.2

ثبّت البرنامج من وسم، وليس من فرع متغير. تمنحك النسخة المستنسخة العارية من main أحدث ما أُضيف قبل ساعة، وقد لا تتطابق مفاتيح الإعداد أدناه معها. وسم v0.3.2 هو الوسم الحالي في 16 August 2026.

sudo install -d -o "$USER" -g "$USER" /opt/sandbase
cd /opt/sandbase
git clone --branch v0.3.2 --depth 1 https://github.com/sandbaseai/sandbase-harness.git
cd sandbase-harness
npm ci
npm run build

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

أنشئ الآن مساحة عمل. مساحة العمل دليل منفصل يحتفظ بملفات الوكيل وكل حالة التشغيل. ويتيح إبقاؤها خارج نسخة المصدر المسحوبة سحب وسم أحدث من دون المساس ببياناتك.

mkdir -p /opt/sandbase/workspace
cd /opt/sandbase/workspace
node /opt/sandbase/sandbase-harness/dist/index.js init
node /opt/sandbase/sandbase-harness/dist/index.js start

يكتب init دليلاً باسم .managed-agents/ داخل مساحة العمل. يشغّل start وحدة التحكم على http://127.0.0.1:3000/dashboard وواجهة API على http://127.0.0.1:3000/v1. لا يمكن الوصول إلى أي منهما من حاسوبك المحمول بعد، وهذا صحيح، وسنغطيه بمزيد من التفصيل أدناه. يمكنك الوصول إلى وحدة التحكم عبر SSH في الوقت الحالي:

ssh -N -L 3000:127.0.0.1:3000 you@your-server

مسار node .../dist/index.js الطويل يصبح مرهقاً، لذا امنحه اسماً.

alias sandbase='node /opt/sandbase/sandbase-harness/dist/index.js'

تُكتب الأوامر أدناه باستخدام sandbase <command> بناءً على ذلك.

لا تثبّته من npm

تذكر وثائق تثبيت المشروع ذلك صراحة: حزمة managed-agents غير ذات النطاق الظاهرة على npm ليست حزمة هذا المشروع. لذلك يجلب الأمران npx managed-agents وnpm install -g managed-agents شيئاً غير مرتبط ببيئة التشغيل التي تريدها. ثبّت المشروع من المصدر المعلَّم على GitHub إلى أن يعلن المشرفون عن حزمة رسمية ذات نطاق. هذه ليست ملاحظة هامشية في سجل المشروع؛ إذ يوجد الإصدار v0.3.1 أساساً لاستبدال خطوات البدء السريع القديمة عبر npm بمسار المصدر المعلَّم والمثبت.

وجّه مساحة العمل إلى مزوّد نماذج

يكتب init.managed-agents/config.yaml. يُضبط مزوّد واحد لمساحة العمل بأكملها، ثم تختار الوكلاء الفرديون معرّفات النماذج المحددة.

model:
  provider: openai
  api_key: ${OPENAI_API_KEY}
storage:
  metadata:
    provider: sqlite
    options: {}
  artifacts:
    provider: local
    options:
      base_path: files

يأخذ النموذج ${OPENAI_API_KEY} القيمة من بيئة العملية، لذلك يبقى المفتاح خارج ملف الإعدادات وخارج كل نسخة احتياطية تنشئها لهذا الملف. ضعه في ملف بيئة لا يستطيع قراءته إلا root، لأن systemd يقرأ EnvironmentFile= بصفته root قبل خفض الامتيازات.

sudo install -d -m 750 /etc/sandbase
sudo touch /etc/sandbase/runtime.env
sudo chmod 600 /etc/sandbase/runtime.env

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

ملف YAML للوكيل: mcp_servers والأدوات وسياسات الصلاحيات

تُعرَّف الوكلاء كملفات YAML في دليل مساحة العمل agents/. هذا هو الجزء من بيئة التشغيل الذي ستقضي فيه معظم وقتك فعلياً. تصبح المفاتيح أوضح بعد أن تكون قد كتبت حلقة وكيل صغيرة يدوياً، لأن كل مفتاح منها يضبط شيئاً كنت ستبرمجه بنفسك لولا ذلك: مطالبة النظام، وقائمة الأدوات، والفحص الذي يُجرى قبل تشغيل الأداة.

name: Incident commander
description: Triages alerts and coordinates response.
model: gpt-4o
system: |-
  You are an on-call incident commander.
mcp_servers:
  - name: sentry
    type: url
    url: https://mcp.sentry.dev/mcp
tools:
  - type: agent_toolset_20260401
    default_config:
      permission_policy: { type: always_ask }
    configs:
      - name: bash
        permission_policy: { type: always_ask }
  - type: mcp_toolset
    mcp_server_name: sentry
metadata:
  template: incident-commander

حمّله وتحقق من استيراده:

sandbase reload
sandbase list
sandbase chat agent_assistant --message "hello"

يستورد reload ملف YAML الأساسي إلى SQLite. يجب أن يطبع list الوكيل مع معرّف الآن. إذا لم يعرضه list، فهذا يعني أن الملف لم يُحلَّل، وستجد سبب ذلك في .managed-agents/logs/runtime.log.

mcp_servers يعرّف نقاط نهاية MCP (بروتوكول سياق النموذج). يعني type: url أن بيئة التشغيل تتصل عبر HTTP بخادم يعمل في مكان آخر، ولذلك يمكنك استخدام أي خدمة تديرها مسبقاً، بما في ذلك خوادم MCP المستضافة على VPS نفسه الذي تعمل عليه بيئة التشغيل. عادةً ما يكون البحث على الويب أول أداة يلجأ إليها المستخدمون، ومن المفيد قراءة تمرير نسخة SearXNG الخاصة بك إلى وكيل قبل ربطها، لأن الأداة التي تعيد صفحات كتبها أشخاص مجهولون تضع نصاً غير موثوق به مباشرةً في سياق النموذج. أما الربط الأول الأبسط، فهو نقطة نهاية للقراءة فقط فوق بيانات تملكها مسبقاً. وهذا ما يتيحُه openGym بجوار متتبّع التمارين نفسه، بحيث يستطيع الوكيل الإجابة عن أسئلة تتعلق بسجل تدريبك دون أن يتمكن من إعادة كتابة أي جزء منه.

لا يؤدي تعريف الخادم إلى إتاحة أدواته للوكيل. تتولى قائمة tools ذلك من خلال إدخال mcp_toolset يطابق فيه mcp_server_name القيمة المذكورة أعلاه في name. إذا تصرف الوكيل كما لو أن أدوات MCP غير موجودة، فقارن السلسلتين حرفاً بحرف قبل أن تبحث عن السبب في أي مكان آخر.

تحتوي agent_toolset_20260401 على مجموعة الأدوات المضمّنة. اللاحقة التي تتضمن التاريخ هي إصدار للمخطط، ولذلك يحتفظ الوكيل المثبّت عليه بتعريفات الأدوات التي كُتب ليتعامل معها. تحدد default_config السياسة المطبقة على كل أداة في المجموعة، ويتجاوز كل إدخال ضمن configs هذه السياسة لأداة واحدة حسب اسمها، وهي bash في المثال.

تُظهر permission_policy القيمة التي تضيفها بيئة التشغيل مقارنةً باستدعاء نموذج مجرد. توقف always_ask الجلسة وتنتظر موافقة بشرية على الاستدعاء قبل تشغيله. وتسمح always_allow بمروره. يعني ضبط bash على always_ask أن الوكيل لا يستطيع تشغيل أمر shell من دون أن ترى الأمر الدقيق أولاً. وهذا هو الإجراء نفسه الذي ستستخدمه عند تشغيل Claude Code بأمان على VPS. إذا كنت تشغّل DeepSeek Harness أيضاً، فستتوفر عناصر التحكم نفسها هناك كإضافات بدلاً من مفاتيح YAML، وتُعد الإضافات التي تحد الميزانيات وتقيّد استدعاءات الأدوات أقرب نظير لهذه الكتلة.

أوضاع sandbox الثلاثة، ومتى يناسب كل منها

تعمل استدعاءات الأدوات التي تنفّذ التعليمات البرمجية داخل sandbox. ويُحدَّد backend لكل بيئة من خلال sandbox_provider في كائن البيئة config، أو من Settings ثم Sandbox في وحدة التحكم. تُنشأ البيئات عبر API في POST /v1/environments.

local ينفّذ التعليمات البرمجية كعملية فرعية لبيئة التشغيل، على المضيف، وباسم مستخدم بيئة التشغيل نفسها. وهو الوضع الافتراضي، ويكون مناسباً ما دمت المستخدم الوحيد وما دام agent يقرأ الملفات التي تملكها فقط. لكنه لا يوفر عزلاً. فإذا حذفت استدعاءات الأدوات ملفات، فستحذف ملفاتك، وإذا قرأت استدعاءات الأدوات /etc/sandbase/runtime.env فستقرأ مفتاح provider الخاص بك.

docker يبدأ حاوية واحدة لكل جلسة.

{
  "sandbox_provider": "docker",
  "image": "node:22-slim",
  "resources": { "memory": "1g", "cpu": 1 }
}

تحصل الجلسة على نظام ملفات خاص بها، وحد أقصى خاص بالذاكرة، وحصة خاصة بها من CPU، وتُزال الحاوية مع الجلسة. انتقل إلى هذا الوضع فوراً عندما ينفّذ agent تعليمات برمجية لم تكتبها أنت. وتتمثل الكلفة في أن مستخدم بيئة التشغيل يحتاج إلى الوصول إلى Docker socket، وأن العضوية في مجموعة docker تعادل امتلاك صلاحيات root على المضيف. وتستخدم الحاويات الخاصة بكل جلسة البنية نفسها التي تستخدمها بيئات sandbox ذاتية الاستضافة لـagent مع حاوية واحدة لكل تشغيل، لذلك ينطبق هنا دون تغيير التحليل المتعلق بما يمكن لعملية أفلتت من العزل الوصول إليه.

kubernetes يشغّل حمل عمل الجلسة في pod ويديره باستخدام kubectl exec وkubectl cp. وتحتاج صورة runtime إلى وجود kubectl، كما يحتاج ServiceAccount الخاص بها إلى أذونات RBAC (التحكم في الوصول المستند إلى الأدوار) لإنشاء pods وحذفها والحصول عليها وسردها ومراقبتها في namespace المستهدف، إضافة إلى المورد الفرعي exec. ولا يستحق هذا الوضع عناء الإعداد إلا إذا كنت تشغّل cluster بالفعل.

لماذا يستمع runtime على 127.0.0.1؟

لأنّه يبدأ مع تعطيل المصادقة. يفعّل runtime المصادقة باستخدام bearer token عند وجود مفتاح API واحد على الأقل، بينما لا ينشئ init جديد أي مفاتيح. إن ربطت runtime غير المصادق عليه، والذي يملك أدوات shell ومفتاح مزود الخدمة، بالعنوان 0.0.0.0 الافتراضي، فستعرّضه للإنترنت العام.

لذلك، عندما تريد الوصول إليه، اترك عنوان الربط كما هو ونفّذ أمرين آخرين.

أولاً، فعّل المصادقة. عيّن MANAGED_AGENTS_API_KEY في ملف بيئة الخدمة، أو أنشئ مفتاحاً باستخدام POST /v1/api-keys. يعرض هذا الأمر حقلاً باسم secret_key مرة واحدة، ولا يعرضه مجدداً. بعد ذلك، يرسل العملاء Authorization: Bearer <key> مع كل طلب. يمثّل كل مفتاح هوية مشتركة واحدة. إذا كنت تريد فعلياً agent معزولاً لكل زميل، مع الاحتفاظ بمفاتيح مزودي الخدمة في بوابة واحدة، فإن OneCLI مصمم لهذا النمط.

ثانياً، ضع reverse proxy أمامه وأنهِ TLS (أمان طبقة النقل) عنده. يقدّم runtime HTTP عاديّاً عن قصد، ويتوقع من مكوّن آخر التعامل مع الشهادات.

server {
    listen 443 ssl;
    server_name agents.example.com;

    ssl_certificate     /etc/letsencrypt/live/agents.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/agents.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Connection "";
        proxy_buffering off;
        proxy_read_timeout 3600s;
    }
}

السطران المذكوران ليسا للزينة. يهم proxy_buffering off لأن الجلسات تُبث عبر server-sent events (SSE). عند تفعيل التخزين المؤقت، يحتفظ nginx بالاستجابة حتى تمتلئ ذاكرته المؤقتة. لذلك لا تعرض وحدة التحكم شيئاً أثناء عمل agent، ثم تعرض كل شيء دفعة واحدة في النهاية. ويهم proxy_read_timeout 3600s لأن القيمة الافتراضية هي 60 ثانية. لذلك يغلق proxy البث في منتصف الدورة إذا ظل ساكناً لأكثر من دقيقة، ويبدو الفشل كأن runtime قد تعطّل.

في جدار الحماية، افتح المنفذين 22 و443. اترك المنفذ 3000 مغلقاً، لأن proxy يصل إليه عبر loopback، ولا ينبغي لأي اتصال خارج الخادم الوصول إليه.

وجّه Anthropic SDK إلى خادمك الخاص

تنفّذ بيئة التشغيل واجهة /v1 مماثلة، لذلك يتصل بها عميل Anthropic SDK بعد تغيير حقل واحد.

import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  apiKey: process.env.MANAGED_AGENTS_API_KEY ?? 'local-dev-key',
  baseURL: 'http://127.0.0.1:3000'
});

كما تقبل رؤوس beta التي ترسلها عملاء Claude Managed Agents، وهما anthropic-beta: managed-agents-2026-04-01 وanthropic-beta: agent-memory-2026-07-22. وهي اختيارية عند استخدام بيئة تشغيل محلية. وُجدت هذه الرؤوس لكي تعمل الشفرة المكتوبة لنشر مستضاف هنا دون تغيير.

التوافق قريب، لكنه غير كامل. اقرأ docs/api-matrix.md في checkout قبل افتراض توفّر واجهة معينة، لأن المشروع يوثّق الثغرات الخاصة به هناك، بما في ذلك custom tools من جهة العميل، التي لا تزال تتطلب تسجيلاً مسمّى فوق بروتوكول event-result الحالي.

يعمل HTTP العادي جيداً أيضاً، وهو أسرع طريقة لإثبات أن بيئة التشغيل تعمل:

curl -N -X POST http://127.0.0.1:3000/v1/sessions/SESSION_ID/messages \
  -H "Content-Type: application/json" \
  -d '{"content": "Hello", "stream": true}'

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

curl -N http://127.0.0.1:3000/v1/sessions/SESSION_ID/events/stream \
  -H "Last-Event-ID: EVENT_ID"

هذا التدفق القابل للاستئناف هو سبب استمرار الجلسة بعد إغلاق الحاسوب المحمول. تُحفَظ الأحداث على الخادم، لذلك يعيد العميل تشغيل سجل بدلاً من الاحتفاظ بالنسخة الوحيدة منه.

مكان حفظ بيانات الاعتماد والذاكرة ومسارات التدقيق على القرص

كل ما يملكه runtime موجود ضمن .managed-agents/ في مساحة العمل.

.managed-agents/
├── config.yaml
├── data.db
├── logs/runtime.log
├── files/
├── skills/
├── snapshots/
└── sandbox/
  • يحتوي data.db على بيانات SQLite الوصفية: الوكلاء والجلسات وإدخالات مخزن بيانات الاعتماد وإدخالات مخزن الذاكرة ومفاتيح API.
  • يحتوي files/ على وحدات بايت الملفات المحمّلة، بينما يحتوي skills/ على حزم المهارات المحمّلة.
  • يحتوي snapshots/ على لقطات مساحة عمل الجلسات، بينما يحتوي sandbox/ على أدلة العمل الخاصة بالجلسات التي تعمل في الوضع المحلي.
  • يمثّل logs/runtime.log أول مكان ينبغي التحقق منه عندما لا يحدث شيء بصمت.

مخازن بيانات الاعتماد هي مجموعات من الأسرار. تضيف كل مجموعة باستخدام auth_type مثل environment_variable، ثم تربطها بجلسة عبر vault_ids عند إنشاء الجلسة. تحتوي مخازن الذاكرة على إدخالات مسماة تثبّتها في جلسة بصفتها memory_store، مع إعداد وصول وتعليمات خاصين بها. يوجد كلا النوعين ضمن data.db. وهذا هو الفرق تحديداً بين runtime واستدعاء نموذج خام: إذ يتذكر runtime المعلومات بين الجلسات، ويسجل ما حدث.

بما أنها موجودة في دليل واحد، انسخها احتياطياً كوحدة واحدة.

sudo systemctl stop sandbase
sudo tar czf /root/sandbase-$(date +%F).tgz -C /opt/sandbase/workspace .managed-agents
sudo systemctl start sandbase

أوقف الخدمة أولاً. قد يؤدي نسخ قاعدة بيانات SQLite أثناء كتابة runtime إليها إلى التقاط ملف لا يمكن فتحه عند الاستعادة، وقد تكتشف ذلك في اليوم الذي تحتاج فيه إلى النسخة الاحتياطية. إذا كنت تفضّل إبقاء YAML الخاص بالوكلاء في git وحالة runtime في موقع آخر، فإن وثيقة النشر تدعم تثبيت موقع الحالة باستخدام --data-dir على start.

الاستعادة هي العملية العكسية: افحص نفس الوسم على خادم جديد، وفك الأرشيف داخل مساحة العمل، ثم ابدأ الخدمة. لن يكون مفتاح المزوّد موجوداً في الأرشيف إذا استخدمت صيغة ${OPENAI_API_KEY}، لذلك احتفظ به في مكان يمكنك الوصول إليه لاحقاً.

شغّله عبر systemd

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

sudo adduser --system --group --no-create-home --home /opt/sandbase sandbase
sudo chown -R sandbase:sandbase /opt/sandbase

احفظ هذا في /etc/systemd/system/sandbase.service.

[Unit]
Description=SandBase Harness runtime
After=network-online.target

[Service]
User=sandbase
Group=sandbase
WorkingDirectory=/opt/sandbase/workspace
EnvironmentFile=/etc/sandbase/runtime.env
ExecStart=/usr/bin/node /opt/sandbase/sandbase-harness/dist/index.js start --host 127.0.0.1 --port 3000
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

يستدعي مثال النشر الخاص بالمشروع ملفاً تنفيذياً باسم managed-agents على PATH. لا ينشئ التثبيت من مصدر موسوم هذا الملف، لذلك يشغّل ExecStart الأمر node على نقطة الدخول المبنية بدلاً من ذلك.

sudo systemctl daemon-reload
sudo systemctl enable --now sandbase
sudo systemctl status sandbase
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3000/dashboard

النتيجة السليمة هي active (running) من status و200 من curl. في أي حالة أخرى، اقرأ journalctl -u sandbase -n 50 أولاً ثم .managed-agents/logs/runtime.log. يمثّل enable --now الجزء المهم، لأن العملية التي شغّلتها يدوياً تختفي بعد إعادة التشغيل التالية.

ما الذي يتعطل، والرسالة التي ستراها

يُنهى npm run build دون ظهور خطأ من npm. في VPS بسعة 1 GB، يوقف kernel عملية compile الخاصة بـTypeScript بسبب نفاد الذاكرة، ويسجل ذلك في kernel log بدلاً من npm. تحقّق باستخدام journalctl -k | grep -i "out of memory"، الذي يطبع سطراً يذكر عملية node التي أُنهِيت. أضف swap، أو نفّذ عملية build على instance أكبر وانسخ dist/ إليه.

Error: listen EADDRINUSE: address already in use 127.0.0.1:3000. توجد عملية أخرى تشغل المنفذ. يحدد sudo ss -lntp | grep 3000 هذه العملية. أوقفها، أو شغّل runtime باستخدام --port 3001 وحدّث proxy.

لن تُحمَّل لوحة المعلومات من حاسوبك المحمول. هذا سلوك مقصود، لأن runtime يستمع على loopback. استخدم نفق SSH المذكور أعلاه، أو أكمل إعداد reverse proxy. لا تصلح ذلك باستخدام --host 0.0.0.0، لأن المصادقة متوقفة حتى يوجد key.

تفشل sandboxes الخاصة بـDocker باستخدام permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock. المستخدم sandbase ليس عضواً في مجموعة docker. أصلح ذلك باستخدام sudo usermod -aG docker sandbase ثم أعد تشغيل الخدمة، وافهم ما منحته: هذه المجموعة تملك صلاحيات root على المضيف، ولذلك تلغي جزءاً من سبب منح runtime مستخدماً خاصاً به.

تفشل sandboxes الخاصة بـKubernetes باستخدام Error from server (Forbidden). يفتقد ServiceAccount صلاحيات pod أو المورد الفرعي exec. تحقّق منه مباشرة باستخدام kubectl auth can-i create pods/exec -n <namespace>، الذي يجيب بـyes أو no.

يعيد كل طلب الحالة 401 بعد إضافة API key. تتفعّل المصادقة عند وجود أول key، وتنطبق على console وAPI معاً. أرسل Authorization: Bearer <key>، وإذا فقدت key فأنشئ أخرى، لأن secret_key تُعرض مرة واحدة ولا تُخزَّن بصيغة قابلة للقراءة.

لا تظهر أدوات خادم MCP مطلقاً في جلسة. تحقّق من mcp_server_name في كتلة tools مقابل name في mcp_servers، ثم تحقّق من قدرة runtime على الوصول إلى URL من الخادم نفسه باستخدام curl -i <url>. خادم MCP من نوع URL هو اعتماد على الشبكة، ويحل VPS الأسماء ويوجّه network traffic بطريقة تختلف عن حاسوبك المحمول.

FAQ

هل يمكنني تشغيل SandBase Harness من دون مفتاح OpenAI أو Anthropic؟

نعم، إذا كان لديك endpoint متوافق مع OpenAI. يدعم runtime مزوّدي OpenAI وAnthropic والمزوّدين المتوافقين مع OpenAI، ولذلك يعمل خادم محلي يستخدم OpenAI API. عيّن مزوّد workspace في .managed-agents/config.yaml، ووجّه api_key وendpoint إليه. لا يتضمن runtime نموذجاً خاصاً به، لذلك يجب أن يستجيب شيء ما لهذه الاستدعاءات.

هل من الآمن كشف runtime على منفذ عام؟

ليس بالإعداد المثبّت. يرتبط بـ127.0.0.1:3000 ويبدأ مع تعطيل المصادقة، والحل ليس استخدام عنوان ربط مختلف. أنشئ API key، أو عيّن MANAGED_AGENTS_API_KEY، لتفعيل المصادقة باستخدام bearer token. ثم ضع nginx أو Caddy أمامه لتوفير TLS، وأبقِ المنفذ 3000 مغلقاً في جدار الحماية، بحيث يكون المسار الوحيد للدخول عبر الـproxy.

ما الفرق بين بيئات العزل المحلية وDocker وKubernetes؟

يشغّل local كود الأدوات كعملية فرعية لـruntime على المضيف، باستخدام صلاحيات مستخدم runtime ومن دون عزل. ينشئ docker حاوية مستقلة لكل جلسة، مع نظام ملفات خاص بها وحد للذاكرة وحصة من CPU، ويحذفها عند انتهاء الجلسة. يشغّل kubernetes الجلسة كـpod ويديرها باستخدام kubectl exec، الذي يحتاج إلى kubectl داخل صورة runtime، وإلى RBAC على pods، إضافةً إلى المورد الفرعي exec في namespace الهدف.

ما الذي أحتاج إلى نسخه احتياطياً تحديداً؟

دليل .managed-agents/ داخل workspace. يحتوي على config.yaml، وقاعدة بيانات SQLite في data.db التي تضم agents والجلسات وإدخالات مخزن بيانات الاعتماد وإدخالات الذاكرة، إضافةً إلى الملفات المرفوعة وحزم المهارات ولقطات الجلسات. أوقف الخدمة قبل نسخه حتى لا تُكتب بيانات SQLite أثناء إنشاء الأرشيف. مفاتيح API الخاصة بالمزوّدين المشار إليها باسم ${OPENAI_API_KEY} ليست داخل النسخة الاحتياطية، لذلك خزّنها بشكل منفصل.

لماذا أستنسخ الوسم v0.3.2 بدلاً من main؟

الوسم يمثل شجرة ثابتة، لذلك تكون مفاتيح الإعداد وأوامر CLI التي تقرأ عنها هي نفسها التي ستحصل عليها فعلياً. يتغير main، وقد يُعاد تسمية مفتاح إعداد بين وقت كتابة الدليل ووقت تشغيلك له. ويحذّر المشروع أيضاً من أن الحزمة غير المقيّدة managed-agents على npm ليست هذا المشروع، ولذلك يثبّت npx managed-agents شيئاً غير مرتبط به. يوجد الإصدار v0.3.1 أساساً لاستبدال البدء السريع عبر npm بمسار المصدر المقيّد بالوسم.