الكتابات/tutorial/2026/08
Tutorial3 أغسطس 2026·22 دقيقة

عزل تنفيذ كود وكلاء الذكاء الاصطناعي باستخدام Microsoft MXC وTypeScript

تعلّم كيف تستخدم Microsoft Execution Containers (MXC) لعزل الكود غير الموثوق الذي تُنفّذه وكلاء الذكاء الاصطناعي. يغطي هذا الدليل التثبيت وضبط السياسات وأنماط تنفيذ الصناديق الرملية وتكامل أدوات Claude في TypeScript.

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

تجعل Microsoft Execution Containers (MXC)، التي أُطلقت في مؤتمر Build 2026، الخيار الثاني أمراً عملياً. MXC هو محرك سياسات على مستوى نظام التشغيل يُقيّد بدقة ما يمكن لأي عملية الوصول إليه — مسارات الملفات، وواجهات الشبكة، ووقت المعالج — باستخدام مخطط JSON موحّد وحزمة TypeScript تعمل على Windows وmacOS وLinux.

يرشدك هذا الدليل خطوة بخطوة نحو تأمين استدعاءات أدوات وكيل الذكاء الاصطناعي بـMXC، بحيث لا يستطيع حتى المخرج الأكثر عدائية للنموذج الهروب من حاويته.

ملاحظة للمعاينة: MXC في مرحلة معاينة مبكرة حتى أغسطس 2026. الحزمة (@microsoft/mxc-sdk v0.7.0، رخصة MIT) مستقرة للاستخدام التطويري وبيئات الإنتاج غير الحساسة أمنياً. تطبيق حدود أمان قوية على مستوى الآلة الافتراضية لا يزال قيد التطوير.

المتطلبات الأساسية

قبل البدء، تأكد من توفر ما يلي:

  • Node.js 20+ مع npm أو pnpm
  • TypeScript 5.5+ مع تفعيل الوضع الصارم
  • نظام تشغيل مدعوم: Windows 11 24H2+، أو macOS 14+، أو Linux بنواة 5.15+
  • إلمام بـ async/await والأنواع العامة في TypeScript
  • مفتاح Anthropic API لخطوة تكامل الوكيل (اختياري)

ما الذي ستبنيه

بنهاية هذا الدليل ستحصل على:

  1. كلاس SandboxExecutor قابل للإعادة بدعم MXC
  2. سياسات JSON دقيقة تُقيّد الوصول للملفات والشبكة
  3. أنماط تنفيذ مفرد ومتعدد الحالات في الصندوق الرملي
  4. تكامل كامل يربط MXC بأداة bash لوكيل Claude

الخطوة 1: تثبيت الحزمة

pnpm add @microsoft/mxc-sdk

يقوم سكريبت postinstall تلقائياً بتنزيل الملف الثنائي المناسب للنظام. على Linux يكتشف أيضاً ما إذا كان Firecracker متاحاً للواجهة الخلفية microvm.

أضف خيارات المُجمِّع التالية إلى tsconfig.json:

{
  "compilerOptions": {
    "moduleResolution": "bundler",
    "target": "ES2022",
    "lib": ["ES2022"],
    "strict": true
  }
}

الخطوة 2: التحقق من دعم المنصة

تحقق دائماً من إمكانيات المنصة قبل إنشاء أي صندوق رملي:

// src/sandbox/platform.ts
import { getPlatformSupport } from '@microsoft/mxc-sdk';
 
export async function requireSandboxSupport() {
  const support = await getPlatformSupport();
 
  if (support.backends.length === 0) {
    throw new Error(
      `MXC غير متاح على هذه المنصة. ` +
      `نظام التشغيل: ${support.os}، النواة: ${support.kernelVersion}`
    );
  }
 
  // تفضيل microvm للعزل الأقوى؛ مع الرجوع لـ process عند عدم توفره
  const preferred = support.backends.includes('microvm') ? 'microvm' : 'process';
 
  console.log(`MXC جاهز — يستخدم واجهة "${preferred}"`);
  return { ...support, preferred };
}

الخطوة 3: تعريف سياسة الصندوق الرملي

تتبع سياسات MXC نموذج الرفض الافتراضي؛ كل صلاحية يجب منحها صراحةً. إليك سياسة مناسبة لتشغيل أوامر الصدفة من وكيل ذكاء اصطناعي:

// src/sandbox/policy.ts
import {
  createConfigFromPolicy,
  getAvailableToolsPolicy,
  getTemporaryFilesPolicy,
  type MxcPolicy,
} from '@microsoft/mxc-sdk';
import * as os from 'node:os';
import * as path from 'node:path';
 
export function buildAgentToolPolicy(projectRoot: string): MxcPolicy {
  const tmpDir = path.join(os.tmpdir(), 'mxc-agent-sandbox');
 
  return {
    network: 'none',
    filesystem: {
      readonlyPaths: [projectRoot],
      readWritePaths: [tmpDir],
      denyPaths: [os.homedir(), '/etc/passwd', '/etc/shadow'],
    },
    process: {
      maxPid: 32,
      allowedExecutables: ['/bin/sh', '/usr/bin/node', '/usr/bin/python3'],
    },
    resources: {
      timeoutSeconds: 30,
      memoryMb: 256,
      cpuPercent: 50,
    },
  };
}
 
export async function buildComposedPolicy() {
  const toolsPolicy = await getAvailableToolsPolicy();
  const tempPolicy = await getTemporaryFilesPolicy();
 
  return {
    ...toolsPolicy,
    ...tempPolicy,
    network: 'none' as const,
  };
}

denyPaths تأخذ الأولوية على كلٍّ من readonlyPaths وreadWritePaths، مما يتيح لك تطبيق صلاحية واسعة ثم استثناء المواقع الحساسة.

الخطوة 4: التنفيذ المفرد

للأوامر التي تُنجَز في استدعاء واحد، استخدم spawnSandboxFromConfig. يُنشئ الحاوية، يُنفّذ الأمر، ثم يُزيلها تلقائياً:

// src/sandbox/exec.ts
import { spawnSandboxFromConfig, createConfigFromPolicy } from '@microsoft/mxc-sdk';
import { buildAgentToolPolicy } from './policy.js';
 
export interface ExecResult {
  exitCode: number;
  stdout: string;
  stderr: string;
  durationMs: number;
}
 
export async function execInSandbox(
  command: string,
  args: string[],
  projectRoot: string,
): Promise<ExecResult> {
  const policy = buildAgentToolPolicy(projectRoot);
  const config = await createConfigFromPolicy(policy);
 
  const start = Date.now();
 
  const result = await spawnSandboxFromConfig(config, {
    command,
    args,
    cwd: projectRoot,
    env: {
      HOME: '/tmp',
      PATH: '/usr/bin:/bin',
    },
  });
 
  return {
    exitCode: result.exitCode,
    stdout: result.stdout,
    stderr: result.stderr,
    durationMs: Date.now() - start,
  };
}

اختبر الوظيفة بهذا الكود البسيط:

import { execInSandbox } from './src/sandbox/exec.js';
 
const result = await execInSandbox('node', ['--version'], process.cwd());
console.log(result.stdout.trim()); // v26.x.x
console.log('كود الخروج:', result.exitCode); // 0

الخطوة 5: دورة حياة الصندوق الرملي المتعدد الحالات

عندما يحتاج الوكيل لتشغيل أوامر متعددة بالتسلسل، يُسرف إنشاء حاوية جديدة لكل أمر في الوقت (100–500 مللي ثانية لكل استدعاء). يدعم MXC دورة حياة صريحة للإعادة:

// src/sandbox/session.ts
import {
  createConfigFromPolicy,
  type MxcSandbox,
} from '@microsoft/mxc-sdk';
import { buildAgentToolPolicy } from './policy.js';
 
export class SandboxSession {
  private sandbox: MxcSandbox | null = null;
 
  constructor(private readonly projectRoot: string) {}
 
  async open() {
    const policy = buildAgentToolPolicy(this.projectRoot);
    const config = await createConfigFromPolicy(policy);
 
    this.sandbox = await config.provision();
    await this.sandbox.start();
  }
 
  async exec(command: string, args: string[] = []) {
    if (!this.sandbox) throw new Error('الجلسة غير مفتوحة');
 
    return this.sandbox.exec({
      command,
      args,
      cwd: this.projectRoot,
      env: { HOME: '/tmp', PATH: '/usr/bin:/bin' },
    });
  }
 
  async close() {
    if (!this.sandbox) return;
    await this.sandbox.stop();
    await this.sandbox.deprovision();
    this.sandbox = null;
  }
}

استخدام أوامر متسلسلة داخل حاوية واحدة:

const session = new SandboxSession(process.cwd());
await session.open();
 
try {
  const install = await session.exec('npm', ['ci', '--ignore-scripts']);
  console.log('خروج التثبيت:', install.exitCode);
 
  const tests = await session.exec('npm', ['test']);
  console.log(tests.stdout);
} finally {
  await session.close();
}

الخطوة 6: التكامل مع أداة Claude

السيناريو الأعلى قيمة هو ربط MXC بوكيل ذكاء اصطناعي يستطيع تشغيل الكود. المثال التالي يستخدم Anthropic TypeScript SDK مع أداة bash مؤمّنة بالصندوق الرملي:

// src/agent/sandbox-agent.ts
import Anthropic from '@anthropic-ai/sdk';
import { execInSandbox } from '../sandbox/exec.js';
 
const client = new Anthropic();
 
const BASH_TOOL: Anthropic.Tool = {
  name: 'bash',
  description: 'تشغيل أمر في الصدفة وإرجاع المخرجات.',
  input_schema: {
    type: 'object' as const,
    properties: {
      command: {
        type: 'string',
        description: 'الأمر المراد تنفيذه.',
      },
    },
    required: ['command'],
  },
};
 
export async function runSandboxedAgent(userPrompt: string): Promise<string> {
  const messages: Anthropic.MessageParam[] = [
    { role: 'user', content: userPrompt },
  ];
 
  while (true) {
    const response = await client.messages.create({
      model: 'claude-sonnet-5',
      max_tokens: 4096,
      tools: [BASH_TOOL],
      messages,
    });
 
    messages.push({ role: 'assistant', content: response.content });
 
    if (response.stop_reason === 'end_turn') {
      const text = response.content.find(b => b.type === 'text');
      return text?.type === 'text' ? text.text : '';
    }
 
    if (response.stop_reason !== 'tool_use') break;
 
    const toolResults: Anthropic.ToolResultBlockParam[] = [];
 
    for (const block of response.content) {
      if (block.type !== 'tool_use') continue;
 
      const input = block.input as { command: string };
 
      try {
        const result = await execInSandbox(
          '/bin/sh',
          ['-c', input.command],
          process.cwd(),
        );
 
        const output =
          result.stdout + (result.stderr ? `\nSTDERR: ${result.stderr}` : '');
 
        toolResults.push({
          type: 'tool_result',
          tool_use_id: block.id,
          content: output || `(كود الخروج ${result.exitCode})`,
        });
      } catch (err) {
        toolResults.push({
          type: 'tool_result',
          tool_use_id: block.id,
          is_error: true,
          content: err instanceof Error ? err.message : 'خطأ غير معروف في الصندوق الرملي',
        });
      }
    }
 
    messages.push({ role: 'user', content: toolResults });
  }
 
  return '';
}

كل أمر صدفة يُصدره النموذج يُعترض ويُلفّ في حاوية MXC وينفَّذ بـ network: 'none' ومهلة 30 ثانية — قبل أن تعود النتيجة للنموذج.

الخطوة 7: معالجة الأخطاء

يرمي MXC فئات أخطاء مسماة يمكن اصطيادها ومعالجتها بشكل منفصل:

import {
  MxcTimeoutError,
  MxcPolicyViolationError,
  MxcBackendUnavailableError,
} from '@microsoft/mxc-sdk';
 
try {
  await execInSandbox('/bin/sh', ['-c', 'sleep 60'], process.cwd());
} catch (err) {
  if (err instanceof MxcTimeoutError) {
    console.error('انتهت المهلة بعد', err.timeoutMs, 'مللي ثانية');
  } else if (err instanceof MxcPolicyViolationError) {
    console.error('انتهاك السياسة — المورد المرفوض:', err.deniedResource);
  } else if (err instanceof MxcBackendUnavailableError) {
    console.error('لا توجد واجهة MXC متاحة على هذا المضيف');
  } else {
    throw err;
  }
}

في حلقة الوكيل، حوّل MxcTimeoutError وMxcPolicyViolationError إلى نتائج أدوات بـ is_error: true مع رسالة واضحة لتمكين النموذج من التعافي بدلاً من تكرار الأمر المحظور.

الخطوة 8: اعتبارات الإنتاج

اختر الواجهة الصحيحة. الواجهة process تبدأ في أقل من 10 مللي ثانية وتعمل في كل مكان لكنها تشترك في نواة المضيف. الواجهة microvm على Linux توفر عزلاً على مستوى VM عبر Firecracker وهي الخيار الصحيح للمخرجات غير الموثوقة تماماً.

ابدأ بأضيق سياسة ممكنة. ابدأ بـ network: 'none' وقائمة allowedExecutables تغطي ما تحتاجه فقط.

شنّ ملاحظة. سجّل durationMs وكود الخروج والأمر الخام في نظام التتبع. مجموعات انتهاكات السياسة هي إشارات مبكرة على محاولات حقن التعليمات.

استكشاف الأخطاء

MxcBackendUnavailableError على Linux — ثبّت Firecracker واضبط FIRECRACKER_BIN=/usr/local/bin/firecracker، أو اطلب صراحةً الواجهة البروسيسية بـ backend: 'process'.

الصندوق الرملي ينتهي فوراً بكود 1 — افحص stderr. السبب الأكثر شيوعاً أن الملف الثنائي المستهدف غير موجود في allowedExecutables.

تأخر عالٍ في أول استدعاء — الواجهة microvm تبدأ VM بـFirecracker في 200–500 مللي ثانية. استخدم SandboxSession للإبقاء على VM نشطاً عبر استدعاءات أدوات متعددة.

الخطوات التالية

  • اقرأ مرجع مخطط السياسة الكامل في مستودع MXC على GitHub
  • ادمج MXC مع تكامل Sentry لـNext.js لتتبع تنفيذات الصندوق الرملي في خط مراقبتك
  • للوكلاء الذين يحتاجون الوصول للشبكة، اضبط network: 'loopback' وأرسل كل الطلبات الخارجية عبر وكيل محلي مدقوق

الخلاصة

يمنحك Microsoft MXC حدوداً مفروضة بنظام التشغيل بين مخرجات النموذج وبيئتك المضيفة. بعشرات الأسطر من TypeScript، كل استدعاء أداة يُصدره وكيلك يعمل داخل حاوية لا تستطيع قراءة الملفات الحساسة أو الاتصال بالخارج أو استهلاك موارد غير محدودة. ستُرقّي نفس الحزمة من الدفاع المتعمق إلى حد أمان صارم على مستوى VM دون أي تغيير في الكود عندما تصل الواجهة microvm للإصدار العام.