Multi-Agent Orchestration: viisi mallia ja milloin yksi voittaa
Sama lasku ratkaistiin neljällä tavalla: orchestrator maksoi 1,66× single agentin hinnan ja päätyi samaan ratkaisuun.
Tällä sivulla
Luku 24 päättyi kysymykseen, jonka se oli ansainnut: kun sub-agent on väärässä, mitä parent tarkalleen pääsee katsomaan?
Tämä luku vastaa siihen laskulla. Yksi tehtävä — asiakas kiistää laskun ja haluaa vastauksen — ratkaistuna neljällä tavalla. Kaikki ajavat luvun 23 harnessia samaa skriptattua provideria vasten, kaikki laskevat samat tokens samalla encoderilla, ja kaikki hinnoitellaan niillä hinnoilla, jotka luku 16 luki 6. syyskuuta 2026.
| asetelma | model-kutsut | input tokens | output | kustannus | wall clock | verdict |
|---|---|---|---|---|---|---|
| prompt chaining | 4 | 900 | 165 | $0.003780 | 1,648 ms | väärä |
| yksi agent, neljä työkalua | 5 | 2,697 | 179 | $0.007542 | 2,224 ms | oikein |
| rinnakkaiset osiot | 9 | 2,910 | 324 | $0.009708 | 2,165 ms | oikein |
| orchestrator-workers | 12 | 3,628 | 438 | $0.012512 | 5,090 ms | oikein, eikä se voi todistaa sitä |
Lue ensimmäinen ja viimeinen rivi yhdessä: niiden välissä on jokainen väittely, jota tämä toimiala käy juuri nyt. Halvin asetelma oli myös nopein ja tuotti itsevarman, väärän, lähetettäväksi kelpaavan vastauksen. Kallein osui oikeaan, vei 3,3-kertaisesti rahaa ja 3,1-kertaisesti aikaa, ja päättyi siteeraamaan työntekijän johtopäätöstä, jota sillä ei ole mitään keinoa tarkistaa.
Rivi, jota kukaan ei lisää näihin taulukoihin, on toinen: yksi agent neljällä työkalulla päätyi samaan verdictiin kuin orchestrator 60 %:lla rahasta ja 44 %:lla wall clockista. Tämä ei ole mieltymys yksinkertaisuuteen. Se on mittaus, ja tämän luvun loppu käsittelee sitä, milloin se lakkaa pitämästä paikkaansa.
Näytä lisätiedot
Mitä tämä luku tarvitsee aiemmista luvuista.
- Luku 18 työkalusopimuksesta: schema, jonka model näkee, ja endpoint, jota se ei koskaan näe. Kokonainen agent mahtuu tuon rajapinnan taakse, ja siinä on multi-agent kokonaisuudessaan.
- Luku 22 kahdesta julkaistusta "agentin" määritelmästä, jotka ovat eri mieltä, sekä aritmetiikasta, jossa prompt-ketju on N kutsua.
- Luku 23 loopista, viidestä ulospääsytavasta, run statesta ja tracesta. Jokainen alla oleva asetelma on tuo tiedosto eri tavalla kutsuttuna.
- Luku 24 siitä, mitä ikkuna maksaa ja mitä siitä putoaa ulos. Sub-agent on sen neljästä strategiasta neljäs, ja ainoa, joka on toinen agent eikä policy.
Ei tensoreita. Kaikki tässä on TypeScriptiä, paitsi kaksi mittausta oikeaa paikallista modelia vasten.
Tehtävä ja sen sisällä oleva ansa
Linkki osioon: Tehtävä ja sen sisällä oleva ansaPortugalilainen yritys kirjoittaa laskusta FT-2026-0918. Sähköpostissa sanotaan, että ALV näyttää väärältä, ja mukana on lasku: netto EUR 248.00, ALV veloitettu 21 %:n mukaan, EUR 52.08, yhteensä EUR 300.08.
Vastaamiseen tarvittavat faktat ovat kolmessa paikassa, ja vain yksi niistä on sähköpostissa:
| missä | mitä siinä sanotaan |
|---|---|
| liitteenä oleva lasku | myyjä Espanjassa, ALV lisätty 21 %:n mukaan, EUR 52.08 |
| tilaustietue | ostaja on rekisteröity Portugaliin, sillä on voimassa oleva ALV-tunniste, business-to-business |
| verotaulukko | Espanjan kotimaan verokanta 21 %; EU:n sisäinen business-to-business voimassa olevalla tunnisteella, käännetty verovelvollisuus, 0 % |
Kun nämä kolme yhdistää, lasku on väärä: käännettyä verovelvollisuutta olisi pitänyt soveltaa, ALV:n olisi pitänyt olla nolla, ja hyvityslasku EUR 52.08 on velkaa. Katso vain laskua, ja se on aritmeettisesti täydellinen — 248.00 plus 52.08 on 300.08 — ja sanot niin.
Sähköposti kyllä sanoo "olemme portugalilainen yritys". Se on väite, ei tietue, eikä mikään laskutusjärjestelmä lähetä hyvityslaskua väitteen perusteella. Ansa ei ole temppu: se on tavallisen yritystyön muoto, jossa päätös tarvitsee faktan, jota kukaan ei tajunnut hakea.
Kaikki yllä oleva ajetaan skriptattua provideria vasten luvun 23 tyyliin, täsmälleen yhdellä säännöllä:
Vastaus saa käyttää vain faktaa, joka on sen promptissa.
"Model" pyytää jokaista työkaluaan kerran, katalogijärjestyksessä, ja soveltaa sitten kiinteää sääntöä tekstiin, jonka se näkee. Mitään ei ole skriptattu asetelmakohtaisesti, joten avaustaulukon erot eivät ole väitteitä model-älykkyydestä: ne ovat mitattua tiedon reititystä. Oikea model lisää omat epäonnistumisensa päälle; se ei poista näitä.
Viisi patternia noin neljässäkymmenessä rivissä
Linkki osioon: Viisi patternia noin neljässäkymmenessä rivissäAlla olevat viisi nimeä ovat Anthropicilta, tekstistä Building effective agents, jossa tämä sanasto vakiintui.1 Mikään viidestä ideasta ei ole uusi, ja sen sanominen, mikä talo nimesi minkäkin — ja mikä idea on vanhempi — on puolet niiden tuntemisen arvosta.
/* 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 };
}Siinä on koko työkalupakki: viisi funktiota, ei frameworkia, ja rinnakkainen on yksi rivi — mikä on juuri syy kirjoittaa se auki sen sijaan, että sen piirtäisi. Nyt jokainen vuorollaan, sukujuurineen, hintoineen ja tapauksineen, jossa se on väärässä.
Chaining ja päätös, jonka se tekee puolestasi
Linkki osioon: Chaining ja päätös, jonka se tekee puolestasiPrompt chaining "pilkkoo tehtävän askelten sarjaksi, jossa jokainen LLM-kutsu käsittelee edellisen outputia".1 Idea on language modeleita vanhempi: se on pipeline, ja pipelinen kauppa on selkeys vastineeksi control flowsta, joka on lukittu ennen kuin data saapuu.
Tehtäväämme varten neljä askelta: poimi laskun kentät, tarkista aritmetiikka, päätä mitä on velkaa, kirjoita vastaus. Tässä se epäonnistuu kahdella eri tavalla, mikä opettaa enemmän kuin yksi epäonnistuminen.
--- 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."Välitysketju maksoi $0.001940 ja kadotti laskun kentät askelten kaksi ja kolme välissä, koska kolmannelle askeleelle annettiin lause aritmetiikasta eikä mitään muuta. Se tuotti odotusviestin: hyödytön ja näkyvästi hyödytön.
Kerryttävä ketju — avaustaulukon rivi — maksoi $0.003780, eli 95 % enemmän neljästä identtisestä kutsusta, koska jokainen askel kantaa nyt kaiken sitä edeltävän. Se tuotti vaarallisen outputin. Sujuva, aritmetiikkaansa siteeraava, oikein jokaisen mainitsemansa numeron osalta, ja kertomassa asiakkaalle, ettei mitään ole velkaa, vaikka EUR 52.08 on velkaa.
Näiden kahden ero on yksi ternary. Ketju, joka kantaa vähemmän, tuottaa vastauksia, jotka ovat ilmiselvästi puutteellisia; ketju, joka kantaa kaiken, tuottaa vastauksia, jotka ovat itsevarmasti väärässä — ja vain jälkimmäinen tyyppi lähetetään.
Kumpikaan ei ole todellinen epäonnistuminen. Todellinen epäonnistuminen on se, että pipeline päätti ennen minkään lukemista, että tämä tehtävä on neljä askelta sähköpostin sisällön yli. Missään tässä rakenteessa ei ole paikkaa sanoa "rekisteröintimaa ei ole tässä sähköpostissa; mene hakemaan se". Chaining on oikein, kun purku tunnetaan etukäteen ja se on vakaa. Tässä se oli arvaus, ja arvaus lähetettiin.
Routing, vanhin niistä, ja plan B, jota kukaan ei kirjoita
Linkki osioon: Routing, vanhin niistä, ja plan B, jota kukaan ei kirjoitaRouting "luokittelee inputin ja ohjaa sen erikoistuneeseen jatkotehtävään".1 Nimi on uusi; mekanismi on dispatcher, vanhempi kuin melkein kaikki muu tässä kirjassa. Uutta on se, että classifier voi olla model — ja juuri se saa sen epäonnistumaan tavoilla, joilla switch ei koskaan epäonnistunut.
const answer = await route(email,
(q) => classifyWithSmallModel(q), // cheap model, one call
{ billing: billingAgent, tax: taxAgent, dunning: dunningAgent },
taxAgent, // deterministic, chosen in advance
);Kaksi asiaa tuosta viimeisestä argumentista. Se ei ole virheenkäsittelyä; se on pattern. Model-pohjaisella routerilla on failure mode, jota dispatcherilla ei ole: se voi palauttaa labelin, jota ei ole olemassa, aikakatkaista tai — kallis tapaus — palauttaa uskottavan väärän labelin ilman signaalia siitä, että se on väärä. Kaikkien kolmen täytyy päätyä jonnekin, eikä se jonnekin voi olla toinen model-kutsu, koska olet jo haarassa, jossa model-kutsut epäonnistuivat.
Toinen asia on, että routerin oma prompt ei ole ilmainen. Modelin valitsemiseen router tarvitsee katalogin modeleista, joista valita, ja jokainen sen merkintä on inputia, josta router maksaa ennen kuin se on lukenut käyttäjän kysymyksen. Input-hinnalla, jolla tämä kurssi hinnoittelee, noin 3 800 tokenin katalogi maksaa jo yhtä paljon kuin avaustaulukon koko viiden kutsun agent-ajo. Käytännössä routing-kutsu ajetaan halvalla modelilla, mikä on koko syy siihen, että routing maksaa itsensä takaisin; mutta aritmetiikka kannattaa tehdä tähän suuntaan olettamisen sijaan. Routing on väärin juuri silloin, kun reititetty tehtävä on halvempi kuin routing-päätös.
Parallelisation: osiot ja äänestys, joka on self-consistency
Linkki osioon: Parallelisation: osiot ja äänestys, joka on self-consistencyAnthropic jakaa tämän kahtia: sectioning — "tehtävän pilkkominen itsenäisiin rinnakkain ajettaviin alitehtäviin" — ja voting — "saman tehtävän ajaminen useita kertoja erilaisten outputien saamiseksi".1 Niillä on sama kaavio eikä juuri mitään muuta yhteistä.
Sectioning on halpa voitto, ja se on rivi kohdasta patterns.ts: kolme spesialistia — laskutus, vero, policy — jokaisella oma ikkuna ja työkalut, saman sähköpostin yli, yksi synthesis-kutsu lopussa. Sama työ, kahdessa järjestyksessä:
| model calls | input | output | kustannus | wall clock | |
|---|---|---|---|---|---|
| kolme työntekijää, yksi toisensa jälkeen | 9 | 2,910 | 324 | $0.009708 | 3,894 ms |
samat kolme, Promise.all | 9 | 2,910 | 324 | $0.009708 | 2,165 ms |
Sama token tokenilta, 1,8 kertaa nopeampi. Siksi pattern ansaitsee oman nimensä: se on ainoa viidestä, joka parantaa jotain maksamatta mitään. Juju on, että osioiden täytyy olla aidosti itsenäisiä — anna osiolle B fakta, jonka osio A tuottaa, ja Promise.all ajaa ne molemmat statea vasten, jota ei ole vielä olemassa. for-loop piilotti tuon bugin; yksirivinen paljastaa sen.
Voting on eri eläin samassa kuvassa. Saman kysymyksen ajaminen k kertaa ja enemmistön valitseminen on self-consistency, jonka Wang et al. julkaisivat maaliskuussa 2022 decoding-strategiana, melkein kolme vuotta ennen kuin kukaan kutsui sitä orchestration patterniksi. Tiivistelmä on täsmällinen mekanismista — "ottaa ensin näytteen monipuolisesta joukosta päättelypolkuja sen sijaan, että ottaisi vain ahneen, ja valitsee sitten johdonmukaisimman vastauksen marginalisoimalla näytteistetyt päättelypolut pois" — ja hyödystä: +17,9 pistettä GSM8K:ssa.2
Tästä seuraa kaksi asiaa, jotka kuva piilottaa. Ensinnäkin voting vaatii luvun 17 samplingin: temperature nollassa kaikki k näytettä ovat sama näyte, ja enemmistö on yksi vastaus, josta maksetaan k kertaa. Toiseksi se toimii vain siellä, missä enemmistö on merkityksellinen — yllä olevassa laskuvastauksessa ei ole mitään laskettavaa, koska viisi luonnosta on viisi eri lausetta. Voting on tehtäviin, joissa on lyhyt, vertailukelpoinen vastaus, mikä on täsmälleen Wangin benchmarkkien maailma eikä juuri lainkaan customer-facing agentin työtä.
Mitattuna tässä 20 kolmivaiheisella sanallisella tehtävällä, joiden vastaukset lasketaan eivätkä arvioida, käyttäen luvun 23 paikallista modelia askel askeleelta päättelemiseen:
| model calls | input | output | kustannus 20:lle | oikein | 95 %:n väli | |
|---|---|---|---|---|---|---|
| yksi greedy chain | 20 | 1,330 | 2,649 | $0.034448 | 9/20 | 26–66 % |
| enemmistö viidestä, temperature 0.8 | 100 | 6,650 | 13,245 | $0.172240 | 9/20 | 26–66 % |
Viisi kertaa kutsut, viisi kertaa tokens, täsmälleen viisi kertaa lasku, eikä yhtään lisäoikeaa vastausta. Voting on veto, ei parannus, ja tämä ajo hävisi sen.
Kaksi varoitusta ennen kuin kukaan siteeraa tätä Wangin kumoamisena. Kaksikymmentä koetta ei erota 45 %:a 60 %:sta — väli on väitteen levyinen, mikä on luvun 4 kurinalaisuus käännettynä omaan tulokseeni. Ja julkaistut hyödyt tulevat kertaluokkia suuremmista modeleista, joissa votingin marginalisoimat monipuoliset päättelypolut ovat oikeasti monipuolisia. Se, mikä siirtyy, ei ole numero: se on se, että kerroin on täsmällinen ja tiedossa etukäteen, kun taas hyöty ei ole kumpaakaan.
Orchestrator-workers ja mitä summary ei ole
Linkki osioon: Orchestrator-workers ja mitä summary ei oleOrchestrator-workers-työnkulussa "keskitetty LLM pilkkoo tehtävät dynaamisesti, delegoi ne worker-LLM:ille ja syntetisoi niiden tulokset", ja ero sectioningiin on se, että "alitehtäviä ei ole määritelty etukäteen, vaan orchestrator määrittää ne".1 Sukujuuret eivät tule language modeleista lainkaan: tämä on master-worker, ja versio, jossa workers kirjoittavat löydöksensä yhteiseen tilaan, jota controller lukee, on blackboard architecture 1970-luvun puheentunnistuksen tutkimuksesta. Uutta vuonna 2026 on se, että controller on model ja siksi purku voidaan päättää input-kohtaisesti — mikä on joustavuus ja kustannus yhdessä lauseessa.
Se maksoi 12 model-kutsua single agentin viittä vastaan ja päätyi samaan verdictiin. Sitten se teki jotain, jota kannattaa katsoa tarkasti:
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-4471Molemmat ovat oikein. Vain toinen tietää miksi. Vero-workerilla oli lasku, tilaus ja verotaulukko omassa ikkunassaan, se päätyi johtopäätökseen ja huomasi myös — kukaan ei pyytänyt — että laskun ostotilausnumero ei täsmää tilauksen kanssa. Sitten se palautti summaryn. Orchestrator voi toistaa molemmat väitteet eikä tarkistaa kumpaakaan, koska evidence jäi ikkunaan, jota se ei koskaan nähnyt. Tämä on luvun 24 päätöskysymys vastattuna: parent pääsee katsomaan sitä, mitä child päätti kirjoittaa muistiin.
Korjaus on flag, ja sillä on hinta:
| mitä worker palauttaa | orchestrator input tokens | kustannus | mitä parent voi tehdä |
|---|---|---|---|
| johtopäätöksensä | 3,628 | $0.012512 | toistaa sen |
| johtopäätöksensä ja evidencensä | 4,065 | $0.013554 | johtaa sen uudelleen ja olla eri mieltä |
Kaksitoista prosenttia enemmän input tokens, 8,3 % enemmän rahaa, ja fraasi source=worker_unverified katoaa vastauksesta. Tämä on jokaisen multi-agent systemin vaihtokauppa, eikä sitä juuri koskaan lausuta ääneen: childin puhdas ikkuna on arvokas, parentin kyky auditoida sitä on maksamisen arvoinen, etkä saa molempia ilmaiseksi.
Milloin siis orchestrator-workers on väärin? Tässä, tässä tehtävässä. Se osti oikean vastauksen, johon yksi agent samoilla neljällä työkalulla myös päätyi, 1,66-kertaisella kustannuksella ja 2,3-kertaisella wall clockilla, ja teki vastauksesta vaikeammin puolustettavan. Anthropicin oma ohje sanoo saman jo ennen patterneja: etsi "mahdollisimman yksinkertainen ratkaisu ja lisää monimutkaisuutta vain tarvittaessa", koska "agentic systems vaihtavat usein latenssia ja kustannusta parempaan tehtäväsuoritukseen".1 Yllä olevat taulukot ovat tuo lause numeroiksi muutettuna.
Evaluator-optimiser ja tuomari, joka kirjoitti kokeen
Linkki osioon: Evaluator-optimiser ja tuomari, joka kirjoitti kokeenYksi kutsu generoi, toinen arvioi, ja loop toistuu, kunnes arviointi menee läpi.1 Julkaistut edeltäjät ovat Self-Refine — sama model "generator, refiner, and feedback provider" -rooleissa, raportoiden noin 20 prosenttiyksikön absoluuttisen parannuksen keskimäärin seitsemässä tehtävässä3 — ja Reflexion, joka tallentaa kritiikin episodic bufferiin yritysten välillä ja raportoi 91 % pass@1 HumanEvalissa, kun baseline ylsi 80 %:iin.4
Kustannusmalli on viidestä yksinkertaisin: kaksi kutsua per kierros, eikä kierrosmäärä ole sinun. Kolme refinement-kierrosta tehtävässä, joka vei yhden kutsun, on kuusi kutsua, joten patternin lattia on 6× ja katto on se raja, jonka asetat — mikä tekee luvun 23 budget exitistä pakollisen eikä vain siistin.
Katto on hienovaraisempi, ja se on mitattavissa. Samoissa 20 tehtävässä paikallinen model vastasi 9 oikein. Sitten sille näytettiin jokainen noista vastauksista ja kysyttiin, oliko se oikeassa — kertomatta, että vastaus oli sen oma, mikä poistaa imarteluhäiriön ja jättää kyvykkyysongelman:
| modelin oma vastaus | se sanoi "kyllä" | se sanoi "ei" |
|---|---|---|
| ne 9, jotka olivat oikein | 9 | 0 |
| ne 11, jotka olivat väärin | 3 | 8 |
Se on parempi tuomari kuin osion otsikko antaa ymmärtää, ja juuri siksi mitataan eikä väitetä: se ei estänyt mitään oikeaa ja nappasi 8 virhettä 11:stä. Suodattimena se on kutsujensa arvoinen.
Pysäytyssääntönä, mikä evaluator-optimiser-loopissa on sen todellinen käyttötapa, nuo kolme hyväksyntää ovat koko tarina: ne päättävät loopin väärä vastaus kädessä, eikä mikään määrä lisäkierroksia koskaan saavuta niitä. Refinement-loop ei voi tulla oikeammaksi kuin sen tuomari. Lisäkierrosten ostaminen ostaa yrityksiä niihin virheisiin, jotka tuomari näkee, täydellä hinnalla, eikä yhtään mitään niitä vastaan, joita se ei näe.
Siksi sääntö: evaluator ansaitsee kutsunsa vain, kun sillä on jotain, mitä generatorilla ei ole. Compiler, test suite, schema validator, eri model, ihminen. Self-Refinen omat tulokset mitataan ihmismieltymyksiä ja tehtävämetriikoita vasten, ei koskaan modelin omaa mielipidettä itsestään vasten. Jos evaluatorin ainoa etu on eri prompt, maksat kaksinkertaisesti samasta mielipiteestä. Luku 29 rakentaa version, jolla on oikea etu: golden set, jonka vastaukset on kirjoitettu etukäteen.
Loopit eivät ole patternit
Linkki osioon: Loopit eivät ole patternitYllä olevat viisi ovat muotoja sinun koodillesi. Niiden alla on toinen perhe, joka usein listataan niiden rinnalle mutta jota ei pitäisi: ReAct, Reflexion, plan-and-execute ja tree of thoughts ovat reasoning loops, ja niiden kustannus on pyynnöissä.
Luku 12 käsitteli reasoningia modelin sisällä, josta maksat output tokens yhdessä kutsussa. Tämä on toinen laji. Erolla on merkitystä, kun lasku saapuu: pidempi chain of thought tekee yhdestä kutsusta kalliimman, ja reasoning loop tekee yhdestä tehtävästä monta kutsua, joista jokainen lähettää kaiken edeltävän uudelleen — kvadraattisen ilmiön, jonka luku 23 mittasi karkaamistaulukossaan.
| loop | kutsut per tehtävä | mitä lisäkutsut ostavat |
|---|---|---|
| ReAct | yksi per askel, kunnes se pysähtyy | model reagoi siihen, mitä työkalut palauttivat5 |
| plan-and-execute | yksi suunnitteluun, sitten yksi per askel | suunnitelma on lukittu ennen ensimmäisen askeleen ajoa6 |
| Reflexion | yritykset × (toimi + reflektoi) | kritiikki säilyy seuraavaan yritykseen4 |
| tree of thoughts | branching factor × syvyys, plus yksi arviointi per node | haku, backtrackingilla7 |
Tree-of-thoughts-paperi julkaisee oman kustannustaulukkonsa, mikä on harvinaisempaa kuin sen pitäisi olla. Game of 24 GPT-4:llä: input/output prompting best-of-100 ratkaisi 33 % hintaan $0.13 per tapaus, chain of thought best-of-100 ratkaisi 49 % hintaan $0.47, ja tree of thoughts ratkaisi 74 % hintaan $0.74, kirjoittajien todetessa, että se "could require 5-100 times more generated tokens than CoT".7
Lähes kuusi kertaa halvan menetelmän hinta hieman yli kaksinkertaisesta onnistumisasteesta. Onko se hyvä kauppa, riippuu siitä, mitä epäonnistunut tapaus sinulle maksaa — kysymys, joka kannattaa kysyä ennen minkä tahansa näistä neljästä käyttöönottoa.
Tämä kurssi ei toteuta niitä uudelleen. Kaikilla neljällä on omien kirjoittajiensa reference implementations Pythonilla, ja niiden arvo on siinä, että ne ovat lähde eivätkä käännös: ysymyth/ReAct, noahshinn/reflexion, princeton-nlp/tree-of-thought-llm ja AGI-Edgerunners/Plan-and-Solve-Prompting. Lue promptit noissa repositoryissä; promptit ovat paperit.
Kaksi topologiaa, ja toinen niistä ei tule takaisin
Linkki osioon: Kaksi topologiaa, ja toinen niistä ei tule takaisinNyt varsinainen multi-agent, jossa suurin osa sekaannuksesta elää. On kaksi tapaa, joilla yksi agent voi ottaa toisen mukaan. Ne eivät ole variantteja, ja ero on siinä, kuka on sen jälkeen vastuussa.
Agent työkaluna. Parent kutsuu sitä, saa vastauksen ja jatkaa. Se on luvun 18 työkalurajapinta kokonainen agent takanaan, eikä parent koskaan menetä kontrollia. Tätä yllä oleva orchestrator tekee.
Handoff. Parent siirtää keskustelun eikä saa sitä takaisin. OpenAI:n opas on selkein julkaistu muotoilu: handoffs ovat "one way transfer that allow an agent to delegate to another agent... If an agent calls a handoff function, we immediately start execution on that new agent that was handed off to while also transferring the latest conversation state."8
Sanastovaroitus, koska tämä kompastuttaa ihmisiä jatkuvasti: "handoff" on yhden SDK:n sana, ei standardi. Se on terminologiaa OpenAI Agents SDK:sta ja tuosta oppaasta, joka myös nimeää kaksi asetelmaa "manager" ja "decentralized" ja huomauttaa, että manager-patternissa "edges represent tool calls whereas in the decentralized pattern, edges represent handoffs".8 Tässä tilassa on avoin standardi — A2A, versiossa 1.0.0, Linux Foundationin copyrightilla, versionoidulla julkaisuhistorialla ja dokumentoidulla listalla breaking changes -muutoksista, jonka ilmoitettu periaate on opaque execution: agents "collaborate based on declared capabilities and exchanged information, without needing to share their internal thoughts, plans, or tool implementations".9 Se ei ole handoff, ja vertailu kuuluu lukuun 26. Tässä tärkeää on, että toinen kahdesta sanasta on kirjaston API ja toinen on governancea omaava spesifikaatio.
Erottelu on tietorakenne, ei kaavio:
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;
}Kaksikymmentä riviä, kaksi bugia, jotka muuten löytäisit tuotannosta. reachable löytää agentin, johon kukaan ei pääse — konfiguroitu, maksettu, ei koskaan kutsuttu. conflicts torjuu edgen, joka on molempia lajeja yhtä aikaa, mikä kuulostaa pedanttiselta, kunnes luet sen ääneen: parent sekä pitää kontrollin että antaa sen pois. Aja se viiden agentin järjestelmään, jossa on yksi orpo ja yksi kaksois-edge:
reachable: lead@0 billing@1 tax@1 dunning@1
orphans: ghost
conflicts: lead->taxMitä rajan yli oikeasti kulkee
Linkki osioon: Mitä rajan yli oikeasti kulkeeNyt mittaus, jota varten tämä osio on olemassa, ja luvun ainoa mittaus oikeaa modelia vasten skriptatun sijaan.
Asiakas kertoo rajoitteen ensimmäisessä viestissään — tilimme on rekisteröity Portugaliin, ei Espanjaan; kaikessa veroon liittyvässä pitää käyttää Portugalia — chattaa muusta, ja kysyy sitten laskutuksen vastattavaa kysymystä. Tapaus siirretään. Kaksikymmentäneljä koetta, joka kerta eri maa ja yritys, neljä transfer payloadia, ja vastaanottavalta agentilta kysytään sitten yksi kysymys: missä maassa tämän asiakkaan tili on rekisteröity?
| mitä siirrettiin | keskimääräinen payload | rajoite oli siinä | specialist muisti sen | 95 %:n väli |
|---|---|---|---|---|
| koko keskustelu | 173 tokens | 24/24 | 20/24 — 83 % | 64–93 % |
| summary, jonka lähettävä agent kirjoitti | 62 tokens | 1/24 | 0/24 — 0 % | 0–14 % |
| vain viimeinen käyttäjäviesti | 61 tokens | 0/24 | 0/24 — 0 % | 0–14 % |
| tyypitetty tietue | 69 tokens | 24/24 | 24/24 — 100 % | 86–100 % |
Kolmas rivi on kontrolli ja käyttäytyy kuten kontrolli: fakta ei ole siinä, joten sitä ei voi muistaa. Muut kolme ovat löydös.
Koko transcript on 173 tokens ja toimii 83 % ajasta; sen neljä epäonnistumista ovat luvun 24 aihe eivätkä tämän. Tyypitetty tietue on 69 tokens — seitsemän enemmän kuin summary — ja toimii joka kerta, koska rajoite istuu nimetyn kentän sisällä lauseen sijaan.
Ja summary on rivi, jota pitää tuijottaa. Se epäonnistui 24 kertaa 24:stä, eikä syy ole se, että lukija missasi sen. Rajoite esiintyi ylipäätään vain yhdessä 24 summarysta. Vastaanottava agent ei ollut huolimaton; sille annettiin teksti, jossa vastausta ei ollut. Summary on tiivistys, jota et kirjoittanut, tuotettu modelilla, jonka ikkunaa et voi nähdä, optimoitu näyttämään summarylta — ja "asiakas sanoo, että tietueissamme on väärä maa" on täsmälleen sellainen sivulause, jonka summariser pudottaa prosessimeluna.
Rehellinen raja tuolle numerolle: summariser on puolen miljardin parametrin model, ja suurempi pitäisi enemmän mukana. Se, mikä ei parane koon mukana, on riskin muoto — lähettävä agent päättää per handoff, per muotoilu, havainnoimattomasti, mitkä faktat säilyvät. Tyypitetty tietue ei riipu tuosta arviosta lainkaan, minkä vuoksi se voittaa rakenteen eikä älykkyyden ansiosta. Minkä tahansa täytyy selvitä transferista, sen pitäisi olla kenttä, ei lause.
Sama päättely pätee toiseen suuntaan, agent-as-tool-topologiaan, ja aiempi taulukko hinnoitteli sen jo: workerilta palaava on myös summary, ja 8,3 % enemmän maksaminen evidencen saamiseksi sen mukana on sama korjaus parentin puolelta nähtynä.
Milloin yksi agent voittaa
Linkki osioon: Milloin yksi agent voittaaKolme loppufaktaa, kaikki yllä olevista taulukoista.
Multi-agent system moninkertaistaa kutsut, ja kutsut ovat kvadraattisia contextin suhteen. Orchestrator teki 12 model-kutsua siinä missä yksi agent teki 5, ja jokainen kantaa omaa kasvavaa transcriptiaan — 3,628 input tokens vastaan 2,697, kuilu joka kasvaa tehtävän pituuden mukana.
Jokainen raja on häviöllinen kanava. Kaksi agents tarkoittaa yhtä summarya. Neljä agents ketjussa tarkoittaa kolmea, koostettuna, jokaisen kirjoittanut model, joka optimoi jotain muuta kuin sinun päätöstäsi.
Single agent löysi jotain, mitä kukaan ei pyytänyt. Ostotilausnumeroiden ristiriita nousi esiin, koska yhdessä ikkunassa oli lasku ja tilaus yhtä aikaa. Työn jakaminen specialistien kesken jakaa myös kyvyn huomata, että kaksi faktaa on ristiriidassa.
Mikään tästä ei ole argumentti julkaistuja multi-agent frameworkeja vastaan; ne kannattaa lukea ensisijaisina lähteinä eikä tutorialien kautta.10 Se on argumentti sen puolesta, että toisen agentin on ansaittava paikkansa.
Siis testi, ei mieltymys. Lisää toinen agent, kun vähintään yksi näistä on totta: alitehtävä tarvitsee puhtaan ikkunan, jota parent ei saa periä (luku 24); alitehtävät ovat aidosti itsenäisiä ja wall clock merkitsee, mikä on yllä oleva 1,8×; alitehtävä tarvitsee eri oikeudet tai eri modelin, minkä luku 30 muuttaa turvallisuusargumentiksi; tai alitehtävä on jonkun muun omistama, jolloin oikealla protocolilla alkaa olla väliä. Jos vastaus on "jotta jokaisella agentilla on selkeämpi prompt", anna yhdelle agentille selkeämpi prompt. Se on ilmaista.
Mihin tämä jatkuu
Linkki osioon: Mihin tämä jatkuuOsaat nyt nimetä viisi patternia, hinnoitella ne toisiaan vasten yhdellä tehtävällä, erottaa orchestratorin sectionerista ja tool callin handoffista, ja puolustaa single agentia taulukolla mieltymyksen sijaan.
Jokainen asetelma täällä jakoi yhden mukavuuden, joka ei selviä kosketuksesta minkään oikean kanssa: kaikki työkalut kuuluivat meille. Lasku, tilaus, verotaulukko, workerit orchestratorin takana — sama repository, sama deploy, samat tyypit, samat ihmiset.
Laita nyt yksi niistä yritysrajan toiselle puolelle. Verotaulukko kuuluu kirjanpitotoimittajalle, tilaustietue varastojärjestelmälle, eikä kumpikaan ole lukenut sinun Tool-rajapintaasi. Tarvitset tavan, jolla model, jota et kirjoittanut, voi löytää, kuvata ja kutsua kyvykkyyttä, jota joku muu operoi — authenticationilla (joka on luvun 27 puolikas), versioningilla ja takuulla siitä, ettei server voi lukea loppua keskustelustasi. Se on protocol-ongelma, sillä on spesifikaatio normatiivisella schemalla, ja melkein kaikki siitä indeksoitu kuvaa revisiota, jota ei enää ole.
Luku 26 lukee tuon spesifikaation sen tiivistämisen sijaan ja aloittaa kirjoittamalla JSON-RPC:tä terminaaliin käsin.
Lähteet ja menetelmä
Linkki osioon: Lähteet ja menetelmäJokainen yllä oleva kustannus ja token-määrä tuli toisessa osiossa kuvatulta skriptatulta providerilta, Node 22:lla loopback-rajapinnan yli, laskettuna o200k_base-encodingilla ja hinnoiteltuna hinnoilla, jotka luku 16 luki 6. syyskuuta 2026 — $2.00 per miljoona input tokens ja $12.00 per miljoona output. Wall-clock-luvut ovat samoista ajoista providerin latenssilla 400 ms per kutsu ja työkaluilla 50 ms, joten ne mittaavat asetelmaa eivätkä mitään provideria. Kaksi oikean modelin mittausta — handoff-taulukko ja voting-and-judging-taulukko — käyttivät Qwen/Qwen2.5-0.5B-Instruct float32-muodossa CPU:lla samanmuotoisen endpointin takana, greedy paitsi missä temperature mainitaan, ja välit laskettiin luvun 4 Wilsonin menetelmällä. Mikään tämän luvun pyyntö ei mennyt maksulliseen endpointiin, eikä yhtään lukua arvioitu.
Viitteet
Linkki osioon: Viitteet-
Anthropic, Building effective agents, 19. joulukuuta 2024,
anthropic.com/engineering/building-effective-agents, luettu 7. syyskuuta 2026. Lähde yllä käytetyille viidelle työnkulun nimelle ja jokaiselle niistä lainatulle fraasille — prompt chaining, routing, parallelisation sectioning- ja voting-variantteineen, orchestrator-workers, evaluator-optimiser — sekä suositukselle etsiä "the simplest solution possible, and only increasing complexity when needed" ja havainnolle, että "agentic systems often trade latency and cost for better task performance". Luvut 22 ja 23 siteeraavat sen agent-määritelmää. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 -
Wang, X., Wei, J., Schuurmans, D., Le, Q., Chi, E., Narang, S., Chowdhery, A. ja Zhou, D. Self-Consistency Improves Chain of Thought Reasoning in Language Models. arXiv:2203.11171 (maaliskuu 2022). Voting-patternin alkuperä, siellä kuvattuna decoding-strategiana eikä arkkitehtuurina: näytteistä monipuolisia päättelypolkuja ja sitten "select the most consistent answer by marginalizing out the sampled reasoning paths", raportoiduilla hyödyillä +17,9 GSM8K:ssa, +11,0 SVAMPissa, +12,2 AQuA:ssa, +6,4 StrategyQA:ssa ja +3,9 ARC-challengessa. ↩
-
Madaan, A. et al. Self-Refine: Iterative Refinement with Self-Feedback. arXiv:2303.17651 (2023). Evaluator-optimiser-loop yhdellä modelilla kaikissa kolmessa roolissa — "generator, refiner, and feedback provider" — parantaen "by ~20% absolute on average in task performance" seitsemässä tehtävässä, mitattuna ihmismieltymyksillä ja automaattisilla metriikoilla eikä modelin omalla verdictillä. ↩
-
Shinn, N., Cassano, F., Berman, E., Gopinath, A., Narasimhan, K. ja Yao, S. Reflexion: Language Agents with Verbal Reinforcement Learning. arXiv:2303.11366 (2023). Lisää yritysten yli säilyvän episodic memoryn self-critiques-kritiikeistä — "reinforce language agents not by updating weights, but through linguistic feedback" — raportoiden 91 % pass@1 HumanEvalissa verrattuna GPT-4-baselinen 80 %:iin. Huomaa vaatimus, josta sen tulokset riippuvat: oikea signaali ympäristöstä, kuten epäonnistuva testi, eikä modelin mielipide itsestään. ↩ ↩2
-
Yao, S., Zhao, J., Yu, D., Du, N., Shafran, I., Narasimhan, K. ja Cao, Y. ReAct: Synergizing Reasoning and Acting in Language Models. arXiv:2210.03629 (2022). Lomittaiset reasoning traces ja toiminnot; luku 23 rakensi tämän loopin. Siteerattu tässä kustannusmuodon eikä tulosten vuoksi: yksi model-kutsu per askel, koko transcript lähetettynä uudelleen joka kerta. ↩
-
Wang, L., Xu, W., Lan, Y., Hu, Z., Lan, Y., Lee, R. K.-W. ja Lim, E.-P. Plan-and-Solve Prompting: Improving Zero-Shot Chain-of-Thought Reasoning by Large Language Models. arXiv:2305.04091 (2023). "First, devising a plan to divide the entire task into smaller subtasks, and then carrying out the subtasks according to the plan" — plan-then-execute-muoto ja lähde vaihtokaupalle, josta tämä luku välittää: suunnitelma lukitaan ennen ensimmäistä havaintoa, mikä on prompt chaining purulla, jonka kirjoittaa model sinun sijastasi. ↩
-
Yao, S., Yu, D., Zhao, J., Shafran, I., Griffiths, T. L., Cao, Y. ja Narasimhan, K. Tree of Thoughts: Deliberate Problem Solving with Large Language Models. arXiv:2305.10601 (2023). Haku välillisten "thoughts" yli self-evaluationilla ja backtrackingilla; 74 % Game of 24:ssä vastaan 4 % chain-of-thought promptingille. Yllä siteeratut kustannusluvut ovat paperin omia, liitteestä B.3, taulukosta 7: per tapaus, input/output prompting best-of-100 hintaan $0.13 tuloksella 33 %, chain of thought best-of-100 hintaan $0.47 tuloksella 49 %, ja tree of thoughts hintaan $0.74 tuloksella 74 %, sekä kirjoittajien huomio, että ToT "could require 5-100 times more generated tokens than CoT". ↩ ↩2
-
OpenAI, A practical guide to building agents (PDF), luettu 7. syyskuuta 2026. Manager-versus-decentralised-jako, yllä siteerattu graafikehys ("in the manager pattern, edges represent tool calls whereas in the decentralized pattern, edges represent handoffs") ja handoffin määritelmä "a one way transfer... we immediately start execution on that new agent that was handed off to while also transferring the latest conversation state". Huomaa, mitä tuo viimeinen lause ratkaisee: tässä SDK:ssa keskustelun state kulkee mukana, mikä on tuon kirjaston design-päätös eikä handoffien ominaisuus yleensä. ↩ ↩2
-
Agent2Agent (A2A) Protocol Specification, viimeisin julkaistu versio 1.0.0,
a2a-protocol.org/latest/specification/, luettu 7. syyskuuta 2026; copyright Linux Foundation, Apache-2.0. Yllä siteerattu: "open standard designed to facilitate communication and interoperability between independent, potentially opaque AI agent systems" ja opaque execution -periaate — agents "collaborate based on declared capabilities and exchanged information, without needing to share their internal thoughts, plans, or tool implementations". Sivulla on julkaisuhistoria (0.1.0, 0.2.6, 0.3.0, 1.0.0), appendix breaking changes -muutoksista ja appendix sen suhteesta MCP:hen. Luku 26 tekee tuon vertailun. ↩ -
Multi-agent frameworkit, joita tämä luku ei opeta, lukijalle joka haluaa ensisijaiset lähteet tutorialin sijaan: Wu, Q. et al., AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation, arXiv:2308.08155 (2023), jossa agents ovat "customizable, conversable" ja keskustelu itsessään on ohjelmointimalli; Hong, S. et al., MetaGPT: Meta Programming for a Multi-Agent Collaborative Framework, arXiv:2308.00352 (2023), joka koodaa standard operating procedures rooli-prompteihin ja sanoo suoraan, että "solutions to more complex tasks are complicated through logic inconsistencies due to cascading hallucinations caused by naively chaining LLMs" — tämän luvun alussa mitattu itsevarmasti väärä ketju, nimettynä abstractissa; ja Park, J. S. et al., Generative Agents: Interactive Simulacra of Human Behavior, arXiv:2304.03442 (2023), kaksikymmentäviisi agents muistilla, reflektiolla ja suunnittelulla, mikä on suurin julkaistu vastaus kysymykseen "mitä tapahtuu, jos jatkat agentsien lisäämistä". ↩