
Claude Code 「Dynamic Workflows」 완전 가이드: 6가지 패턴과 14단계
요약
Claude Code의 새로운 기능인 Dynamic Workflows를 활용하여 복잡한 코딩 태스크를 해결하는 방법론을 소개합니다. 에이전트가 스스로 맞춤형 하네스를 작성하여 에이전트적 태만, 자기 우선 편향, 목표 드리프트 문제를 구조적으로 해결하는 6가지 패턴을 다룹니다.
핵심 포인트
- Dynamic Workflows는 Claude가 태스크 전용 하네스를 직접 작성하는 메커니즘임
- 에이전트적 태만, 자기 우선 편향, 목표 드리프트 문제를 해결 가능
- 정적 워크플로우와 달리 컨텍스트에 맞춘 맞춤형(Order-made) 워크플로우 생성
- agent(), parallel(), pipeline() 등의 코어 API를 활용한 협업 가능
Claude Code를 능숙하게 사용하는 사람이라도, Dynamic Workflows를 아직 시도해보지 않은 경우가 많은 것 같습니다. 2026년 5월 28일에 출시된 이 기능에 대해, Anthropic의 엔지니어들이 실제로 사용하고 있는 6가지 패턴과 14단계 로드맵을 정리했습니다.
Dynamic Workflows란 무엇인가
일반적인 Claude Code는 계획과 실행을 동일한 컨텍스트 윈도우 (Context Window) 내에서 수행합니다. 단기~중기 규모의 코딩 태스크라면 이것으로 충분합니다. 하지만 장시간 가동, 대규모 병렬 처리, 고도로 구조화된 태스크, 또는 적대적 검증 (Adversarial Verification)이 필요한 케이스에서는 단일 윈도우 접근 방식이 한계에 부딪히게 됩니다.
Dynamic Workflows란, Claude가 해당 태스크 전용 하네스 (Harness)를 그 자리에서 작성하는 메커니즘입니다. 서브 에이전트 (Sub-agent)의 생성과 협업을 담당하는 특수 함수와 일반적인 JavaScript (Math・JSON・Array)를 조합한 파일을 Claude가 생성하여, 에이전트 간에 흐르는 데이터를 처리합니다.
실행 방법은 두 가지가 있습니다. Claude에게 직접 "이 워크플로우를 만들어줘"라고 요청하거나, ultracode라는 트리거 워드를 사용하는 것입니다. 워크플로우가 중단되더라도 세션을 재개하면 멈췄던 지점부터 다시 시작할 수 있습니다.
워크플로우가 해결하는 3가지 실패 패턴
동적 워크플로우가 필요한지 판단하려면, 그것이 무엇을 수정하는지 이해해야 합니다. Claude가 복잡한 태스크를 단일 컨텍스트 윈도우에서 장시간 처리하면 다음과 같은 세 가지 문제가 발생하기 쉽습니다.
Agentic laziness (에이전트적 태만): 복잡한 다단계 태스크를 완료하기 전에 멈추고 "완료"라고 선언해 버리는 경우. 보안 리뷰 20건에 대응해야 하는데 나머지는 "처리 완료"라고 주장하는 케이스가 이에 해당합니다. -
Self-preferential bias (자기 우선 편향): 자신의 출력을 루브릭 (Rubric)과 대조하여 검증 및 평가할 때, Claude는 자신의 결과를 우선시합니다. 이해관계가 얽힌 검증자는 공정한 심판이 될 수 없습니다. -
Goal drift (목표 드리프트): 많은 턴 (Turn)이 지나면서 원래 목표에 대한 충실도가 점차 떨어지는 현상입니다. 컨텍스트 압축 (Context Compression) 이후에 특히 두드러지며, "X를 하지 않는다"라는 제약 조건이 47번째 턴에서는 슬그머니 사라져 버리기도 합니다.
워크플로우는 이를 구조적으로 해결합니다. 고유한 컨텍스트, 집중된 목표, 독립된 상태를 각각 가진 별도의 Claude를 사용하기 때문입니다.
정적 워크플로우와 Dynamic Workflows의 차이
Claude Agent SDK나 claude -p를 사용하여 여러 Claude Code 인스턴스를 협업시키는 정적 워크플로우를 이미 사용 중인 분들도 있을 것입니다. 차이점은 다음과 같습니다.
정적 워크플로우: 모든 엣지 케이스 (Edge Case)를 다루기 위해 단 한 번 작성되는 범용적인 방식입니다. 작동은 하지만 보수적일 수밖에 없습니다. -
Dynamic Workflows: Claude가 이 태스크를 위해 이 워크플로우를 직접 작성합니다. 하네스는 맞춤형(Order-made)으로 제작됩니다.
동적 버전이 우월한 이유는 단계의 수가 아니라, 워크플로우 자체가 당신의 컨텍스트에 맞춰 스스로를 형성할 수 있기 때문입니다. 자신의 코드를 읽고, 실제 새로운 프로바이더 (Provider)의 문서와 각 기능을 대조하며, 트랜잭션 양에 따른 가격을 산출하고, 자신이 내놓은 답에 대해 "왜 이전을 하지 않는가"라는 적대적 검증 패스를 실행할 수 있습니다.
agent(), parallel(), pipeline()
코어 API: 세 가지 함수로 대부분의 작업을 수행합니다. 이를 파악해 두면 Claude가 작성하는 어떤 워크플로우도 읽을 수 있고, 특정 형태로 유도할 수도 있습니다.
: 단일 서브 에이전트를 생성하는 agent()`
: 배리어 (Barrier) 타입. 한꺼번에 전개하여 모든 결과가 돌아올 때까지 기다리는 parallel()`
: 스트리밍 (Streaming) 타입. 각 아이템이 모든 스테이지를 독립적으로 통과하는 pipeline()`
선택 기준은 "다음 처리를 하기 전에 모든 결과가 필요한가?"라는 질문으로 결정됩니다. 필요하다면 parallel(), 필요하지 않다면 pipeline() (비용 및 처리량 측면에서 유리)을 선택합니다.
6가지 패턴
패턴 1: Classify-and-act (분류 후 실행)
태스크의 종류를 분류 에이전트가 결정하면, 워크플로우가 그 답변에 따라 서로 다른 에이전트나 처리 과정으로 배분합니다.
효과가 높은 상황은 다음과 같습니다.
- 태스크가 이종 혼재되어 있어, 서브타입(Subtype)별로 서로 다른 처리가 필요할 때
- 고가의 모델을 복잡한 부분에만 사용하고 싶을 때 (분류는 저렴한 모델, 복잡한 처리는 Opus에만 할당)
예를 들어, "인증 모듈의 구조를 설명해줘"라는 요청이 있을 때입니다. 분류 서브 에이전트(Sub-agent)가 먼저 코드베이스를 읽고 복잡도를 추정하여, 10개의 파일로 구성된 모듈이라면 Sonnet에, 100개의 파일이라면 내용을 이해한 뒤 Opus에 할당합니다.
패턴 2: Fan-out-and-synthesize (전개 및 통합)
태스크를 많은 작은 단계로 분할하고, 각 단계에 에이전트를 병렬로 실행한 뒤, 결과를 하나의 답변으로 통합합니다.
// 전개: 파일마다 1개의 에이전트. 배리어(Barrier): 모두가 완료될 때까지 대기
const reviews = await parallel(
files.map(file => () => agent(
...
이 패턴이 실무에서 다용되는 이유는, 단일 컨텍스트 작업의 "한 번에 너무 많은 양을 처리하려는" 실패를 해결하기 때문입니다. 각 서브 에이전트는 자신의 담당 부분만 봅니다. 오케스트레이터(Orchestrator)가 50개의 무관한 세부 사항에 주의를 빼앗기지 않습니다.
사용 시점의 기준은 3가지입니다.
- 작업 항목을 명확하게 열거할 수 있을 때 (50개 파일, 200개 엔드포인트, 100개 리뷰)
- 각 항목이 독립적이며, 다른 항목의 출력을 필요로 하지 않을 때
- 마지막에 파편화된 부분 보고서가 아니라, 통합된 하나의 답변을 원할 때
패턴 3: Adversarial verification (적대적 검증)
자기 선호 편향(Self-preferential bias)에 대한 구조적인 수정책입니다. 생성된 에이전트마다, 별도로 생성된 다른 에이전트가 루브릭(Rubric)에 기반하여 출력을 적대적으로 검증합니다. 검증자는 원래의 작업을 보지 않았기 때문에, 그 작업에 편향될 수 없습니다.
중요한 것은 페어링(Pairing) 규칙입니다: 검증자는 루브릭과 결과물만 알아야 하며, 누가 생성했는지는 알지 못해야 한다. 그렇지 않으면 프롬프트의 힌트를 통해 자기 선호 편향이 개입될 수 있습니다.
이 패턴이 특히 중요한 상황은 다음과 같습니다.
- 보고서 내의 모든 사실적 기술을 별도의 검증 서브 에이전트가 원본 소스에 대해 확인하는 팩트 체크(Fact check)
- 작성자 에이전트가 수정 사항을 작성하면, 리뷰어 에이전트(별도의 컨텍스트)가 이를 검토하는 코드 리뷰(Code review)
- 무언가가 출시되기 전, 그것에 대한 가장 취약한 사례를 찾아내려는 품질 게이트(Quality gate)
패턴 4: Generate-and-filter (생성 및 필터링)
특정 주제에 대해 아이디어를 생성하고, 루브릭이나 검증을 통해 필터링하며, 중복을 제거하여 품질이 높은 것들만 반환합니다.
"최선의 답변"을 찾는 것의 반대 방식입니다. 최선의 답변만을 찾으려 하면 Claude는 조기에 결론을 내립니다(Commit). Generate-and-filter는 모든 옵션이 평가된 후에야 뒤늦게 결론을 내리도록 합니다.
패턴 5: Tournament (토너먼트)
작업을 분할하는 대신, 에이전트들을 경쟁시킵니다. N개의 에이전트가 각각 서로 다른 접근 방식으로 동일한 태스크에 임하며, 한 쪽이 승리할 때까지 페어와이즈(Pairwise) 형식으로 결과를 심사합니다.
점수로 정렬하는 것보다 신뢰도가 높은 이유: 1,000개의 아이템을 하나의 프롬프트로 정렬하려고 하면 품질이 저하되고 컨텍스트(Context)에도 담기지 않습니다. 토너먼트는 대진표(Bracket)를 신선한 에이전트들에게 분할하여, 각각이 단 2개의 아이템만 비교하게 합니다. 대진표 자체는 코드 내의 결정론적인 루프(Loop, 컨텍스트가 아님)에 존재합니다.
디자인 선택, 후보자 선정, 콘텐츠 우선순위 지정과 같은 선호도 기반의 랭킹에도 동일한 아이디어를 사용할 수 있습니다.
패턴 6: Loop until done (완료될 때까지 반복)
작업량이 불분명한 태스크에 대해, 고정된 횟수의 패스(Pass)를 실행하는 대신, 중지 조건이 충족될 때까지 에이전트 생성을 루프(Loop)합니다. 중지 조건의 예로는 "새로운 발견이 없음", "로그에 에러가 없음", "이론이 검증됨" 등이 있습니다.
"실제로 완료될 때까지 계속한다"에 대한 해답입니다.
- 불안정한(Flaky) 테스트 디버깅: 재현, 가설 수립, 테스트를 하나의 이론이 성립할 때까지 반복
- 버그 헌팅(Bug hunting): 완전한 패스에서 결과가 0이 나올 때까지 계속해서 버그를 탐색
- 패턴 발굴: 새로운 클러스터가 나타나지 않을 때까지 클러스터링과 규칙 식별을 반복
/goal
와(과) 쌍을 이루어 완료 요건을 설정하세요 ("하나의 이론이 작동할 때까지 멈추지 마라"). 정지 조건은 코드에 있습니다. 활성 반복(Active iteration)만이 컨텍스트에 남습니다.
패턴의 조합 방법
실제 워크플로우에서는 2~4개의 패턴을 조합합니다.
| 유스케이스 | 사용하는 패턴 |
|---|---|
| 마이그레이션·리팩터링 | Fan-out → Adversarial verification → Loop until done |
| ... |
패턴을 내면화하는 올바른 방법은, 현재 태스크가 어떤 실패 모드에 빠져 있는지를 식별하고, 그것을 구조적으로 방지할 패턴을 선택하는 것입니다.
- 드리프트(Drift)가 발생하고 있다 → Fan-out
- 자기 우선주의(Self-preferential bias)가 문제다 → Adversarial verification
- 끝이 보이지 않는다 → Loop until done
- 스코어링(Scoring)이 어렵다 → Tournament
/goal
, /loop
, 토큰 예산
운용 팁: 워크플로우는 비용이 증가합니다. 세 가지 설정을 통해 "멋지지만 비싼 것"에서 "무인으로 실행 가능한 도구"로 바뀝니다.
: 엄격한 완료 요건을 설정합니다. Loop 패턴과 쌍을 이룹니다 ("하나의 이론이 작동할 때까지 멈추지 마라"). /goal
/goal
이 없으면 첫 번째 소프트한 완료 지점에서 멈춥니다. -
: 워크플로우 전체를 반복적인 스케줄로 실행합니다. 지속적으로 실행하고 싶은 워크플로우에 사용합니다 (트리아지(Triage), 주간 리서치 업데이트, 정기 검증). /loop
명시적인 토큰 예산: 프롬프트로 "1만 토큰을 사용해"라고 전달합니다. 이것이 없으면 야심 찬 워크플로우가 기대치의 5~10배로 불어납니다.
> ultracode 이 전제에 대한 빠른 적대적 리뷰:
"Postgres로의 마이그레이션에서 샤드 재균형(rebalancing)이 불필요해짐"
5k 토큰 사용해. /goal 반례 혹은 3가지 독립적인 확인이
...
Anthropic 팀도 "베스트 프랙티스는 아직 발전 중입니다. Dynamic Workflows는 토큰을 많이 사용하는 경우가 많으므로, 언제 어떻게 사용할지 신중하게 생각하십시오"라고 말합니다. 일반적인 Claude Code 세션이 5분이면 끝날 태스크라면 워크플로우는 불필요합니다.
신뢰할 수 없는 입력에는 Quarantine 패턴을
지원 티켓, 버그 리포트, 사용자 피드백, 스크레이핑된 데이터 등 신뢰할 수 없는 공개 콘텐츠를 읽는 워크플로우는 프롬프트 인젝션(Prompt Injection) 가능성을 전제로 해야 합니다.
해결책은 Quarantine(격리)입니다. 신뢰할 수 없는 콘텐츠를 읽는 에이전트는 높은 권한의 액션을 실행할 수 없도록 제한합니다. 원본 콘텐츠에 직접 접촉하지 않는 별도의 에이전트가 실제 액션을 담당합니다.
사용자가 제출한 콘텐츠를 처리할 때, 공개 웹 페이지를 스크레이핑할 때, 서드파티 API의 출력을 처리할 때는 반드시 적용하십시오. 읽기 전용 리더 에이전트는 비용이 거의 들지 않으면서 프롬프트 인젝션 리스크를 통째로 제거할 수 있습니다.
워크플로우를 저장하여 Skill로 배포하기
워크플로우가 제대로 작동한다면 저장하십시오. 워크플로우 메뉴에서 s를 누릅니다. 저장된 워크플로우는 ~/.claude/workflows에 들어갑니다. 거기서 두 가지 선택지가 있습니다.
- 로컬에 유지하여 자신의 프로젝트 전체에서 재사용한다.
- Skill로 배포한다: JavaScript 파일을 Skill 폴더 내에 번들링하고,
SKILL.md에서 참조하면 해당 Skill을 설치한 누구라도 동일한 워크플로우를 실행할 수 있습니다.
한 가지 실용적인 포인트: 워크플로우를 Skill로 패키징할 때, Claude에게 "이 워크플로우를 그대로 실행하는 스크립트가 아니라, 템플릿으로 취급해줘"라고 지시하십시오. 그렇게 하면 전체적인 구조를 유지하면서도 태스크에 따라 워크플로우의 형태를 적용할 여지가 생깁니다.
흔한 실수
- 일반적인 Claude Code 세션으로 충분한데 워크플로우를 사용한다. 대부분의 전통적인 코딩 태스크는 5명의 리뷰어 패널을 필요로 하지 않는다.
- 토큰 예산 없음. 명시적인 캡(Cap)이 없는 야심 찬 워크플로우는 5~10배로 불어난다.
- 하나의 에이전트가 작업과 검증을 모두 수행한다. 자기 우선주의 편향(Self-preferential bias)이 검증자가 작업자를 편들게 만든다. 두 역할은 분리되어야 한다.
parallel()
및 pipeline()
을 호환되는 것으로 취급한다. 배리어(Barrier)가 중요하다. parallel()은 모든 것을 기다리고, pipeline()은 스트림(Stream)한다. 루프(Loop) 패턴에서 /goal을 생략한다. 워크플로(Workflow)가 첫 번째 소프트 완료 지점에서 조기 종료되도록 한다. 신뢰할 수 없는 콘텐츠를 액터(Actor)에게 전달하지 마라. 사용자 제출물을 처리한다면 격리(Isolation)는 생략할 수 없다.
- 절대 점수(Absolute score)로 정렬한다. 비교 판단이 신뢰성이 더 높으므로 토너먼트(Tournament) 방식을 사용한다.
- 작동하는 워크플로를 저장하지 않는다. 매주 같은 형태를 다시 프롬프트(Re-prompt)하는 것은 시간 낭비다.
Dynamic Workflows는 아직 베스트 프랙티스(Best practice)가 발전 중인 기능입니다. 하지만 6가지 패턴과 실패 모드(Failure mode) 사이의 대응 관계를 머릿속에 넣어둔다면, 어떤 태스크가 "워크플로에 적합한지"에 대한 판단이 상당히 명확해질 것입니다. ultracode에서 시도해 보는 것이 가장 빠른 길입니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기