Workflow와 Agent: 제어 흐름의 두 축
제어 흐름의 소재지
섹션 제목: “제어 흐름의 소재지”에이전틱 시스템을 설계할 때 가장 먼저 던져야 하는 질문이 있다. “누가 다음 단계를 결정하는가?” 이 물음에 대한 답이 워크플로와 에이전트를 가르는 핵심 기준이다.
워크플로(Workflow) 는 제어 흐름이 코드에 하드코딩된 시스템이다. 개발자가 “A 단계 다음에 B, 조건 C이면 D, 그렇지 않으면 E”라고 사전에 정의해 놓는다. LLM은 이 미리 짜인 파이프라인의 각 노드에서 텍스트를 생성하거나 판단을 내리는 역할을 할 뿐, 파이프라인 자체의 구조를 바꾸지는 않는다. 실행 경로는 항상 예측 가능하고 결정론적이다.
에이전트(Agent) 는 제어 흐름의 결정권이 모델에게 있는 시스템이다. 모델이 어떤 도구를 쓸지, 몇 번 반복할지, 언제 멈출지를 스스로 판단한다. 코드는 루프의 뼈대와 가드레일만 제공한다. 실행 경로는 런타임까지 알 수 없다.
두 방식의 구조 비교
섹션 제목: “두 방식의 구조 비교”워크플로 (제어 흐름이 코드에 고정)───────────────────────────────────────────────── [입력] → [LLM 1: 분류] → [LLM 2: 처리A] └→ [LLM 3: 처리B] → [출력] 경로는 개발자가 사전에 결정. 런타임 변경 없음.
에이전트 (제어 흐름이 모델에게 위임)───────────────────────────────────────────────── [입력] → ┌─────────────────────────────┐ │ LLM: 다음 행동 결정 │ │ ↕ (tool_calls / end_turn) │ │ 도구 실행 → 관찰 → 재추론 │ └─────────────────────────────┘ → [출력] 루프 횟수·도구 선택은 모델이 런타임에 결정.Anthropic은 이 두 가지를 상호 배타적인 범주가 아니라 스펙트럼으로 본다. 많은 실용적 시스템은 워크플로의 특정 단계 안에서 에이전트를 호출하거나, 에이전트가 하위 워크플로를 실행하는 혼합 구조를 취한다.
비교표: 언제 무엇을 선택할까
섹션 제목: “비교표: 언제 무엇을 선택할까”| 기준 | 워크플로 | 에이전트 |
|---|---|---|
| 제어 흐름 결정자 | 개발자 (코드) | 모델 (런타임) |
| 예측 가능성 | 높음 | 낮음 |
| 유연성 | 낮음 | 높음 |
| 디버깅 난이도 | 쉬움 | 어려움 |
| 적합 작업 | 반복·정형화된 프로세스 | 불확실·개방적 문제 |
| 실패 모드 | 경로 설계 오류 | 루프 이탈·목표 표류 |
| 비용 예측성 | 결정론적 | 이터레이션 수에 따라 가변 |
“단순하게 시작하라” 원칙
섹션 제목: ““단순하게 시작하라” 원칙”Anthropic의 Building Effective AI Agents 가이드에서 가장 강조하는 권고 사항이 있다. 작업에 필요한 최소한의 구조를 선택하라. 에이전트는 더 유연하지만 그만큼 설계·디버깅·비용 통제가 어렵다. 워크플로로 충분히 풀 수 있는 문제에 에이전트를 도입하는 것은 불필요한 복잡도를 추가하는 일이다.
일반적인 선택 기준은 다음과 같다.
- 작업 경로가 예측 가능하고 단계가 고정되어 있다면 → 워크플로
- 작업의 단계나 순서가 입력에 따라 달라지고 사전에 정의하기 어렵다면 → 에이전트
- 확신이 없다면 → 워크플로로 시작해 에이전트가 필요한 순간에 점진적으로 전환
Simon Willison도 같은 맥락에서 경고한다. 에이전틱 루프는 멈추지 않거나, 실패를 반복하거나, 엉뚱한 방향으로 흘러갈 수 있다. 이 리스크를 감수할 만큼 유연성이 필요한지 먼저 물어봐야 한다.
코드로 보는 구조적 차이
섹션 제목: “코드로 보는 구조적 차이”개념 이해용 의사 코드이며 실제 API와 다를 수 있습니다.
# ── 워크플로: 경로가 코드에 고정 ──────────────────────────────def classify_and_route(text: str) -> str: # 단계 1: 분류 (항상 실행) category = model.generate(f"분류하라: {text}")
# 단계 2: 분기 (개발자가 결정) if "고객 불만" in category: return model.generate(f"사과 응답 작성: {text}") else: return model.generate(f"일반 응답 작성: {text}") # 경로는 고정. 추가 이터레이션 없음.
# ── 에이전트: 경로를 모델이 런타임에 결정 ──────────────────────def agent_handle(task: str, tools: list) -> str: messages = [{"role": "user", "content": task}]
while True: response = model.generate(messages, tools=tools)
if response.stop_reason == "end_turn": return response.text
# 모델이 어떤 도구를 몇 번 쓸지 스스로 결정 for call in response.tool_calls: result = execute_tool(call) messages.append({"role": "tool", "content": result})워크플로 함수는 최대 두 번의 모델 호출이 발생한다. 에이전트 함수는 모델이 end_turn을 선언할 때까지 임의의 횟수로 반복한다.
혼합 접근: 현실의 시스템
섹션 제목: “혼합 접근: 현실의 시스템”대부분의 프로덕션 에이전틱 시스템은 순수 워크플로도 순수 에이전트도 아니다. 예를 들어, 고객 서비스 시스템에서 “어떤 팀에 라우팅할지”는 워크플로로 정의하고, 라우팅된 이후 “구체적인 문제 해결”은 에이전트에게 맡기는 구조가 흔하다. Anthropic은 이를 “에이전트를 적절한 제약 안에 배치하라”는 원칙으로 요약한다.
다음 챕터에서는 프롬프트 엔지니어링, 컨텍스트 엔지니어링, 루프 엔지니어링이 어떻게 서로를 흡수하며 발전해 왔는지 그 계보를 살펴본다.
참고 자료
- Anthropic — Building Effective AI Agents — 접속 2026-06-30
- Simon Willison — Designing Agentic Loops — 접속 2026-06-30