에이전트 관련 책과 프레임워크가 쏟아지면서 “일단 에이전트로 만들자”는 결정이 늘고 있습니다. 그런데 막상 구현에 들어가면 첫 갈림길에서 막힙니다. ReAct로 충분한지, 계획을 먼저 세우는 구조가 나은지, 에이전트를 여러 개로 나눠야 하는지 — 패턴 선택 기준이 없으면 프레임워크 예제를 복사하는 수준을 벗어나기 어렵습니다.
결론부터 말하면 절차가 미리 정해지는 일은 워크플로로, 경로를 실행 중에 정해야 하는 일만 에이전트로 만들고, 에이전트는 단일 ReAct 루프에서 시작해 병목이 확인될 때만 Plan-Execute·Multi-Agent로 확장하는 것이 안전합니다. 이 글에서는 실무에서 검증된 에이전트 설계 패턴 5가지와 선택 기준, 안전장치 설계를 정리합니다.
에이전트의 도구 호출 출력을 안정화하는 방법은 vLLM Structured Outputs 완전정리와 함께 보면 좋습니다. 개념을 책으로 먼저 잡고 싶다면 『에이전트 시대의 AI 시스템 설계』 리뷰를 참고하세요.
핵심 요약
- 에이전트의 최소 정의는 “LLM이 도구 호출 결과를 보고 다음 행동을 스스로 정하는 루프”입니다. 루프가 없으면 워크플로입니다.
- ReAct는 가장 단순하고 디버깅이 쉬운 기본값입니다. 대부분의 사내 자동화는 여기서 끝나도 됩니다.
- Plan-and-Execute는 단계가 많고 중간에 길을 잃는 작업에, Reflection은 품질 기준이 명확한 생성 작업에 효과적입니다.
- Multi-Agent는 도구가 너무 많거나 역할별 컨텍스트 분리가 필요할 때만 도입합니다. 에이전트 수가 늘수록 비용·지연·실패 지점이 곱으로 늘어납니다.
- 모든 패턴에 최대 반복 횟수, 도구 권한 범위, 사람 승인 지점이라는 3중 안전장치를 먼저 설계해야 운영에 올릴 수 있습니다.
- 도구 연결의 사실상 표준으로 MCP(도구·컨텍스트 연결)와 A2A(에이전트 간 통신) 같은 프로토콜이 자리 잡는 추세입니다.
1. 에이전트가 필요한 일인지부터 판단하기
가장 흔한 실패는 패턴 선택이 아니라 에이전트가 필요 없는 일에 에이전트를 쓰는 것입니다.
| 구분 | 워크플로(체인) | 에이전트 |
|---|---|---|
| 실행 경로 | 코드로 미리 고정 | LLM이 실행 중 결정 |
| 예시 | 문서 요약 → 분류 → 저장 | “이 장애 원인 찾아서 티켓 만들어줘” |
| 예측 가능성 | 높음 | 낮음 (같은 입력에도 경로가 달라질 수 있음) |
| 비용·지연 | 호출 수 고정 | 루프 길이에 따라 가변 |
| 디버깅 | 쉬움 | 추적 도구 없이는 어려움 |
단계가 미리 열거되는 일이라면 워크플로가 더 싸고, 빠르고, 안정적입니다. 입력마다 필요한 도구와 순서가 달라질 때만 에이전트의 자율성이 값을 합니다.
2. 모든 패턴의 뼈대 — Tool Calling 루프
어떤 패턴이든 바닥에는 같은 루프가 있습니다.
messages = [system_prompt, user_request]
while step < MAX_STEPS:
response = llm(messages, tools=tool_schemas)
if response.tool_calls: # 도구 호출 요청
for call in response.tool_calls:
result = execute(call) # 실제 실행은 코드가 담당
messages.append(tool_result(call.id, result))
else: # 도구 없이 최종 답변
return response.content
설계 관점에서 중요한 사실이 두 가지 있습니다. 첫째, LLM은 도구를 “실행”하지 않고 “요청”만 합니다. 실행·검증·권한 통제는 전부 우리 코드의 책임입니다. 둘째, 도구 스키마 설명이 곧 에이전트의 실력입니다. 파라미터 설명이 모호하면 어떤 패턴을 써도 도구를 엉뚱하게 부릅니다.
3. 패턴 1 — ReAct: 생각하고, 행동하고, 관찰한다
ReAct(Reason + Act)는 추론 → 도구 호출 → 결과 관찰을 반복하는 가장 기본 패턴입니다. 위 루프에 “행동 전에 짧게 추론하라”는 지시를 더한 형태로 이해하면 됩니다.
- 강점: 구조가 단순해서 실패 지점을 찾기 쉽고, 중간 결과를 보고 방향을 바꿀 수 있습니다.
- 약점: 단계가 10개를 넘는 긴 작업에서 목표를 잊거나 같은 도구를 맴도는 문제가 생깁니다.
- 어울리는 일: 검색·조회 후 답변, 간단한 조작 자동화, 3~7단계 안에서 끝나는 작업.
사내 문서를 검색해 답하는 RAG 에이전트, 로그를 조회해 원인을 좁히는 진단 도우미 정도는 ReAct 하나로 충분한 경우가 대부분입니다.
4. 패턴 2 — Plan-and-Execute: 계획을 먼저 쓴다
계획 단계에서 작업을 하위 단계 목록으로 분해하고, 실행 단계에서 하나씩 처리하며 필요 시 계획을 수정하는 패턴입니다.
- 강점: 긴 작업에서 목표 이탈이 줄고, 진행 상황을 사용자에게 보여주기 좋습니다. 계획은 큰 모델, 실행은 작은 모델로 나눠 비용을 줄일 수도 있습니다.
- 약점: 처음 계획이 틀리면 전체가 흔들리므로 재계획(re-plan) 조건을 반드시 넣어야 합니다. 호출 수가 늘어 지연도 커집니다.
- 어울리는 일: 리서치 보고서 작성, 다단계 마이그레이션, 여러 시스템을 순서대로 조작하는 작업.
5. 패턴 3 — Reflection: 자기 결과를 검증한다
생성 결과를 검토자 역할의 프롬프트(또는 별도 모델)가 평가하고, 지적 사항을 반영해 다시 생성하는 패턴입니다. 생성-평가-수정 루프를 1~2회만 돌려도 품질이 눈에 띄게 좋아지는 작업이 많습니다.
- 핵심 조건: 평가 기준이 구체적이어야 합니다. “더 잘 써줘”가 아니라 “컴파일 오류, 테스트 통과 여부, 스타일 규칙 위반”처럼 검증 가능한 체크리스트를 평가자에게 줘야 합니다.
- 가장 좋은 평가자는 코드: 테스트 실행, 린터, 스키마 검증처럼 결정적인 도구가 있으면 LLM 평가보다 우선하세요.
- 주의: 반복 횟수 상한이 없으면 비용이 폭주합니다. 보통 1~3회로 제한하고, 개선 폭이 없으면 중단합니다.
6. 패턴 4 — Router: 크기가 다른 문제를 나눈다
요청을 먼저 분류해 가벼운 질문은 작은 모델·단순 체인으로, 복잡한 요청만 에이전트 루프로 보내는 관문 패턴입니다.
intent = classify(request) # 소형 모델, 구조화 출력
if intent == "faq": return faq_chain(request)
elif intent == "lookup": return rag_chain(request)
else: return react_agent(request)
운영 비용의 대부분은 “모든 요청을 가장 비싼 경로로 보내는 것”에서 나옵니다. 라우터는 패턴이라기보다 비용·지연 방어선이며, 분류 자체는 Structured Outputs로 고정된 JSON을 받는 것이 안정적입니다.
7. 패턴 5 — Multi-Agent: 역할을 나눈다
Supervisor(조정자)가 작업을 나눠 전문 에이전트에게 위임하는 구조가 대표적입니다. 리서처·작성자·검토자처럼 역할별로 시스템 프롬프트와 도구 세트를 분리합니다.
멀티 에이전트가 정당화되는 신호
- 도구가 수십 개를 넘어 단일 에이전트의 도구 선택 정확도가 떨어질 때 (역할별로 도구를 나누면 선택지가 줄어듭니다)
- 서로 다른 권한 경계가 필요할 때 (조회 전용 에이전트 vs 쓰기 가능 에이전트)
- 병렬로 처리 가능한 독립 하위 작업이 명확할 때 (여러 주제 동시 리서치)
- 컨텍스트가 길어져 역할별로 분리해야 할 때
흔한 착각
“에이전트를 늘리면 더 똑똑해진다”는 기대는 대부분 배신당합니다. 에이전트 간 전달 과정에서 정보가 유실되고, 실패 지점과 비용은 곱으로 늘어납니다. 단일 에이전트로 한계를 측정한 뒤에 나누세요. 싱글에서 멀티로 확장하는 판단 과정은 『이것이 멀티 에이전트다』 리뷰에서 다룬 내용과 이어집니다.
8. 상태와 메모리 설계
패턴을 정했다면 다음 병목은 컨텍스트 관리입니다.
| 메모리 종류 | 내용 | 구현 방법 |
|---|---|---|
| 작업 메모리 | 현재 루프의 대화·도구 결과 | 메시지 배열 (길어지면 오래된 도구 결과부터 요약·절삭) |
| 세션 메모리 | 대화 세션 간 이어지는 맥락 | 요약 저장 후 다음 세션 시스템 프롬프트에 주입 |
| 장기 메모리 | 사용자 선호·과거 결정 | 벡터 검색 또는 명시적 프로필 저장소 |
특히 도구 결과가 큰 경우(수천 줄 로그, 대형 JSON) 원문을 그대로 메시지에 쌓으면 몇 스텝 만에 컨텍스트가 넘칩니다. 도구 단에서 요약·필터링해 반환하는 것이 에이전트 프롬프트를 고치는 것보다 효과적입니다.
9. 안전장치 — 운영에 올리기 위한 최소 조건
- 반복 상한: MAX_STEPS(보통 10~20)와 시간·토큰 예산을 두고, 초과 시 중간 결과와 함께 중단 보고하게 합니다.
- 도구 권한 분리: 조회 도구는 자유, 변경 도구(쓰기·삭제·발송)는 화이트리스트로 제한합니다. 에이전트 정체성이 아니라 도구 실행 계층에서 권한을 강제해야 합니다.
- Human-in-the-loop: 비가역 작업(배포, 메일 발송, 데이터 삭제) 앞에는 승인 대기 상태를 넣습니다. “확인 후 실행” 한 단계가 사고 대부분을 막습니다.
- 관찰성: 스텝별 프롬프트·도구 호출·결과를 트레이스로 남기지 않으면 실패 원인을 재현할 수 없습니다. 루프 로그는 처음부터 구조화해 저장하세요.
10. 도구 연결 표준 — MCP와 A2A는 어디에 놓이나
패턴과 별개로, 도구와 에이전트를 “어떻게 연결하느냐”의 표준화가 빠르게 진행됐습니다.
- MCP(Model Context Protocol): 에이전트가 외부 도구·데이터 소스에 접속하는 공통 규격입니다. 도구를 서비스별 커스텀 연동 대신 MCP 서버로 한 번 만들어 여러 클라이언트에서 재사용하는 방향입니다.
- A2A(Agent-to-Agent): 서로 다른 프레임워크로 만든 에이전트끼리 작업을 주고받기 위한 통신 규격입니다. 멀티 에이전트를 조직 경계 너머로 확장할 때 등장합니다.
사내 도입 순서로는 도구를 MCP 서버로 표준화 → 단일 에이전트 안정화 → 필요 시 멀티 에이전트가 무리 없는 경로입니다.
11. 패턴 선택 기준 한 장 정리
| 상황 | 추천 패턴 | 이유 |
|---|---|---|
| 절차가 미리 정해짐 | 워크플로(체인) | 에이전트 불필요, 예측 가능 |
| 3~7단계, 도구 소수 | ReAct | 단순함이 곧 안정성 |
| 10단계 이상, 목표 이탈 발생 | Plan-and-Execute | 계획으로 방향 고정, 재계획 조건 필수 |
| 품질 기준이 검증 가능 | Reflection | 생성-평가-수정 1~3회 |
| 요청 난이도 편차가 큼 | Router + 위 패턴 | 비용·지연 방어 |
| 도구 수십 개, 권한·역할 분리 | Multi-Agent | 역할별 도구·컨텍스트 분리 |
12. 흔한 실수
실수 1. 처음부터 멀티 에이전트로 시작한다
단일 에이전트의 한계를 측정한 데이터 없이 나누면, 복잡도만 사고 성능은 그대로인 경우가 많습니다.
실수 2. 반복 상한 없이 운영에 올린다
도구 오류 → 재시도 → 같은 오류의 무한 루프는 반드시 발생합니다. 스텝·토큰·시간 3중 상한은 선택이 아니라 필수입니다.
실수 3. 도구 설명을 대충 쓴다
패턴을 바꾸기 전에 도구 이름·설명·파라미터 문서를 먼저 다듬으세요. 도구 선택 오류의 대부분은 스키마 품질 문제입니다.
실수 4. 데모 성공을 완성으로 착각한다
에이전트는 같은 입력에도 경로가 달라집니다. 대표 시나리오 수십 개로 반복 실행해 성공률을 측정하는 평가 체계 없이는 개선도 회귀 감지도 불가능합니다.
실전 체크리스트
- 이 작업이 워크플로로 충분하지 않은지 먼저 검토했다.
- ReAct 단일 루프로 기준 성공률을 측정했다.
- MAX_STEPS·토큰 예산·시간 제한을 설정했다.
- 변경성 도구에 권한 제한과 사람 승인 지점을 넣었다.
- 도구 스키마 설명을 리뷰했다 (이름·설명·파라미터·반환 형식).
- 스텝별 트레이스 로그를 저장하고 있다.
- 대표 시나리오 테스트셋으로 성공률을 반복 측정한다.
마치며
에이전트 설계의 핵심은 화려한 패턴이 아니라 자율성을 필요한 만큼만 허용하는 것입니다. 워크플로로 되는 일은 워크플로로, 에이전트가 필요한 일은 ReAct에서 시작해 측정 결과가 요구할 때만 Plan-Execute·Reflection·Multi-Agent로 확장하세요.
그리고 어떤 패턴을 고르든 반복 상한·권한 분리·승인 지점·트레이스라는 안전장치 네 가지가 먼저입니다. 이 바닥이 있어야 에이전트를 데모가 아니라 운영 시스템으로 키울 수 있습니다.
FAQ
Q1. 프레임워크(LangGraph 등) 없이 직접 구현해도 되나요?
됩니다. 위의 Tool Calling 루프는 수십 줄이면 구현됩니다. 상태 그래프·체크포인트·휴먼 승인 같은 운영 기능이 필요해지는 시점에 프레임워크 도입을 검토하는 순서가 학습에도 좋습니다.
Q2. ReAct의 “생각(Thought)”을 사용자에게 보여줘야 하나요?
내부 추론은 숨기고 진행 상황 요약만 보여주는 것이 일반적입니다. 다만 디버깅용 트레이스에는 반드시 남겨야 합니다.
Q3. 에이전트에 어떤 모델을 써야 하나요?
도구 호출 정확도가 높은 모델이 우선입니다. 라우터·단순 실행은 작은 모델로 내리고, 계획·검토처럼 판단이 필요한 자리에 큰 모델을 쓰는 계층 구성이 비용 효율적입니다.
Q4. 멀티 에이전트에서 에이전트끼리는 뭘 주고받아야 하나요?
대화 전체가 아니라 작업 명세와 결과 요약을 주고받는 것이 기본입니다. 전체 히스토리를 넘기면 컨텍스트가 폭발하고, 너무 요약하면 맥락이 유실되므로 역할별로 필요한 필드를 명시한 구조화 메시지를 정의하는 것이 좋습니다.
참고 자료
- ReAct: Synergizing Reasoning and Acting in Language Models
- Anthropic — Building Effective Agents
- Model Context Protocol
함께 읽으면 좋은 글
'AI·LLM 엔지니어링' 카테고리의 다른 글
| RAG 전처리의 진짜 시작점, 문서 구조 분석 - 한컴 데이터 로더로 보고서 PDF를 직접 돌려봤습니다 (0) | 2026.08.11 |
|---|---|
| vLLM 멀티 GPU 서빙 완전정리 — Tensor·Pipeline·Data Parallel 선택 기준 (0) | 2026.08.09 |
| RAG Reranker 완전정리 — Bi-Encoder·Cross-Encoder 2단계 검색 설계 (0) | 2026.07.26 |
| RAG Hybrid Search 실전 가이드 — Dense·BM25·RRF로 검색 정확도 높이기 (0) | 2026.07.26 |
| vLLM Speculative Decoding 실전 가이드 — Draft Model·N-gram·EAGLE 선택법 (0) | 2026.07.26 |