Orquestración multi-agent: cinco patróns e cando gaña un só
A mesma factura resolta de catro formas: o orquestrador custou 1,66 veces o agent único e chegou ao mesmo veredicto.
Nesta páxina
O capítulo 24 rematou cunha pregunta que tiña ben gañada: cando un sub-agent se equivoca, que é exactamente o que pode mirar o pai?
Este capítulo respóndea cunha factura. Unha tarefa —un cliente impugna unha factura e quere unha resposta— resolta de catro maneiras, todas executando o harness do capítulo 23 contra o mesmo provedor guionizado, todas contando os mesmos tokens co mesmo codificador, todas taxadas cos prezos que o capítulo 16 leu o 6 de setembro de 2026.
| arranxo | chamadas ao modelo | input tokens | output | custo | wall clock | veredicto |
|---|---|---|---|---|---|---|
| prompt chaining | 4 | 900 | 165 | $0.003780 | 1,648 ms | incorrecto |
| un agent, catro ferramentas | 5 | 2,697 | 179 | $0.007542 | 2,224 ms | correcto |
| seccións en paralelo | 9 | 2,910 | 324 | $0.009708 | 2,165 ms | correcto |
| orchestrator-workers | 12 | 3,628 | 438 | $0.012512 | 5,090 ms | correcto, e non pode demostralo |
Le xuntas a primeira e a última fila: entre elas está todo o debate que agora mesmo ten esta industria. O arranxo máis barato tamén foi o máis rápido e produciu unha resposta segura, incorrecta e lista para enviar. O máis caro acertou, levou 3,3 veces máis diñeiro e 3,1 veces máis reloxo, e rematou citando a conclusión dun traballador que non ten maneira de comprobar.
A fila que ninguén pon nestas táboas é a segunda: un agent coas catro ferramentas chegou ao mesmo veredicto ca o orquestrador polo 60 % do diñeiro e o 44 % do wall clock. Iso non é unha preferencia pola simplicidade. É unha medición, e o resto deste capítulo vai de cando deixa de ser certa.
Mostrar detalles
O que este capítulo necesita dos anteriores.
- Capítulo 18 polo contrato da ferramenta: un esquema que ve o modelo, un endpoint que nunca ve. Un agent enteiro cabe detrás desa interface, que é todo o multi-agent.
- Capítulo 22 polas dúas definicións publicadas de «agent» que discrepan, e pola aritmética de que unha cadea de prompts son N chamadas.
- Capítulo 23 polo bucle, as cinco saídas, o estado da execución e o trace. Cada arranxo de abaixo é ese ficheiro, chamado de maneira distinta.
- Capítulo 24 polo que custa unha xanela e o que cae fóra dela. Un sub-agent é a cuarta das súas catro estratexias, e a única que é un segundo agent en vez dunha política.
Sen tensores. Todo aquí é TypeScript, agás dúas medicións tomadas contra un modelo local real.
A tarefa, e a trampa que leva dentro
Ligazón á sección: A tarefa, e a trampa que leva dentroUnha empresa portuguesa escribe sobre a factura FT-2026-0918. O correo di que o IVE parece incorrecto, e anexa a factura: neto EUR 248.00, IVE cobrado ao 21 %, EUR 52.08, total EUR 300.08.
Os feitos necesarios para responder viven en tres lugares, e só un deles está no correo:
| onde | que di |
|---|---|
| a factura anexada | vendedor en España, IVE aplicado ao 21 %, EUR 52.08 |
| o rexistro do pedido | o comprador está rexistrado en Portugal, cun identificador de IVE válido, empresa a empresa |
| a táboa fiscal | tipo doméstico español 21 %; empresa a empresa intra-UE cun identificador válido, investimento do suxeito pasivo, 0 % |
Xunta os tres e a factura está mal: aplícase o investimento do suxeito pasivo, o IVE debería ser cero, e débese unha factura rectificativa por EUR 52.08. Mira só a factura e é aritmeticamente perfecta —248.00 máis 52.08 son 300.08— e iso dirás.
O correo si afirma «somos unha empresa portuguesa». Iso é unha afirmación, non un rexistro, e ningún sistema de facturación emite unha rectificativa por unha afirmación. A trampa non é un truco: é a forma habitual do traballo empresarial, onde a decisión necesita un feito que a ninguén se lle ocorreu buscar.
Todo o anterior execútase contra un provedor guionizado ao estilo do do capítulo 23, cunha soa regra:
Unha resposta só pode usar un feito que estea no seu prompt.
O «modelo» pide cada ferramenta que ten, unha vez, en orde de catálogo, e logo aplica unha regra fixa ao texto que pode ver. Non hai nada guionizado por arranxo, así que as diferenzas da táboa inicial non son afirmacións sobre a intelixencia do modelo: son enrutamento de información, medido. Un modelo real engade os seus propios fallos por riba; non elimina estes.
Os cinco patróns, nunhas corenta liñas
Ligazón á sección: Os cinco patróns, nunhas corenta liñasOs cinco nomes de abaixo son os de Anthropic, de Building effective agents, que é onde se asentou este vocabulario.1 Ningunha das cinco ideas é nova, e dicir que casa puxo que nome —e que idea é máis antiga— é a metade do valor de coñecelas.
/* 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 };
}Esa é toda a caixa de ferramentas: cinco funcións, ningún framework, e a paralela é unha soa liña —que é precisamente o sentido de escribila en vez de debuxala. Agora unha por unha, coa súa ascendencia, o seu prezo e o caso no que se equivoca.
Chaining, e a decisión que toma por ti
Ligazón á sección: Chaining, e a decisión que toma por tiPrompt chaining «descompón unha tarefa nunha secuencia de pasos, onde cada chamada ao LLM procesa a saída da anterior».1 A idea é anterior aos modelos de linguaxe: é unha pipeline, co intercambio propio da pipeline —claridade a cambio dun fluxo de control fixado antes de que cheguen os datos.
Catro pasos para a nosa tarefa: extraer os campos da factura, comprobar a aritmética, decidir que se debe, escribir a resposta. Aquí falla de dúas maneiras distintas, o que ensina máis ca fallar unha soa vez.
--- 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."A cadea de relevo custou $0.001940 e perdeu os campos da factura entre os pasos dous e tres, porque ao paso tres entregóuselle unha frase sobre aritmética e nada máis. Produciu unha mensaxe de espera: inútil, e visiblemente inútil.
A cadea acumulativa —a fila da táboa inicial— custou $0.003780, que é un 95 % máis por catro chamadas idénticas, porque cada paso agora leva todo o anterior. Produciu a saída perigosa. Fluída, citando a súa aritmética, correcta en cada número que menciona, e dicíndolle a un cliente que non se debe nada cando se deben EUR 52.08.
A diferenza entre as dúas é un ternario. Unha cadea que leva menos produce respostas obviamente incompletas; unha cadea que leva todo produce respostas seguras e incorrectas —e só o segundo tipo se envía.
Ningún dos dous é o fallo real. O fallo real é que a pipeline decidiu, antes de ler nada, que esta tarefa son catro pasos sobre o contido dun correo. En ningures desa estrutura hai un lugar para dicir «o país de rexistro non está neste correo; vai buscalo». Chaining é correcto cando a descomposición se coñece de antemán e é estable. Aquí era unha suposición, e a suposición saíu a produción.
Routing, o máis vello, e o plan B que ninguén escribe
Ligazón á sección: Routing, o máis vello, e o plan B que ninguén escribeRouting «clasifica unha entrada e diríxea a unha tarefa posterior especializada».1 O nome é novo; o mecanismo é o despachador, máis antigo ca case todo o demais deste libro. O novo é que o clasificador pode ser un modelo —e iso é o que fai que falle de formas nas que un switch nunca fallaba.
const answer = await route(email,
(q) => classifyWithSmallModel(q), // cheap model, one call
{ billing: billingAgent, tax: taxAgent, dunning: dunningAgent },
taxAgent, // deterministic, chosen in advance
);Dúas cousas sobre ese último argumento. Non é xestión de erros; é o patrón. Un router baseado en modelo ten un modo de fallo que un despachador non ten: pode devolver unha etiqueta que non existe, esgotar o tempo, ou —a cara— devolver unha etiqueta plausible e incorrecta sen sinal de que o é. As tres teñen que aterrar nalgures, e ese nalgures non pode ser outra chamada ao modelo, porque xa estás na rama na que fallaron as chamadas ao modelo.
A segunda cousa é que o prompt propio do router non é gratis. Para escoller un modelo, un router necesita un catálogo de modelos entre os que escoller, e cada elemento del é input polo que o router paga antes de ler a pregunta do usuario. Á tarifa de input coa que este curso pon os prezos, un catálogo de arredor de 3.800 tokens xa custa tanto como a execución enteira do agent de cinco chamadas da táboa do comezo. Na práctica, a chamada de enrutamento execútase nun modelo barato, que é xustamente a razón pola que o enrutamento se paga a si mesmo; pero paga a pena facer a aritmética nese sentido en vez de dala por suposta. Enrutar é un erro precisamente cando a tarefa enrutada é máis barata que a decisión de enrutamento.
Paralelización: seccións, e votación, que é self-consistency
Ligazón á sección: Paralelización: seccións, e votación, que é self-consistencyAnthropic divide isto en dous: sectioning —«dividir unha tarefa en subtarefas independentes que se executan en paralelo»— e voting —«executar a mesma tarefa varias veces para obter saídas diversas».1 Comparten un diagrama e case nada máis.
Sectioning é a vitoria barata, e é a liña de patterns.ts: tres especialistas —facturación, impostos, política— cada un coa súa propia xanela e ferramentas, sobre o mesmo correo, cunha chamada de síntese ao final. Traballo idéntico, ordenado de dúas maneiras:
| chamadas ao modelo | input | output | custo | wall clock | |
|---|---|---|---|---|---|
| os tres traballadores, un tras outro | 9 | 2,910 | 324 | $0.009708 | 3,894 ms |
os mesmos tres, Promise.all | 9 | 2,910 | 324 | $0.009708 | 2,165 ms |
O mesmo token por token, 1,8 veces máis rápido. Por iso o patrón merece nome propio: é o único dos cinco que mellora algo sen custar nada. A trampa é que as seccións deben ser realmente independentes: dálle á sección B un feito que produce a sección A e Promise.all execútaas ambas contra un estado que aínda non existe. O bucle for ocultaba ese bug; a liña única expóno.
Voting é outro animal vestido coa mesma imaxe. Executar a mesma pregunta k veces e coller a maioría é self-consistency, publicado por Wang et al. en marzo de 2022 como estratexia de decodificación, case tres anos antes de que alguén o chamase patrón de orquestración. O seu resumo é preciso sobre o mecanismo —«primeiro mostraxa un conxunto diverso de camiños de razoamento en vez de tomar só o greedy, e despois selecciona a resposta máis consistente marxinalizando os camiños de razoamento mostraxados»— e sobre a mellora: +17,9 puntos en GSM8K.2
Disto seguen dúas cousas que a imaxe oculta. Primeiro, voting require a mostraxe do capítulo 17: a temperatura cero, todas as k mostras son a mesma mostra, e a maioría é unha resposta pagada k veces. Segundo, só funciona onde unha maioría ten sentido: na resposta á factura de arriba non hai nada que contar, porque cinco borradores son cinco frases distintas. Voting é para tarefas cunha resposta curta e comparable, exactamente os benchmarks de Wang e case nada do que fai un agent orientado a clientes.
Medido aquí en 20 problemas verbais de tres pasos cuxas respostas se calculan en vez de xulgarse, co modelo local do capítulo 23 razoando paso a paso:
| chamadas ao modelo | input | output | custo para os 20 | correcto | intervalo 95 % | |
|---|---|---|---|---|---|---|
| unha cadea greedy | 20 | 1,330 | 2,649 | $0.034448 | 9/20 | 26–66 % |
| maioría de 5, temperatura 0.8 | 100 | 6,650 | 13,245 | $0.172240 | 9/20 | 26–66 % |
Cinco veces as chamadas, cinco veces os tokens, exactamente cinco veces a factura, e nin unha resposta correcta adicional. Voting é unha aposta, non unha mellora, e esta execución perdeuna.
Dúas cautelas, antes de que alguén cite isto como refutación de Wang. Vinte ensaios non distinguen o 45 % do 60 %: o intervalo é da anchura da afirmación, que é a disciplina do capítulo 4 aplicada ao meu propio resultado. E as melloras publicadas veñen de modelos ordes de magnitude maiores, onde os camiños de razoamento diversos sobre os que voting marxinaliza son de verdade diversos. O que se transfire non é o número: é que o multiplicador é exacto e coñecido de antemán mentres que a mellora non o é.
Orchestrator-workers, e o que non é un resumo
Ligazón á sección: Orchestrator-workers, e o que non é un resumoNo fluxo orchestrator-workers «un LLM central descompón dinamicamente tarefas, delegaas en LLMs traballadores e sintetiza os seus resultados», e a diferenza co sectioning é que «as subtarefas non están predefinidas, senón determinadas polo orquestrador».1 A ascendencia aquí non vén dos modelos de linguaxe: isto é master-worker, e a versión na que os traballadores escriben achados nun espazo compartido que le un controlador é a arquitectura blackboard, da investigación en comprensión da fala dos anos 70. O novo en 2026 é que o controlador é un modelo e, polo tanto, a descomposición pode decidirse por entrada —a flexibilidade e o custo nunha soa frase.
Custou 12 chamadas ao modelo fronte ás 5 do agent único, e chegou ao mesmo veredicto. Logo fixo algo que paga a pena mirar de preto:
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-4471Ambas son correctas. Só unha sabe por que. O traballador fiscal tiña a factura, o pedido e a táboa fiscal na súa propia xanela, chegou á conclusión, e tamén detectou —ninguén llo pedira— que o número de orde de compra da factura non coincide co do pedido. Logo devolveu un resumo. O orquestrador pode repetir ambas afirmacións e non comprobar ningunha, porque a evidencia quedou nunha xanela que nunca viu. Esa é a pregunta final do capítulo 24, respondida: o pai pode mirar o que o fillo decidiu escribir.
A corrección é unha bandeira, e ten un prezo:
| o que devolve o traballador | input tokens do orquestrador | custo | que pode facer o pai |
|---|---|---|---|
| a súa conclusión | 3,628 | $0.012512 | repetila |
| a súa conclusión e a súa evidencia | 4,065 | $0.013554 | derivalo de novo, e discrepar |
Doce por cento máis de input tokens, 8,3 % máis diñeiro, e a frase source=worker_unverified desaparece da resposta. Ese é o intercambio en cada sistema multi-agent e case nunca se explicita: a xanela limpa do fillo paga a pena, a capacidade do pai de auditala paga a pena pagala, e non podes ter ambas gratis.
Entón, cando é incorrecto orchestrator-workers? Aquí, nesta tarefa. Mercou unha resposta correcta que un agent coas mesmas catro ferramentas tamén alcanzou, por 1,66 veces o custo e 2,3 veces o wall clock, e fixo que esa resposta fose máis difícil de defender. A propia guía de Anthropic di o mesmo antes de empezar cos patróns: atopar «a solución máis simple posible, e só aumentar a complexidade cando sexa necesario», porque «os sistemas agentic adoitan intercambiar latencia e custo por mellor rendemento da tarefa».1 As táboas de arriba son esa frase con números debaixo.
Evaluator-optimiser, e o xuíz que escribiu o exame
Ligazón á sección: Evaluator-optimiser, e o xuíz que escribiu o exameUnha chamada xera, outra avalía, e o bucle repítese ata que a avaliación pasa.1 Os devanceiros publicados son Self-Refine —o mesmo modelo como «generator, refiner, and feedback provider», con arredor de 20 puntos de mellora absoluta de media en sete tarefas3— e Reflexion, que garda a crítica nun búfer episódico entre intentos e informa dun 91 % pass@1 en HumanEval onde a liña base alcanzaba o 80 %.4
O modelo de custo é o máis simple dos cinco: dúas chamadas por rolda, e o número de roldas non é teu. Tres roldas de refinamento nunha tarefa que levaba unha chamada son seis chamadas, así que o chan do patrón é 6× e o seu teito é o límite que poñas —o que fai que a saída por orzamento do capítulo 23 sexa obrigatoria, non simplemente ordeada.
O teito é máis sutil, e é medible. Nos mesmos 20 problemas, o modelo local respondeu correctamente 9. Despois amosáronselle cada unha desas respostas e preguntóuselle se era correcta —sen dicirlle que era súa, o que elimina o sesgo de adulación e deixa o de capacidade:
| a resposta propia do modelo | dixo «si» | dixo «non» |
|---|---|---|
| as 9 que eran correctas | 9 | 0 |
| as 11 que eran incorrectas | 3 | 8 |
É un xuíz mellor do que suxire o título da sección, e dicilo é precisamente o sentido de medir en vez de afirmar: non bloqueou nada correcto e pillou 8 de 11 erros. Como filtro, vale as súas chamadas.
Como regra de parada, que é para o que realmente usa isto un bucle evaluator-optimiser, esas tres aprobacións son toda a historia: rematan o bucle cunha resposta incorrecta na man, e ningunha cantidade de roldas extra chega nunca a elas. Un bucle de refinamento non pode volverse máis correcto ca o seu xuíz. Mercar máis roldas compra intentos sobre os erros que o xuíz pode ver, a prezo completo, e nada de nada contra os que non pode.
Daquela a regra: un avaliador gaña as súas chamadas só cando ten algo que o xerador non ten. Un compilador, unha suite de tests, un validador de esquema, un modelo distinto, unha persoa. Os propios resultados de Self-Refine mídense contra preferencia humana e métricas de tarefa, nunca contra a opinión do modelo sobre si mesmo. Se a única vantaxe do teu avaliador é un prompt distinto, estás pagando o dobre por acordo. O capítulo 29 constrúe a versión cunha vantaxe real: un conxunto dourado coas respostas escritas de antemán.
Os bucles non son os patróns
Ligazón á sección: Os bucles non son os patrónsOs cinco anteriores son formas para o teu código. Por baixo deles hai unha segunda familia que adoita listarse canda eles e non debería: ReAct, Reflexion, plan-and-execute e tree of thoughts son bucles de razoamento, e o seu custo está nas solicitudes.
O capítulo 12 trataba do razoamento dentro do modelo, que pagas en output tokens nunha chamada. Este é o outro tipo. A diferenza importa cando chega a factura: unha chain of thought máis longa fai máis cara unha chamada, e un bucle de razoamento converte unha tarefa en moitas chamadas, cada unha das cales reenvía todo o anterior —o cuadrático que o capítulo 23 mediu na súa táboa desbocada.
| bucle | chamadas, por tarefa | que compran as chamadas extra |
|---|---|---|
| ReAct | unha por paso, ata que para | o modelo reacciona ao que devolveron as ferramentas5 |
| plan-and-execute | unha para planificar, logo unha por paso | o plan fíxase antes de executar o primeiro paso6 |
| Reflexion | intentos × (act + reflect) | a crítica sobrevive ata o seguinte intento4 |
| tree of thoughts | factor de ramificación × profundidade, máis unha avaliación por nodo | busca, con backtracking7 |
O paper de tree-of-thoughts publica a súa propia táboa de custos, algo máis raro do que debería ser. En Game of 24 con GPT-4: input/output prompting best-of-100 resolveu o 33 % a $0.13 por caso, chain of thought best-of-100 resolveu o 49 % a $0.47, e tree of thoughts resolveu o 74 % a $0.74, cos autores sinalando que «could require 5-100 times more generated tokens than CoT».7
Case seis veces o prezo do método barato por algo máis do dobre de taxa de éxito. Que iso sexa unha ganga depende de canto che custa un caso fallido —a pregunta que debes facer antes de adoptar calquera destes catro.
Este curso non os reimplementa. Os catro teñen implementacións de referencia dos seus propios autores, en Python, e o seu valor é seren a fonte en vez dunha tradución: ysymyth/ReAct, noahshinn/reflexion, princeton-nlp/tree-of-thought-llm e AGI-Edgerunners/Plan-and-Solve-Prompting. Le os prompts neses repositorios; os prompts son os papers.
Dúas topoloxías, e unha delas non volve
Ligazón á sección: Dúas topoloxías, e unha delas non volveAgora o multi-agent propiamente dito, onde vive a maior parte da confusión. Hai dúas maneiras de que un agent implique outro, non son variantes, e a diferenza é quen queda ao mando despois.
Agent como ferramenta. O pai chámao, recibe unha resposta e continúa. É a interface de ferramenta do capítulo 18 cun agent enteiro detrás, e o pai nunca perde o control. Isto é o que fai o orquestrador de arriba.
Handoff. O pai transfire a conversa e non a recupera. A guía de OpenAI é a formulación publicada máis clara: os handoffs son «a 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
Un aviso de vocabulario, porque isto fai tropezar a xente constantemente: «handoff» é a palabra dun SDK, non un estándar. É terminoloxía do OpenAI Agents SDK e desa guía, que tamén chama aos dous arranxos «manager» e «decentralized» e sinala que no patrón manager «edges represent tool calls whereas in the decentralized pattern, edges represent handoffs».8 Si hai un estándar aberto neste espazo —A2A, na versión 1.0.0, baixo copyright da Linux Foundation, cun historial de versións e unha lista documentada de cambios incompatibles, cuxo principio declarado é opaque execution: os agents «collaborate based on declared capabilities and exchanged information, without needing to share their internal thoughts, plans, or tool implementations».9 Iso non é un handoff, e a comparación corresponde ao capítulo 26. O que importa aquí é que unha das dúas palabras é a API dunha biblioteca e a outra é unha especificación con gobernanza.
A distinción é unha estrutura de datos, non un diagrama:
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;
}Vinte liñas, dous bugs que doutro xeito atoparías en produción. reachable atopa o agent ao que ninguén pode chegar —configurado, pagado, nunca chamado. conflicts rexeita a aresta que é dos dous tipos á vez, o que soa pedante ata que o les en voz alta: o pai á vez conserva o control e entrégao. Execútao nun sistema de cinco agents cun orfo e unha aresta dobre:
reachable: lead@0 billing@1 tax@1 dunning@1
orphans: ghost
conflicts: lead->taxQue cruza realmente a fronteira
Ligazón á sección: Que cruza realmente a fronteiraAgora a medición pola que existe esta sección, e a única do capítulo tomada contra un modelo real en vez dun guionizado.
Un cliente expresa unha restrición na súa primeira mensaxe —a nosa conta está rexistrada en Portugal, non en España; todo o relacionado con impostos ten que usar Portugal— conversa sobre outra cousa e despois fai unha pregunta que facturación debe responder. O caso transfírese. Vinte e catro ensaios, un país e unha empresa distintos cada vez, catro payloads de transferencia, e logo ao agent receptor fáiselle unha pregunta: en que país está rexistrada a conta deste cliente?
| que se transferiu | payload medio | a restrición estaba nel | o especialista lembrouna | intervalo 95 % |
|---|---|---|---|---|
| a conversa completa | 173 tokens | 24/24 | 20/24 — 83 % | 64–93 % |
| un resumo escrito polo agent emisor | 62 tokens | 1/24 | 0/24 — 0 % | 0–14 % |
| só a última mensaxe do usuario | 61 tokens | 0/24 | 0/24 — 0 % | 0–14 % |
| un rexistro tipado | 69 tokens | 24/24 | 24/24 — 100 % | 86–100 % |
A terceira fila é un control e compórtase como tal: o feito non está aí, así que non pode lembrarse. As outras tres son o achado.
A transcrición completa ten 173 tokens e funciona o 83 % das veces; os seus catro fallos son asunto do capítulo 24 máis ca deste. O rexistro tipado son 69 tokens —sete máis ca o resumo— e funciona sempre, porque a restrición está nun campo con nome en vez dunha frase.
E a fila do resumo é a que hai que mirar fixamente. Fallou 24 veces de 24, e a razón non é que o lector a pasase por alto. A restrición apareceu só en 1 dos 24 resumos. O agent receptor non foi descoidado; entregóuselle un texto que non contiña a resposta. Un resumo é unha compactación que ti non escribiches, producida por un modelo cuxa xanela non podes ver, optimizada para lerse como un resumo —e «o cliente di que os nosos rexistros teñen o país mal» é exactamente o tipo de cláusula que un resumidor solta como ruído procedimental.
Un límite honesto dese número: o resumidor é un modelo de medio billón de parámetros e un máis grande retería máis. O que non mellora co tamaño é a forma do risco: o agent emisor decide, por handoff, por formulación, de maneira non observable, que feitos sobreviven. O rexistro tipado non depende dese xuízo en absoluto, e por iso gaña por construción, non por intelixencia. Todo o que deba sobrevivir a unha transferencia debería ser un campo, non unha frase.
O mesmo razoamento aplícase na outra dirección, á topoloxía agent-as-tool, e a táboa anterior xa lle puxo prezo: o que volve dun traballador tamén é un resumo, e pagar un 8,3 % máis para recibir a evidencia con el é a mesma corrección vista desde o lado do pai.
Cando gaña un agent
Ligazón á sección: Cando gaña un agentTres feitos finais, todos das táboas anteriores.
Un sistema multi-agent multiplica chamadas, e as chamadas son cuadráticas no contexto. O orquestrador fixo 12 chamadas ao modelo onde un agent fixo 5, e cada unha leva a súa propia transcrición crecente: 3,628 input tokens fronte a 2,697, unha fenda que se amplía coa lonxitude da tarefa.
Cada fronteira é unha canle con perdas. Dous agents significan un resumo. Catro agents nunha cadea significan tres, compostos, cada un escrito por un modelo que optimiza para algo distinto da túa decisión.
O agent único atopou algo que ninguén pedira. A discrepancia da orde de compra apareceu porque unha xanela tiña á vez a factura e o pedido. Dividir o traballo entre especialistas tamén divide a capacidade de notar que dous feitos discrepan.
Nada disto argumenta contra os frameworks multi-agent publicados, que paga a pena ler como fontes primarias e non a través de titoriais.10 Argumenta por facer que o segundo agent gañe o seu lugar.
Así que unha proba, non unha preferencia. Engade un segundo agent cando polo menos unha destas cousas sexa certa: a subtarefa necesita unha xanela limpa que o pai non debe herdar (capítulo 24); as subtarefas son realmente independentes e o wall clock importa, que é o 1,8× de arriba; a subtarefa necesita permisos distintos ou un modelo distinto, que o capítulo 30 converte nun argumento de seguridade; ou a subtarefa é propiedade doutra persoa, que é onde un protocolo real empeza a importar. Se a resposta é «para que cada agent teña un prompt máis claro», dálle ao único agent un prompt máis claro. É gratis.
A onde vai isto agora
Ligazón á sección: A onde vai isto agoraAgora podes nomear os cinco patróns, poñerlles prezo uns fronte a outros nunha tarefa, distinguir un orquestrador dun sectioner e unha chamada de ferramenta dun handoff, e defender un agent único cunha táboa en vez dunha preferencia.
Todos os arranxos de aquí compartían unha comodidade que non sobrevivirá ao contacto con nada real: todas as ferramentas eran nosas. Factura, pedido, táboa fiscal, os traballadores detrás do orquestrador —o mesmo repositorio, o mesmo deploy, os mesmos tipos, a mesma xente.
Agora pon unha delas ao outro lado dunha fronteira empresarial. A táboa fiscal pertence a un provedor contable, o rexistro do pedido a un sistema de almacén, e ningún dos dous leu a túa interface Tool. Necesitas unha maneira de que un modelo que ti non escribiches descubra, describa e chame unha capacidade que opera outra persoa —con autenticación (que é a metade do capítulo 27), versionado, e a garantía de que un servidor non pode ler o resto da túa conversa. Iso é un problema de protocolo, ten unha especificación cun esquema normativo, e case todo o indexado sobre el describe unha revisión que xa non existe.
O capítulo 26 le esa especificación en vez de resumila, e empeza escribindo JSON-RPC nun terminal á man.
Fontes e método
Ligazón á sección: Fontes e métodoCada custo e reconto de tokens anterior veu do provedor guionizado descrito na segunda sección, en Node 22 sobre unha interface loopback, contando coa codificación o200k_base e cos prezos das tarifas que o capítulo 16 leu o 6 de setembro de 2026: $2.00 por millón de input tokens e $12.00 por millón de output. As cifras de wall-clock son das mesmas execucións coa latencia do provedor fixada en 400 ms por chamada e as ferramentas en 50 ms, así que miden o arranxo e non ningún provedor. As dúas medicións con modelo real —a táboa de handoff e a táboa de voting e xuízo— usaron Qwen/Qwen2.5-0.5B-Instruct en float32 na CPU detrás dun endpoint da mesma forma, greedy agás onde se indica unha temperatura, con intervalos calculados polo método de Wilson do capítulo 4. Ningunha solicitude deste capítulo foi a un endpoint de pago, e ningún número nel foi estimado.
Referencias
Ligazón á sección: Referencias-
Anthropic, Building effective agents, 19 de decembro de 2024,
anthropic.com/engineering/building-effective-agents, lido o 7 de setembro de 2026. Fonte dos cinco nomes de workflows usados arriba e de cada frase citada deles —prompt chaining, routing, parallelisation coas súas variantes sectioning e voting, orchestrator-workers, evaluator-optimiser— así como da recomendación de atopar «the simplest solution possible, and only increasing complexity when needed» e da observación de que «agentic systems often trade latency and cost for better task performance». Os capítulos 22 e 23 citan a súa definición de agent. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 -
Wang, X., Wei, J., Schuurmans, D., Le, Q., Chi, E., Narang, S., Chowdhery, A. e Zhou, D. Self-Consistency Improves Chain of Thought Reasoning in Language Models. arXiv:2203.11171 (marzo de 2022). A orixe do patrón voting, descrito alí como unha estratexia de decodificación en vez dunha arquitectura: mostraxar camiños de razoamento diversos, logo «select the most consistent answer by marginalizing out the sampled reasoning paths», con melloras reportadas de +17,9 en GSM8K, +11,0 en SVAMP, +12,2 en AQuA, +6,4 en StrategyQA e +3,9 en ARC-challenge. ↩
-
Madaan, A. et al. Self-Refine: Iterative Refinement with Self-Feedback. arXiv:2303.17651 (2023). O bucle evaluator-optimiser cun modelo nos tres papeis —«generator, refiner, and feedback provider»— que mellora «by ~20% absolute on average in task performance» ao longo de sete tarefas, medido por preferencia humana e métricas automáticas en vez de polo veredicto do propio modelo. ↩
-
Shinn, N., Cassano, F., Berman, E., Gopinath, A., Narasimhan, K. e Yao, S. Reflexion: Language Agents with Verbal Reinforcement Learning. arXiv:2303.11366 (2023). Engade unha memoria episódica de autocríticas entre intentos —«reinforce language agents not by updating weights, but through linguistic feedback»— e informa dun 91 % pass@1 en HumanEval fronte ao 80 % da liña base GPT-4. Observa o requisito do que dependen os seus resultados: un sinal real do contorno, como un test que falla, en vez da opinión do modelo sobre si mesmo. ↩ ↩2
-
Yao, S., Zhao, J., Yu, D., Du, N., Shafran, I., Narasimhan, K. e Cao, Y. ReAct: Synergizing Reasoning and Acting in Language Models. arXiv:2210.03629 (2022). Trazas de razoamento e accións entrelazadas; o capítulo 23 construíu este bucle. Citado aquí pola súa forma de custo máis ca polos seus resultados: unha chamada ao modelo por paso, coa transcrición completa reenviada cada vez. ↩
-
Wang, L., Xu, W., Lan, Y., Hu, Z., Lan, Y., Lee, R. K.-W. e 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» —a forma plan-then-execute, e a fonte do intercambio que importa neste capítulo: o plan fíxase antes de que chegue a primeira observación, que é prompt chaining coa descomposición escrita por un modelo en vez de por ti. ↩
-
Yao, S., Yu, D., Zhao, J., Shafran, I., Griffiths, T. L., Cao, Y. e Narasimhan, K. Tree of Thoughts: Deliberate Problem Solving with Large Language Models. arXiv:2305.10601 (2023). Busca sobre «thoughts» intermedios con autoavaliación e backtracking; 74 % en Game of 24 fronte ao 4 % de chain-of-thought prompting. As cifras de custo citadas arriba son as do propio paper, do Appendix B.3, Table 7: por caso, input/output prompting best-of-100 a $0.13 para 33 %, chain of thought best-of-100 a $0.47 para 49 %, e tree of thoughts a $0.74 para 74 %, coa nota dos autores de que ToT «could require 5-100 times more generated tokens than CoT». ↩ ↩2
-
OpenAI, A practical guide to building agents (PDF), lido o 7 de setembro de 2026. A división manager fronte a decentralised, o framing de grafo citado arriba («in the manager pattern, edges represent tool calls whereas in the decentralized pattern, edges represent handoffs»), e a definición dun handoff como «a one way transfer... we immediately start execution on that new agent that was handed off to while also transferring the latest conversation state». Observa o que resolve esa última cláusula: neste SDK o estado da conversa si viaxa, que é unha decisión de deseño desa biblioteca e non unha propiedade dos handoffs en xeral. ↩ ↩2
-
Agent2Agent (A2A) Protocol Specification, última versión publicada 1.0.0,
a2a-protocol.org/latest/specification/, lido o 7 de setembro de 2026; copyright da Linux Foundation, Apache-2.0. Citado arriba: un «open standard designed to facilitate communication and interoperability between independent, potentially opaque AI agent systems», e o principio de opaque execution: os agents «collaborate based on declared capabilities and exchanged information, without needing to share their internal thoughts, plans, or tool implementations». A páxina inclúe un historial de versións (0.1.0, 0.2.6, 0.3.0, 1.0.0), un apéndice de cambios incompatibles e un apéndice sobre a súa relación con MCP. O capítulo 26 fai esa comparación. ↩ -
Os frameworks multi-agent que este capítulo non ensina, para quen queira as fontes primarias en vez dun titorial: Wu, Q. et al., AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation, arXiv:2308.08155 (2023), onde os agents son «customizable, conversable» e a propia conversa é o modelo de programación; Hong, S. et al., MetaGPT: Meta Programming for a Multi-Agent Collaborative Framework, arXiv:2308.00352 (2023), que codifica procedementos operativos estándar en prompts de rol e é explícito en que «solutions to more complex tasks are complicated through logic inconsistencies due to cascading hallucinations caused by naively chaining LLMs» —a cadea segura e incorrecta medida ao comezo deste capítulo, nomeada nun resumo—; e Park, J. S. et al., Generative Agents: Interactive Simulacra of Human Behavior, arXiv:2304.03442 (2023), vinte e cinco agents con memoria, reflexión e planificación, que é a maior resposta publicada a «que pasa se segues engadindo agents». ↩