تنسيق multi-agent: خمسة أنماط، ومتى يفوز أحدها
الفاتورة نفسها حُلّت بأربع طرق في جدول تكلفة واحد: كلّف المنسّق 1.66× من agent واحد ووصل إلى الحكم نفسه.
في هذه الصفحة
انتهى الفصل 24 بسؤال استحقه: عندما يخطئ sub-agent، ما الذي يستطيع الأب أن ينظر إليه تحديدًا؟
يجيب هذا الفصل بفاتورة. مهمة واحدة — عميل يعترض على فاتورة ويريد ردًا — حُلّت بأربع طرق، وكلها تشغّل harness الفصل 23 على المزوّد النصّي المبرمج نفسه، وكلها تعدّ tokens نفسها بالمشفّر نفسه، وكلها مسعّرة بالأسعار التي قرأها الفصل 16 في 6 سبتمبر 2026.
| الترتيب | استدعاءات النموذج | input tokens | output | التكلفة | زمن التنفيذ | الحكم |
|---|---|---|---|---|---|---|
| prompt chaining | 4 | 900 | 165 | $0.003780 | 1,648 ms | خطأ |
| agent واحد، أربع أدوات | 5 | 2,697 | 179 | $0.007542 | 2,224 ms | صحيح |
| أقسام متوازية | 9 | 2,910 | 324 | $0.009708 | 2,165 ms | صحيح |
| orchestrator-workers | 12 | 3,628 | 438 | $0.012512 | 5,090 ms | صحيح، ولا يستطيع إثبات ذلك |
اقرأ الصفين الأول والأخير معًا: بينهما كل جدال تخوضه هذه الصناعة الآن. كان الترتيب الأرخص هو الأسرع أيضًا، وأنتج إجابة واثقة وخاطئة وقابلة للإرسال. أما الأغلى فأصاب، واستغرق 3.3 أضعاف المال و3.1 أضعاف الوقت، ثم انتهى باقتباس استنتاج عامل لا يملك أي طريقة لفحصه.
الصف الذي لا يضعه أحد في هذه الجداول هو الثاني: agent واحد مع الأدوات الأربع وصل إلى الحكم نفسه الذي وصل إليه المنسّق مقابل 60 % من المال و44 % من زمن التنفيذ. هذا ليس تفضيلًا للبساطة. إنه قياس، وبقية هذا الفصل تدور حول اللحظة التي يتوقف فيها ذلك عن الصدق.
عرض التفاصيل
ما يحتاجه هذا الفصل من الفصول السابقة.
- الفصل 18 لعقد الأداة: schema يراه النموذج، ونقطة نهاية لا يراها أبدًا. يمكن أن يختبئ agent كامل خلف تلك الواجهة، وهذا هو جوهر multi-agent.
- الفصل 22 للتعريفين المنشورين لـ "agent" اللذين يختلفان، وللحساب الذي يقول إن سلسلة prompts هي N استدعاءات.
- الفصل 23 للحلقة، والطرق الخمس للخروج، وحالة التشغيل وtrace. كل ترتيب أدناه هو ذلك الملف نفسه، مستدعى بطريقة مختلفة.
- الفصل 24 لما تكلّفه النافذة وما يسقط خارجها. sub-agent هو الاستراتيجية الرابعة من استراتيجياته الأربع، والوحيدة التي تكون agent ثانيًا بدلًا من سياسة.
لا tensors. كل شيء هنا TypeScript، باستثناء قياسين أُخذا مقابل نموذج محلي حقيقي.
المهمة، والفخ داخلها
رابط إلى القسم: المهمة، والفخ داخلهاتكتب شركة برتغالية بخصوص الفاتورة FT-2026-0918. تقول الرسالة إن VAT يبدو خاطئًا، وتُرفق الفاتورة: الصافي EUR 248.00، VAT محتسب بنسبة 21 %، EUR 52.08، والإجمالي EUR 300.08.
الحقائق اللازمة للإجابة موجودة في ثلاثة أماكن، وواحدة منها فقط في الرسالة:
| أين | ماذا يقول |
|---|---|
| الفاتورة المرفقة | البائع في إسبانيا، طُبّق VAT بنسبة 21 %، EUR 52.08 |
| سجل الطلب | المشتري مسجل في البرتغال، ولديه معرّف VAT صالح، business-to-business |
| جدول الضرائب | المعدل المحلي الإسباني 21 %؛ intra-EU business-to-business مع معرّف صالح، reverse charge، 0 % |
اجمع الثلاثة معًا وستكون الفاتورة خاطئة: ينطبق reverse charge، وكان يجب أن يكون VAT صفرًا، وتستحق إشعار دائن بقيمة EUR 52.08. انظر إلى الفاتورة وحدها وستجدها مثالية حسابيًا — 248.00 زائد 52.08 يساوي 300.08 — وستقول ذلك.
تنص الرسالة فعلًا على "نحن شركة برتغالية". هذا ادعاء، لا سجل، ولا يصدر أي نظام فواتير إشعارًا دائنًا بناءً على ادعاء. الفخ ليس خدعة: إنه الشكل العادي للعمل التجاري، حيث يحتاج القرار إلى حقيقة لم يفكر أحد في جلبها.
كل ما سبق يعمل ضد مزوّد مبرمج على نمط مزوّد الفصل 23، وبقاعدة واحدة تحديدًا:
لا يجوز للإجابة أن تستخدم إلا حقيقة موجودة في prompt الخاص بها.
"النموذج" يطلب كل أداة لديه، مرة واحدة، بترتيب الكتالوج، ثم يطبّق قاعدة ثابتة على النص الذي يستطيع رؤيته. لا شيء مبرمج لكل ترتيب على حدة، لذلك فالاختلافات في جدول البداية ليست ادعاءات عن ذكاء النموذج: إنها توجيه معلومات، مقاس. يضيف النموذج الحقيقي إخفاقاته فوق ذلك؛ ولا يزيل هذه.
الأنماط الخمسة، في نحو أربعين سطرًا
رابط إلى القسم: الأنماط الخمسة، في نحو أربعين سطرًاالأسماء الخمسة أدناه هي أسماء Anthropic، من Building effective agents، وهو المكان الذي استقر فيه هذا المعجم.1 لا فكرة من الأفكار الخمس جديدة، والقول أي بيت سمّى ماذا — وأي فكرة أقدم — نصف قيمة معرفتها.
/* 1. Prompt chaining: a fixed pipeline. The control flow is yours. */
export async function chain(steps: Step[], first: string) {
let carry = first, all = first;
for (const s of steps) {
const r = await step(s.role, s.system, s.accumulate ? all : carry);
carry = r.text;
all = `${all}\n${r.text}`;
}
return carry;
}
/* 2. Routing: one cheap call picks the branch. The fallback is not a model. */
export async function route<T>(input: string, classify: Classifier,
routes: Record<string, Branch<T>>, fallback: Branch<T>) {
let label: string | undefined;
try { label = await classify(input); } catch { label = undefined; }
return ((label && routes[label]) || fallback)(input);
}
/* 3. Parallelisation. The pattern IS this line. */
export const parallel = <T>(workers: Branch<T>[], input: string) =>
Promise.all(workers.map((w) => w(input)));
/* 4. Orchestrator-workers: an agent behind a tool. Chapter 18's interface, unchanged. */
export function agentTool(o: WorkerSpec): Tool {
return {
name: o.name, description: o.description, readOnly: true,
parameters: { type: "object", properties: { question: { type: "string" } } },
async run(args: { question: string }) {
const child = newRun(o.system, args.question); // its own window
await runTracked(child, o.tools, o.usage); // its own limits
const conclusion = child.output ?? "no result";
if (!o.carryFindings) return conclusion;
return `${conclusion}\nFINDINGS ${evidence(child)}`;
},
};
}
/* 5. Evaluator-optimiser: make, judge, remake. Rounds are calls. */
export async function refine(make: Make, judge: Judge, maxRounds: number) {
let draft = "", feedback: string | undefined;
for (let r = 1; r <= maxRounds; r++) {
draft = (await make(feedback)).text;
const j = await judge(draft);
if (j.ok) return { draft, rounds: r };
feedback = j.note;
}
return { draft, rounds: maxRounds };
}هذه هي مجموعة الأدوات كلها: خمس دوال، بلا framework، والمتوازي منها سطر واحد — وهذه هي فائدة كتابته بدلًا من رسمه. والآن كل واحد بدوره، مع أصله، وسعره، والحالة التي يخطئ فيها.
Chaining، والقرار الذي يتخذه نيابة عنك
رابط إلى القسم: Chaining، والقرار الذي يتخذه نيابة عنكPrompt chaining "يفكك مهمة إلى تسلسل من الخطوات، حيث يعالج كل استدعاء LLM ناتج الاستدعاء السابق".1 الفكرة أقدم من نماذج اللغة: إنها pipeline، ومعها مقايضة pipeline المعتادة — الوضوح مقابل تدفق تحكم ثابت قبل وصول البيانات.
أربع خطوات لمهمتنا: استخراج حقول الفاتورة، فحص الحساب، تقرير المستحق، كتابة الرد. هنا يفشل بطريقتين مختلفتين، وهذا يعلّم أكثر من فشل واحد.
--- relay: each step sees only the previous step's output
extract: FIELDS invoice_id=FT-2026-0918 net=248.00 vat_rate_applied=21 vat_amount=52.08 ...
check: ARITHMETIC ok 248.00+52.08=300.08
decide: VERDICT=unknown reason=no_invoice_in_context
draft: "we are looking into invoice FT-2026-0918 and will come back to you."
--- accumulating: each step sees the email and everything produced so far
extract: FIELDS invoice_id=FT-2026-0918 net=248.00 vat_rate_applied=21 ...
check: ARITHMETIC ok 248.00+52.08=300.08
decide: VERDICT=invoice_correct reason=net_248.00_plus_21pct_vat_52.08_equals_300.08
draft: "we have checked FT-2026-0918 and it is correct... Nothing is owed back."كلّفت سلسلة الترحيل $0.001940 وفقدت حقول الفاتورة بين الخطوتين الثانية والثالثة، لأن الخطوة الثالثة سُلّمت جملة عن الحساب ولا شيء آخر. أنتجت رسالة انتظار: عديمة الفائدة، وعديمة الفائدة بوضوح.
سلسلة التجميع — الصف في جدول البداية — كلّفت $0.003780، أي أكثر بنسبة 95 % لأربع استدعاءات متطابقة، لأن كل خطوة تحمل الآن كل ما سبقها. أنتجت الناتج الخطِر. سلس، يستشهد بحسابه، صحيح في كل رقم يذكره، ويخبر العميل أن لا شيء مستحق بينما EUR 52.08 مستحقة.
الفرق بين الاثنين هو ternary واحد. السلسلة التي تحمل أقل تنتج إجابات ناقصة بوضوح؛ والسلسلة التي تحمل كل شيء تنتج إجابات خاطئة بثقة — والنوع الثاني فقط هو الذي يُرسل.
ولا واحد منهما هو الفشل الحقيقي. الفشل الحقيقي أن pipeline قرر، قبل أن يقرأ أي شيء، أن هذه المهمة أربع خطوات فوق محتويات رسالة بريد. لا يوجد في ذلك البناء أي مكان للقول: "بلد التسجيل ليس في هذه الرسالة؛ اذهب واجلبه". يكون Chaining صحيحًا عندما يكون التفكيك معروفًا مسبقًا ومستقرًا. هنا كان تخمينًا، والتخمين وصل إلى الإنتاج.
Routing، الأقدم، وخطة B التي لا يكتبها أحد
رابط إلى القسم: Routing، الأقدم، وخطة B التي لا يكتبها أحدRouting "يصنّف مدخلًا ويوجهه إلى مهمة متابعة متخصصة".1 الاسم جديد؛ الآلية هي dispatcher، أقدم من كل شيء تقريبًا في هذا الكتاب. الجديد أن المصنّف يمكن أن يكون نموذجًا — وهذا ما يجعله يفشل بطرق لم يفشل بها switch قط.
const answer = await route(email,
(q) => classifyWithSmallModel(q), // cheap model, one call
{ billing: billingAgent, tax: taxAgent, dunning: dunningAgent },
taxAgent, // deterministic, chosen in advance
);شيئان عن تلك الوسيطة الأخيرة. إنها ليست معالجة أخطاء؛ إنها النمط. لدى router قائم على نموذج نمط فشل لا يملكه dispatcher: يمكنه أن يعيد تسمية غير موجودة، أو ينتهي وقته، أو — وهذا المكلف — يعيد تسمية خاطئة لكنها معقولة بلا إشارة إلى أنها خاطئة. يجب أن تهبط الحالات الثلاث في مكان ما، ولا يمكن أن يكون ذلك المكان استدعاء نموذج آخر، لأنك بالفعل في الفرع الذي فشلت فيه استدعاءات النماذج.
والشيء الثاني أن prompt الخاص بالـ router ليس مجانيًا. لكي يختار router نموذجًا، يحتاج إلى كتالوج نماذج يختار منها، وكل مدخل فيه هو input يدفع الـ router ثمنه قبل أن يقرأ سؤال المستخدم. بسعر الإدخال الذي يسعّر به هذا الدرس، فإن كتالوجًا من نحو 3,800 tokens يكلّف بالفعل بقدر تشغيل الـ agent كاملًا باستدعاءاته الخمسة في الجدول الافتتاحي. عمليًا يعمل استدعاء التوجيه على نموذج رخيص، وهذا هو السبب كله في أن التوجيه يسدد تكلفته بنفسه؛ لكن الحساب يستحق أن يُجرى في ذلك الاتجاه بدل الافتراض. التوجيه خاطئ تحديدًا حين تكون المهمة الموجَّهة أرخص من قرار التوجيه.
Parallelisation: الأقسام، والتصويت، وهو self-consistency
رابط إلى القسم: Parallelisation: الأقسام، والتصويت، وهو self-consistencyتقسّم Anthropic هذا إلى اثنين: sectioning — "تقسيم مهمة إلى subtasks مستقلة تُشغّل بالتوازي" — وvoting — "تشغيل المهمة نفسها عدة مرات للحصول على مخرجات متنوعة".1 يشتركان في رسم واحد ولا يشتركان في شيء تقريبًا غير ذلك.
Sectioning هو المكسب الرخيص، وهو السطر من patterns.ts: ثلاثة متخصصين — الفوترة، الضرائب، السياسة — لكل منهم نافذته وأدواته، على الرسالة نفسها، مع استدعاء synthesis واحد في النهاية. العمل نفسه، مرتّب بطريقتين:
| استدعاءات النموذج | input | output | التكلفة | زمن التنفيذ | |
|---|---|---|---|---|---|
| العمال الثلاثة، واحدًا تلو الآخر | 9 | 2,910 | 324 | $0.009708 | 3,894 ms |
الثلاثة أنفسهم، Promise.all | 9 | 2,910 | 324 | $0.009708 | 2,165 ms |
نفس الشيء token مقابل token، أسرع 1.8 مرة. لذلك يستحق النمط اسمه الخاص: إنه الوحيد بين الخمسة الذي يحسّن شيئًا بلا تكلفة. القيد أن الأقسام يجب أن تكون مستقلة فعلًا — أعطِ القسم B حقيقة ينتجها القسم A وسيشغّل Promise.all الاثنين معًا ضد حالة لم توجد بعد. أخفت حلقة for ذلك العيب؛ والسطر الواحد يكشفه.
التصويت كائن مختلف يرتدي الصورة نفسها. تشغيل السؤال نفسه k مرات وأخذ الأغلبية هو self-consistency، نشره Wang وآخرون في مارس 2022 كاستراتيجية decoding، قبل نحو ثلاث سنوات من أن يسميه أحد نمط orchestration. ملخصه دقيق في الآلية — "يأخذ أولًا عينة من مجموعة متنوعة من مسارات reasoning بدل الاكتفاء بالمسار greedy، ثم يختار الإجابة الأكثر اتساقًا عبر تهميش مسارات reasoning المأخوذة كعينات" — ودقيق في المكسب: +17.9 نقطة على GSM8K.2
ينتج عن ذلك شيئان تخفيهما الصورة. أولًا، يتطلب التصويت أخذ العينات من الفصل 17: عند temperature صفر، كل عينات k هي العينة نفسها، والأغلبية إجابة واحدة مدفوعة الثمن k مرات. ثانيًا، لا يعمل إلا حيث تكون الأغلبية ذات معنى — في رد الفاتورة أعلاه لا يوجد ما يُعدّ، لأن خمس مسودات هي خمس جمل مختلفة. التصويت للمهام ذات إجابة قصيرة وقابلة للمقارنة، وهذا يصف معايير Wang تمامًا ولا يكاد يصف أي شيء يفعله agent مواجه للعميل.
قيس هنا على 20 مسألة كلامية من ثلاث خطوات تُحسب إجاباتها بدل أن تُحكم، مع النموذج المحلي من الفصل 23 وهو يفكر خطوة بخطوة:
| استدعاءات النموذج | input | output | تكلفة الـ20 | صحيح | فاصل 95 % | |
|---|---|---|---|---|---|---|
| سلسلة greedy واحدة | 20 | 1,330 | 2,649 | $0.034448 | 9/20 | 26–66 % |
| أغلبية 5، temperature 0.8 | 100 | 6,650 | 13,245 | $0.172240 | 9/20 | 26–66 % |
خمسة أضعاف الاستدعاءات، خمسة أضعاف tokens، خمسة أضعاف الفاتورة بالضبط، ولا إجابة صحيحة إضافية واحدة. التصويت رهان، لا تحسين، وهذه الجولة خسرته.
تحفظان، قبل أن يقتبس أحد ذلك كدحض لـ Wang. عشرون تجربة لا تستطيع تمييز 45 % من 60 % — الفاصل بعرض الادعاء، وهذا هو انضباط الفصل 4 مطبقًا على نتيجتي أنا. والمكاسب المنشورة تأتي من نماذج أكبر بعدة رتب من حيث الحجم، حيث تكون مسارات reasoning المتنوعة التي يهمّشها التصويت متنوعة فعلًا. ما ينتقل ليس الرقم: بل أن المضاعِف دقيق ومعروف مسبقًا بينما المكسب ليس كذلك.
Orchestrator-workers، وما ليسه الملخص
رابط إلى القسم: Orchestrator-workers، وما ليسه الملخصفي سير عمل orchestrator-workers "يفكك LLM مركزي المهام ديناميكيًا، ويفوضها إلى LLMs عاملين، ويؤلف نتائجهم"، والاختلاف عن sectioning هو أن "subtasks ليست محددة مسبقًا، بل يحددها المنسّق".1 الأصل هنا ليس من نماذج اللغة إطلاقًا: هذا master-worker، والنسخة التي يكتب فيها العمال نتائجهم في مساحة مشتركة يقرأها متحكم هي معمارية blackboard، من أبحاث فهم الكلام في سبعينيات القرن العشرين. الجديد في 2026 أن المتحكم نموذج ولذلك يمكن تحديد التفكيك لكل مدخل — وهذه هي المرونة، والتكلفة، في جملة واحدة.
كلّف 12 استدعاء نموذج مقابل 5 للـ agent الواحد، ووصل إلى الحكم نفسه. ثم فعل شيئًا يستحق النظر إليه عن قرب:
orchestrator final: VERDICT=credit_note_due amount=52.08 source=worker_unverified
| PO_MISMATCH=yes source=worker_unverified
single agent: VERDICT=credit_note_due amount=52.08 reason=reverse_charge_should_have_applied
| PO_MISMATCH=yes invoice_says=PO-4417 order_says=PO-4471كلاهما صحيح. واحد فقط يعرف لماذا. كان لدى عامل الضرائب الفاتورة والطلب وجدول الضرائب في نافذته الخاصة، وتوصل إلى الاستنتاج، ولاحظ أيضًا — ولم يطلب أحد ذلك — أن رقم أمر الشراء على الفاتورة لا يطابق رقم الطلب. ثم أعاد ملخصًا. يستطيع المنسّق تكرار العبارتين ولا يستطيع فحص أي منهما، لأن الأدلة بقيت في نافذة لم يرها. هذا جواب سؤال ختام الفصل 24: يرى الأب كل ما اختار الابن كتابته.
الإصلاح flag، وله ثمن:
| ما يعيده العامل | orchestrator input tokens | التكلفة | ما يستطيع الأب فعله |
|---|---|---|---|
| استنتاجه | 3,628 | $0.012512 | يكرره |
| استنتاجه وأدلته | 4,065 | $0.013554 | يستنتجه مرة أخرى، ويختلف معه |
اثنا عشر في المئة أكثر من input tokens، و8.3 % أكثر من المال، وتختفي عبارة source=worker_unverified من الإجابة. هذه هي المقايضة في كل نظام multi-agent، ونادرًا ما تُذكر: نافذة الابن النظيفة تستحق، وقدرة الأب على تدقيقها تستحق الدفع، ولا يمكنك الحصول على الاثنين مجانًا.
إذًا متى يكون orchestrator-workers خاطئًا؟ هنا، في هذه المهمة. اشترى إجابة صحيحة وصل إليها أيضًا agent واحد بالأدوات الأربع نفسها، مقابل 1.66 ضعف التكلفة و2.3 ضعف زمن التنفيذ، وجعل تلك الإجابة أصعب دفاعًا. تقول إرشادات Anthropic نفسها ذلك قبل أن تبدأ الأنماط: ابحث عن "أبسط حل ممكن، ولا تزد التعقيد إلا عند الحاجة"، لأن "الأنظمة agentic غالبًا ما تقايض زمن الاستجابة والتكلفة مقابل أداء أفضل للمهام".1 الجداول أعلاه هي تلك الجملة مع أرقام تحتها.
Evaluator-optimiser، والقاضي الذي كتب الامتحان
رابط إلى القسم: Evaluator-optimiser، والقاضي الذي كتب الامتحاناستدعاء يولّد، وآخر يقيّم، وتتكرر الحلقة حتى ينجح التقييم.1 الأسلاف المنشورون هم Self-Refine — النموذج نفسه بصفته "مولّدًا، ومحسّنًا، ومقدم feedback"، مع الإبلاغ عن نحو 20 نقطة من التحسن المطلق في المتوسط عبر سبع مهام3 — وReflexion، الذي يخزّن النقد في مخزن episodic عبر المحاولات ويبلغ 91 % pass@1 على HumanEval حيث وصل baseline إلى 80 %.4
نموذج التكلفة هو الأبسط بين الخمسة: استدعاءان في كل جولة، وعدد الجولات ليس ملكك. ثلاث جولات تحسين على مهمة احتاجت استدعاء واحدًا تعني ستة استدعاءات، ولذلك أرضية النمط 6× وسقفه هو أي حد تضعه — ما يجعل مخرج الميزانية من الفصل 23 إلزاميًا لا مجرد ترتيب أنيق.
السقف أدهى، ويمكن قياسه. في المسائل العشرين نفسها أجاب النموذج المحلي عن 9 إجابات صحيحة. ثم عُرضت عليه كل واحدة من تلك الإجابات وسُئل هل هي صحيحة — من دون إخباره أن الإجابة إجابته، وهذا يزيل عامل المجاملة ويبقي عامل القدرة:
| إجابة النموذج نفسه | قال "نعم" | قال "لا" |
|---|---|---|
| التسع التي كانت صحيحة | 9 | 0 |
| الإحدى عشرة التي كانت خاطئة | 3 | 8 |
هذا قاضٍ أفضل مما يوحي به عنوان القسم، وقول ذلك هو معنى القياس بدل الادعاء: لم يمنع شيئًا صحيحًا والتقط 8 من 11 خطأ. كمرشح، يستحق استدعاءاته.
أما كـ قاعدة توقف، وهو ما تستخدمه حلقة evaluator-optimiser فعليًا، فتلك الموافقات الثلاث هي القصة كلها: تنهي الحلقة وإجابة خاطئة في اليد، ولا يصل إليها أي عدد من الجولات الإضافية. لا تستطيع حلقة تحسين أن تصبح أصح من قاضيها. شراء جولات أكثر يشتري محاولات عند الأخطاء التي يستطيع القاضي رؤيتها، بالسعر الكامل، ولا يشتري شيئًا على الإطلاق ضد الأخطاء التي لا يستطيع رؤيتها.
لذلك القاعدة: لا يستحق evaluator استدعاءاته إلا عندما يملك شيئًا لا يملكه المولّد. compiler، test suite، schema validator، نموذج مختلف، إنسان. نتائج Self-Refine نفسها تُقاس مقابل تفضيل البشر ومقاييس المهمة، لا مقابل رأي النموذج في نفسه. إذا كانت ميزة evaluator الوحيدة prompt مختلفًا، فأنت تدفع الضعف مقابل اتفاق. يبني الفصل 29 النسخة ذات الميزة الحقيقية: مجموعة ذهبية مكتوبة إجاباتها مسبقًا.
الحلقات ليست الأنماط
رابط إلى القسم: الحلقات ليست الأنماطالخمسة أعلاه أشكال لـ كودك. وتحتها توجد عائلة ثانية كثيرًا ما تُدرج بجانبها ولا ينبغي: ReAct وReflexion وplan-and-execute وtree of thoughts هي حلقات reasoning، وتكلفتها في الطلبات.
كان الفصل 12 عن reasoning داخل النموذج، الذي تدفع ثمنه output tokens في استدعاء واحد. هذا هو النوع الآخر. يهم الفرق عندما تصل الفاتورة: تجعل chain of thought أطول الاستدعاء الواحد أغلى، وتجعل حلقة reasoning المهمة الواحدة استدعاءات كثيرة، كل منها يعيد إرسال كل ما قبله — التربيعية التي قاسها الفصل 23 في جدول الانفلات.
| الحلقة | الاستدعاءات، لكل مهمة | ماذا تشتري الاستدعاءات الإضافية |
|---|---|---|
| ReAct | واحد لكل خطوة، حتى يتوقف | يتفاعل النموذج مع ما أعادته الأدوات5 |
| plan-and-execute | واحد للتخطيط، ثم واحد لكل خطوة | الخطة ثابتة قبل تشغيل الخطوة الأولى6 |
| Reflexion | المحاولات × (الفعل + التأمل) | يبقى النقد إلى المحاولة التالية4 |
| tree of thoughts | عامل التفرع × العمق، زائد تقييم واحد لكل عقدة | بحث، مع backtracking7 |
تنشر ورقة tree-of-thoughts جدول تكلفتها الخاص، وهذا أندر مما ينبغي. في Game of 24 مع GPT-4: input/output prompting best-of-100 حلّ 33 % بسعر $0.13 لكل حالة، وchain of thought best-of-100 حلّ 49 % بسعر $0.47، وtree of thoughts حلّ 74 % بسعر $0.74، مع ملاحظة المؤلفين أنه "قد يتطلب 5-100 ضعفًا من generated tokens مقارنة بـ CoT".7
نحو ستة أضعاف سعر الطريقة الرخيصة مقابل أكثر قليلًا من ضعف معدل النجاح. هل هذه صفقة رابحة يعتمد على تكلفة الحالة الفاشلة عليك — وهذا هو السؤال الذي يجب طرحه قبل اعتماد أي من الأربعة.
لا يعيد هذا الدرس تنفيذها. للأربعة كلها تطبيقات مرجعية من مؤلفيها أنفسهم، في Python، وقيمتها أنها المصدر لا ترجمة له: ysymyth/ReAct وnoahshinn/reflexion وprinceton-nlp/tree-of-thought-llm وAGI-Edgerunners/Plan-and-Solve-Prompting. اقرأ prompts في تلك المستودعات؛ prompts هي الأوراق.
طوبولوجيتان، وواحدة منهما لا تعود
رابط إلى القسم: طوبولوجيتان، وواحدة منهما لا تعودوالآن multi-agent بمعناه الصحيح، حيث يعيش معظم الالتباس. هناك طريقتان ليُدخل agent واحد agent آخر في العمل، وهما ليستا نسختين من الشيء نفسه، والفرق هو من يبقى مسؤولًا بعد ذلك.
Agent كأداة. يستدعيه الأب، ويحصل على إجابة، ويواصل. إنها واجهة الأداة من الفصل 18 مع agent كامل خلفها، ولا يفقد الأب السيطرة أبدًا. هذا ما يفعله المنسّق أعلاه.
التسليم. ينقل الأب المحادثة ولا يستردها. دليل OpenAI هو أوضح بيان منشور: handoffs هي "نقل باتجاه واحد يسمح لـ agent بتفويض Agent آخر... إذا استدعى agent دالة handoff، نبدأ فورًا التنفيذ على agent الجديد الذي سُلّم إليه مع نقل أحدث حالة للمحادثة أيضًا".8
تحذير مصطلحي، لأن هذا يوقع الناس باستمرار: "handoff" كلمة SDK واحد، وليست معيارًا. إنها مصطلح من OpenAI Agents SDK وذلك الدليل، الذي يسمي أيضًا الترتيبين "manager" و"decentralized" ويلاحظ أنه في نمط manager "تمثل الحواف tool calls بينما في النمط decentralized تمثل الحواف handoffs".8 يوجد بالفعل معيار مفتوح في هذا المجال — A2A، بالإصدار 1.0.0، تحت حقوق نشر Linux Foundation، وله تاريخ إصدارات موثق وقائمة موثقة بالتغييرات الكاسرة، ومبدؤه المعلن هو opaque execution: تتعاون agents "بناءً على القدرات المعلنة والمعلومات المتبادلة، من دون الحاجة إلى مشاركة أفكارها الداخلية أو خططها أو تطبيقات أدواتها".9 هذا ليس handoff، والمقارنة مكانها الفصل 26. ما يهم هنا أن إحدى الكلمتين API مكتبة، والأخرى مواصفة لها حوكمة.
التمييز بنية بيانات، لا رسم:
export type EdgeKind = "tool" | "handoff";
export interface AgentEdge { from: string; to: string; kind: EdgeKind }
export interface AgentGraph { root: string; agents: Record<string, AgentSpec>; edges: AgentEdge[] }
/** One agent may not be both a tool of X and a handoff target of X. */
export function conflicts(g: AgentGraph): AgentEdge[] {
const seen = new Map<string, EdgeKind>();
const bad: AgentEdge[] = [];
for (const e of g.edges) {
const key = `${e.from}->${e.to}`;
const other = seen.get(key);
if (other && other !== e.kind) bad.push(e);
else seen.set(key, e.kind);
}
return bad;
}
/** Every agent reachable from the root, and at what depth. */
export function reachable(g: AgentGraph): Map<string, number> {
const depth = new Map([[g.root, 0]]);
const queue = [g.root];
while (queue.length) {
const id = queue.shift()!;
for (const e of g.edges.filter((x) => x.from === id)) {
if (depth.has(e.to)) continue;
depth.set(e.to, depth.get(id)! + 1);
queue.push(e.to);
}
}
return depth;
}عشرون سطرًا، وعيبان كنت ستجدهما في الإنتاج لولاها. يجد reachable الـ agent الذي لا يستطيع أحد الوصول إليه — مُهيّأ، مدفوع ثمنه، لا يُستدعى أبدًا. ويرفض conflicts الحافة التي هي من النوعين في وقت واحد، وهذا يبدو تدقيقًا زائدًا حتى تقرأه بصوت عالٍ: الأب يحتفظ بالسيطرة ويتخلى عنها في الوقت نفسه. شغّله على نظام من خمسة agents فيه orphan واحد وحافة مزدوجة واحدة:
reachable: lead@0 billing@1 tax@1 dunning@1
orphans: ghost
conflicts: lead->taxما يعبر الحدود فعليًا
رابط إلى القسم: ما يعبر الحدود فعليًاوالآن القياس الذي وُجد هذا القسم لأجله، والوحيد في الفصل المأخوذ على نموذج حقيقي بدل نموذج مبرمج.
يذكر عميل قيدًا في رسالته الأولى — حسابنا مسجل في البرتغال، لا إسبانيا؛ وكل ما يخص الضرائب يجب أن يستخدم البرتغال — ثم يتحدث عن شيء آخر، ثم يطرح سؤالًا يجب أن تجيب عنه الفوترة. تُنقل الحالة. أربع وعشرون تجربة، بلد وشركة مختلفان كل مرة، أربع حمولات نقل، ثم يُسأل agent المتلقي سؤالًا واحدًا: في أي بلد سُجل حساب هذا العميل؟
| ما نُقل | متوسط الحمولة | كان القيد موجودًا فيه | تذكره المتخصص | فاصل 95 % |
|---|---|---|---|---|
| المحادثة كاملة | 173 tokens | 24/24 | 20/24 — 83 % | 64–93 % |
| ملخص كتبه agent المُرسل | 62 tokens | 1/24 | 0/24 — 0 % | 0–14 % |
| رسالة المستخدم الأخيرة فقط | 61 tokens | 0/24 | 0/24 — 0 % | 0–14 % |
| سجل typed | 69 tokens | 24/24 | 24/24 — 100 % | 86–100 % |
الصف الثالث ضبط ويتصرف كضبط: الحقيقة ليست هناك، فلا يمكن تذكرها. أما الثلاثة الأخرى فهي النتيجة.
النص الكامل 173 tokens ويعمل 83 % من الوقت، وإخفاقاته الأربع موضوع الفصل 24 لا هذا الفصل. السجل typed هو 69 tokens — أكثر من الملخص بسبعة فقط — ويعمل كل مرة، لأن القيد في حقل مسمّى بدل جملة.
والملخص هو الصف الذي ينبغي التحديق فيه. فشل 24 مرة من 24، والسبب ليس أن القارئ لم يلحظه. ظهر القيد في 1 فقط من أصل 24 ملخصًا أصلًا. لم يكن agent المتلقي مهملًا؛ بل سُلّم نصًا لا يحتوي على الإجابة. الملخص ضغط لم تكتبه، ينتجه نموذج لا تستطيع رؤية نافذته، ومُحسّن ليبدو كملخص — و"يقول العميل إن سجلاتنا فيها البلد الخطأ" هي بالضبط نوع العبارة التي يسقطها الملخّص كضجيج إجرائي.
حد صادق لذلك الرقم: الملخّص نموذج نصف مليار parameter، ونموذج أكبر سيحتفظ بالمزيد. ما لا يتحسن مع الحجم هو شكل الخطر — يقرر agent المُرسل، لكل handoff، ولكل صياغة، وبلا إمكانية مراقبة، أي حقائق تبقى. لا يعتمد السجل typed على ذلك الحكم إطلاقًا، ولهذا يفوز بالبناء لا بالذكاء. كل ما يجب أن ينجو من نقل ينبغي أن يكون حقلًا، لا جملة.
ينطبق المنطق نفسه في الاتجاه الآخر، على طوبولوجيا agent-as-tool، وقد سعّر الجدول السابق ذلك بالفعل: ما يعود من عامل هو ملخص أيضًا، ودفع 8.3 % أكثر لاستلام الأدلة معه هو الإصلاح نفسه كما يُرى من جهة الأب.
متى يفوز agent واحد
رابط إلى القسم: متى يفوز agent واحدثلاث حقائق ختامية، كلها من الجداول أعلاه.
نظام multi-agent يضاعف الاستدعاءات، والاستدعاءات تربيعية في context. أنشأ المنسّق 12 استدعاء نموذج حيث أنشأ agent واحد 5، وكل منها يحمل transcript ناميًا خاصًا به — 3,628 input tokens مقابل 2,697، وفجوة تتسع مع طول المهمة.
كل حد قناة فاقدة. agentان يعنيان ملخصًا واحدًا. أربعة agents في سلسلة تعني ثلاثة، مركبة، يكتب كل منها نموذج يحسّن لشيء غير قرارك.
وجد agent الواحد شيئًا لم يطلبه أحد. ظهر عدم تطابق أمر الشراء لأن نافذة واحدة حملت الفاتورة والطلب معًا. تقسيم العمل على متخصصين يقسم أيضًا القدرة على ملاحظة أن حقيقتين متعارضتان.
لا يعني أي من ذلك حجة ضد frameworks المنشورة لـ multi-agent، فهي تستحق القراءة كمصادر أولية لا عبر شروحات.10 بل يعني أن تجعل agent الثاني يستحق مكانه.
إذًا، اختبار لا تفضيل. أضف agent ثانيًا عندما يصدق واحد على الأقل مما يلي: تحتاج sub-task إلى نافذة نظيفة يجب ألا يرثها الأب (الفصل 24)؛ أو تكون sub-tasks مستقلة حقًا ويهم زمن التنفيذ، وهذا هو 1.8× أعلاه؛ أو تحتاج sub-task إلى صلاحيات مختلفة أو نموذج مختلف، وهو ما يحوله الفصل 30 إلى حجة أمنية؛ أو تكون sub-task مملوكة لشخص آخر، وهنا يبدأ البروتوكول الحقيقي في أن يهم. إذا كانت الإجابة "حتى يكون لكل agent prompt أوضح"، فأعطِ agent الواحد prompt أوضح. هذا مجاني.
إلى أين نذهب بعد ذلك
رابط إلى القسم: إلى أين نذهب بعد ذلكيمكنك الآن تسمية الأنماط الخمسة، وتسعيرها مقابل بعضها على مهمة واحدة، وتمييز orchestrator عن sectioner وtool call عن handoff، والدفاع عن agent واحد بجدول بدل تفضيل.
اشتركت كل الترتيبات هنا في راحة واحدة لن تصمد أمام أي شيء حقيقي: كل الأدوات كانت لنا. الفاتورة، والطلب، وجدول الضرائب، والعمال خلف الـ orchestrator — المستودع نفسه، والنشر نفسه، والأنواع نفسها، والناس أنفسهم.
ضع الآن واحدًا منها على الجانب الآخر من حدود شركة. جدول الضرائب يملكه مزود محاسبة، وسجل الطلب يملكه نظام مستودعات، ولا أحد منهما قرأ واجهة Tool الخاصة بك. تحتاج إلى طريقة كي يكتشف نموذج لم تكتبه قدرة يشغّلها شخص آخر، ويصفها، ويستدعيها — مع المصادقة (وهي نصف الفصل 27)، والإصدارات، وضمان أن الخادم لا يستطيع قراءة بقية محادثتك. هذه مشكلة بروتوكول، ولها مواصفة مع schema معيارية، وتقريبًا كل ما فُهرس عنها يصف مراجعة لم تعد موجودة.
يقرأ الفصل 26 تلك المواصفة بدل تلخيصها، ويبدأ بكتابة JSON-RPC في طرفية يدويًا.
المصادر والمنهج
رابط إلى القسم: المصادر والمنهججاءت كل تكلفة وعدّ tokens أعلاه من المزوّد المبرمج الموصوف في القسم الثاني، على Node 22 عبر واجهة loopback، مع العد بترميز o200k_base والتسعير بالأسعار التي قرأها الفصل 16 في 6 سبتمبر 2026 — $2.00 لكل مليون input tokens و$12.00 لكل مليون output. أرقام زمن التنفيذ من التشغيلات نفسها مع ضبط زمن استجابة المزوّد على 400 ms لكل استدعاء والأدوات على 50 ms، لذلك فهي تقيس الترتيب لا أي مزوّد. قياسا النموذج الحقيقي — جدول handoff وجدول voting-and-judging — استخدما Qwen/Qwen2.5-0.5B-Instruct في float32 على CPU خلف نقطة نهاية بالشكل نفسه، greedy إلا حيث يُذكر temperature، مع فواصل محسوبة بطريقة Wilson من الفصل 4. لم يذهب أي طلب في هذا الفصل إلى نقطة نهاية مدفوعة، ولم يُقدّر أي رقم فيه.
المراجع
رابط إلى القسم: المراجع-
Anthropic، Building effective agents، 19 ديسمبر 2024،
anthropic.com/engineering/building-effective-agents، قُرئ في 7 سبتمبر 2026. مصدر أسماء سير العمل الخمسة المستخدمة أعلاه وكل عبارة مقتبسة منها — prompt chaining، وrouting، وparallelisation بمتغيريه sectioning وvoting، وorchestrator-workers، وevaluator-optimiser — وكذلك التوصية بالبحث عن "أبسط حل ممكن، ولا تزد التعقيد إلا عند الحاجة" والملاحظة أن "الأنظمة agentic غالبًا ما تقايض زمن الاستجابة والتكلفة مقابل أداء أفضل للمهام". يقتبس الفصلان 22 و23 تعريفها لـ agent. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 -
Wang, X., Wei, J., Schuurmans, D., Le, Q., Chi, E., Narang, S., Chowdhery, A. and Zhou, D. Self-Consistency Improves Chain of Thought Reasoning in Language Models. arXiv:2203.11171 (مارس 2022). أصل نمط voting، موصوفًا هناك كاستراتيجية decoding لا كمعمارية: خذ عينات من مسارات reasoning متنوعة، ثم "اختر الإجابة الأكثر اتساقًا عبر تهميش مسارات reasoning المأخوذة كعينات"، مع مكاسب مبلّغ عنها قدرها +17.9 على GSM8K، و+11.0 على SVAMP، و+12.2 على AQuA، و+6.4 على StrategyQA، و+3.9 على ARC-challenge. ↩
-
Madaan, A. et al. Self-Refine: Iterative Refinement with Self-Feedback. arXiv:2303.17651 (2023). حلقة evaluator-optimiser بنموذج واحد في الأدوار الثلاثة — "generator, refiner, and feedback provider" — وتحسن "بنحو ~20% مطلقًا في المتوسط في أداء المهمة" عبر سبع مهام، مقاسًا بتفضيل البشر ومقاييس آلية لا بحكم النموذج نفسه. ↩
-
Shinn, N., Cassano, F., Berman, E., Gopinath, A., Narasimhan, K. and Yao, S. Reflexion: Language Agents with Verbal Reinforcement Learning. arXiv:2303.11366 (2023). يضيف ذاكرة episodic للنقد الذاتي عبر المحاولات — "تعزيز language agents ليس بتحديث الأوزان، بل عبر feedback لغوي" — ويبلغ 91 % pass@1 على HumanEval مقابل 80 % لـ GPT-4 baseline. لاحظ الشرط الذي تعتمد عليه نتائجه: إشارة حقيقية من البيئة، مثل اختبار فاشل، بدل رأي النموذج في نفسه. ↩ ↩2
-
Yao, S., Zhao, J., Yu, D., Du, N., Shafran, I., Narasimhan, K. and Cao, Y. ReAct: Synergizing Reasoning and Acting in Language Models. arXiv:2210.03629 (2022). آثار reasoning وأفعال متداخلة؛ بنى الفصل 23 هذه الحلقة. يُستشهد به هنا لشكل تكلفته لا لنتائجه: استدعاء نموذج واحد لكل خطوة، مع إعادة إرسال transcript كله كل مرة. ↩
-
Wang, L., Xu, W., Lan, Y., Hu, Z., Lan, Y., Lee, R. K.-W. and Lim, E.-P. Plan-and-Solve Prompting: Improving Zero-Shot Chain-of-Thought Reasoning by Large Language Models. arXiv:2305.04091 (2023). "أولًا، وضع خطة لتقسيم المهمة كلها إلى subtasks أصغر، ثم تنفيذ subtasks وفقًا للخطة" — شكل خطط-ثم-نفّذ، ومصدر المقايضة التي يهتم بها هذا الفصل: الخطة ثابتة قبل وصول الملاحظة الأولى، وهذا prompt chaining بتفكيك يكتبه نموذج بدل أن تكتبه أنت. ↩
-
Yao, S., Yu, D., Zhao, J., Shafran, I., Griffiths, T. L., Cao, Y. and Narasimhan, K. Tree of Thoughts: Deliberate Problem Solving with Large Language Models. arXiv:2305.10601 (2023). بحث عبر "thoughts" وسيطة مع self-evaluation وbacktracking؛ 74 % على Game of 24 مقابل 4 % لـ chain-of-thought prompting. أرقام التكلفة المقتبسة أعلاه هي أرقام الورقة نفسها، من Appendix B.3، Table 7: لكل حالة، input/output prompting best-of-100 بسعر $0.13 لـ 33 %، وchain of thought best-of-100 بسعر $0.47 لـ 49 %، وtree of thoughts بسعر $0.74 لـ 74 %، مع ملاحظة المؤلفين أن ToT "قد يتطلب 5-100 ضعفًا من generated tokens مقارنة بـ CoT". ↩ ↩2
-
OpenAI، A practical guide to building agents (PDF)، قُرئ في 7 سبتمبر 2026. تقسيم manager مقابل decentralized، وتأطير graph المقتبس أعلاه ("في نمط manager، تمثل الحواف tool calls بينما في النمط decentralized تمثل الحواف handoffs")، وتعريف handoff بأنه "نقل باتجاه واحد... نبدأ فورًا التنفيذ على agent الجديد الذي سُلّم إليه مع نقل أحدث حالة للمحادثة أيضًا". لاحظ ما تحسمه العبارة الأخيرة: في هذا SDK تنتقل حالة المحادثة فعلًا، وهذا قرار تصميمي لتلك المكتبة لا خاصية لـ handoffs عمومًا. ↩ ↩2
-
Agent2Agent (A2A) Protocol Specification، أحدث إصدار منشور 1.0.0،
a2a-protocol.org/latest/specification/، قُرئ في 7 سبتمبر 2026؛ حقوق النشر لـ Linux Foundation، Apache-2.0. المقتبس أعلاه: "معيار مفتوح مصمم لتسهيل الاتصال وقابلية التشغيل البيني بين أنظمة AI agent مستقلة وربما معتمة"، ومبدأ opaque execution — تتعاون agents "بناءً على القدرات المعلنة والمعلومات المتبادلة، من دون الحاجة إلى مشاركة أفكارها الداخلية أو خططها أو تطبيقات أدواتها". تحمل الصفحة تاريخ إصدارات (0.1.0، 0.2.6، 0.3.0، 1.0.0)، وملحقًا للتغييرات الكاسرة، وملحقًا عن علاقتها بـ MCP. يجري الفصل 26 تلك المقارنة. ↩ -
أطر multi-agent التي لا يعلّمها هذا الفصل، للقارئ الذي يريد المصادر الأولية بدل شرح تعليمي: Wu, Q. et al., AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation, arXiv:2308.08155 (2023)، حيث agents "customizable, conversable" والمحادثة نفسها هي نموذج البرمجة؛ وHong, S. et al., MetaGPT: Meta Programming for a Multi-Agent Collaborative Framework, arXiv:2308.00352 (2023)، الذي يرمّز إجراءات التشغيل القياسية في role prompts ويصرّح بأن "حلول المهام الأكثر تعقيدًا تصبح معقدة بسبب عدم اتساق المنطق الناتج عن cascading hallucinations سببه naive chaining لـ LLMs" — السلسلة الخاطئة بثقة المقاسة في أعلى هذا الفصل، مسماة في ملخص؛ وPark, J. S. et al., Generative Agents: Interactive Simulacra of Human Behavior, arXiv:2304.03442 (2023)، خمسة وعشرون agents بذاكرة وتأمل وتخطيط، وهو أكبر جواب منشور على سؤال "ماذا يحدث إذا واصلت إضافة agents". ↩