الكتابات/blog/2026/08
Blog3 أغسطس 2026·6 دقيقة

دليل GitHub Copilot SDK: تضمين محرّك الوكيل

حزمة Copilot SDK تتيح محرّك الوكيل الحقيقي بست لغات برمجية. تعرّف على الجلسات والخطّافات والأدوات المخصّصة ووضع الأسطول وميزانية الأرصدة بأمثلة عملية.

على مدى عامين كان السؤال المهم في البرمجة بالذكاء الاصطناعي هو: أيّ نموذج؟ أمّا في 2026 فقد تحوّل السؤال بهدوء إلى: أيّ محرّك تشغيل؟ أي الحلقة التي تخطّط وتستدعي الأدوات وتعدّل الملفات وتطلب الأذونات وتعرف متى تتوقف. كل مزوّد جادّ يقدّم اليوم محرّكه الخاص: OpenAI لديها محرّك Codex، وGoogle دمجت عملها في سطر الأوامر داخل Antigravity، وAnthropic تكشف حلقة Claude Code عبر حزمة Agent SDK.

مساهمة GitHub في هذا السباق هي Copilot SDK، وطرحها مباشر بشكل غير معتاد. فهي ليست إعادة بناء ولا غلافًا رقيقًا فوق HTTP، بل هي محرّك التشغيل نفسه الذي يشغّل تطبيق Copilot وواجهة سطر الأوامر، لكن مكشوفًا كمكتبة برمجية. ومع الإصدار العام أصبحت متاحة بست لغات: TypeScript وPython وGo و.NET وRust وJava، جميعها برخصة MIT.

يشرح هذا الدليل ما تقدّمه الحزمة فعليًا، وواجهة البرمجة التي تهمّ، والمقايضة المعمارية التي تقبلها عند تبنّيها.

ما معنى «محرّك التشغيل الحقيقي»؟

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

عمليًا، الحزمة عميل يتحدث ببروتوكول JSON-RPC إلى واجهة Copilot CLI العاملة في وضع الخادم. الحزمة طبقة نقل، وواجهة سطر الأوامر هي المنسّق الذي يدير دورة استخدام الأدوات ويجري استدعاءات النموذج.

هذا التمييز مهمّ لفهم التكلفة والسلوك. وتوثيق GitHub صريح بشكل مريح في وصف الآلية:

كل دورة من هذه الحلقة تساوي بالضبط استدعاءً واحدًا لواجهة النموذج، يظهر كزوج واحد من assistant.turn_start وassistant.turn_end في سجل الأحداث. لا توجد استدعاءات خفية.

الدورة (turn) هي استدعاء واحد للنموذج وما يترتب عليه. والرسالة الواحدة من المستخدم تُنتج عادةً عدة دورات: بحث في الشيفرة، ثم قراءة الملفات المطابقة، ثم قراءة ملفات إضافية، ثم الإجابة. يرى النموذج المحادثة المتراكمة كاملةً في كل دورة، ويقرّر في كل مرة ما إذا كان السياق كافيًا للتوقف. وحين يعيد ردًّا بلا طلبات أدوات تنتهي الحلقة وتُصدر الجلسة الحدث session.idle.

من جرّب بناء هذا بنفسه يعرف أن الجزء الصعب ليس المسار المثالي، بل الإلغاء وفشل الأدوات الجزئي ونوافذ الأذونات وحساب السياق. هذا تحديدًا ما تشتريه.

البداية

الشرط الحقيقي الوحيد هو واجهة Copilot CLI: يجب تثبيتها وتوثيق الدخول بها، لأن الحزمة تشغّلها وتتحدث إليها. تحقّق بالأمر copilot --version. تحتاج TypeScript إلى Node.js 20 أو أحدث، وتحتاج Python إلى الإصدار 3.11 أو أحدث.

npm install @github/copilot-sdk

أبسط برنامج بلغة TypeScript يتكوّن من أربعة أسطر ذات معنى:

import { CopilotClient } from "@github/copilot-sdk";
 
const client = new CopilotClient();
const session = await client.createSession({ model: "auto" });
 
const response = await session.sendAndWait({ prompt: "What is 2 + 2?" });
console.log(response?.data.content);
 
await client.stop();

وتتبع Python الشكل نفسه — إنشاء عميل، ثم جلسة، ثم إرسال — مع معالج أذونات صريح:

import asyncio
from copilot import CopilotClient
from copilot.session import PermissionHandler
 
async def main():
    client = CopilotClient()
    await client.start()
 
    session = await client.create_session(
        on_permission_request=PermissionHandler.approve_all,
        model="auto",
    )
    response = await session.send_and_wait("What is 2 + 2?")
    print(response.data.content)
 
    await client.stop()
 
asyncio.run(main())

يحجب sendAndWait التنفيذ حتى تصل الحلقة إلى حالة الخمول. أمّا في أي واجهة يراها المستخدم فالأفضل استخدام مسار البثّ.

البثّ وسجل الأحداث

تكشف الحزمة أكثر من أربعين نوعًا من الأحداث. أوّل ما ستحتاجه هو أجزاء النصّ المتدفّقة وإشارة الخمول:

const session = await client.createSession({ model: "gpt-4.1", streaming: true });
 
session.on("assistant.message_delta", (event) => {
  process.stdout.write(event.data.deltaContent);
});
 
session.on("session.idle", () => console.log());

وإلى جانب أجزاء النصّ تحصل على assistant.turn_start وassistant.turn_end لحدود الدورات، وtool.execution_start وtool.execution_complete حول كل استدعاء أداة. هذا التدفّق هو الفارق بين شريط تقدّم يعني شيئًا ومؤشّر دوّار يكذب على المستخدم. وهو عمليًا طبقة المراقبة لديك: اجمعه مع تتبّع OpenTelemetry المدمج في الحزمة لتتبّع تشغيل الوكيل من طرف إلى طرف عبر سياق التتبّع القياسي W3C داخل بنيتك الحالية.

الخطّافات: طبقة الحوكمة

الخطّافات (hooks) هي ما يبرّر وجود هذه الحزمة في شيفرة مؤسسية. فهي تتيح اعتراض الحلقة عند نقاط محدّدة بدل الاعتماد على تقدير النموذج.

const session = await client.createSession({
  hooks: {
    onSessionStart: async (input, invocation) => { /* حقن السياق */ },
    onPreToolUse: async (input, invocation) => { /* موافقة أو رفض أو تعديل الوسائط */ },
    onPostToolUse: async (input, invocation) => { /* تحويل النتائج أو إخفاؤها */ },
  },
  onPermissionRequest: async () => ({ kind: "approve-once" }),
});

يُستدعى onPreToolUse قبل تشغيل أي أداة، ويستطيع الموافقة على التنفيذ أو رفضه، أو تعديل وسائط الأداة، أو إضافة سياق، أو إخفاء المخرجات من المحادثة تمامًا. هذا خطّاف سياسات حقيقي لا مجرّد دالة تسجيل. فإذا احتاج فريق الامتثال إلى قاعدة مثل: «لا يُسمح للوكيل بتشغيل git push على الفرع الرئيسي، وكل كتابة ملف خارج /src تُسجَّل» — فأنت تعبّر عنها هنا، في شيفرتك وداخل عمليتك، بدل الأمل في أن يصمد توجيه نصّي.

تغطّي عائلة الخطّافات دورة حياة الجلسة، وما قبل وما بعد استخدام الأداة، وإرسال المستخدم للتوجيه، ومعالجة الأخطاء. وتستخدم Python الأسماء نفسها بصيغة snake_case:

session = await client.create_session(
    on_permission_request=lambda req, inv: PermissionDecisionApproveOnce(),
    hooks={
        "on_session_start": on_session_start,
        "on_pre_tool_use": on_pre_tool_use,
        "on_post_tool_use": on_post_tool_use,
    },
)

الأدوات المخصّصة

تغطّي الأدوات المدمجة القراءة والبحث وتعديل الملفات، أمّا أدواتك فتغطّي أعمالك أنت. وفي Python تكون التجربة ممتازة: مُزخرِف واحد يشتقّ مخطّط JSON من تلميحات الأنواع:

@define_tool
def deploy_to_staging(branch: str, region: str) -> str:
    """نشر فرع إلى بيئة الاختبار وإرجاع رابط النشر."""
    return run_deployment(branch, region)

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

وتقبل تعريفات الأدوات خيارات تستحق المعرفة. الخيار skipPermission يتجاوز طلب الإذن للأدوات التي قرّرت سلفًا أنها آمنة. والخيار overridesBuiltInTool يتيح استبدال أداة من واجهة سطر الأوامر بتنفيذك الخاص، وهو مفيد حين يكون لمؤسستك غلاف معتمَد حول تنفيذ الأوامر. والخيار defer يتحكّم في التحميل الكسول حتى لا يستهلك كتالوج أدوات كبير مساحة السياق في كل دورة.

أمّا .NET فتسلك مسارًا أقرب إلى طبيعتها عبر تغليف الدوال العادية بـ AIFunctionFactory.Create والجَسْر إلى Microsoft.Extensions.AI، بينما تكشف Java الدالة ToolDefinition.create() بمعاملات مُنمَّطة. والمفهوم واحد في اللغات الست.

التوجيه وإدارة الطابور

من راقب وكيلًا يمضي بثقة في الاتجاه الخطأ يعرف مرارة الاضطرار إلى إنهاء التشغيل. تعالج الحزمة هذا عبر حقل mode في خيارات الرسالة.

التوجيه (mode: "immediate") يحقن رسالتك داخل الدورة الجارية بالفعل، فيرى الوكيل التصحيح فورًا ويعدّل مساره دون إجهاض العملية:

const msgId = await session.send({
  prompt: "Refactor the authentication module to use sessions",
});
 
// الوكيل يعمل بالفعل — أعد توجيهه
await session.send({
  prompt: "Actually, use JWT tokens instead of sessions",
  mode: "immediate",
});

أمّا الطابور (mode: "enqueue") فيحتجز الرسالة حتى تنتهي الدورة الحالية، وهو الخيار الصحيح لطلب مثل «وبعد ذلك أصلح الاختبارات». سطران من الواجهة البرمجية مقابل تمييز لا تصل إليه معظم المحرّكات المصنوعة داخليًا.

وضع الأسطول: وكلاء فرعيون على التوازي

يوزّع وضع الأسطول (fleet mode) عدة وكلاء فرعيين على التوازي انطلاقًا من جلسة أمّ واحدة، مع تنسيق عبر حالة مهامّ مشتركة. والدالة على مستوى البروتوكول هي session.fleet.start:

const result = await session.rpc.fleet.start({
  prompt: "Refactor each SDK package independently, then summarize the changes.",
});
 
if (result.started) {
  console.log("Fleet mode started");
}

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

وثمة تحفّظ مأخوذ حرفيًا من التوثيق: ارتباط الأسطول تجريبي في واجهة RPC المولّدة. فإن اعتمدت عليه، ثبّت إصدارَي الحزمة وواجهة سطر الأوامر معًا.

التحكّم في الفاتورة

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

const session = await client.createSession({
  onPermissionRequest: approveAll,
  sessionLimits: {
    maxAiCredits: 30,
  },
});

اقرأ الدلالة بعناية: هذا سقف ليّن. يُفحص الاستهلاك بعد عودة استدعاءات النموذج، لذا قد يتجاوز ردٌّ واحد القيمة المحدّدة قبل أن يمنع المحرّك الاستدعاء التالي. خطّط لتجاوز محتمل بدل التعامل معه كسقف صارم. ويسري الكائن sessionLimits نفسه عند استئناف الجلسة، كما تكشف واجهة الاستخدام والفوترة عدد الرموز ونسبة استغلال نافذة السياق وحصة الحساب إن أردت بناء ضوابطك الخاصة فوقها.

أمّا من ناحية الوصول، فالحزمة مشمولة في اشتراكات Copilot القائمة — بما فيها الخطة المجانية باستخدام شهري محدود — وتُحتسب تشغيلات الوكيل ضمن سعة Copilot المعتادة. ويقبل التوثيق بيانات المستخدم المسجَّل، أو رموز تطبيقات GitHub عبر OAuth، أو متغيّرات البيئة مثل COPILOT_GITHUB_TOKEN وGITHUB_TOKEN، أو إحضار مفتاحك الخاص (BYOK) لدى مزوّد نماذج مدعوم. وخيار BYOK هو المخرج المهم للفرق خارج علاقة الفوترة مع GitHub، إذ يلغي شرط الاشتراك تمامًا.

المقايضة بصراحة

أعظم نقاط قوة الحزمة وقيدها الأساسي حقيقة واحدة: إنها عميل لواجهة Copilot CLI، لا مكتبة HTTP عديمة الحالة.

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

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

اخترها إن كنت مستثمرًا أصلًا في GitHub وتريد برمجة وكيلة مدمجة — أدوات داخلية للمطورين، أو مساعدات في التكامل المستمر، أو ميزات موجّهة للعملاء — دون بناء التنسيق من الصفر. وتوخَّ الحذر إن كنت تحتاج استدعاءات عديمة الحالة بأقل الاعتماديات، أو تعمل في بيئة serverless مقيّدة، أو تنشط أساسًا خارج منظومة GitHub. في تلك الحالات قد يناسبك محرّك أخفّ مثل حزمة Claude Agent SDK أو محرّك TypeScript مفتوح المصدر.

ماذا يعني هذا لنقاش المحرّكات؟

وجود هذه الحزمة بحدّ ذاته حجّة حول موضع القيمة. تراهن GitHub على أن الحلقة وتنفيذات الأدوات ونموذج الأذونات وتصنيف الأحداث هي الجزء الصعب والمميّز، وأن النموذج صار خيارًا في الإعدادات أكثر فأكثر. والقيمة الافتراضية model: "auto" ودعم BYOK الكامل يقولان ذلك صراحةً.

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

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


قراءات ذات صلة: وكيل GitHub Copilot البرمجي وطلبات الدمج التلقائية · هندسة المحرّكات للوكلاء في الإنتاج · حقن التوجيهات وأمن وكلاء الذكاء الاصطناعي

هل تبني ميزات مدعومة بالوكلاء داخل منتجك؟ نقطة تساعد الفرق في تونس والخليج على تصميم أنظمة ذكاء اصطناعي إنتاجية وتأمينها وإطلاقها.