본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 29. 12:08

워크플로우 시리즈 (02): 디자인 패턴 — 4계층 아키텍처, 3가지 컨텍스트 모드, 그리고 승인 게이트 설계

요약

에이전트 워크플로우의 확장성 문제를 해결하기 위한 4계층 아키텍처와 효율적인 컨텍스트 전달 모드 설계 방법을 다룹니다. 하드코딩된 스크립트의 한계를 극복하고 보안, 비즈니스 로직, 실행 규칙을 분리하는 구조적 접근법을 제시합니다.

핵심 포인트

  • 4계층 아키텍처를 통해 정책, 워크플로우, 템플릿 등을 분리하여 유지보수성 향상
  • 컨텍스트 폭발을 방지하기 위해 필요한 정보만 전달하는 설계의 중요성 강조
  • 상황에 따른 3가지 컨텍스트 모드(accumulate, last_only, explicit) 활용법 제시
  • 계층 분리를 통해 보안 정책과 비즈니스 로직의 간섭을 최소화

스크립트에서 엔지니어링으로

초기 단계의 워크플로우는 종종 모든 설정이 하드코딩된, 모든 것을 설명하는 단일 Markdown 파일인 경우가 많습니다. 이는 소규모 규모에서는 작동합니다. 하지만 워크플로우가 성장함에 따라 세 가지 문제가 발생합니다:

  • 타임아웃 (timeout)을 변경하려면 여러 위치를 찾아 업데이트해야 함
  • 서브에이전트 (Subagent) 작업 프롬프트가 워크플로우 정의 곳곳에 흩어져 있어 독립적인 테스트가 불가능함
  • 보안 정책 (Security policy)과 비즈니스 로직 (business logic)이 뒤섞여 있어 컴플라이언스 (compliance) 검토가 고통스러움

4계층 아키텍처 (four-layer architecture)는 이 세 가지 문제를 모두 해결합니다.

4계층 아키텍처 (Four-Layer Architecture)

정책 계층 (Policy Layer)     policy.md         실행 규칙, 글로벌 제약 조건
                                    → 누가 무엇을 할 수 있는지; 고위험 작업에 대한 권한 부여

...

핵심 원칙: 각 계층은 오직 자신의 관심사만 변경하며, 계층 간에 아무것도 교차하지 않습니다.

# ✅ 올바른 예: 분석 타임아웃 변경 → workflow.md 수정
phase_3_analyze:
  timeout: 30m  ← 워크플로우 계층 (Workflow Layer) 변경
...

계층 분리는 변경을 안전하게 만듭니다: templates/를 편집하는 것은 해당 서브에이전트의 출력에만 영향을 미칩니다. policy.md를 편집한다고 해서 라우팅 로직 (routing logic)이 실수로 깨지지는 않습니다.

컨텍스트 전달 모드 (Context Passing Modes)

서브에이전트가 무엇을 알아야 하는지를 결정하는 과정에서 워크플로우 설계가 가장 자주 실패합니다.

메인 에이전트 (Agent)의 전체 히스토리를 모든 서브에이전트에게 전달하는 것이 가장 흔한 실수입니다. 컨텍스트 (Context)가 폭발합니다: 서브에이전트의 속도가 느려지고, 출력 품질이 떨어지며, 토큰 비용 (token cost)이 두 배로 증가합니다.

서브에이전트가 실제로 필요로 하는 것에 따라 전달 모드를 선택하세요. 세 가지 모드가 있습니다:

accumulate (누적)

정의: 워크플로우가 지금까지 생성한 모든 관련 출력을 전달합니다.

사용 시기: 서브에이전트가 이전의 여러 단계로부터 결론을 종합해야 할 때 사용합니다.

# 단계 7: 종료 알림 작성, 워크플로우 전체의 결론이 필요함
phase_7_notify:
  context_mode: accumulate
...

단계 7의 서브에이전트는 근본 원인 (root cause), 수정 요약 (fix summary), 커밋 결과 (commit outcome), 그리고 리뷰 상태 (review status)가 필요합니다. 이 중 하나라도 누락되면 불완전한 알림이 생성됩니다.

last_only (마지막 항목만)

정의 (Definition): 직전 단계 또는 단계의 출력값만 전달합니다.

사용 시점 (When to use): 서브에이전트(subagent)의 작업이 직전 단계에 전적으로 의존하며, 이전 히스토리가 무관할 때 사용합니다.

# Phase 2: 로그 파일 추출 — Phase 1의 첨부 파일 경로만 필요함
phase_2_extract_logs:
  context_mode: last_only
...

로그를 추출할 때는 Jira 티켓의 전체 상세 정보가 필요하지 않으며, 파일이 어디에 있는지만 알면 됩니다. Phase 1의 모든 출력을 전달하는 것은 컨텍스트 (context)를 낭비하는 일입니다. last_only는 필요한 것만 가져오도록 강제합니다.

explicit (명시적)

정의 (Definition): 이전의 어떤 단계에서든 가져오더라도, 서브에이전트가 필요로 하는 모든 특정 필드 (field)를 지정합니다.

사용 시점 (When to use): 서브에이전트가 여러 단계에서 특정 필드들을 필요로 하지만, 단일 단계의 전체 출력값은 필요하지 않을 때 사용합니다.

# Phase 3: 근본 원인 분석 — bug_info (Phase 1) + log_dir (Phase 2) 필요
phase_3_analyze:
  context_mode: explicit
...

Phase 3에는 버그 설명(Phase 1에서 가져옴)과 로그 디렉토리(Phase 2에서 가져옴)가 필요하지만, Phase 1의 첨부 파일 경로 나 Phase 2의 원시 추출 로그는 필요하지 않습니다. explicit 모드는 서브에이전트로 흐르는 데이터를 정밀하게 제어합니다.

모드 선택하기 (Choosing a Mode)

서브에이전트가 여러 단계의 결론을 종합함  → accumulate
서브에이전트가 직전 단계에만 의존함        → last_only
서브에이전트가 여러 소스에서 특정 필드를 필요로 함 → explicit (권장 기본값)

explicit은 가장 안전한 기본값입니다. 서브에이전트에게 무엇이 필요한지 확실하지 않더라도, 특정 필드들을 지정하는 것부터 시작하십시오. 과도하게 많은 정보를 전달하는 것보다 디버깅하기가 더 쉬우며, 데이터 의존성 (data dependencies)을 명시적으로 문서화할 수 있습니다.

승인 게이트 설계 (Approval Gate Design)

승인 게이트 (Approval gates)는 사람이 개입하는 노드 (node)입니다. 불완전한 게이트 정의는 운영 사고 (production incidents)의 흔한 원인이 됩니다.

세 가지 게이트 유형 (Three Gate Types)

interrupt (차단형)
  사람이 응답할 때까지 워크플로우가 완전히 일시 중지됨
  용도: 고위험 작업 (코드 병합, 운영 환경 배포)
...

다섯 가지 필수 필드 (Five Required Fields)

# 완전한 승인 게이트 정의
- gate_id: gate_B
  type: interrupt
...

timeout_action은 가장 빈번하게 누락되는 필드입니다. 옵션은 다음과 같습니다:

pause    → 타임아웃 후 워크플로우를 일시 중단하고, 사람이 재개할 때까지 대기 (가장 일반적)
continue → 타임아웃 후 기본 옵션으로 진행 (저위험 알림 게이트)
abort    → 타임아웃 후 전체 워크플로우를 종료 (엄격한 시간 제한 작업)

timeout_action이 없는 게이트는 워크플로우를 무기한 대기 상태로 방치합니다. 즉, 알림이 발생하지 않고, 기록이 작성되지 않으며, 복구 경로도 존재하지 않게 됩니다.

승인 게이트 메시지 설계 (Approval Gate Message Design)

게이트 메시지는 사람이 읽습니다. 이는 의사결정이 얼마나 빨리 내려질지를 직접적으로 결정합니다.

✅ 효과적인 게이트 메시지:
  "테스트 통과율: 67% (8/12 통과)
   실패한 테스트: test_null_input, test_overflow
...

좋은 메시지는 검토자가 30초 이내에 결정할 수 있게 합니다. 나쁜 메시지는 검토자를 로그(logs)로 달려가게 만듭니다.

직렬 재시도 vs 병렬 후보군 (Serial Retry vs Parallel Candidates)

워크플로우가 실패에 직면했을 때, 두 가지 대응 전략이 존재합니다. 잘못된 전략을 선택하면 효율성이나 품질이 저하됩니다.

직렬 재시도 (Serial Retry)

시도 1 → 실패
           ↓ (실패 원인 + 피드백 포함)
시도 2 → 실패
...

사용 시점: 오류 원인이 구체적이고, 이후의 시도가 이전의 실패로부터 학습할 수 있으며, 관점이나 접근 방식에 유의미한 변화를 줄 수 있을 때 사용합니다.

예시: 근본 원인 분석 (Phase 3)
  시도 1: 코드 관점에서 분석
  시도 2: 피드백 "코드 분석 신뢰도 낮음 — 로그 이상 패턴을 시도할 것"
...

병렬 후보군 (Parallel Candidates)

            → 후보 A → 테스트 → 통과  ← 이것을 선택
분석 →  → 후보 B → 테스트 → 실패
            → 후보 C → 테스트 → 실패

사용 시점: 솔루션 공간(solution space)이 다양하고, 어떤 접근 방식이 작동할지 예측하는 것이 불가능하며, 여러 옵션을 동시에 탐색한 후 최적의 것을 선택하는 것이 직렬 탐색보다 효율적일 때 사용합니다.

예시: 코드 수정 (Phase 4)
  후보 A: 경계 검사(boundary check) 로직 수정
  후보 B: 호출자(caller)의 입력 유효성 검사 수정
...

선택 원칙 (Selection Principle)

이전의 실패로부터 이후의 시도가 학습할 수 있음 → 직렬 재시도 (serial retry)
여러 접근 방식이 동일하게 타당함 → 병렬 후보 (parallel candidates)
시간에 민감하여 직렬 지연을 감수할 수 없음 → 병렬 후보 (parallel candidates)
...

워크플로우 정의(workflow definition)에 전략을 문서화하세요. 이는 디버깅을 직관적으로 만들어 줍니다:

phase_3_analyze:
  retry_strategy: serial          # 다양한 관점, 실패로부터 학습
  max_retries: 3
...

디자인 체크리스트 (Design Checklist)

4계층 분리 (Four-layer separation)

  • 정책 (Policy, 권한/보안)과 워크플로우 (Workflow, 라우팅/구조)가 별도의 파일로 분리되어 있는가
  • 서브에이전트 (Subagent) 작업 프롬프트가 독립적인 templates/ 파일에 존재하는가
  • config.yaml에 가변 파라미터 (타임아웃, 재시도 횟수 등)가 중앙 집중화되어 있는가

컨텍스트 전달 (Context passing)

  • 모든 서브에이전트 호출 시 context_mode를 선언하는가
  • explicit 모드에서 특정 필드만 나열하는가 — 단계(Phase) 전체 출력을 전달하지 않는가
  • 메인 에이전트 (Main Agent)의 전체 히스토리가 모든 서브에이전트에게 전송되지 않는가

승인 게이트 (Approval gates)

  • 모든 게이트에 timeouttimeout_action이 모두 설정되어 있는가
  • 메시지가 30초 이내의 의사결정을 내릴 수 있을 만큼 충분한 정보를 포함하고 있는가
  • 옵션 값들이 자유 텍스트가 아닌 열거형 타입 (enumerated types)으로 되어 있는가

재시도 전략 (Retry strategy)

  • 재시도 로직이 있는 모든 노드에 serial 또는 parallel 레이블이 붙어 있는가
  • 직렬 재시도 (Serial retries)의 경우 feedback_mode가 설정되어 있는가 (실패 원인이 생성기(generator)로 피드백됨)
  • 병렬 후보 (Parallel candidates)의 경우 정의된 selection_criteria가 있는가

요약 (Summary)

  1. 4계층 아키텍처 (four-layer architecture)의 가치는 격리(isolation)에 있습니다: 정책(Policy) 변경이 라우팅(routing)에 영향을 주지 않으며, templates/ 변경 사항은 독립적으로 테스트할 수 있습니다. 이것이 유지보수성(maintainability)의 근간입니다.
  2. 컨텍스트 (Context) 전달 시 explicit 방식이 가장 안전한 기본값입니다: 모든 필드를 명시하며, accumulate 방식보다 토큰(token) 소모가 적고, last_only 방식보다 유연하며, 문제가 발생했을 때 디버깅(debug)하기가 더 쉽습니다.
  3. 직렬 재시도 (Serial retry) 대 병렬 후보 (Parallel candidates)는 방향성의 선택입니다: 근본 원인 분석 (root cause analysis)에는 직렬 재시도가 유리하며 (학습이 효과적임), 코드 수정 (code fix)에는 병렬 후보 방식이 유리합니다 (솔루션 공간이 다양함). 이 둘을 반대로 적용하면 효율성과 품질이 모두 저하됩니다.

실제 엔터프라이즈급 워크플로우에서 검증된 AI 에이전트와 기술의 큐레이션 마켓플레이스인 PrimeSkills를 확인해 보세요. 군더더기 없이 실제로 작동하는 것들만 제공합니다.

홈페이지에서 더 유용한 지식과 흥미로운 제품들을 찾아보세요.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0