Agent Mentor Learn
루프에서 그래프로: 에이전트 시스템을 위한 오케스트레이션 엔지니어링 · 5 / 6강

레슨 5: 리뷰 회로, 그리고 패턴을 그래프로 조합하기

학습 목표:

  • 리뷰-수정 루프(초안 생성, 평가, 피드백에 따른 개정)를 구현하고, 이 루프를 지을 값어치가 있는지 판단하는 두 기준 쓰기
  • "최대 N회"보다 똑똑한 정지 조건을 쓰고, 결정론적 검사를 심판 앞에 두기
  • 다섯 패턴을 이 레슨이 "그래프"라 부르는 것으로 조합하고, 이 시각 체계가 특정 1차 자료 인용에 닻을 내린 자체 은유임을 여러분의 문서에 밝히기

전제: 레슨 1~4를 읽고(계획을 누가 쥐는가, 체이닝과 라우팅, 병렬화, 오케스트레이터-워커), stop_reason으로 구동되는 하네스 루프를 손으로 쓸 수 있어야 합니다 | 이전: 레슨 4 << | 다음: 레슨 6 >>

언제나 한 걸음 모자란 초안

에이전트에게 데이터베이스 마이그레이션 계획을 쓰라고 시킵니다. 첫 초안은 그럴듯해 보입니다. 배경, 단계, 시간 창이 다 있습니다. 그런데 한눈에 구멍 둘이 보입니다. 롤백 항목은 "필요하면 롤백한다"라고만 되어 있고, 위험 등급은 어디에도 없습니다. 여러분이 이것을 짚는 피드백 두 줄을 타이핑하면, 두 번째 초안이 돌아오고, 구멍 둘이 메워지고, 전체가 품질 등급 하나만큼 뛰어오릅니다.

이 과정을 여러분은 수십 번 되풀이했습니다. 매번 똑같습니다. 출력이 모자라고, 사람이 두 문장의 피드백을 주고, 출력이 눈에 띄게 좋아집니다.

문제는 모델이 글을 못 쓴다는 것이 아닙니다. 문제는 여러분의 두 문장짜리 피드백이 만들어 내기 어려운 것이 아니라는 데 있습니다. "롤백 단계에는 구체적인 명령이 들어가야 한다", "각 단계에 위험 등급이 필요하다" — 이런 것들은 체크리스트가 담을 수 있는 것들입니다. 여러분이 또렷하게 말할 수 있다면, 모델도 아마 또렷하게 말할 수 있습니다. 그런데 왜 매번 그 말을 여러분이 해야 합니까?

이 모양은 루프로 쓸 값어치가 있습니다.

리뷰-수정: "한 번 더 고쳐라"를 제어 흐름에 써넣기

1차 자료는 한 문장으로 정의합니다. LLM 호출 하나가 응답을 생성하고, 다른 하나가 루프 안에서 평가와 피드백을 제공합니다1.

앞의 네 레슨이 다룬 네 패턴은 각자의 위상을 가집니다. 체이닝은 작업을 일련의 단계로 분해하고 각 단계가 앞 단계의 출력을 처리합니다1. 라우팅은 분류한 뒤 전문화된 후속 작업으로 보냅니다1. 병렬화는 동시에 돌리고 결과를 프로그램으로 집계합니다1. 오케스트레이터-워커는 중앙의 LLM이 작업을 동적으로 쪼개고 워커에게 위임하고 결과를 종합합니다1. 이들은 공통점 하나를 가집니다. 데이터가 앞으로 흐릅니다. 리뷰 회로는 되돌아가는 엣지를 가진 첫 패턴입니다. 출력이 생성 노드로 되돌아 들어갑니다.

제품에서는 어떤 모습입니까? Claude Code의 동적 워크플로 문서가 평이한 영어로 하나를 설명합니다. 검사기를 돌리고, 실패한 것을 고치고, 통과하거나 더는 진척이 없을 때까지 되풀이합니다2. 같은 분업의 다른 쓰임을 다루는 설명도 있습니다. 독립적인 에이전트들이 보고되기 전에 서로의 발견을 적대적으로 리뷰하게 하는 것입니다2. 그것은 보고 전에 한 번 하는 교차 리뷰이고, 되돌아가는 엣지도 반복도 없습니다. 그것을 리뷰 회로에 함께 묶는 것은 이 레슨의 분류이지, 원문이 같은 위상을 설명한 것이 아닙니다.

하나의 개념, 세 개의 이름

여기서 다리를 명시적으로 놓아야 합니다. 그러지 않으면 서로 다른 셋을 배우고 있다고 여기게 됩니다.

이 시리즈의 코스 6은 멀티 에이전트 협업을 가르치며, "하나가 일하고 하나가 비평한다"는 이 분업을 생산자-리뷰어라 부릅니다. 그것은 우리 쪽 교육 어휘입니다. 1차 자료에서는 Claude Code의 워크플로 문서가 제품에서의 쓰임을 한 문장으로 설명합니다. 독립적인 에이전트들이 서로의 발견을 적대적으로 리뷰하게 한다(이 레슨은 그 문장을 "적대적 교차 리뷰"로 줄여 부릅니다). 같은 모양이 1차 자료에서 두 이름을 가집니다. Anthropic의 패턴 레퍼런스는 그것을 **평가자-최적화자(evaluator-optimizer)**라 부르고1, Claude Code의 워크플로 문서는 이름을 붙이지 않고 쓰임만 설명합니다 — 서로의 발견을 적대적으로 리뷰한다는 그 문장입니다2.

세 이름, 하나의 모양. 차이는 어느 각도에서 보느냐입니다. 협업 역할을 논할 때는 배우 둘이 보이고, 오케스트레이션 패턴을 논할 때는 되돌아가는 엣지가 보이고, 제품 기능을 논할 때는 재사용 가능한 품질 기법이 보입니다.

정리해 둘 분업이 하나 더 있습니다. 이 시리즈의 코스 10은 좋은 심판이 되는 법을 코스 하나를 통째로 써서 가르칩니다. 루브릭을 어떻게 쓰는지, 심판의 출력 형식을 어떻게 제약하는지, 심판에게 왜 자기만의 독립적인 컨텍스트가 필요한지, 워커가 왜 동시에 심판이면 안 되는지. 그 코스는 심판 자체의 품질을 가르칩니다. 이 레슨은 그 주제들을 되풀이하지 않습니다. 이 레슨은 심판을 제어 흐름에 어떻게 배선하는가를 가르칩니다. 루프의 어디에 앉는지, 언제 도는지, 몇 바퀴 도는지, 언제 멈추는지입니다.

이 루프를 지을 값어치가 있을 때

1차 자료의 적용 기준: 이 워크플로는 명확한 평가 기준이 있고 반복적인 다듬기가 측정 가능한 가치를 줄 때 특히 효과적입니다. 잘 맞는다는 두 신호는, 첫째로 사람이 피드백을 또렷하게 말했을 때 LLM 응답이 눈에 띄게 개선될 수 있다는 것이고, 둘째로 LLM이 그런 피드백을 줄 수 있다는 것입니다1.

이 인용은 전에도 봤습니다. 이 시리즈의 코스 10이 "리뷰-수정 루프를 지을 값어치가 있는가"라는 질문에 답하며 정확히 이 문장을 인용했습니다. 같은 기준을 오케스트레이션 맥락에서 다시 놓은 것이며, 다만 이번에는 그 답을 제어 흐름의 루프로 구현합니다.

쪼개어 보면 이 두 신호는 각각 다른 실패 유형을 막습니다.

첫 신호는 "고쳐도 나아지지 않는다"를 막습니다. 어떤 작업은 피드백을 아무리 또렷하게 말해도 두 번째 초안에서 좋아지지 않습니다. 문제가 출력의 표현이 아니라 빠진 입력 데이터나 모호하게 정의된 작업에 있기 때문입니다. 이 경우 루프를 짓는다는 것은 똑같이 쓸 수 없는 두 판본을 얻으려고 값을 두 번 치른다는 뜻일 뿐입니다. 검증 방법은 투박하지만 효과적입니다. 직접 세 번 손으로 해 보십시오. 그 셋 중 몇 번이 "사람의 피드백 뒤에 분명히 좋아졌다"였습니까? 셋 중 둘이 "피드백이 도움이 되지 않았다"라면 루프를 짓지 마십시오.

둘째 신호는 "심판이 그런 종류의 피드백을 줄 수 없다"를 막습니다. 사람의 피드백이 통한다 해도 여전히 물어야 합니다. 모델 자신이 같은 종류의 피드백을 줄 수 있습니까? 여러분의 피드백이 여러분만 아는 것에 기대고 있다면(이 고객이 지난 분기에 무엇을 항의했는지, 법무가 지난주에 구두로 무엇을 알렸는지), 모델에게는 그 정보가 없으므로 그것이 주는 피드백은 전혀 다른 무언가가 됩니다. 그럴 때는 그 정보를 심판의 프롬프트에 넣어 모델이 평가할 수 있는 기준으로 바꾸거나, 이 단계에 사람이 필요하다는 것을 받아들이십시오.

이 두 신호보다 더 먼저 작동하는 전제가 하나 있습니다. 평가 기준이 명확해야 합니다. 기준이 명확하지 않으면 루프는 특정한 실패를 어김없이 만들어 냅니다. 심판이 매 회차마다 서로 다르거나 심지어 모순되는 방향의 피드백을 주고, 출력이 두 판본 사이를 오가고, 회차가 소진되고, 최종 초안이 첫 초안보다 나쁩니다. 이것은 루프의 잘못이 아닙니다. 기준이 아직 정의되지 않은 것입니다.

결정론적 검사는 심판보다 앞에 온다

결정론적 시스템과 비결정론적 시스템에 대한 1차 자료의 정의적 구분: 결정론적 시스템은 같은 입력이 주어지면 매번 같은 출력을 내고, 에이전트 같은 비결정론적 시스템은 같은 시작 조건에서도 서로 다른 응답을 낼 수 있습니다3.

심판은 비결정론적입니다. "코드가 확정적으로 판정할 수 있는" 규칙을 심판에게 넘길 때마다, 매번 같은 결과를 내야 하는 것을 매번 다른 결과를 낼 수 있는 것으로 평가하는 셈이며, 게다가 모델 호출 값도 하나 더 치릅니다.

이 시리즈의 코스 10은 이 규율을 계층화된 채점이라 부릅니다. 코드가 정할 수 있는 것은 코드로 정하고, 코드가 정할 수 없는 것만 모델에게 넘깁니다. 이 레슨은 그것을 루프의 노드 순서에 그대로 옮겨 옵니다. 레슨 2의 인용이 여기서도 통합니다. 과정이 여전히 궤도 위에 있는지 확인하기 위해 어떤 중간 단계에든 프로그램적 검사를 더할 수 있습니다1. 루프 안의 모든 초안이 중간 단계입니다.

마이그레이션 계획 예시에 적용하면, "각 단계에 대응하는 롤백 명령이 있는가?"는 정규식이나 구조화된 파싱으로 확정적으로 판정할 수 있습니다 — 그것이 게이트입니다. "롤백 명령이 믿을 만하게 쓰였는가?"는 심판이 필요합니다. 앞의 것이 실패하면 심판을 깨우지도 않고, 어느 단계가 빠졌는지만 작성자에게 알려 주고 넘어갑니다.

루프의 코드 뼈대

따로 짚어 둘 만한 세부가 몇 개 있습니다.

runAgent는 완전한 하네스 루프입니다. 레슨 2 이후로 달라지지 않았습니다. 이 스크립트의 모든 await runAgent(...) 뒤에서는 이 시리즈의 코스 7에 나온 stop_reason 구동 루프가 돌고 있습니다. 이것은 그 루프를 감싼, 코드로 쓰인 또 한 겹의 제어 흐름일 뿐입니다.

reason 값들은 서로 다른 결과이므로 불리언으로 뭉개지 마십시오(실제 시스템은 더 잘게 나눠야 하는 경우가 많습니다 — 예를 들어 게이트가 거듭 실패하는 경우는 자기 칸을 가집니다). passed는 그대로 내보낼 수 있습니다. max-rounds는 통과하지 못한 채 회차가 소진된 것이므로 사람에게 넘겨야 할 가능성이 큽니다. no-progress는 모델이 막힌 것이므로 돈을 더 태워도 나아지지 않습니다. 이 세 결과는 여러분의 관측 데이터에서 세 개의 서로 다른 줄이어야 합니다. 이 시리즈의 코스 11이 가르치는 로깅 방식이 여기 이 reason 필드에 내려앉아야 합니다.

게이트 실패도 한 회차로 셉니다. continue 앞에서 rounds는 이미 증가했습니다. 이것은 의도적입니다. 게이트를 거듭 실패한다는 것은 작성자 프롬프트에 문제가 있다는 뜻이고, 무한정 재시도하게 두면 같은 구멍에 돈만 태웁니다.

정지 조건은 두 종류가 다 필요합니다. 에이전트 루프를 논하는 1차 자료는 이렇게 말합니다. 작업은 완료되면 종료되는 경우가 많지만, 제어를 유지하기 위해 정지 조건(예를 들어 최대 반복 횟수)을 함께 두는 것도 흔합니다1. "최대 N회"는 여기서 나옵니다. 그것은 퓨즈이며, 어떤 상황에서도 이 코드가 멈추도록 보장합니다. "더는 진척이 없음"이라는 정지 메커니즘은 다른 데서 옵니다. 검사기를 돌리고, 실패한 것을 고치고, 통과하거나 더는 진척이 없을 때까지 되풀이합니다2. 이쪽이 퓨즈보다 똑똑한 이유는 몇 회차를 돌았는지가 아니라 이번 회차가 지난 회차를 넘어섰는지를 보기 때문입니다.

점수가 오르지 않으면 나간다는 것은 가장 쉬운 구현이지 유일한 구현은 아닙니다. 심판이 점수를 내지 않는다면 실패 항목 수가 줄었는지를 보는 쪽으로 바꿀 수 있습니다. 작업 자체의 분산이 크다면 stalled 카운터를 두고 "두 회차 연속으로 개선이 없을 때만 나간다"로 바꿀 수 있습니다. 어느 것을 고를지는 여러분의 심판이 얼마나 안정적인가에 달렸지, 어느 쪽이 정교하게 들리는가에 달린 것이 아닙니다. (뼈대의 bestDraft에 주목하십시오. 점수가 오르지 않을 때 나가는 방식은 언제나 최고점 초안을 붙들고 있다는 것을 전제합니다. bestDraft 없이 bestScore만 추적하면 no-progressmax-rounds 출구가 더 나쁜 현재 판본을 내주게 됩니다.)

패턴 조합하기: 이 레슨은 그것을 "그래프"라 부른다

다섯 패턴이 모두 갖춰졌습니다. 다음 질문은 그것들을 어떻게 함께 배치하는가입니다.

먼저 공식 입장입니다. 이 구성 요소들은 규범이 아니라, 개발자가 서로 다른 용례에 맞게 다듬고 조합할 수 있는 흔한 패턴들입니다. 성공의 열쇠는 여느 LLM 기능과 마찬가지로 성능을 측정하고 구현을 반복해 다듬는 것입니다1.

다시 말해 "어떻게 조합하는가"에 대해 1차 자료는 허가를 주지 레시피를 주지 않습니다. 레시피는 여러분이 씁니다.

그래프 용어에 대한 정직한 선언

이 레슨이 전체에 걸쳐 쓰는 "그래프 / 노드 / 엣지"는 이 레슨 자체의 엔지니어링 은유이지 공식 용어가 아닙니다(앞선 절들이 이미 이 뜻으로 "노드"와 "되돌아가는 엣지"를 썼습니다).

이 문장을 여러분의 아키텍처 문서에 복사해 두십시오. "그래프", "노드", "엣지", "DAG", "상태 기계"라는 낱말은 이 레슨이 인용하는 1차 자료 전체에 걸쳐 0번 등장합니다. 1차 자료의 어휘는 워크플로, 패턴, 오케스트레이터-워커, 팬아웃입니다. 위상 구조가 아니라 패턴 목록을 논하고 있습니다.

그래도 우리는 "그래프"라는 낱말을 써야 합니다. 다섯 패턴이 함께 놓였을 때 그것들을 또렷하게 말할 언어가 필요하고, "그래프"가 가장 품이 덜 드는 선택지이기 때문입니다. 다만 이 은유에는 닻이 있어야 합니다. 그러지 않으면 그저 지어낸 은어입니다. 닻은 1차 자료에 실제로 존재하는 이 문장입니다. 워크플로 스크립트 자체가 루프, 분기, 중간 결과를 쥐고, 모델의 컨텍스트는 최종 답만 쥡니다2.

그 문장이 이미 그래프의 세 요소를 다 이름 짓고 있습니다. 루프(되돌아가는 엣지), 분기(갈래점), 중간 결과(상태). 우리가 하는 일이라고는 각각에 이름을 붙이는 것뿐입니다.

그리기 규약

이 레슨의 시각 체계에서는 이렇습니다.

  • 노드 = runAgent 루프 하나, 또는 순수 코드 한 덩이(게이트, 분류, 집계, 배치 묶기). 각 노드의 유형을 표시하는 것이 그릴 때 가장 값진 행동입니다. "이 단계에 정말로 모델이 필요한가?"에 답하도록 강제하기 때문입니다.
  • 엣지 = "누구의 출력이 누구에게 들어가는가". 엣지는 자료 구조가 아니라, 앞 줄의 변수를 읽는 다음 줄의 코드일 뿐입니다.
  • 상태 = 스크립트 변수. 1차 자료의 닻에 이에 관한 문장도 있습니다. 중간 결과는 모델의 컨텍스트에 내려앉지 않고 스크립트 변수에 머뭅니다2. "노드 사이를 오가는 상태 객체"라는 공식 개념은 없습니다. 그것은 우리가 다른 영역에서 빌려 온 표현이며, 이 레슨은 그 추상을 짓지 않습니다. 필요한 변수를 그냥 넘기십시오.

이 시각 체계로 그린 다섯 패턴

text
체이닝         A ──> B ──> C                    직선 하나
라우팅            ┌──> B1               A ─┼──> B2                       갈래점 하나                  └──> B3
병렬화            ┌──> W1 ──┐               A ─┼──> W2 ──┼──> 병합           부채: 펼쳤다가 합침                  └──> W3 ──┘
오케스트레이터-   ┌──> W? ──┐                   갈래점이 동적: 엣지 몇 개를,  워커         A ─┼──> W? ──┼──> 병합           각각 무엇을 할지 A가 입력을                  └──> W? ──┘                   본 뒤에 정함
리뷰 회로      A ──> J ──┐                      되돌아가는 엣지가 달린 회로 하나               ^         │               └──아니오─┘

넷째 모양의 주석은 다시 읽어 볼 값어치가 있습니다. 병렬화와 오케스트레이터-워커는 모양이 지형적으로 비슷하며, 핵심 차이는 하위 작업이 미리 정의되어 있지 않고 구체적인 입력에 근거해 오케스트레이터가 정한다는 것입니다1. 종이 위에 그리면 차이는 "내가 엣지 셋을 그렸다"와 "A가 엣지 셋을 그렸다"입니다. 종이 위에서는 구별되지 않지만, 코드에서는 아주 다릅니다.

조합 예시

라우팅, 팬아웃, 병합, 리뷰 회로를 엮으면 이렇습니다.

text
[분류] ────┬─ 단순 ──> [바로 답변] ──────────────────────> 전달 순수 코드 │(키워드 +  └─ 복잡 ──┬─> [워커1] ─┐  규칙)              ├─> [워커2] ─┼─> {병합} ─> [초안] <──────┐                     └─> [워커3] ─┘            runAgent │       │                                                     v      │       │                                                  {게이트} ─아니오──┤                                                     │ 통과  │       │                                                     v      │       │                                                  [리뷰] ─아니오────┘                                                     │ 예    runAgent                                                     v                                                   전달
노드 유형: [ ] = runAgent 루프    { } = 순수 코드엣지 = 누구의 출력이 누구에게 들어가는가. {게이트}는 결정론적 검사이며 [리뷰]보다 앞에 온다. 게이트 실패나 리뷰 아니오는 둘 다 [초안]으로 되돌린다.[분류]가 {순수 코드}가 아니라 모델 루프로 그려진 것은 환불/기술/불만의 경계가 흐릿하기 때문이다. 경계가 명확하다면 전통적인 분류기로 바꾸십시오(이것이 계층화된 채점입니다. 코드가 정할 수 있으면 코드를 먼저 쓴다).

레슨 6은 이 그래프의 변형을 구현합니다. 그 티켓 묶음은 마침 합격 기준을 전부 규칙으로 쓸 수 있어서 [리뷰] 계층이 {게이트}로 낮아지고, 팬아웃은 "복잡한 것 하나를 워커 셋에게"에서 "티켓 한 묶음을 각각 하나의 처리자에게"로 바뀝니다. 어디가 왜 바뀌었는지는 레슨 6의 도입부가 항목별로 나열합니다. 여기서는 모양을 먼저 보고, 코드는 다음 레슨을 기다리십시오.

조합에서 나오는 엔지니어링 이득

제어 흐름을 코드로 옮기면 "이해할 수 있다"는 것 이상이 따라옵니다. 1차 자료의 뒷받침이 있는 이득이 몇 가지 있습니다.

단계별 추적이 복구 가능성을 데려옵니다. 런타임은 실행이 진행되는 동안 각 에이전트의 결과를 추적하며, 그것이 같은 세션 안에서 실행을 재개할 수 있게 하는 것입니다2. 이 레슨의 시각 체계로 옮기면, 그래프의 모든 노드는 자연스럽게 체크포인트 자리입니다. 노드가 끝나고, 결과가 스크립트 변수에 내려앉고, 그 변수가 "어디까지 왔는가"의 기록입니다. 이 시리즈의 코스 9가 가르친 체크포인트 설계는 여기서 따로 기반을 놓을 필요가 없습니다. 노드 경계가 자연스러운 착지 지점입니다.

잘게 나눈 팬아웃이 진척을 더 많이 지켜 냅니다. 1차 자료의 표현은 이렇습니다. 일을 여러 작은 에이전트에게 펼쳐 내보내는 워크플로는 긴 에이전트 하나보다 진척을 더 많이 지켜 냅니다2. 40분짜리 긴 에이전트 하나가 죽으면 40분이 사라집니다. 1분짜리 작은 노드 40개 중 하나가 죽으면 1분을 잃고, 그것도 어느 1분인지 압니다.

되풀이 가능한 품질 기법이 재사용 가능해집니다. 계획을 코드로 옮기면 워크플로가 에이전트를 더 많이 돌리는 데 그치지 않고 되풀이 가능한 품질 패턴을 적용할 수 있게 됩니다. 독립적인 에이전트들이 보고되기 전에 서로의 발견을 적대적으로 리뷰하게 하거나, 여러 각도에서 계획 초안을 잡아 서로 견주게 할 수 있으며, 그렇게 하면 한 번에 끝내는 것보다 더 믿을 만한 결과를 얻습니다2. 여기서 핵심 낱말은 "되풀이 가능한"입니다. 교차 리뷰를 손으로 한 번 하는 것은 작업이고, 그것을 스크립트에 써넣는 것은 능력입니다.

결정론적 가드레일이 비결정론적 에이전트를 감쌉니다. Anthropic의 멀티 에이전트 리서치 시스템 회고는 이렇게 밝힙니다. 이들은 Claude 위에 지은 AI 에이전트의 적응성을, 재시도 로직과 정기 체크포인트 같은 결정론적 안전장치와 결합합니다4. 이 레슨의 시각 체계로 옮기면, 그래프의 골격은 결정론적이고(누가 누구를 부르는지, 언제 멈추는지, 실패 시 어느 엣지를 타는지) 노드의 내부는 비결정론적입니다. 이 계층 나눔은 미적 취향이 아니라 시스템을 운용 가능하게 만드는 전제입니다.

조합의 규율: 더한 계층은 하나하나 관문을 통과해야 한다

이득을 말했으니 이제 제약입니다.

더한 계층은 하나하나 "측정 가능한 개선" 관문을 통과해야 합니다. 1차 자료는 같은 말을 두 곳에서 하며, 두 번째는 되풀이임을 명시합니다. 결과를 눈에 띄게 개선함이 증명될 때에만 복잡도를 더하는 것을 고려해야 합니다1. 이것은 이 레슨에서 특히 결정론적입니다. 다섯 패턴이 눈앞에 펼쳐져 있으면 가장 저지르기 쉬운 실수가 그것들을 다 쓰는 것입니다. 노드를 하나 더한다는 것은 모델 호출이 하나 늘고, 실패할 수 있는 자리가 하나 늘고, 문제를 찾아야 할 대상이 하나 는다는 뜻입니다. 더하기 전에 물으십시오. 이것을 빼면 지표가 떨어집니까? 답할 수 없다면 아직 측정하지 않은 것입니다.

노드 수준의 재시도와 타임아웃은 엔지니어링 관행이지 공식 설계가 아닙니다. 1차 자료는 이것을 종속절로만 언급합니다(재시도 로직과 정기 체크포인트 같은 결정론적 안전장치4). 그러므로 아래는 엔지니어링 관행으로 씁니다. 어느 1차 문서에서도 이에 대한 승인을 찾을 수 없을 것입니다. 모든 runAgent 노드를 타임아웃으로 감싸고, 타임아웃 뒤에는 재시도하거나 이 노드를 실패로 표시하고 계속 진행합니다. 재시도 횟수는 노드의 성격에 달렸습니다(읽기 전용 조회 노드는 몇 번 재시도해도 되지만, 부수 효과가 있는 노드는 한 번도 자동 재시도하지 않는 편이 좋습니다). 노드가 실패하면 "이 엣지는 건너뛰어도 된다"와 "그래프 전체가 멈춰야 한다"를 구분하고, 선택적인 노드 하나의 실패가 실행 전체를 끌어내리지 않게 하십시오. 이것들은 평범한 분산 시스템 상식이며, 에이전트에 적용했을 뿐입니다. 무슨 새로운 것으로 여기지 마십시오.

깊이에는 한계가 있습니다. 제품 수준의 참조가 바로 여기 있습니다. 기본적으로 서브에이전트는 자기 서브에이전트를 띄울 수 있으며, 메인 대화 아래로 최대 3계층까지입니다5. 3계층은 이 레슨이 지어낸 임계값이 아니지만 메시지는 분명합니다. 실제 제품에서 중첩 깊이는 무제한이 아니고, 누군가 어디서 멈출지를 진지하게 고민했습니다. 여러분의 그래프에도 비슷한 답이 있어야 합니다. 그린 그래프가 5계층 중첩이라면, 더 깊이 지원할 방법을 궁리하기 전에 작업을 너무 잘게 분해한 것부터 의심하십시오.

그래프가 목적이 아니라, 작업 모양의 서술이다

이 코스의 끝에서 특히 막아 둘 만한 실패 유형이 하나 있습니다. 멋진 위상을 먼저 고르고, 거기에 밀어 넣을 작업을 찾는 것입니다.

순서가 뒤집혀야 합니다. 작업 자체의 의존 모양을 먼저 그리십시오. 어느 단계들이 줄을 서야 하는지(앞 단계의 출력이 다음 단계의 입력), 어느 단계들이 서로에게 영향을 주지 않는지(누가 먼저 돌든 상관없음), 어느 단계가 입력을 봐야 몇 조각으로 나눌지 알 수 있는지, 어느 단계의 출력이 누군가의 비평을 거쳐야 믿을 만해지는지. 그 그림이 끝나면 어떤 패턴을 쓸지는 사실상 정해집니다. 줄을 서는 자리는 체인이고, 서로 독립인 자리는 부채이고, 보고 나서 정하는 자리는 오케스트레이터이고, 비평이 필요한 자리는 회로입니다.

패턴은 작업 모양에 붙인 이름이지, 마음대로 고를 수 있는 메뉴가 아닙니다.

그리고 그 규율보다 더 먼저 작동하는 것이 있습니다. 가능한 가장 단순한 해법을 찾고, 필요할 때에만 복잡도를 올리십시오1. 이 문장은 레슨 1에 나왔고, 이 레슨의 끝에서도 여전히 같은 문장입니다. 다섯 패턴을 배운 뒤에도 "LLM 호출 한 번이면 충분하다"는 완전히 유효한 답으로 남습니다. 1차 자료 자신이 많은 애플리케이션에서는 검색과 인컨텍스트 예시로 단일 LLM 호출을 최적화하는 것으로 대개 충분하다고 말합니다1.

완전히 돌아가는 조합 코드는 레슨 6에 있습니다. 이 레슨은 여기서 멈춥니다. 이제 여러분에게 있는 것은 다섯 패턴, 하나의 시각 체계, 그리고 그것들을 쓰지 말아야 할 때의 목록입니다.

💻 연습

정리

  • 리뷰-수정은 LLM 호출 하나가 응답을 생성하고 다른 하나가 루프 안에서 평가와 피드백을 제공하는 것이다1. 제품에서의 모습은 "검사기를 돌리고, 실패한 것을 고치고, 통과하거나 더는 진척이 없을 때까지 되풀이한다"이며2, 적대적 교차 리뷰는 같은 분업의 다른 쓰임이다(교차 리뷰 한 번, 되돌아가는 엣지 없음). 그것을 리뷰 회로에 함께 묶는 것은 이 레슨의 분류다2. 이 시리즈의 코스 6은 그것을 생산자-리뷰어라 부르며 그것은 우리 교육 어휘이고, 1차 자료의 어휘는 평가자-최적화자다1.
  • 지을 값어치는 두 신호에 달렸다. 사람이 피드백을 또렷하게 말했을 때 LLM 응답이 눈에 띄게 개선될 수 있어야 하고, LLM도 그런 피드백을 줄 수 있어야 한다. 평가 기준이 명확하고 반복적인 다듬기가 측정 가능한 가치를 줄 때 특히 효과적이다1. 기준이 명확하지 않으면 회로를 먼저 짓지 말고 기준을 먼저 정의하라.
  • 정지 조건은 한 종류가 아니다. 제어를 유지하기 위해 최대 반복 횟수 같은 정지 조건을 쓰고1, "더는 진척 없음"은 비용 효율이 더 좋은 또 하나의 정지 메커니즘이다2. 세 결과(통과 / 회차 소진 / 진척 없음)는 세 개의 서로 다른 하류 행동으로 이어지므로 불리언으로 뭉개지 마라. 결정론적 게이트는 심판보다 앞에 온다.
  • 다섯 패턴은 조합할 수 있다. 이 구성 요소들은 규범이 아니라 개발자가 서로 다른 용례에 맞게 다듬고 조합할 수 있는 흔한 패턴들이며, 성공의 열쇠는 성능을 측정하고 구현을 반복해 다듬는 것이다1.
  • "그래프 / 노드 / 엣지"는 이 레슨 자체의 시각 체계이지 공식 용어가 아니다. 그 1차 자료 닻은 단 한 문장 — 워크플로 스크립트 자체가 루프, 분기, 중간 결과를 쥐고 모델의 컨텍스트는 최종 답만 쥔다2 — 에 중간 결과가 스크립트 변수에 머문다는 것2을 더한 것뿐이다. 여러분 문서에서 이 어휘를 쓸 때는 이 선언을 함께 실어라.
  • 조합의 이득은 문서로 뒷받침된다. 런타임은 실행이 진행되는 동안 각 에이전트의 결과를 추적하며 그것이 같은 세션 안에서 실행을 재개할 수 있게 한다2. 일을 여러 작은 에이전트에게 펼쳐 내보내는 워크플로는 긴 에이전트 하나보다 진척을 더 많이 지켜 낸다2. 계획을 코드로 옮기면 워크플로가 되풀이 가능한 품질 기법(적대적 교차 리뷰, 여러 각도의 초안을 견주기)을 적용할 수 있다2. 결정론적 안전장치(재시도 로직과 정기 체크포인트)가 비결정론적 에이전트를 감싼다4.
  • 제약도 똑같이 분명하다. 결과를 눈에 띄게 개선함이 증명될 때에만 복잡도를 더하는 것을 고려해야 한다1. 노드 수준의 재시도와 타임아웃은 평범한 엔지니어링 관행이며 1차 자료는 종속절 하나만 내놓는다4. 깊이에도 한계가 있어, 제품 수준의 참조는 서브에이전트가 메인 대화 아래로 최대 3계층까지 중첩된다는 것이다5. 가장 단순한 해법이 먼저다1.

>> 레슨 6: 실습: 하네스를 작은 그래프로 끌어올리기

Footnotes

  1. Building Effective AI Agents — Anthropic Engineering — https://www.anthropic.com/engineering/building-effective-agents 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

  2. Orchestrate subagents at scale with dynamic workflows — Claude Code official documentation — https://code.claude.com/docs/en/workflows 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

  3. Writing effective tools for agents — with agents — Anthropic Engineering — https://www.anthropic.com/engineering/writing-tools-for-agents

  4. How we built our multi-agent research system — Anthropic Engineering — https://www.anthropic.com/engineering/multi-agent-research-system 2 3 4

  5. Create custom subagents — Claude Code official documentation — https://code.claude.com/docs/en/sub-agents 2

연습

01

코드는 없습니다. 아래 두 작업 각각에 대해 이 레슨의 시각 체계로 ASCII 그림을 그리되(text 펜스 안에), 모든 노드를 runAgent 루프인지 순수 코드인지 표시하십시오.

레벨 1: 그래프 둘을 그리고 그 회로의 정지 조건 설계하기

작업 하나 · 고객 티켓: 티켓이 들어오면 먼저 분류하고(환불 / 기술 / 불만), 범주에 따라 서로 다른 처리 흐름으로 보냅니다. 처리 뒤에 위험 점수를 매기고, 고위험은 보내기 전에 리뷰 회로를 통과해야 하며, 저위험은 바로 보냅니다.

작업 둘 · 40개 모듈 코드 평가: 한 번의 실행으로 모듈 40개를 평가합니다. 배치로 묶어 팬아웃해 병렬 평가하고, 끝나면 병합하고, 노드 하나가 요약 보고서를 씁니다. 보고서는 게이트를 통과해야 합니다(40개 모듈에 결론이 다 있는가? 점수가 유효 범위인가? 참조가 파싱되는가?). 실패하면 다시 쓰도록 되돌립니다.

그린 다음, 각 그래프의 회로에 정지 조건을 설계하십시오(작업 하나의 리뷰 회로, 작업 둘의 보고서 게이트 회로). 최대 회차는 필수 퓨즈이며 선택에 참여하지 않습니다. "통과"와 "더는 진척 없음" 사이에서 어느 것을 주 정지 메커니즘으로 삼을지 정하고, 다른 하나를 남긴 이유 또는 버린 이유를 설명하십시오.

완료 기준 · 로컬에서 확인
02

코드는 없습니다. 이 레슨의 두 판단 신호 — (1) 사람이 피드백을 또렷하게 말하면 출력이 실제로 눈에 띄게 개선된다, (2) LLM도 그런 피드백을 줄 수 있다 — 로 아래 세 시나리오를 각각 판단하고, 처리 권고를 제시하십시오.

레벨 2: 시나리오 셋, 각 회로를 지을 값어치가 있는지 판단하기

시나리오 하나 · 카피 다듬기: 마케팅 랜딩 페이지 헤드라인 생성기입니다. 프로덕트 매니저는 지금 생성되는 카피가 "쓸 수는 있는데 밋밋하다"고 말하며, 매번 구체적인 지적을 두세 개 줍니다(셀링 포인트가 첫 문장에 안 꽂힌다, 행동 유도가 너무 약하다, 길이가 모바일 두 줄 제한을 넘는다). 그리고 그 피드백 뒤의 판본은 눈에 띄게 좋습니다. 팀은 리뷰 회로를 붙일지 묻습니다.

시나리오 둘 · 재무 합계 검증: 원시 영수증에서 월간 재무 요약을 생성하는 에이전트입니다. 요약의 여러 합계가 자주 맞지 않습니다. 누군가 "감사 에이전트"를 붙여 요약을 읽고 잘못 계산된 부분을 짚어 되돌려 재계산시키고, 감사 에이전트가 승인할 때까지 되풀이하자고 제안합니다.

시나리오 셋 · 컴포넌트 명명 스타일: 새 컴포넌트의 이름을 짓고 문서를 쓰는 에이전트입니다. 프런트엔드 동료 셋의 출력 평가가 만성적으로 어긋납니다. A는 이름이 너무 장황하다고 하고, B는 충분히 설명적이지 않다고 하고, C는 둘 다 괜찮은데 문서 어조가 너무 딱딱하다고 합니다. 누군가 "스타일 리뷰 에이전트"를 문지기로 세운 리뷰 회로를 붙이자고 제안합니다.

완료 기준 · 로컬에서 확인