دمج A2A مع أُطر الوكلاء القائمة: عرض تطبيقي باستخدام Hermes Agent
لماذا يُهمّ A2A لتنسيق الوكلاء
بروتوكول Agent2Agent Protocol (A2A) هو معيار مفتوح قدّمته Google في أبريل 2025 للتواصل بين الوكلاء. يُعرّف كيفية اكتشاف وكيل ذكاء اصطناعي لقدرات وكيل آخر، وإرسال مهمة إليه، واستقبال المُخرجات المتدفقة، وتتبّع المهمة عبر دورة حياتها — كل ذلك عبر JSON-RPC 2.0، دون افتراض أن الوكيلين يتشاركان الإطار، أو مزوّد النموذج، أو طوبولوجيا النشر.
يملأ A2A فجوة لا يغطّيها MCP. يربط MCP وكيلًا بالأدوات ومصادر البيانات — فهو بروتوكول استدعاء أدوات. أمّا A2A فيربط الوكلاء بالوكلاء. وكيل يحتاج إلى قدرة متخصّصة (منطق تسعير، أو بحث في الكتالوج، أو معالجة RFQ) يستطيع تفويض العمل إلى وكيل بعيد يكشف عن تلك القدرة عبر نقطة نهاية A2A، واستقبال النتيجة كمهمة A2A، ومواصلة تدفّق عمله الخاص. البروتوكولان مُتكاملان: MCP يمنح الوكيل أيديًا؛ وA2A يمنحه زملاء.
تُعرّف مواصفة A2A ثلاثة عناصر أساسية:
- Agent Card — مستند JSON على المسار
/.well-known/agent-card.jsonيصف هوية الوكيل وقدراته ومهاراته ونقطة نهاية الخدمة. هكذا يكتشف الوكلاء بعضهم بعضًا. - Task — وحدة العمل. يُرسل العميل مهمة عبر
message/send(غير متدفّق) أوmessage/stream(متدفّق). تنتقل المهمة عبر الحالات:submitted، وworking، وinput-required، وcompleted، وfailed، وcanceled. - Artifact — مُخرجات مُنظَّمة تُنتَج أثناء تنفيذ المهمة، وتُبثّ إلى العميل متى توافرت.
بالنسبة لنشر B2B، فإن القيمة المُقدَّمة محدّدة: بدلًا من بناء وكيل واحد ضخم يفعل كل شيء، تُركّب وكلاء متخصّصون يمتلك كل واحد منهم مجالًا — ويتناسقون عبر بروتوكول، لا عبر ذاكرة مشتركة أو استدعاءات دوال مشفّرة برمجيًا.
مشكلة التكامل
معظم أُطر الوكلاء القائمة لا تتحدث A2A. تمتلك كل منها سطوح API أصلية خاصة، ونماذج مهام خاصة، وآليات تدفّق خاصة. يكشف Hermes Agent (من Nous Research) عن API Server متوافق مع OpenAI على /v1/chat/completions وواجهة تدفّق SSE قائمة على runs على /v1/runs و/v1/runs/{id}/events. يقدّم OpenClaw API متوافق مع OpenResponses على POST /v1/responses. يمتلك LangGraph نموذج تنفيذ رسومي خاص به. ويمتلك CrewAI آلية إرسال فرق خاصة به.
لن يعيد أي من هذه الأُطر كتابة داخله لدعم A2A. ولا ينبغي له ذلك — فـ API الأصلية تخدم أنظمتها البيئية الخاصة بشكل جيد. السؤال هو: هل يمكنها المشاركة في شبكة وكلاء A2A دون تغيير شيفرتها؟
الجواب هو طبقة جسر — مكوّن يقف بين بروتوكول A2A وAPI الأصلية للأُطار. يُنفّذ الجسر سطح JSON-RPC الخاص بـ A2A على جهة (Agent Card، ودورة حياة المهمة، والتدفّق) ويُترجم إلى استدعاءات الأُطار الأصلية على الجهة الأخرى. الأُطار لا يعرف أنه يُستدعى عبر A2A. وعميل A2A لا يعرف أي أُطار ينفّذ المهمة.
يستعرض هذا المقال نمط الجسر باستخدام Hermes Agent كمثال تطبيقي. النمط ذاته ينطبق على OpenClaw وغيرها من الأُطر — مُعالج الجسر هو القطعة الوحيدة التي تتغير.
بنية الجسر
تطبيق مرجعي عامل لهذا النمط هو a2a_daemon_engine — خفيّ بروتوكول A2A يعمل كوحدة بوابة ويُوجّه التنفيذ إلى مُعالجات قابلة للإضافة. البنية هي:
A2A Client (any agent or application)
│
POST /{endpoint_id}/a2a (message/send | message/stream)
│
▼
Gateway (auth, routing, SSE client management)
│
▼
A2A Daemon Executor
│
resolve_agent(uuid) → Database lookup
load_agent_handler() ← data-driven, metadata-based routing
│
├── HermesAgentHandler
│ → POST /v1/runs → GET /v1/runs/{id}/events → SSE streaming
│ → POST /v1/chat/completions (non-streaming)
│
└── [AnyFrameworkHandler] ← same interface, different translation
→ framework's native API
للجسر ثلاث طبقات:
طبقة بروتوكول A2A — تُعالج توجيه JSON-RPC، وخدمة Agent Card، وآلة حالة المهمة، وA2A SDK EventQueue. هذه مستقلة عن الأُطر. هي نفسها لكل تكامل.
طبقة النقل عبر البوابة — تُعالج HTTP، والمصادقة، ودورة حياة عميل SSE، والتوجيه. مستقلة عن الأُطر أيضًا. البوابة تمتلك السلك؛ والجسر يمتلك الترجمة.
مُعالج الأُطار — الكود الوحيد الخاص بالأُطار. يُنفّذ واجهة
ask_model(): يستقبل أجزاء رسالة A2A والسياق، ويستدعي API الأصلية للأُطار، ويُحوّل الاستجابة إلى أجزاء رسالة A2A، و(في التدفّق) يُمرّر فروقات الرموز إلى قناة SSE.
إضافة أُطار جديد تعني كتابة صنف مُعالج واحد. كل ما عداه — سطح البروتوكول، وتوجيه البوابة، وإدارة SSE، واستمرارية المهمة — هو بنية تحتية مشتركة.
عرض تطبيقي: جسر Hermes Agent
HermesAgentHandler هو المثال المُنفَّذ. يجسر دلالات مهام A2A إلى Hermes Agent API Server. يدعم المُعالج نمطَي تنفيذ:
غير متدفّق: message/send مع message_response
يستدعي المُعالج POST /v1/chat/completions على Hermes API Server — النقطة المتوافقة مع OpenAI. يحمل الطلب أجزاء رسالة A2A المُحوَّلة كحمولة chat completion. يُعالج Hermes الطلب (استدلال النموذج، واستدعاءات الأدوات، وتفكير الوكيل) ويُعيد استجابة واحدة. يُحوّل المُعالج الاستجابة إلى Message في A2A مع ROLE_AGENT ويُرسلها إلى SDK EventQueue.
يستقبل العميل استجابة JSON-RPC واحدة بالنص الكامل للوكيل. لا أحداث حالة وسيطة، ولا أجزاء متدفّقة — يبقى الطلب محجوبًا حتى يُكمل Hermes.
متدفّق: message/send مع task_execution وstream: true
يستدعي المُعالج POST /v1/runs لإنشاء run، ثم يفتح اتصال SSE إلى GET /v1/runs/{id}/events. يبثّ Hermes الأحداث وهي تحدث: فروقات الرموز، وبيانات النقل الوصفية للتفكير، وإشعارات استدعاء/نتيجة الأدوات، وطلبات الموافقة، وأحداث دورة الحياة (run.created، وrun.completed، وrun.failed).
يُشغّل المُعالج حلقة تصريف في خيط خلفي. كل حدث message.delta يُدفع إلى مدير SSE الخاص بالبوابة للتسليم الفوري للعملاء المتصلين. يجمع المُعالج الرموز في ذاكرة مؤقتة واحدة. عند وصول run.completed، يُرسل النص المُتراكم كـ Message واحد في A2A إلى SDK EventQueue، ويُدفع حدث حالة COMPLETED إلى SSE فقط.
هذا التصميم ذو المسارين — SSE للأجزاء الفورية، وSDK EventQueue للرسالة المُتراكمة النهائية — هو ردّ على قيد في A2A SDK v2، يُناقش أدناه.
الموافقة البشرية في الحلقة عبر حدود الوكلاء
يدعم Hermes بوابات موافقة بشرية في الحلقة — عندما يحتاج الوكيل إذنًا لتنفيذ إجراء حسّاس، يتوقّف ويُرسل طلب موافقة. يُترجم الجسر ذلك إلى حالة A2A INPUT_REQUIRED، التي تُشير إلى الوكيل المُستدعي (أو المُشغّل البشري) أن مدخلًا مطلوب. تعود الاستجابة عبر POST /v1/runs/{id}/approval، ويُكمل الـ run.
هنا تُظهر قيمة نمط الجسر. يُعرّف A2A حالة INPUT_REQUIRED كحالة مهمة من الدرجة الأولى. لدى Hermes آلية موافقة خاصة به. يُطابق الجسر بينهما، والوكيل المُستدعي — الذي قد يكون هو نفسه عميل A2A يعمل على إطار مختلف تمامًا — يرى انتقال حالة بروتوكول قياسي، لا تفصيلًا خاصًا بـ Hermes. تستطيع سلسلة تفويض وكلاء أن تتضمّن خطوة تتطلب موافقة بشرية (تفويض شراء، أو قرار وصول إلى بيانات، أو موافقة عرض سعر)، ويحمل بروتوكول A2A تلك البوابة بشفافية عبر حدود الأُطر.
مطابقة حالة A2A
يُعرّف A2A آلة حالة مهمة: submitted ← working ← input-required | completed | failed | canceled. كل أُطر يمتلك مفردات أحداث خاصة به. الجسر يُطابق بينها.
مطابقة أحداث Hermes إلى حالات A2A:
| حدث Hermes SSE | حالة مهمة A2A | إجراء الجسر |
|---|---|---|
run.created |
WORKING |
تسجيل run_id لدعم الإلغاء |
message.delta |
WORKING |
تجميع الرمز؛ إرسال إلى SSE لكل جزء |
reasoning.available |
WORKING |
بيانات النقل الوصفية للتفكير — لا إرسال رمز |
tool.call / tool.result |
WORKING |
بيانات النقل الوصفية لتنفيذ الأداة فقط |
approval.required |
INPUT_REQUIRED |
إرسال جزء موافقة؛ تخزين pending_approval |
run.completed |
COMPLETED |
ضبط حدث التدفّق؛ تجميع النص النهائي |
run.failed |
FAILED |
إرسال جزء خطأ؛ ضبط حالة FAILED |
POST /v1/runs/{id}/stop |
CANCELED |
إلغاء خارجي عبر tasks/cancel |
POST /v1/runs/{id}/approval |
(يُكمل الـ run) | يُحلّ عبر operation="approval_response" |
هذا الجدول هو قلب الجسر. كل تكامل أُطار يُنتج جدولًا مكافئًا — أحداث الأُطار الأصلية على اليسار، حالات A2A على اليمين، إجراءات الجسر في الوسط. يُوثّق HERMES_INTEGRATION.md في التطبيق المرجعي صيغة حدث Hermes الدقيقة، ومفاتيح الإعداد، وتفاصيل التدفّق من النهاية إلى النهاية.
قيد A2A SDK v2 وإصلاح المسار المزدوج
يفرض A2A SDK v2 (a2a-sdk==1.0.2) قيدين على مسار on_message_send شكّلا كل تنفيذ للجسر:
- رسالة واحدة فقط. إرسال عدة كائنات
Messageإلى SDK EventQueue يُطلقInvalidAgentResponseError: Multiple Message objects received. - لا TaskStatusUpdateEvent. أحداث الحالة تُطلق
InvalidAgentResponseError: Received TaskStatusUpdateEvent in message mode.
جسر ساذج سيُرسل Message واحدًا لكل فرق رمز — نمط التدفّق الطبيعي. SDK يرفض ذلك. كما يرفض أحداث الحالة (WORKING، COMPLETED) على مسار message/send.
الحل هو قناة إخراج ذات مسارين:
- SSE (تُديره البوابة): تُدفع أجزاء الرموز إلى SSE في الزمن الحقيقي. يرى العملاء المتصلون المُخرجات المتدفّقة وهي تحدث. أحداث الحالة (WORKING، COMPLETED، FAILED) تذهب إلى SSE فقط أيضًا.
- SDK EventQueue: بعد اكتمال التدفّق، تُرسل
Messageمُتراكمة واحدة تحتوي على نص الاستجابة الكامل إلى SDK EventQueue. هذا ما تُعيده استجابة JSON-RPCmessage/send.
يحصل العميل على تدفّق فوري عبر SSE واستجابة JSON-RPC بنقطة رسالة واحدة عبر SDK. كلتا القناتين تعملان؛ ولا تنتهك أي منهما قيود SDK. هذا النمط مستقل عن الأُطار — ينطبق سواء كان الواجهة الخلفية Hermes أو OpenClaw أو أي مُعالج مستقبلي.
تطبيق النمط ذاته على OpenClaw
تكشف Gateway API الخاصة بـ OpenClaw سطحًا أصليًا مختلفًا عن Hermes، لكن نمط الجسر ذاته. سيُنفّذ OpenClawHandler واجهة ask_model() ذاتها ويُترجم دلالات مهمة A2A إلى استدعاءات OpenClaw Gateway:
- غير متدفّق يُطابق
POST /v1/responsesمع تحويل أجزاء رسالة A2A إلى عناصر مدخلات OpenResponses. تُحوّل الاستجابة إلىMessageفي A2A. - متدفّق يُطابق
POST /v1/responsesمعstream: true، باستهلاك تدفّق أحداث SSE وتمرير فروقات الرموز إلى قناة SSE الخاصة بـ A2A. تستخدم صيغة تدفّق OpenResponsesresponse.output_text.deltaلأجزاء الرموز وresponse.completedللانتهاء — أسماء أحداث مختلفة، بنية جسر ذاتها. - اختيار الوكيل يستخدم الحقل
model(openclaw/<agentId>) أو ترويسةx-openclaw-agent-id، مُطابَقًا من بيانات النقل الوصفية لوكيل A2A. - استمرارية الجلسة تستفيد من حقل
previous_response_idأوuserفي OpenClaw لتوجيه جلسة مستقر، ما يُطابق بشكل طبيعي استمرارية مهمة A2A.
سيبدو جدول مطابقة الحالة لـ OpenClaw كالتالي:
| حدث OpenClaw | حالة مهمة A2A | إجراء الجسر |
|---|---|---|
response.created |
WORKING |
تسجيل مُعرّف الاستجابة |
response.output_text.delta |
WORKING |
تجميع الرمز؛ إرسال إلى SSE |
response.completed |
COMPLETED |
تجميع النص النهائي؛ إرسال Message |
response.failed |
FAILED |
إرسال خطأ؛ ضبط FAILED |
الأعمدة ذاتها، البنية ذاتها، أسماء أحداث مختلفة. مُعالج الجسر هو القطعة الوحيدة التي تتغير بين الأُطر.
الإعداد: التوجيه المُحرَّك بالبيانات الوصفية
توجيه الوكلاء مُحرَّك بالبيانات الوصفية، لا بمتغيرات البيئة. يحمل كل سجل وكيل في قاعدة البيانات إعداد مُعالجه في عمود metadata من نوع JSON. لوكيل مدعوم بـ Hermes:
{
"module_name": "a2a_daemon_engine.handlers.a2a_hermes_handler",
"class_name": "HermesAgentHandler",
"hermes_api_url": "http://127.0.0.1:8642",
"hermes_api_key": "hermes-local-key",
"hermes_model": "hermes-agent",
"hermes_timeout": 300.0
}
لوكيل مدعوم بـ OpenClaw، ستشير البيانات الوصفية إلى مُعالج OpenClaw:
{
"module_name": "a2a_daemon_engine.handlers.a2a_openclaw_handler",
"class_name": "OpenClawHandler",
"openclaw_api_url": "http://127.0.0.1:3000",
"openclaw_api_key": "openclaw-key",
"openclaw_agent_id": "pricing-agent",
"openclaw_timeout": 300.0
}
يتبع حلّ الإعداد سلسلة أولوية: بيانات النقل الوصفية للوكيل (DB) ← قاموس الإعداد ← افتراضات Config (متغيرات البيئة). تتفوّق التجاوزات الخاصة بكل وكيل على الافتراضات العامة. يستطيع وكيلان الإشارة إلى أُطر مختلفة — أحدهما إلى Hermes للمهام كثيفة الاستدلال، والآخر إلى OpenClaw لمهام تنسيق تدفّق العمل — ويبدو سطح بروتوكول A2A مطابقًا للوكيل المُستدعي.
ماذا يُتيح هذا
يمنحك نمط الجسر ثلاث قدرات يصعب تجميعها من الصفر:
1. تفويض بين الوكلاء مع التدفّق. يستطيع وكلاء عملاء A2A إرسال مهام إلى وكيل مدعوم بـ Hermes واستقبال تدفّق رموز فوري عبر SSE. لا يحتاج الوكيل المُستدعي أن يعرف أن الوكيل البعيد يشغّل Hermes — يرى نقطة نهاية A2A مع Agent Card وواجهة JSON-RPC.
2. الموافقة البشرية في الحلقة عبر حدود الوكلاء. بوابات الموافقة الأصلية للأُطر (طلبات موافقة Hermes، موافقات مُشغّل OpenClaw) تُطابَق إلى حالات A2A INPUT_REQUIRED. تستطيع سلسلة تفويض وكلاء أن تتضمّن خطوة تتطلب موافقة بشرية، ويحمل بروتوكول A2A انتقال الحالة هذا إلى الوكيل المُنشئ أو المُشغّل — بغضّ النظر عن أي أُطار يشغّل كل وكيل في السلسلة.
3. توجيه متعدد الأُطر من بوابة واحدة. البوابة ذاتها، والمُنفّذ ذاته، وسطح بروتوكول A2A ذاته يخدمون مُعالجات لأُطر مختلفة. إضافة أُطار جديد هي كتابة صنف مُعالج واحد وإدراج سجل وكيل واحد — لا نشر جديد، ولا تنفيذ بروتوكول جديد.
يدعم التطبيق المرجعي أيضًا إرسال AWS Lambda لـ A2A serverless، ونقل gRPC تجريبي مع تدفّق ثنائي الاتجاه، واستمرارية خلفية مزدوجة (DynamoDB أو PostgreSQL) مع عزل متعدد المستأجرين عبر مفاتيح تقسيم مُركّبة. يحتوي مستودع a2a_daemon_engine ودليل تكامل Hermes الخاص به على التنفيذ الكامل ومرجع الإعداد وتفاصيل مطابقة الحالة.
موزّع متوسط السوق يحتاج وكلاء تسعير يتحدثون إلى وكلاء كتالوج يتحدثون إلى وكلاء مخزون — كل مدعوم بإطار مختلف، وكل مملوك لفريق مختلف. يمنح A2A هؤلاء الوكلاء بروتوكولًا مشتركًا. وتسمح طبقة الجسر لـ Hermes Agent وOpenClaw وأي إطار آخر بالمشاركة دون إعادة كتابة داخله. a2a_daemon_engine هو تطبيق مرجعي عامل لنمط الجسر هذا، عُرض باستخدام Hermes Agent.
اطلب بناءً محدود النطاق
اكتشاف أسبوع واحد. تحصل على جرد نظام، وخريطة تدفّق عمل، ونطاق ثابت — سواء بنيتم معنا أم لا.
هل تريد هذا مبنياً لأنظمتك؟
كل وثيقة هنا من عمل إنتاجي حقيقي. إذا كان لديك نظام مُستهدَف وسير عمل في الذهن، نستطيع تحديد نطاق بناء في أسبوع واحد.
اطلب بناءً محدد النطاقاكتشاف مدته أسبوع واحد. تحصل على جرد للأنظمة وخريطة لسير العمل ونطاق ثابت — سواء بنيت معنا أم لا.