본문으로 건너뛰기
25/3030개 중 25장

Multi-Agent 오케스트레이션: 다섯 가지 패턴과 승리하는 순간

같은 인보이스를 네 가지 방식으로 해결하고 비용을 비교했습니다. orchestrator는 단일 agent의 1.66배 비용으로 같은 결론에 도달했습니다.

이 페이지에서

24장은 스스로 얻어낸 질문으로 끝났습니다. sub-agent가 틀렸을 때, parent는 정확히 무엇을 들여다볼 수 있을까요?

이 장은 그 질문에 청구서로 답합니다. 한 가지 작업 — 고객이 인보이스에 이의를 제기하고 답장을 원한다 — 을 네 가지 방식으로 풀었습니다. 모두 같은 scripted provider를 대상으로 23장 harness를 실행했고, 모두 같은 encoder로 같은 tokens를 세었으며, 모두 16장이 2026년 9월 6일에 읽은 요율로 가격을 매겼습니다.

구성model callsinput tokensoutputcostwall clockverdict
prompt chaining4900165$0.0037801,648 ms틀림
agent 하나, 도구 네 개52,697179$0.0075422,224 ms맞음
병렬 섹션92,910324$0.0097082,165 ms맞음
orchestrator-workers123,628438$0.0125125,090 ms맞음, 그리고 증명할 수 없음

첫 행과 마지막 행을 함께 읽어보세요. 그 사이에 이 업계가 지금 벌이고 있는 모든 논쟁이 들어 있습니다. 가장 싼 구성은 가장 빠르기도 했고, 자신감 있고 틀렸으며 그대로 보낼 수 있는 답을 만들었습니다. 가장 비싼 구성은 맞혔지만 비용은 3.3배, 시간은 3.1배 들었고, 마지막에는 자신이 검증할 방법이 없는 worker의 결론을 인용했습니다.

이런 표에 아무도 넣지 않는 행은 두 번째입니다. 네 도구를 가진 agent 하나는 orchestrator와 같은 verdict에 도달했고, 비용은 60 %, wall clock은 44 %였습니다. 이것은 단순함에 대한 선호가 아닙니다. 측정값입니다. 이 장의 나머지는 언제 이 사실이 더 이상 참이 아니게 되는지에 관한 이야기입니다.

세부 정보 보기

이 장이 앞선 장들에서 필요로 하는 것.

  • **18장**은 도구 계약을 위해 필요합니다. model이 보는 schema와, model이 절대 보지 않는 endpoint입니다. agent 하나 전체가 그 interface 뒤에 들어갈 수 있고, 그것이 multi-agent의 전부입니다.
  • **22장**은 서로 맞지 않는 두 가지 공개된 “agent” 정의와, prompt 체인이 N calls라는 산술을 위해 필요합니다.
  • 23장은 loop, 다섯 가지 탈출 방법, run state와 trace를 위해 필요합니다. 아래의 모든 구성은 같은 파일을 다르게 호출한 것입니다.
  • 24장은 window의 비용과 그 밖으로 떨어져 나가는 것들을 위해 필요합니다. sub-agent는 네 가지 전략 중 네 번째이며, policy가 아니라 두 번째 agent인 유일한 전략입니다.

텐서는 없습니다. 실제 local model을 대상으로 한 두 가지 측정을 제외하면, 여기의 모든 것은 TypeScript입니다.

작업, 그리고 그 안의 함정

섹션 링크: 작업, 그리고 그 안의 함정

한 포르투갈 회사가 인보이스 FT-2026-0918에 대해 문의합니다. 이메일에는 VAT가 잘못된 것 같다고 쓰여 있고, 첨부된 인보이스에는 순액 EUR 248.00, VAT 21 %로 부과된 EUR 52.08, 총액 EUR 300.08이 적혀 있습니다.

답변에 필요한 사실은 세 곳에 있고, 그중 이메일 안에 있는 것은 하나뿐입니다.

위치적힌 내용
첨부 인보이스판매자는 스페인, VAT 21 % 적용, EUR 52.08
주문 기록구매자는 포르투갈에 등록되어 있고, 유효한 VAT identifier가 있으며, business-to-business
세율표스페인 국내 세율 21 %; EU 역내 business-to-business이고 유효한 identifier가 있으면 reverse charge, 0 %

셋을 합치면 인보이스는 틀렸습니다. reverse charge가 적용되므로 VAT는 0이어야 했고, EUR 52.08에 대한 credit note가 필요합니다. 인보이스만 보면 산술적으로 완벽합니다 — 248.00 더하기 52.08은 300.08입니다 — 그래서 그렇게 말하게 됩니다.

이메일에는 “우리는 포르투갈 회사입니다”라고 적혀 있기는 합니다. 그러나 그것은 주장이지 기록이 아닙니다. 어떤 billing system도 주장만으로 credit note를 발행하지 않습니다. 함정은 속임수가 아닙니다. 이것은 비즈니스 업무의 평범한 형태입니다. 결정에는 아무도 가져와야 한다고 생각하지 않은 사실이 필요합니다.

위의 모든 것은 23장의 방식과 같은 scripted provider를 대상으로 실행되며, 규칙은 정확히 하나입니다.

답변은 prompt 안에 있는 사실만 사용할 수 있다.

“model”은 자신이 가진 각 도구를 catalogue 순서대로 한 번씩 요청한 뒤, 볼 수 있는 텍스트에 고정된 규칙을 적용합니다. 구성별로 script된 것은 없습니다. 따라서 첫 표의 차이는 model 지능에 대한 주장이 아닙니다. 측정된 정보 routing입니다. 실제 model은 여기에 자기 실패를 더할 뿐, 이것을 제거하지 않습니다.

다섯 가지 패턴, 약 40줄로

섹션 링크: 다섯 가지 패턴, 약 40줄로

아래 다섯 이름은 Anthropic의 Building effective agents에서 온 것이며, 이 어휘가 정착한 곳입니다.1 다섯 아이디어 중 새로운 것은 없습니다. 누가 무엇에 어떤 이름을 붙였는지 — 그리고 어떤 아이디어가 더 오래되었는지 — 를 말하는 것이 이들을 아는 가치의 절반입니다.

patterns.tsTS
/* 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 };
}

이것이 전체 toolkit입니다. 다섯 함수, framework 없음, 그리고 parallel은 한 줄입니다. 그게 그림으로 그리지 않고 직접 적어보는 이유입니다. 이제 각각을 차례로, 그 계보와 가격, 그리고 틀리는 경우와 함께 보겠습니다.

Chaining, 그리고 당신 대신 내려지는 결정

섹션 링크: Chaining, 그리고 당신 대신 내려지는 결정

Prompt chaining은 “작업을 단계의 sequence로 분해하며, 각 LLM call이 이전 call의 output을 처리”합니다.1 이 아이디어는 language model보다 오래되었습니다. pipeline입니다. 그리고 pipeline의 거래는 데이터가 도착하기 전에 고정된 control flow와 맞바꾼 명확성입니다.

우리 작업에는 네 단계가 있습니다. 인보이스 필드 추출, 산술 확인, 무엇이 owed인지 결정, 답장 작성. 여기서는 두 가지 다른 방식으로 실패하는데, 한 번 실패하는 것보다 더 많은 것을 가르쳐 줍니다.

TEXT
--- 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."

relay chain은 $0.001940이 들었고 2단계와 3단계 사이에서 인보이스 필드를 잃었습니다. 3단계에는 산술에 관한 문장 하나만 전달되었기 때문입니다. 결과는 보류 메시지였습니다. 쓸모없고, 눈에 띄게 쓸모없었습니다.

누적 chain — 첫 표의 행 — 은 $0.003780이 들었습니다. 동일한 네 calls에 대해 95 % 더 비쌌습니다. 이제 모든 단계가 앞의 모든 것을 들고 다니기 때문입니다. 이 방식은 위험한 output을 만들었습니다. 유창하고, 자기 산술을 인용하며, 언급한 모든 숫자에서는 맞고, EUR 52.08이 owed인데 고객에게 owed된 것이 없다고 말합니다.

둘의 차이는 ternary 하나입니다. 덜 들고 다니는 chain은 명백히 불완전한 답을 만들고, 모든 것을 들고 다니는 chain은 자신 있게 틀린 답을 만듭니다 — 그리고 실제로 보내지는 것은 두 번째 종류뿐입니다.

진짜 실패는 둘 중 어느 것도 아닙니다. 진짜 실패는 pipeline이 무엇을 읽기도 전에 이 작업이 이메일 내용 위의 네 단계라고 결정했다는 점입니다. 그 구조 안에는 “등록 국가는 이 이메일에 없다. 가서 가져와라”라고 말할 자리가 없습니다. Chaining은 분해가 미리 알려져 있고 안정적일 때 맞습니다. 여기서는 추측이었고, 그 추측이 배포되었습니다.

Routing, 가장 오래된 것, 그리고 아무도 쓰지 않는 plan B

섹션 링크: Routing, 가장 오래된 것, 그리고 아무도 쓰지 않는 plan B

Routing은 “input을 분류하고 특화된 후속 작업으로 보냅니다”.1 이름은 새롭지만 mechanism은 dispatcher이며, 이 책의 거의 모든 것보다 오래되었습니다. 새로워진 것은 classifier가 model일 수 있다는 점입니다. 바로 그래서 switch에는 없던 방식으로 실패합니다.

route.tsTS
const answer = await route(email,
  (q) => classifyWithSmallModel(q),          // cheap model, one call
  { billing: billingAgent, tax: taxAgent, dunning: dunningAgent },
  taxAgent,                                  // deterministic, chosen in advance
);

마지막 인자에 대해 두 가지를 말해야 합니다. 그것은 error handling이 아닙니다. 그것이 pattern입니다. model-based router에는 dispatcher에 없는 failure mode가 있습니다. 존재하지 않는 label을 반환할 수 있고, timeout될 수 있으며, 비싼 경우로는 그럴듯하지만 틀린 label을 아무 신호 없이 반환할 수 있습니다. 세 경우 모두 어딘가로 떨어져야 하고, 그 어딘가는 또 다른 model call일 수 없습니다. 이미 model calls가 실패한 branch에 있기 때문입니다.

두 번째는 router 자신의 prompt도 공짜가 아니라는 점입니다. model을 고르려면 router에는 고를 수 있는 model catalogue가 필요하고, 그 안의 모든 entry는 router가 사용자의 질문을 읽기도 전에 비용을 치르는 input입니다. 이 course가 가격을 매기는 input rate로 보면, 약 3,800 tokens의 catalogue만으로도 이미 첫머리 표에 나온 5-call agent run 전체만큼의 비용이 듭니다. 실제로는 routing call이 저렴한 model에서 실행되며, 바로 그것이 routing이 제값을 하는 이유 전부입니다. 하지만 이 산수는 가정하기보다 그 방향으로 직접 해볼 가치가 있습니다. routing이 틀린 선택이 되는 것은 정확히 route된 task가 routing decision보다 쌀 때입니다.

Parallelisation: 섹션, 그리고 voting, 즉 self-consistency

섹션 링크: Parallelisation: 섹션, 그리고 voting, 즉 self-consistency

Anthropic은 이것을 둘로 나눕니다. sectioning — “작업을 독립적인 subtasks로 나누어 parallel 실행” — 과 voting — “같은 작업을 여러 번 실행해 다양한 outputs를 얻기”입니다.1 둘은 diagram을 공유하지만 그 외에는 거의 아무것도 공유하지 않습니다.

Sectioning은 저렴한 승리이며, patterns.ts의 한 줄입니다. billing, tax, policy라는 세 specialists가 각자의 window와 tools를 가지고 같은 이메일을 보고, 마지막에 synthesis call 하나가 붙습니다. 동일한 work를 두 가지 순서로 실행했습니다.

model callsinputoutputcostwall clock
세 workers, 하나씩 순서대로92,910324$0.0097083,894 ms
같은 세 개, Promise.all92,910324$0.0097082,165 ms

token 단위로 동일하고, 1.8배 빠릅니다. 그래서 이 pattern은 자기 이름을 얻을 자격이 있습니다. 다섯 중 무언가를 개선하면서 아무 비용도 더 들지 않는 유일한 pattern입니다. 단, 섹션들은 진짜로 독립적이어야 합니다. section A가 만드는 사실을 section B에 주면 Promise.all는 아직 존재하지 않는 state를 상대로 둘 다 실행합니다. for loop는 그 버그를 숨겼고, 한 줄짜리는 그것을 드러냅니다.

Voting은 같은 그림을 입은 다른 동물입니다. 같은 질문을 k번 실행하고 majority를 취하는 것은 self-consistency입니다. Wang 등이 2022년 3월 decoding strategy로 발표했으며, 누군가 이것을 orchestration pattern이라고 부르기 거의 3년 전입니다. 초록은 mechanism을 정확히 설명합니다. “greedy 하나만 취하는 대신 다양한 reasoning paths 집합을 먼저 sample하고, sample된 reasoning paths를 marginalizing out하여 가장 consistent한 답을 선택한다.” 그리고 이득도 명시합니다. GSM8K에서 +17.9 points입니다.2

그림이 숨기는 두 가지가 따라옵니다. 첫째, voting은 17장의 sampling을 필요로 합니다. temperature가 0이면 모든 k samples는 같은 sample이고, majority는 k번 비용을 낸 하나의 답입니다. 둘째, majority가 의미 있는 곳에서만 작동합니다. 위의 인보이스 답장에서는 셀 것이 없습니다. 다섯 초안은 다섯 가지 다른 문장이기 때문입니다. Voting은 짧고 비교 가능한 답을 가진 작업을 위한 것이며, Wang의 benchmarks가 정확히 그렇고 고객-facing agent가 하는 일은 거의 그렇지 않습니다.

여기서는 판단이 아니라 계산으로 답이 정해지는 20개의 세 단계 word problems에 대해, 23장의 local model이 step by step reasoning하도록 측정했습니다.

model callsinputoutputcost for the 20correct95 % interval
one greedy chain201,3302,649$0.0344489/2026–66 %
majority of 5, temperature 0.81006,65013,245$0.1722409/2026–66 %

calls 5배, tokens 5배, 정확히 5배의 청구서, 그리고 correct answer는 하나도 늘지 않았습니다. Voting은 개선이 아니라 베팅이고, 이번 run은 졌습니다.

누군가 이것을 Wang에 대한 반박으로 인용하기 전에 두 가지 caveat가 있습니다. 20 trials로는 45 %와 60 %를 구분할 수 없습니다. interval의 폭이 claim의 폭이며, 이것은 4장의 discipline을 내 결과에 적용한 것입니다. 그리고 공개된 gains는 훨씬 더 큰 models에서 나오며, 그곳에서는 voting이 marginalise하는 다양한 reasoning paths가 실제로 다양합니다. 이전되는 것은 숫자가 아닙니다. multiplier는 정확하고 미리 알려져 있지만 gain은 그렇지 않다는 사실입니다.

Orchestrator-workers, 그리고 summary가 아닌 것

섹션 링크: Orchestrator-workers, 그리고 summary가 아닌 것

orchestrator-workers workflow에서는 “central LLM이 tasks를 동적으로 분해하고, worker LLMs에 delegate하고, 그 결과를 synthesize”합니다. sectioning과의 차이는 “subtasks가 미리 정의되지 않고 orchestrator가 결정한다”는 점입니다.1 여기의 계보는 language model에서 온 것이 전혀 아닙니다. 이것은 master-worker입니다. workers가 findings를 shared space에 쓰고 controller가 읽는 버전은 1970년대 speech understanding 연구의 blackboard architecture입니다. 2026년에 새로운 점은 controller가 model이므로 decomposition을 input마다 결정할 수 있다는 것입니다. 한 문장 안에 flexibility와 cost가 함께 있습니다.

single agent의 5 calls에 비해 12 model calls가 들었고, 같은 verdict에 도달했습니다. 그런 다음 자세히 볼 만한 일을 했습니다.

TEXT
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

둘 다 맞습니다. 왜 맞는지 아는 것은 하나뿐입니다. tax worker는 자기 window 안에서 인보이스, 주문, 세율표를 모두 가지고 결론에 도달했습니다. 또한 — 아무도 묻지 않았지만 — 인보이스의 purchase order number가 주문의 것과 맞지 않는다는 점도 발견했습니다. 그런 다음 summary를 반환했습니다. orchestrator는 두 진술을 반복할 수는 있지만 어느 것도 확인할 수 없습니다. evidence가 자신이 본 적 없는 window 안에 남아 있기 때문입니다. 이것이 24장의 마지막 질문에 대한 답입니다. parent는 child가 적어두기로 선택한 것만 볼 수 있습니다.

수정은 flag 하나이며, 가격이 있습니다.

worker가 반환하는 것orchestrator input tokenscostparent가 할 수 있는 것
결론3,628$0.012512반복하기
결론과 evidence4,065$0.013554다시 도출하고, disagree하기

input tokens 12 % 증가, 비용 8.3 % 증가, 그리고 source=worker_unverified라는 문구가 답에서 사라집니다. 이것이 모든 multi-agent system의 trade이며 거의 말해지지 않습니다. child의 깨끗한 window는 가질 가치가 있고, parent가 그것을 audit할 능력은 지불할 가치가 있으며, 둘 다 공짜로 가질 수는 없습니다.

그렇다면 언제 orchestrator-workers가 틀린 선택일까요? 여기, 이 작업에서입니다. 같은 네 도구를 가진 agent 하나도 도달한 correct answer를 비용 1.66배, wall clock 2.3배로 샀고, 그 답을 방어하기 더 어렵게 만들었습니다. Anthropic의 자체 guidance도 patterns가 시작되기 전에 같은 말을 합니다. “가능한 가장 단순한 solution을 찾고, 필요할 때만 complexity를 늘려라.” 왜냐하면 “agentic systems는 종종 더 나은 task performance를 위해 latency와 cost를 trade하기” 때문입니다.1 위 표들은 그 문장 아래에 숫자를 붙인 것입니다.

Evaluator-optimiser, 그리고 시험을 쓴 judge

섹션 링크: Evaluator-optimiser, 그리고 시험을 쓴 judge

한 call이 생성하고, 다른 call이 평가하며, evaluation이 통과할 때까지 loop가 반복됩니다.1 공개된 조상은 Self-Refine — 같은 model이 “generator, refiner, and feedback provider” 역할을 하며 일곱 tasks 평균 약 20 points의 absolute improvement를 보고했습니다3 — 과 Reflexion입니다. Reflexion은 attempts 사이의 episodic buffer에 critique를 저장하고 baseline이 80 %였던 HumanEval에서 91 % pass@1을 보고했습니다.4

cost model은 다섯 중 가장 단순합니다. round당 두 calls, 그리고 round count는 당신 것이 아닙니다. 한 call이면 끝났을 task에 refinement 3 rounds를 돌리면 6 calls입니다. 따라서 이 pattern의 floor는 6×이고 ceiling은 당신이 정한 cap입니다. 그래서 23장의 budget exit은 깔끔한 장치가 아니라 필수입니다.

ceiling은 더 미묘하고, 측정 가능합니다. 같은 20 problems에서 local model은 9개를 맞혔습니다. 그런 다음 그 답들을 model에게 보여주고 맞는지 물었습니다. 그 답이 자기 것이라고는 말하지 않았습니다. 이것은 아첨 confound를 제거하고 capability만 남깁니다.

model 자신의 답“yes”라고 함“no”라고 함
맞았던 9개90
틀렸던 11개38

section title이 암시하는 것보다 나은 judge입니다. 그리고 그렇게 말하는 것이 주장하지 않고 측정하는 이유입니다. correct한 것은 하나도 막지 않았고, 11 mistakes 중 8개를 잡았습니다. filter로서는 call 값을 합니다.

하지만 evaluator-optimiser loop가 실제로 사용하는 stopping rule로서는, 그 세 approval이 전부입니다. 그것들은 wrong answer를 손에 든 채 loop를 끝내며, 추가 rounds가 아무리 많아도 거기에 도달하지 못합니다. refinement loop는 자기 judge보다 더 correct해질 수 없습니다. 더 많은 rounds를 사는 것은 judge가 볼 수 있는 errors에 대한 시도를 full price로 사는 것이며, judge가 볼 수 없는 것에는 아무것도 사지 않는 것입니다.

따라서 규칙은 이렇습니다. evaluator는 generator에게 없는 무언가를 가질 때만 calls 값을 합니다. compiler, test suite, schema validator, 다른 model, human. Self-Refine의 자체 결과는 human preference와 task metrics로 측정되었지, model이 스스로를 어떻게 평가하는지로 측정되지 않았습니다. evaluator의 유일한 장점이 다른 prompt뿐이라면, 당신은 동의에 두 배를 내는 것입니다. 29장은 진짜 장점을 가진 버전을 만듭니다. 답을 미리 적어둔 golden set입니다.

위의 다섯 가지는 당신의 code를 위한 shapes입니다. 그 아래에는 종종 함께 나열되지만 그래서는 안 되는 두 번째 family가 있습니다. ReAct, Reflexion, plan-and-execute, tree of thoughts는 reasoning loops이며, 비용은 requests에 있습니다.

12장은 model 내부의 reasoning에 관한 것이었고, 당신은 그것을 한 call의 output tokens로 지불합니다. 이것은 다른 종류입니다. 청구서가 도착하면 차이가 중요해집니다. 더 긴 chain of thought는 한 call을 더 비싸게 만들고, reasoning loop는 한 task를 많은 calls로 만들며, 각 call은 앞의 모든 것을 다시 보냅니다. 23장이 runaway table에서 측정한 quadratic입니다.

loopcalls, per taskextra calls가 사는 것
ReAct멈출 때까지 step당 하나model이 tools가 반환한 것에 반응함5
plan-and-executeplan에 하나, 그다음 step당 하나첫 step이 실행되기 전에 plan이 고정됨6
Reflexionattempts × (act + reflect)critique가 다음 attempt까지 살아남음4
tree of thoughtsbranching factor × depth, plus one evaluation per nodebacktracking이 있는 search7

tree-of-thoughts paper는 자체 cost table을 공개합니다. 더 흔해야 하는 일입니다. GPT-4로 Game of 24에서 input/output prompting best-of-100은 case당 $0.13에 33 %를 풀었고, chain of thought best-of-100은 $0.47에 49 %, tree of thoughts는 $0.74에 74 %를 풀었습니다. 저자들은 이것이 “CoT보다 5-100배 더 많은 generated tokens를 요구할 수 있다”고 적었습니다.7

가장 싼 방법 가격의 거의 6배로 success rate는 조금 넘게 2배입니다. 그것이 bargain인지는 failed case가 당신에게 얼마의 비용인지에 달려 있습니다. 이 네 가지 중 무엇이든 도입하기 전에 물어야 할 질문입니다.

이 course는 그것들을 다시 구현하지 않습니다. 네 가지 모두 각자의 저자가 만든 Python reference implementations가 있으며, 그것들의 가치는 번역본이 아니라 원천이라는 데 있습니다. ysymyth/ReAct, noahshinn/reflexion, princeton-nlp/tree-of-thought-llm, AGI-Edgerunners/Plan-and-Solve-Prompting. 그 repositories의 prompts를 읽으세요. prompts가 곧 papers입니다.

두 가지 topologies, 그리고 그중 하나는 돌아오지 않는다

섹션 링크: 두 가지 topologies, 그리고 그중 하나는 돌아오지 않는다

이제 대부분의 혼란이 있는 진짜 multi-agent입니다. 한 agent가 다른 agent를 관여시키는 방법은 두 가지입니다. 둘은 variants가 아니며, 차이는 그 뒤에 누가 통제권을 가지는가입니다.

도구로서의 agent. parent가 그것을 호출하고, 답을 받고, 계속합니다. 이것은 뒤에 agent 전체가 있는 18장의 tool interface이며, parent는 control을 잃지 않습니다. 위의 orchestrator가 하는 것이 이것입니다.

Handoff. parent가 conversation을 넘기고 다시 받지 않습니다. OpenAI의 guide가 가장 명확한 공개 설명입니다. handoffs는 “agent가 다른 agent에 delegate할 수 있게 하는 one way transfer입니다... agent가 handoff function을 호출하면, 우리는 최신 conversation state도 transfer하면서 handoff된 그 새 agent에서 즉시 execution을 시작합니다.”8

어휘 경고가 필요합니다. 사람들이 계속 걸려 넘어지는 부분입니다. “handoff”는 한 SDK의 단어이지 표준이 아닙니다. OpenAI Agents SDK와 그 guide의 terminology입니다. 그 guide는 두 구성을 “manager”와 “decentralized”라고도 부르며, manager pattern에서는 “edges가 tool calls를 나타내는 반면 decentralized pattern에서는 edges가 handoffs를 나타낸다”고 적습니다.8 이 영역에는 실제 open standard가 있습니다. A2A는 version 1.0.0이고, Linux Foundation copyright 아래에 있으며, versioned release history와 breaking changes의 documented list를 갖고 있습니다. 명시된 원칙은 opaque execution입니다. agents는 “internal thoughts, plans, tool implementations를 공유할 필요 없이 declared capabilities와 exchanged information을 기반으로 collaborate”합니다.9 그것은 handoff가 아니며, 비교는 26장에 속합니다. 여기서 중요한 것은 두 단어 중 하나는 library의 API이고, 다른 하나는 governance가 있는 specification이라는 점입니다.

이 구분은 diagram이 아니라 data structure입니다.

graph.tsTS
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;
}

20줄, 그리고 그렇지 않았다면 production에서 발견했을 두 버그입니다. reachable는 아무도 도달할 수 없는 agent를 찾습니다. configured되고, paid for 되었지만, never called입니다. conflicts는 한 edge가 두 종류를 동시에 갖는 것을 거부합니다. 소리 내어 읽기 전까지는 pedantic해 보입니다. parent가 control을 유지하면서 동시에 넘겨준다는 뜻이기 때문입니다. orphan 하나와 double edge 하나가 있는 five-agent system에서 실행하면 다음과 같습니다.

TEXT
reachable: lead@0 billing@1 tax@1 dunning@1
orphans:   ghost
conflicts: lead->tax

실제로 경계를 건너는 것

섹션 링크: 실제로 경계를 건너는 것

이제 이 section이 존재하는 이유인 measurement입니다. 그리고 이 장에서 scripted model이 아니라 real model을 대상으로 한 유일한 측정입니다.

고객이 첫 message에서 constraint를 말합니다. 우리 account는 스페인이 아니라 포르투갈에 등록되어 있습니다. tax-related한 것은 모두 포르투갈을 사용해야 합니다. 그런 다음 다른 이야기를 하다가 billing이 답해야 하는 질문을 합니다. case가 transfer됩니다. 24 trials, 매번 다른 나라와 회사, 네 가지 transfer payloads, 그리고 receiving agent에게 질문 하나를 묻습니다. 이 고객의 account는 어느 나라에 등록되어 있습니까?

transfer된 것mean payloadconstraint가 그 안에 있었나specialist가 recall했나95 % interval
전체 conversation173 tokens24/2420/24 — 83 %64–93 %
sending agent가 쓴 summary62 tokens1/240/24 — 0 %0–14 %
마지막 user message만61 tokens0/240/24 — 0 %0–14 %
typed record69 tokens24/2424/24 — 100 %86–100 %

세 번째 행은 control이고 control처럼 행동합니다. 그 사실이 없으므로 recall될 수 없습니다. 나머지 세 행이 finding입니다.

전체 transcript는 173 tokens이고 83 %의 경우 작동합니다. 네 번의 failures는 이 장이 아니라 24장의 주제입니다. typed record는 69 tokens — summary보다 7개 더 많을 뿐 — 이고 매번 작동합니다. constraint가 문장 대신 named field에 있기 때문입니다.

그리고 summary는 눈여겨봐야 할 행입니다. 24번 중 24번 실패했고, 이유는 reader가 놓쳤기 때문이 아닙니다. constraint는 24 summaries 중 단 1개에만 등장했습니다. receiving agent가 부주의했던 것이 아닙니다. 답이 들어 있지 않은 text를 건네받았던 것입니다. summary는 당신이 쓰지 않은 compaction입니다. 볼 수 없는 window를 가진 model이 만들고, summary처럼 읽히도록 optimized됩니다. 그리고 “고객이 우리 기록의 국가가 잘못되었다고 말한다”는 절차적 noise로 summariser가 떨어뜨리기 딱 좋은 clause입니다.

그 숫자에 대한 정직한 한계가 있습니다. summariser는 5억-parameter model이고 더 큰 model은 더 많이 유지할 것입니다. 크기로 개선되지 않는 것은 risk의 형태입니다. sending agent가 handoff마다, phrasing마다, 관측 불가능하게 어떤 사실이 살아남을지 결정합니다. typed record는 그 판단에 전혀 의존하지 않으므로, intelligence가 아니라 construction으로 이깁니다. transfer에서 반드시 살아남아야 하는 것은 sentence가 아니라 field여야 합니다.

같은 reasoning은 반대 방향, 즉 agent-as-tool topology에도 적용됩니다. 앞의 표가 이미 가격을 매겼습니다. worker에게서 돌아오는 것도 summary이며, evidence를 함께 받기 위해 8.3 % 더 지불하는 것은 parent 쪽에서 본 같은 수정입니다.

마지막으로 세 가지 사실입니다. 모두 위 표에서 나온 것입니다.

multi-agent system은 calls를 곱하고, calls는 context에서 quadratic입니다. orchestrator는 agent 하나가 5번 호출한 곳에서 12 model calls를 만들었습니다. 그리고 각각은 자기만의 growing transcript를 들고 다닙니다. 3,628 input tokens 대 2,697이며, task가 길어질수록 gap은 커집니다.

모든 boundary는 lossy channel입니다. agent 둘은 summary 하나를 뜻합니다. chain 안의 agents 넷은 summary 셋을 뜻하고, 그것들은 합성되며, 각각은 당신의 decision이 아닌 다른 무언가에 최적화하는 model이 작성합니다.

single agent는 아무도 요청하지 않은 것을 발견했습니다. purchase-order mismatch가 surfaced된 것은 한 window가 인보이스와 주문을 동시에 들고 있었기 때문입니다. 일을 specialists로 나누면 두 사실이 서로 맞지 않는다는 점을 알아차릴 능력도 나뉩니다.

이 중 어느 것도 공개된 multi-agent frameworks에 반대하는 주장이 아닙니다. 그것들은 tutorials를 통해서가 아니라 primary sources로 읽을 가치가 있습니다.10 주장은 두 번째 agent가 자기 자리를 벌어야 한다는 것입니다.

그러니 선호가 아니라 test입니다. 다음 중 적어도 하나가 참일 때 두 번째 agent를 추가하세요. sub-task가 parent가 inherit해서는 안 되는 clean window를 필요로 할 때(24장), subtasks가 진짜로 independent이고 wall clock이 중요할 때 — 위의 1.8×입니다 — sub-task에 different permissions 또는 다른 model이 필요할 때 — 30장이 이것을 security argument로 바꿉니다 — 또는 sub-task가 someone else에게 owned될 때, 즉 진짜 protocol이 중요해지기 시작하는 곳입니다. 답이 “각 agent가 더 명확한 prompt를 갖도록”이라면, agent 하나에게 더 명확한 prompt를 주세요. 공짜입니다.

이제 당신은 다섯 patterns의 이름을 말할 수 있고, 한 task에서 서로의 가격을 비교할 수 있으며, orchestrator와 sectioner, tool call과 handoff를 구분할 수 있고, 선호가 아니라 표로 single agent를 방어할 수 있습니다.

여기 모든 구성은 real한 것과 만나면 살아남지 못할 편의를 공유했습니다. 모든 tools가 우리 것이었습니다. 인보이스, 주문, 세율표, orchestrator 뒤의 workers — 같은 repository, 같은 deploy, 같은 types, 같은 people입니다.

이제 그중 하나를 회사 boundary 반대편에 두어 보세요. 세율표는 accounting vendor의 것이고, 주문 기록은 warehouse system의 것이며, 둘 다 당신의 Tool interface를 읽지 않았습니다. 당신이 쓰지 않은 model이 다른 사람이 운영하는 capability를 discover, describe, call할 방법이 필요합니다. authentication — 이것은 27장의 절반입니다 — versioning, 그리고 server가 당신 conversation의 나머지를 읽을 수 없다는 guarantee도 필요합니다. 이것은 protocol problem이고, normative schema가 있는 specification을 갖고 있으며, index된 거의 모든 글은 더 이상 존재하지 않는 revision을 설명합니다.

26장은 그것을 요약하지 않고 specification을 읽습니다. 그리고 terminal에 JSON-RPC를 손으로 입력하는 것부터 시작합니다.


위의 모든 cost와 token count는 두 번째 section에서 설명한 scripted provider에서 나왔습니다. Node 22, loopback interface에서 실행했고, o200k_base encoding으로 세었으며, 16장이 2026년 9월 6일에 읽은 요율 — input tokens 백만 개당 $2.00, output 백만 개당 $12.00 — 로 가격을 매겼습니다. Wall-clock figures는 같은 runs에서 provider latency를 call당 400 ms, tools를 50 ms로 설정한 값이므로 provider가 아니라 arrangement를 측정합니다. 두 real-model measurements — handoff table과 voting-and-judging table — 는 같은 형태의 endpoint 뒤 CPU에서 float32로 Qwen/Qwen2.5-0.5B-Instruct를 사용했고, temperature가 명시된 곳을 제외하면 greedy였으며, intervals는 4장의 Wilson method로 계산했습니다. 이 장의 어떤 request도 paid endpoint로 가지 않았고, 어떤 숫자도 추정되지 않았습니다.

  1. Anthropic, Building effective agents, 2024년 12월 19일, anthropic.com/engineering/building-effective-agents, 2026년 9월 7일 읽음. 위에서 사용한 다섯 workflow 이름과, 그들로부터 인용한 모든 phrase — prompt chaining, routing, sectioning과 voting variants가 있는 parallelisation, orchestrator-workers, evaluator-optimiser — 의 출처입니다. 또한 “가능한 가장 단순한 solution을 찾고, 필요할 때만 complexity를 늘려라”는 recommendation과, “agentic systems는 종종 더 나은 task performance를 위해 latency와 cost를 trade한다”는 observation의 출처입니다. 22장과 23장은 agent 정의를 여기서 인용합니다. 2 3 4 5 6 7

  2. 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년 3월). voting pattern의 기원이며, 그곳에서는 architecture가 아니라 decoding strategy로 설명됩니다. 다양한 reasoning paths를 sample한 뒤 “select the most consistent answer by marginalizing out the sampled reasoning paths”하며, GSM8K +17.9, SVAMP +11.0, AQuA +12.2, StrategyQA +6.4, ARC-challenge +3.9의 gains를 보고했습니다.

  3. Madaan, A. et al. Self-Refine: Iterative Refinement with Self-Feedback. arXiv:2303.17651 (2023). 세 역할 모두에 하나의 model을 사용하는 evaluator-optimiser loop — “generator, refiner, and feedback provider” — 로, 일곱 tasks 전반에서 task performance가 “by ~20% absolute on average” 향상되었다고 보고했습니다. 이는 model 자신의 verdict가 아니라 human preference와 automatic metrics로 측정되었습니다.

  4. Shinn, N., Cassano, F., Berman, E., Gopinath, A., Narasimhan, K. and Yao, S. Reflexion: Language Agents with Verbal Reinforcement Learning. arXiv:2303.11366 (2023). attempts 사이에 self-critiques의 episodic memory를 추가합니다 — “reinforce language agents not by updating weights, but through linguistic feedback” — GPT-4 baseline 80 %에 대해 HumanEval에서 91 % pass@1을 보고했습니다. 결과가 의존하는 requirement에 주목하세요. model 자신의 opinion이 아니라 failing test 같은 environment의 real signal이 필요합니다. 2

  5. 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 traces와 actions의 interleaving입니다. 23장이 이 loop를 만들었습니다. 여기서는 결과보다 cost shape 때문에 인용합니다. step당 model call 하나이며, 매번 전체 transcript가 다시 전송됩니다.

  6. 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). “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 shape이며, 이 장이 신경 쓰는 trade의 출처입니다. 첫 observation이 도착하기 전에 plan이 고정됩니다. 이는 decomposition을 당신이 아니라 model이 쓴 prompt chaining입니다.

  7. 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). intermediate “thoughts” 위의 search와 self-evaluation, backtracking입니다. chain-of-thought prompting 4 %에 대해 Game of 24에서 74 %를 기록했습니다. 위에서 인용한 cost figures는 논문 자체의 Appendix B.3, Table 7에서 왔습니다. case당 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가 “could require 5-100 times more generated tokens than CoT”라고 적었습니다. 2

  8. OpenAI, A practical guide to building agents (PDF), 2026년 9월 7일 읽음. manager-versus-decentralised 구분, 위에서 인용한 graph framing(“manager pattern에서는 edges가 tool calls를 나타내는 반면 decentralized pattern에서는 edges가 handoffs를 나타낸다”), 그리고 handoff를 “one way transfer... we immediately start execution on that new agent that was handed off to while also transferring the latest conversation state”로 정의한 출처입니다. 마지막 clause가 결정하는 것을 주목하세요. 이 SDK에서는 conversation state가 함께 이동합니다. 그것은 그 library의 design decision이지 handoffs 일반의 속성이 아닙니다. 2

  9. Agent2Agent (A2A) Protocol Specification, latest released version 1.0.0, a2a-protocol.org/latest/specification/, 2026년 9월 7일 읽음; copyright the Linux Foundation, Apache-2.0. 위에서 인용한 내용: “open standard designed to facilitate communication and interoperability between independent, potentially opaque AI agent systems”, 그리고 opaque execution 원칙 — agents는 “collaborate based on declared capabilities and exchanged information, without needing to share their internal thoughts, plans, or tool implementations”. 이 page에는 release history(0.1.0, 0.2.6, 0.3.0, 1.0.0), breaking changes appendix, MCP와의 관계에 대한 appendix가 있습니다. 26장이 그 비교를 합니다.

  10. 이 장이 가르치지 않는 multi-agent frameworks입니다. tutorial이 아니라 primary sources를 원하는 독자를 위해 남깁니다. Wu, Q. et al., AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation, arXiv:2308.08155 (2023), 여기서 agents는 “customizable, conversable”이고 conversation 자체가 programming model입니다. Hong, S. et al., MetaGPT: Meta Programming for a Multi-Agent Collaborative Framework, arXiv:2308.00352 (2023), standard operating procedures를 role prompts로 encode하며 “solutions to more complex tasks are complicated through logic inconsistencies due to cascading hallucinations caused by naively chaining LLMs”라고 명시합니다. 이 장 첫머리에서 측정한 confidently-wrong chain이 abstract 안에서 이름 붙은 것입니다. 그리고 Park, J. S. et al., Generative Agents: Interactive Simulacra of Human Behavior, arXiv:2304.03442 (2023), memory, reflection, planning을 가진 25 agents로, “agents를 계속 추가하면 무슨 일이 일어나는가”에 대한 가장 큰 공개 답입니다.

이제 모델 선택은 LIA에게 맡기세요

모든 AI 모델을 한곳에서. 오늘 무료로 시작하세요.