Skip to content
Published on

LLM 에이전트 실전 완전 가이드: ReAct, Plan-Execute, Tool Use, 다중 에이전트 (2025)

Authors

Season 4 Ep 3 — RAG가 "재료", 프롬프트가 "지시"라면 에이전트는 **"반복 행동"**이다. 한 번의 질의·응답이 아니라 루프 돌리는 AI를 제품에 녹이는 법.

Prologue — "에이전트"라는 단어의 인플레이션

2024년 한 해 "AI agent"라는 단어는 너무 남발되었다. 단일 LLM 호출에 도구 하나 붙이면 "에이전트"라고 부르는 회사부터, 수십 개 툴을 쓰는 자율 시스템까지 모두 같은 이름으로 팔렸다.

이 글에선 에이전트를 다음과 같이 정의한다.

에이전트 = 목표를 받아, 자체 판단으로 툴(또는 다른 에이전트)을 반복 호출하며, 관찰 결과를 바탕으로 다음 행동을 결정하는 시스템.

즉 "반복", "판단", "관찰"이 핵심. 이 세 조건을 충족하지 않으면 그건 "도구 쓰는 LLM"이지 에이전트가 아니다. 에이전트가 "필요 없을 때 쓰면" 비용과 지연만 늘어난다. Ep 3은 경계를 명확히 그으면서 실전 구현법을 정리한다.


1장 · 에이전트 vs 워크플로우 — 경계 긋기

1.1 스펙트럼

단계특징
0. 단일 LLM 호출입력 → 응답. 툴 없음요약, 번역
1. Tool-augmented LLM1회 도구 호출 허용계산기 붙인 QA
2. 결정적 워크플로우정해진 순서로 도구들 호출"RAG → LLM → 포맷" 파이프라인
3. Planner + Executor계획 세우고 실행, 실패 시 재계획조사 봇
4. 반복 에이전트 (ReAct)관찰에 따라 매 스텝 판단코딩 에이전트
5. 다중 에이전트역할 나눠서 협업연구팀 시뮬레이션

2025년의 중요한 깨달음: 대부분의 제품 문제는 0–2단계로 충분히 풀린다. 3단계 이상은 높은 판단 복잡도 + 실패 허용도가 있을 때만 정당화된다.

1.2 언제 에이전트인가

  • 한 번에 답할 수 없는 복합 문제 (여러 도구·여러 단계)
  • 실행 결과에 따라 다음 행동이 달라져야 함
  • 에러·타임아웃을 스스로 복구하길 기대
  • 사용자가 "목표"만 주고 세부는 위임

1.3 언제 에이전트가 아닌가

  • 결과 순서가 늘 같음 → 워크플로우로 충분
  • 지연 민감 (1초 안에 응답) → 루프는 사치
  • 모든 출력이 검증돼야 함 → 결정적 파이프라인 + 단일 LLM이 안전
  • 비용 강제 상한이 있음 → 루프는 예측 불가

2장 · ReAct — 추론과 행동의 루프

2.1 기본 형태

Reasoning + Acting(Yao et al., 2022).

Thought: 사용자가 X에 대한 최신 정보를 원한다. 검색이 필요.
Action: web_search("X 2025 기준")
Observation: [검색 결과 5]
Thought: 이 중 2번째가 가장 관련성 높다. 내용을 열어본다.
Action: fetch_url("https://...")
Observation: [본문]
Thought: 충분한 정보를 얻었다. 정리해서 답한다.
Action: final_answer("X에 대한 2025년 현황은 …")

2.2 구현 방식

  • 옛날 방식: LLM이 Thought/Action/Observation 텍스트를 그대로 생성 → 파서가 액션 추출
  • 2024–2025 방식: Tool use(function calling) 네이티브 지원. 모델이 구조화된 tool call을 반환하면 런타임이 실행 → 결과를 다시 넣어줌

2.3 LangGraph로 ReAct

from langgraph.prebuilt import create_react_agent

tools = [web_search_tool, calculator_tool, fetch_url_tool]
agent = create_react_agent(llm, tools, state_schema=State)

result = agent.invoke({"messages": [("user", query)]})

LangGraph는 상태 머신 기반이라 체크포인트·재시도·인간 승인 삽입이 쉽다.

2.4 ReAct의 한계

  • 루프 무한증식: 해결 못 하는 문제에 계속 같은 툴 호출
  • Tool coverage 오인: 필요한 도구가 없는데 "생각만 빙빙"
  • 상태 오염: 초반 실수가 후반 추론을 왜곡

→ 2장 5절의 가드레일 필수.

2.5 가드레일

  • Max iterations: 10–30 사이 상한. 초과 시 실패 반환.
  • Max tokens per run: 누적 토큰 한도.
  • Progress detector: 같은 툴·같은 인자로 N회 호출 = 무한 루프로 판정.
  • Budget 재확인: 절반 소진 시 "요약 후 재계획".
  • Human-in-the-loop trigger: 특정 조건 시 사람에게 승인 요청.

3장 · Plan-and-Execute, Reflexion — 고차 패턴

3.1 Plan-and-Execute

단계:

  1. Planner: 작업을 여러 서브 태스크로 쪼갠 계획 작성
  2. Executor: 각 서브 태스크 실행 (툴 호출 or 하위 에이전트)
  3. Replanner: 결과 확인 후 계획 조정

장점:

  • 복잡한 문제를 처음부터 구조화
  • 중간 결과 가시성 ↑
  • Planner를 더 큰 모델, Executor를 더 작은 모델로 분리 가능 (비용 절감)

적합 태스크: 조사/리서치, 데이터 분석 리포트, 다단계 배포.

3.2 Reflexion

자기 비판 루프. 매 시도 후 "무엇을 잘못했나?" 메모를 남기고 다음 시도에 반영.

  • 코딩 벤치(HumanEval 등)에서 큰 향상 확인
  • 단점: 반복 횟수·비용 증가

3.3 선택 가이드

문제 유형추천 패턴
단순 QA + 1–2 툴ReAct
복잡 조사·다단계 작업Plan-and-Execute
코딩·시행착오ReAct + Reflexion
다중 참여자 시뮬레이션다중 에이전트
결과 포맷 엄격결정적 워크플로우 (에이전트 아님)

4장 · Tool Use 설계 원칙

4.1 Tool = API 계약

  • 이름: 영문 snake_case, 동사로 시작, 단일 책임
  • 설명: "무엇을 하는지"만 5줄 이내
  • 인자: JSON Schema로 명확히. 예시 포함 권장
  • 반환: LLM이 이해하기 쉬운 자연어 or JSON 요약. 거대한 원문 그대로 반환 금지

4.2 좋은 Tool 예

{
  "name": "search_confluence",
  "description": "사내 위키에서 키워드로 문서를 검색한다. 최대 10건 반환. 페이지 본문 미포함, 제목·경로·스니펫만.",
  "parameters": {
    "type": "object",
    "required": ["query"],
    "properties": {
      "query": { "type": "string", "description": "검색어. 한국어/영어 가능" },
      "space": { "type": "string", "description": "선택적 space key. 예: 'ENG', 'PROD'" },
      "limit": { "type": "integer", "minimum": 1, "maximum": 10, "default": 5 }
    }
  }
}

4.3 Tool 개수와 명칭

  • 툴이 10개를 넘어가면 모델의 선택 정확도가 떨어진다
  • 유사 이름("search_wiki", "find_wiki") 혼재 금지
  • 필요하면 툴 카테고리 에이전트를 중간에 두고, 상위 에이전트는 카테고리만 선택

4.4 반환값 설계

  • 토큰 낭비 방지: 10KB 넘는 응답은 요약 또는 페이징
  • 에러도 구조화된 포맷으로: {"error": "NotFound", "hint": "space_key를 확인하세요"}
  • "다음 액션 힌트"를 반환에 포함하면 에이전트가 더 빠르게 수렴 (예: "이 페이지에 하위 섹션이 있습니다. fetch_section으로 조회 가능")

4.5 위험한 툴

  • 코드 실행/쉘: 반드시 샌드박스 (Docker, gVisor, Firecracker, E2B, Modal, Daytona)
  • 파일 쓰기: 경로 allowlist, 덮어쓰기 전 백업
  • 결제/송금: 인간 승인 강제(휴먼 인 더 루프)
  • 외부 API POST: rate limit, cost guard

"LLM이 stdin에 들어오는 대로 실행"은 사고의 지름길.


5장 · 상태 관리와 메모리

5.1 상태의 종류

  • Short-term: 현재 대화/세션의 히스토리, 스크래치패드
  • Episodic: 최근 실행들의 경험 메모
  • Long-term: 사용자·조직의 지속 선호와 지식

5.2 Short-term 전략

  • 모든 메시지 누적 → 결국 컨텍스트 초과
  • 슬라이딩 윈도우 + 요약: 오래된 부분은 요약으로 압축
  • 상태 머신(LangGraph) 방식: 필요한 필드만 보존

5.3 Long-term 메모리

  • 사용자 프로필(선호, 스타일, 반복 작업) → 별도 Key-Value
  • 중요한 사실은 추출 에이전트가 대화에서 뽑아 저장
  • 프라이버시 고려: 저장 범위·TTL·삭제 API 필수

5.4 LangGraph 체크포인트

LangGraph는 각 노드 실행 후 상태를 checkpointer(SQLite, Postgres 등)에 저장한다. 장점:

  • 장시간 실행(수 분 ~ 수 시간) 복구 가능
  • 인간 승인 지점에서 일시 중단 → 재개
  • 실행 리플레이(디버깅에 필수)

6장 · 다중 에이전트 — 패턴과 함정

6.1 패턴

  • Orchestrator-Worker: 상위가 계획, 하위들이 분업 (Plan-and-Execute의 확장)
  • Debate: 두 에이전트가 상반 입장에서 토론, 중재자가 결론
  • Supervisor + Specialists: 라우터가 전문 에이전트에 위임(고객 지원)
  • Swarm / CrewAI: 느슨한 협업, 역할 카드 기반

6.2 장점

  • 각 에이전트의 프롬프트/툴셋을 단순화 가능
  • 역할 분리로 테스트·디버깅 쉬움
  • 한 영역 전문 모델 + 다른 영역 일반 모델 혼합 가능

6.3 함정

  • 통신 비용 폭증: 에이전트 간 메시지가 토큰을 엄청 태움
  • 책임 희석: 누구 잘못인지 불분명 → 디버깅 어려움
  • 오버 엔지니어링: 하나로 가능한 걸 셋으로 나눠서 복잡도 증가

"에이전트 하나면 충분한데 셋으로 쪼갰다"는 2025년 팀들의 가장 흔한 후회.

6.4 선택 원칙

다중 에이전트가 정당화되려면 (역할 이질성 + 병렬성 필요 + 단일 에이전트로 프롬프트가 감당 안 됨) 셋 중 둘 이상 충족해야 한다.


7장 · LangGraph · DSPy · OpenAI Agents · Claude Agent

7.1 LangGraph

  • Python/JS, LangChain 생태계
  • 상태 머신 + 체크포인트 + 인간 승인 지원
  • ReAct 프리셋, 멀티 에이전트 서브그래프
  • 운영 친화적인 기본 선택

7.2 DSPy

  • "시그니처 + 옵티마이저"로 프롬프트 자동 튜닝 (Ep 2 참고)
  • ReAct 등 에이전트 패턴도 제공
  • 평가셋 + 자동 개선이 핵심 가치

7.3 OpenAI Assistants / Responses API

  • 2024년 Assistants API → 2025년 Responses API로 진화
  • 툴 실행·상태·파일 검색을 OpenAI가 호스팅
  • 락인이 강하지만 운영 부담이 적음

7.4 Claude Agent / Claude Code

  • Anthropic의 에이전트 레이어
  • Claude Code는 코딩 에이전트의 사실상 표준 중 하나
  • Bash, Edit, Glob/Grep/Read, TodoWrite 같은 툴셋이 기본 제공
  • 2025년엔 Claude Agent SDK로 사용자 정의 에이전트 제작 가능

7.5 MCP와의 관계

**Model Context Protocol(MCP)**은 모델 ↔ 툴/데이터 소스의 표준 인터페이스. 에이전트 프레임워크는 MCP 서버를 툴로 바로 쓰면, 툴 생태계 재사용이 가능해진다.

[에이전트 프레임워크]  <—— Tool use ——>  [MCP 클라이언트]
                            [MCP 서버들: GitHub, Slack, 사내 DB, 파일시스템]

즉 LangGraph 에이전트든 Claude Agent든, 대부분의 사내 도구 연결은 MCP 서버 한 번 만들어두면 공유된다.


8장 · 관측성 (Observability)

8.1 왜 에이전트 관측성은 특히 어려운가

  • 실행 트리가 동적 (입력에 따라 Node 수 달라짐)
  • 각 스텝이 토큰·비용·지연을 소비
  • 실패가 "왜" 일어났는지 원인 추적 필요

8.2 필수 Trace 정보

  • 전체 run_id, 각 step_id, parent_step_id
  • 입력·출력 토큰 수 & 비용 (model별)
  • 툴 이름, 인자 (민감정보 마스킹), 결과 요약
  • 에러·재시도 이유
  • 사용자 피드백

8.3 도구

  • LangSmith / LangFuse: LangGraph와 강한 통합
  • Phoenix (Arize): 오픈, OpenTelemetry 호환
  • Helicone: 게이트웨이형, 저지연
  • OpenTelemetry + 자체 대시보드: 커스텀 필요시

8.4 Replay

LangGraph의 체크포인트는 과거 실행을 재생할 수 있게 한다. "왜 이 에이전트가 엉뚱한 답을 했지?"를 1시간 후에도 분석 가능. 에이전트 디버깅의 최고 무기.


9장 · 실패·루프 방지의 엔지니어링

9.1 대표 실패 모드

  • 무한 루프: 같은 툴·같은 질문 반복
  • 방황(wandering): 관련 없는 툴 계속 탐색
  • 자가 가스라이팅: 초반 오류를 정당화하려 계속 같은 전제 고수
  • 권한 거부 연쇄: 매 툴이 거부 → 다른 툴로 시도 → 또 거부
  • 출력 형식 깨짐: 마지막에 자유 텍스트 반환

9.2 방어 설계

  • Max iterations + progress detector (2장 재강조)
  • Token / Cost budget: 소프트(경고) → 하드(강제 종료) 두 단계
  • Escape plan: N회 실패 시 "사용자에게 물어봐" 또는 "안전한 디폴트"
  • Output validator: 최종 응답이 스키마에 맞는지 확인, 아니면 한 번 더 LLM 호출로 보정
  • Retry with summarization: 오류 맥락을 요약해 재시도. 전체 히스토리 유지 금지(비용 폭발)

9.3 Human-in-the-loop 디자인

  • 민감 작업(결제, 삭제, 외부 이메일 발송)은 사전 승인
  • 모호할 때(신뢰도 낮음) 명확화 질문
  • UX: "지금 에이전트가 하려는 일 = X, 승인/거절/수정" 버튼
  • 기록: 승인·거절 로그가 다음 개선의 학습 데이터

10장 · 실전 케이스 3

10.1 코딩 에이전트 (Claude Code 유형)

  • Plan 단계에서 TodoWrite 비슷한 체크리스트 생성
  • 파일 읽기/쓰기·테스트 실행을 주 툴
  • Reflexion 패턴으로 테스트 실패 → 수정 반복
  • 가드레일: 금지 경로(/etc, secrets/), max 편집 파일 수

운영 팁:

  • 체크포인트로 중단 가능: 사용자가 언제든 "여기까지"
  • 커밋 전 diff 사람 확인 필수 (자동 커밋 금지)

10.2 고객 지원 에이전트

  • Supervisor가 라우팅(환불·기술지원·계정) → 전문 에이전트
  • 각 전문 에이전트는 작은 툴셋만 (격리)
  • 민감 동작(환불, 계정 삭제)은 인간 승인

운영 팁:

  • 사용자 대화는 초단위 스트리밍 필수 → 에이전트 내부가 느려도 "생각 중" 표시
  • FAQ로 해결 가능한 80%는 RAG만으로 처리하고, 나머지 20%만 에이전트 경로로

10.3 데이터 분석 에이전트

  • SQL 생성 → 실행 → 결과 검증 → 차트/요약
  • Python 샌드박스(pandas, matplotlib)
  • Reflexion으로 SQL 오류 → 수정 반복

운영 팁:

  • 읽기 전용 DB 계정만 주기
  • 비용 많이 드는 쿼리(풀 스캔) 사전 차단
  • 결과를 PII 필터 거쳐 사용자에게

11장 · 한국어·한국 환경 특수성

11.1 한국어 Tool use

  • 툴 설명·스키마는 영문으로 유지(OpenAPI 표준과 맞추기)
  • 사용자 발화는 한국어 그대로 → 모델이 알아서 번역 판단
  • 한국어 전용 툴(국민비서, 공공API)이 필요하면 별도 카테고리로 묶기

11.2 엔터프라이즈 연결

  • 사내 시스템: 카카오워크·네이버웍스·잔디·플로우 등 커넥터는 아직 성숙 중
  • 대안: 해당 시스템의 공식 API로 자체 MCP 서버 구축 → 에이전트에 노출

11.3 규제

  • 개인정보보호법, 금융: 망분리·가명처리 요구
  • 에이전트가 외부 LLM에 데이터를 전송한다는 사실 자체가 감사 대상
  • On-prem 모델(Qwen, Llama, Solar) 기반 에이전트 수요가 증가

12장 · 평가 — 에이전트는 어떻게 측정하나

12.1 평가 차원

  • Task success rate: 골든 태스크에서 최종 결과가 정답에 도달?
  • Step efficiency: 몇 스텝 만에 끝났나? (적을수록 좋음, but too few = 대충)
  • Cost / Latency: 분포(p50, p95)
  • Safety: 금지 동작 시도 횟수, 탈옥 성공률
  • User experience: 썸업/썸다운, 태스크 포기율

12.2 평가셋 구축

  • 실제 사용 로그에서 샘플링 + 합성(LLM 생성) 혼합
  • 난이도 라벨: easy / medium / hard
  • 유형 태그: 검색/분석/작성/실행

12.3 자동 평가

  • LLM-as-judge: "결과가 X를 만족하는가?" 이진 판정
  • 스텝 수·비용은 로그에서 자동
  • 회귀 테스트: CI에서 주요 태스크 10–30개 실행

13장 · 보안 체크리스트

  • 모든 툴에 대해 권한 최소화(read-only, 특정 경로/DB)
  • 코드 실행 툴은 샌드박스 + egress 제한
  • 결제·삭제류 툴은 인간 승인 강제
  • 프롬프트 인젝션 방어 (Ep 2 참고)
  • 외부에서 들어오는 문서·웹페이지 텍스트를 "지시"로 취급 금지
  • 출력에 민감정보(API key, PII) 포함 여부 최종 필터
  • 로그에 비밀값 마스킹
  • MCP 서버 별 OAuth/토큰 스코프 최소화
  • 에이전트가 수정 가능한 파일 경로 allowlist
  • 최대 비용/이터레이션 하드 캡
  • 모든 자동 커밋/배포 비활성화 (사람 한 번은 본다)
  • 실행 감사 로그 보관 기간/접근권한 정의

14장 · 체크리스트 — 에이전트 런칭 전 12가지

  • 이 문제는 정말 에이전트가 필요한가(단일 LLM/워크플로우로 안 됨을 확증)
  • Max iterations, Token budget 하드 캡 설정
  • 주요 툴 10개 이하, 이름·설명 명확
  • 위험 툴은 샌드박스/승인 게이트 적용
  • 상태 체크포인트로 장시간 실행 복구 가능
  • Trace 관측 + Replay 가능 (LangSmith/LangFuse/Phoenix 등)
  • 평가셋 30개 이상, CI 자동 실행
  • 실패 시 사용자에게 "에이전트가 포기" 경로
  • 비용·지연 대시보드(p50/p95/p99)
  • 인간 승인 포인트 정의(결제·삭제·외부발송)
  • 출력 스키마 검증 + 민감정보 필터
  • 온콜 플레이북(에이전트 폭주 시 대응)

15장 · 안티패턴 10선

15.1 "에이전트로 만들어두면 나중에 도움될 것"

지금 안 필요한 복잡도는 나중에도 안 필요하다.

15.2 툴 30개 한 에이전트에 몰기

선택 정확도 급락. 카테고리별 에이전트로 분산.

15.3 Max iterations 없음

무한 루프는 시간 문제. 반드시 상한.

15.4 모델·프롬프트만 바꾸고 평가셋 없음

Ep 1·Ep 2 교훈이 에이전트에도 그대로 적용.

15.5 모든 중간 결과를 LLM에 다시 넣기

컨텍스트 폭발. 요약·선택 필수.

15.6 에러 메시지를 그대로 노출

사용자가 내부 스택 트레이스를 보게 하지 말 것.

15.7 자동 커밋/자동 송신

사람이 한 번은 봐야 한다. 특히 초기.

15.8 인간 승인 UX를 나중에

사후에 붙이면 UX가 어색해진다. 첫 설계부터.

15.9 다중 에이전트를 근거 없이 도입

오케스트레이션 복잡도·비용 3–10배. 꼭 필요할 때만.

15.10 MCP 서버 권한을 넓게

"편의상 write 다 주자" → 사고의 시작. 최소 권한.


16장 · 다음 글 예고 — Season 4 Ep 4: "Fine-tuning 완전 가이드"

Ep 1(RAG)·Ep 2(프롬프트)·Ep 3(에이전트)는 모델을 그대로 쓰는 세계였다. Ep 4는 모델 자체를 바꾸는 길.

  • SFT, DPO/IPO/KTO, RLHF 개요
  • LoRA/QLoRA로 소비자 GPU 파인튜닝
  • 합성 데이터로 레이블 비용 줄이기
  • 작은 모델(Qwen, Llama, Mistral)을 태스크별로 조련
  • Fine-tuning vs RAG vs Prompt 경계선 재점검
  • 평가: Fine-tune 전후 회귀 방지
  • 비용 비교: 외부 API vs 자체 Fine-tune 운영
  • 한국어 데이터·모델(Solar, Polyglot, KoAlpaca)
  • 배포 방법(vLLM, TGI, TensorRT-LLM)
  • 실전 케이스 (분류기 치환, 포맷 강제, 톤 고정)

**"모델을 바꿀 때 vs 안 바꿀 때"**의 경계선이 흐릿한 팀이 아직 많다. Ep 4에서 선명하게 긋는다.

다음 글에서 만나자.


요약: 2025년 에이전트는 "남용하면 독, 잘 쓰면 약"이다. 스펙트럼에서 0–2단계(LLM+툴·워크플로우)로 먼저 풀고, 판단 복잡도와 실패 허용도가 충분할 때만 3단계 이상으로 간다. ReAct·Plan-Execute·Reflexion은 태스크 유형으로 선택하고, 툴은 10개 이하·최소 권한·샌드박스, 상태는 체크포인트로 복구, 관측은 Trace + Replay, 위험 동작은 인간 승인. 단일 에이전트로 가능한 걸 셋으로 쪼개지 말 것. 그리고 평가셋 없는 에이전트 운영은 지뢰밭 산책이다.