Agent를 5층으로 뜯으면 제품 평가가 가능해진다

이 글은 「AI 공부 지도 20부작」의 13편 (M3) 입니다.
앞 편: M1 — Retrieval Layer가 왜 필요한가 · M2 — Long-context와 Memory가 갈리는 지점
다음 편: M4 — Harness가 agent를 agent로 만드는 방식

0. 들어가기 전에

FIG. Agent 5층 분해
Tool — 외부 API · 파일 · 셸
State — 지금까지 한 일 추적
Plan — 다음에 무엇을
Reflect — 잘 됐나? 다시?
Memory — 이번 작업의 학습
에이전트는 한 덩어리가 아니라 5개 책임이 위에서 아래로 쌓인 구조

B1에서 agent를 “LLM이라는 엔진이 올라탄 자동차 한 대 전체”라고 썼어요. 거기선 다섯 층을 개념 으로만 그렸습니다. 목표 수용, 상태 추적, 도구 사용, 루프, 적응. 차 한 대라는 비유가 감각을 잡는 데는 좋은데, 실제로 agent를 뜯어서 평가 해야 하는 단계로 오면 이 비유만으론 부족해요. 차 한 대라는 말로는 “이 차가 좋은 차인지” 를 못 판단하거든요.

이번 편은 그 다섯 층을 실제 기술 요소 로 내려놓습니다. Tool use, state management, planning, reflection, multi-agent. 이름이 조금 달라진 이유는 기술 문서에서 실제로 이렇게 불리기 때문이고, 제품을 뜯을 때 이 용어로 접근하는 게 훨씬 빠르거든요. B1의 다섯 층을 기술자 어휘로 번역한다고 보시면 됩니다.

이 글을 다 읽고 나면 이런 게 가능해져요.

  • Claude Code · Cursor · Devin · Auto-GPT를 같은 기준으로 비교할 수 있음
  • 누가 “AI agent 솔루션을 팔겠다” 고 왔을 때 10가지 질문으로 진짜 수준을 잴 수 있음
  • 왜 Auto-GPT가 2023년에 실패했고 Claude Code가 2024~2025년에 실용화됐는지를 구조로 설명할 수 있음

B1을 “대기실” 이라고 하면 이 글은 “정비소” 예요. 차를 올려놓고 밑에 기어 들어가서 부품을 하나씩 빼보는 작업이에요. 좀 길지만, 한 번 같이 기어 들어가 봅시다.

1. B1 복습 — agent는 엔진 아닌 자동차

한 문단으로 지나갈게요. B1에서 잡은 감각은 이거였어요. LLM 한 번 호출은 답변기고, LLM을 시스템 안에 끼워 넣으면 agent가 된다. 시스템이라는 건 목표를 받는 창구, 지금까지 한 일을 보는 계기판, 밖에 작용하는 팔다리, 실패하면 다시 도는 루프, 결과를 보고 다음 행동을 바꾸는 적응 회로. 이 다섯 개가 맞물려야 차 한 대가 된다는 얘기였죠.

이걸 기술자 어휘로 바꾸면 이래요. 목표 수용은 프롬프트 레이어라서 따로 빼기보다 다른 층에 녹이고, 상태는 state management, 팔다리는 tool use, 루프는 autonomous loop, 적응은 reflection + planning. 여기에 하나 더, 복잡한 작업을 여러 agent가 나눠 맡는 multi-agent 층이 붙어요. 이 다섯을 이제 하나씩 정비소에 올려 볼 거예요.

2. Tool use를 진짜로 뜯어보면

Tool use를 멀리서 보면 “LLM이 도구를 쓴다” 는 한 줄인데, 가까이서 뜯으면 JSON 왕복 다섯 번 이에요. 이걸 주문 창구 비유로 그려볼게요.

패스트푸드점에 주문 창구가 있어요. 손님(LLM)은 카운터 너머의 주방(외부 도구)에 직접 못 들어가요. 손님이 할 수 있는 건 주문지 를 적는 것뿐이에요. 주문지는 정해진 양식이 있어요. 햄버거 종류, 사이드, 음료 칸이 딱 나뉘어 있죠. 손님이 자유로운 문장으로 “고기 좀 구워주세요” 라고 쓰면 주방이 못 알아들어요. 카운터는 그 양식대로 쓰인 주문지만 주방에 넘겨줘요. 주방은 주문을 받아서 음식을 만들고 쟁반에 담아서 다시 카운터로 내려보내요. 카운터는 그 쟁반을 다시 손님에게 보여주고, 손님은 그걸 받아서 “다음에 뭘 시킬까” 를 생각해요.

이 전체가 tool use예요. LLM이 손님, 주문지 양식이 JSON schema, 카운터가 agent harness, 주방이 실제 함수나 API예요. 한 장면씩 뜯어볼게요.

(1) 도구 정의 — 주문지 양식을 짜는 단계

Agent를 만드는 사람이 LLM에게 “너는 이런 도구들을 쓸 수 있어” 라고 미리 알려줘요. Anthropic의 tool use 공식 문서를 보면 이런 식으로 생겼어요.

{
  "name": "get_weather",
  "description": "특정 도시의 현재 날씨를 가져옵니다. 현지 시각 기준.",
  "input_schema": {
    "type": "object",
    "properties": {
      "city": {"type": "string", "description": "도시 이름 (한글 또는 영어)"},
      "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
    },
    "required": ["city"]
  }
}

이 정의가 프롬프트의 일부로 모델에 주입돼요. 모델은 여기서 세 가지 정보를 읽어요. 이름 (이 도구를 부를 때 쓸 식별자), 설명 (언제 써야 하는지), 입력 스키마 (어떤 파라미터를 넣어야 하는지). 설명이 엉성하면 LLM이 엉뚱한 상황에서 이 도구를 부르거나, 반대로 이 도구가 필요한 상황에서 안 불러요. 도구 정의가 agent 품질의 절반이라는 말이 여기서 나와요.

(2) 모델의 결정 — 다음 토큰 예측이 JSON을 뱉는 지점

여기가 제일 신기한 지점이에요. LLM은 원래 “다음 단어 확률” 기계라고 F1·F4에서 배웠잖아요. 그런데 어떻게 깨끗한 JSON이 나올까요.

답은 좀 허무해요. JSON도 그냥 토큰의 연속 이라서요. { 라는 토큰 다음에 " 가 올 확률이 높고, 그다음 n a m e 같은 토큰이 올 확률이 높고, 그다음 " 가 올 확률이 높고. 이 패턴을 수천만 번 훈련받은 모델은 JSON을 “자연스러운 다음 토큰 흐름” 으로 인식해요. 구조화된 출력이 아니라 구조처럼 보이는 텍스트 인 거예요.

다만 이대로만 두면 가끔 이상한 JSON이 나와요. 괄호가 안 닫히거나 키가 중복되거나. 그래서 현대 agent 프레임워크는 constrained decoding 이라는 장치를 써요. 모델이 토큰을 고를 때 “지금 이 위치에 올 수 있는 토큰” 을 스키마 기반으로 제한해요. 예를 들어 {"name": 까지 나왔으면 다음엔 반드시 문자열 토큰이 와야 한다고 강제해요. 이렇게 하면 JSON 형식이 100% 유효해져요. 대신 모델이 내고 싶었던 토큰을 못 내게 막는 거라 품질이 살짝 떨어질 수도 있어요. 그 트레이드오프를 각 프레임워크가 다르게 풀고 있습니다.

Anthropic은 여기에 tool_use 라는 전용 출력 타입을 만들어서, 모델이 도구를 부르고 싶을 때 일반 텍스트 대신 이 타입을 뱉도록 별도로 훈련했어요. OpenAI의 function calling 도 같은 아이디어고요. Google의 Gemini는 또 살짝 다른 포맷이에요. 뼈대는 같지만 JSON 필드 이름과 호출 방식이 API마다 달라서, 프레임워크 갈아탈 때 이 부분을 맞춰줘야 해요. 여기서 LangChain 같은 프레임워크가 해주는 일 의 큰 부분이 바로 세 provider의 포맷 차이를 가려주는 거예요.

(3) Harness의 실행 — 카운터가 주방으로 넘기는 단계

모델이 {"name": "get_weather", "input": {"city": "Seoul"}} 같은 JSON을 뱉으면, 이제 agent harness가 이걸 받아요. Harness는 코드예요. 파이썬이든 타입스크립트든. Harness는 이 JSON을 읽고, 미리 등록해 둔 get_weather 함수를 찾아서, city="Seoul" 로 실제 호출해요. 네트워크를 때리든 DB를 조회하든 실제 행동이 여기서 일어나요.

중요한 건 LLM이 직접 함수를 실행하는 게 아니라는 점 이에요. LLM은 “이 함수를 이렇게 불러 줘” 라고 요청 만 하고, 실제 실행은 harness가 해요. 이 분리 덕분에 LLM이 위험한 일을 못 하게 막을 수 있어요. Harness가 중간에서 “이 함수는 허용, 이 함수는 확인 필요, 이 함수는 금지” 를 거를 수 있거든요. Agent 안전성의 상당 부분이 이 카운터 층에서 설계돼요.

(4) 결과 재주입 — 쟁반이 다시 손님에게 가는 단계

함수가 실행돼서 결과 (예: {"temp": 14, "condition": "cloudy"}) 가 나오면, harness는 이 결과를 다시 LLM의 다음 호출에 붙여 넣어요. 이때 “아까 네가 get_weather를 불렀는데 결과가 이거야” 라는 맥락으로 프롬프트에 끼워요. Anthropic API에서는 tool_result 블록, OpenAI에서는 role: tool 메시지예요.

LLM은 이 결과를 읽고 다음 결정 을 해요. “서울은 14도 흐림” 이라고 사용자에게 답해도 되고, 아니면 “날씨가 흐리니까 우산 정보도 더 찾아보자” 라고 다시 다른 도구를 부를 수도 있어요. 이 선택이 agent의 지능의 정체예요.

(5) 왕복의 반복 — 한 번으론 거의 안 끝난다

단순한 질문이면 왕복 한 번에 끝나요. 하지만 실제 작업은 거의 여러 왕복 을 돌아요. 예를 들어 “우리 블로그 최근 3편을 요약해 줘” 라고 하면, 최소 이런 순서가 돼요. 첫 왕복: 블로그 목록 API를 부름. 둘째 왕복: 각 기사 본문을 하나씩 가져옴 (혹은 병렬로). 셋째 왕복: 각 본문을 읽고 요약문을 생성. 이 세 번이 안에서 자동으로 돌아가요.

이 왕복의 누적이 context window를 먹는다 는 점이 중요해요. 도구 호출 한 번마다 요청 JSON + 결과 JSON이 프롬프트에 쌓여요. 길어지면 수만 토큰이 금방 찹니다. M2에서 다룬 long-context 얘기가 여기랑 붙어요. Agent의 컨텍스트 관리가 왜 까다로운지가 tool use 왕복 구조에서 직접 나와요.

정리하면 tool use는 JSON 스키마 + 왕복 실행 + 결과 재주입 이에요. 이걸 알고 보면 agent가 “도구를 쓴다” 는 한 문장이 실제로는 다섯 단계 왕복 장치라는 게 보여요.

3. State — “지금까지 한 일”을 어디에 두나

상태 관리는 agent의 기억 창고 설계예요. B1에서 “LLM은 기억이 없고 상태는 바깥에서 관리한다” 고 했었죠. 그 “바깥” 이 구체적으로 어디인지 정비소에 올려볼게요.

세 종류의 저장소

Agent의 상태는 보통 세 군데에 나눠져 있어요.

(1) 세션 컨텍스트 (conversation history). 지금 돌고 있는 대화 안의 메시지들. LLM 호출할 때마다 이게 통째로 프롬프트에 붙어요. 가장 빠르고 가장 비싸요. 100만 토큰 컨텍스트가 가능하다고 해도 매번 100만 토큰을 붙이면 호출 비용이 폭발해요. 그래서 현대 agent는 세션 컨텍스트를 요약해서 압축 하거나 중요하지 않은 걸 잘라내는 로직이 붙어요.

(2) Workspace 디렉토리. 작업 중 만드는 파일들. Agent가 생성한 코드, 메모, 로그, 중간 산출물이 여기 쌓여요. Claude Code는 현재 작업 디렉토리를 workspace로 써요. Devin은 전용 가상 컴퓨터 안에 workspace를 띄워요. Cursor는 열려 있는 프로젝트 폴더가 workspace고요. 이 workspace가 있는지 없는지 가 agent의 작업 규모를 결정해요. Workspace 없는 agent는 한 번의 대화 이상을 할 수 없어요.

(3) Scratchpad 파일. Agent가 자기 생각을 정리하려고 쓰는 메모장. 유명한 예가 Claude Code의 TODO.md 패턴이에요. Agent가 복잡한 작업을 받으면 먼저 “해야 할 일 목록” 을 TODO.md에 적어요. 그 다음 하나씩 체크하면서 진행해요. 중간에 새로운 일이 생기면 TODO.md에 추가하고요. 이 파일이 agent의 단기 플랜을 외부화한 장치예요. LLM 본체가 기억이 없으니까, “지금 뭘 하고 있었지?” 를 파일로 외주 낸 거죠.

이 세 저장소의 조합을 memory architecture 라고 불러요. B1의 “상태 추적” 층이 실제로는 이 세 저장소 설계 문제인 거예요.

Scratchpad의 비밀

Scratchpad 얘기를 한 문단 더 하고 갈게요. 왜 TODO.md 같은 파일이 agent 성능을 크게 올리는지가 한 번에 직관적이지 않거든요. 짧게 말하면, 계획을 쓰는 행위 자체가 추론을 끌어올려요.

LLM은 “Chain of Thought” 라는 훈련 덕분에 중간 생각을 텍스트로 뱉으면 성능이 올라가요. 2022년 Google의 CoT 논문이 이걸 보여줬어요. 같은 문제도 “바로 답해” 보다 “단계별로 생각해 봐” 가 정답률이 훨씬 높아요. Scratchpad에 TODO를 쓰는 건 이 Chain of Thought를 파일로 외부화한 거예요. LLM이 매 호출마다 “지금 내 TODO 상태” 를 읽으면서, 자연스럽게 이전의 추론 흐름을 이어받아요.

Before 상태를 상상해 보세요. Scratchpad 없는 agent는 각 호출이 섬처럼 떨어져 있어요. “지금 3단계 중 2단계 중인데 다음엔 뭘 해야 하지?” 를 매번 처음부터 재구성해요. 컨텍스트가 긴 경우 앞쪽이 희미해지면서 중간에 탈선해요. After는 이래요. Scratchpad가 있으면 agent가 TODO.md를 첫 줄에 읽고, “아 2단계까지 했구나, 3단계로 넘어가면 되겠네” 를 즉시 복구해요. 탈선율이 눈에 띄게 떨어지고 긴 작업을 끝까지 완수하는 비율이 올라가요.

이 Before/After 차이가 실제로 관찰되니까 Anthropic이 Claude Code에 TODO.md 패턴을 “권장 워크플로” 로 박아 넣었어요. Cursor도 최근 버전에서 비슷한 planning scratchpad를 도입했어요. State 관리의 핵심 팁 하나만 가져가시면 돼요. “agent에게 외부 노트장을 줘라”.

4. Planning — 복잡한 목표를 잘게 쪼개는 기법

Agent가 “이 버그 고쳐” 같은 한 문장을 받아서 여러 단계로 쪼개는 능력, 이게 planning이에요. Planning에는 역사적으로 몇 가지 패턴이 나왔어요. 세 개만 보고 갈게요.

ReAct — 생각 → 행동 → 관찰의 사이클

2022년 Princeton과 Google이 낸 “ReAct: Synergizing Reasoning and Acting in Language Models” 논문이 이름의 출처예요. Reasoning + Acting 의 줄임말이에요.

구조는 단순해요. LLM이 매 스텝마다 세 가지를 출력해요. Thought (지금 상황 분석), Action (어떤 도구를 부를지), Observation (결과를 보고 뭘 배웠는지). 그리고 이 세 줄이 반복돼요.

예를 들면 이래요.

Thought: 사용자가 버그 원인을 물었으니 일단 로그를 봐야겠다.
Action: read_file("logs/error.log")
Observation: "TypeError: undefined is not a function" 에러가 3번 반복됨.

Thought: undefined 에러니까 함수 호출 쪽을 봐야겠다. 스택 트레이스의 파일을 열자.
Action: read_file("src/parser.ts")
Observation: 27번째 줄에서 `data.parse()` 를 부르는데 data가 null일 수 있음.

Thought: null 체크를 추가하면 해결될 것 같다.
Action: edit_file("src/parser.ts", ...)
Observation: 수정 완료. 테스트를 돌려보자.

ReAct의 강점은 생각을 명시적으로 쓴다 는 거예요. 그냥 도구만 호출하는 agent는 왜 그 도구를 불렀는지 안 적어요. ReAct는 Thought를 의무적으로 써요. 이것만으로도 LLM의 추론 품질이 유의미하게 올라간다는 게 논문의 발견이었어요. 앞의 scratchpad 얘기랑 같은 맥락이에요. 생각을 글로 쓰면 더 잘 생각하게 됩니다.

Claude Code, Cursor, Devin은 내부적으로 ReAct 패턴을 기본 베이스로 씁니다. 각자 미세한 변형이 있지만 “Thought → Action → Observation 의 반복” 이라는 뼈대는 공통이에요.

Plan-and-Execute — 먼저 전체 계획, 그다음 실행

ReAct는 한 스텝씩 생각하면서 간다 는 방식이에요. 장점은 유연함이고 단점은 큰 그림을 놓칠 수 있다는 거예요. 스텝마다 근시안적으로 “지금 뭐 할까” 만 고르다 보면, 열 스텝 뒤의 목표를 놓치기도 해요.

Plan-and-Execute는 반대 방향이에요. 먼저 전체 계획 을 세우고, 그다음 계획대로 실행해요. 2023년 LangChain이 이 패턴을 프레임워크로 정형화했어요.

구조는 이래요. 첫 단계에서 Planner 라는 LLM 호출이 “이 작업을 끝내려면 다음 10단계가 필요하다” 를 출력해요. 그다음 Executor 라는 LLM 호출이 1단계부터 하나씩 실행해요. 각 단계가 끝나면 체크하고 다음으로 넘어가요. 계획에 없던 상황이 나오면 Planner로 돌아가서 계획을 다시 짜요.

장점은 큰 그림을 놓치지 않는다 는 거예요. 10단계 계획이 서 있으니까 중간에 탈선해도 “아 내가 지금 어느 단계인지” 를 계획서로 복구할 수 있어요. 단점은 경직성 이에요. 계획이 틀렸을 때 고치는 비용이 크고, 짧은 작업에는 오버헤드가 과해요.

Devin이 이 패턴을 강하게 써요. Devin의 UI를 보면 화면 한쪽에 “Plan” 이라는 영역이 있어서 10~30단계짜리 체크리스트가 실시간으로 돌아가요. 이게 Plan-and-Execute의 시각적 구현이에요.

Hierarchical — 상위 agent가 하위 agent에게 시킨다

세 번째 패턴은 계층 분해 예요. 상위 agent는 큰 작업을 받아서 서브 작업으로 나누고, 각 서브 작업을 하위 agent에게 넘겨요. 하위 agent가 끝나면 결과를 상위로 보고해요.

예를 들어 “우리 블로그 기사 10편을 분석해서 리뷰 리포트를 써 줘” 라는 작업이 있다고 해봐요. 계층 분해는 이래요. 상위 agent는 “기사 10편 분석 → 공통 패턴 추출 → 리포트 작성” 의 세 큰 작업으로 쪼개요. 첫 작업은 10개의 하위 agent를 병렬로 띄워서 각자 1편씩 분석하게 시켜요. 10개가 다 끝나면 결과를 모아서 두 번째 작업으로 넘어가요.

이 패턴의 장점은 병렬화 예요. 10편을 순차로 하면 10배 시간이 들지만 병렬로 하면 1편 시간에 끝나요. Token 비용은 늘지만 총 걸리는 시간이 짧아져요.

Claude Code의 Task tool, LangGraph의 subgraph, AutoGen의 group chat이 이 계층 분해를 구현한 예예요. 2025년 이후 agent 설계의 주류가 점점 hierarchical 쪽으로 기울고 있어요. 작업 복잡도가 올라갈수록 한 agent가 다 하는 건 한계가 명확해지거든요.

세 패턴의 선택 기준

실무에서는 이렇게 섞어 써요. 작은 작업 (5스텝 이내) 에는 ReAct, 복잡하지만 예측 가능한 작업 (번역, 리팩토링) 에는 Plan-and-Execute, 병렬화가 가능한 큰 작업에는 Hierarchical. 한 제품 안에 세 패턴이 다 섞여 있기도 해요. Claude Code는 기본 루프가 ReAct이고, 복잡한 작업에선 Task tool로 subagent를 띄우는 hierarchical가 올라붙어요.

5. Reflection — “내가 낸 답이 맞나” 확인 루프

Planning이 “다음에 뭐 할까” 라면, reflection은 “내가 방금 한 게 맞나” 예요. 사람으로 치면 자기 검토에 해당해요.

Self-Critique 패턴

가장 단순한 형태의 reflection은 self-critique 예요. LLM이 답을 낸 뒤에, 같은 LLM이 자기 답을 비판 하는 두 번째 호출을 해요. 프롬프트는 이런 식이에요. “너는 방금 이런 답을 냈어. 이 답에 문제가 있는지, 놓친 게 있는지, 틀린 게 있는지 검토해 봐.”

놀라운 점은 이게 실제로 작동한다는 거예요. 같은 모델이 같은 문제를 두 번 보는 건데, 두 번째 볼 때 이미 답이 있는 상태에서 검토하는 task 니까 성격이 달라져요. 처음에는 백지에서 답을 만드느라 놓친 걸, 두 번째에는 “완성된 답을 감시하는” 입장에서 잡아내요. OpenAI의 o1 같은 추론 모델이 내부적으로 이런 self-critique를 수백 번 돌리는 걸 학습 단계에서 훈련받았어요.

Verification Loop

조금 더 정교한 형태가 verification loop 예요. Agent가 작업을 끝내고 “완료” 라고 선언하기 전에, 검증 단계 를 강제로 거쳐요.

코딩 agent의 경우 전형적인 verification은 이거예요. 코드를 고쳤어? → 테스트를 돌려 봐 → 테스트가 통과했나? → 통과했으면 완료, 실패했으면 다시 고쳐. 이 루프가 reflection이에요. 단순 “내가 짠 코드가 맞는 것 같아” 라는 자기 확신이 아니라, 외부 신호 (테스트 결과) 로 검증하는 거죠.

좋은 agent는 verification이 여러 층 으로 설계돼 있어요. Type check, unit test, integration test, lint, manual review. 각 층을 통과해야 다음으로 넘어가요. Claude Code가 코드를 수정한 후 자동으로 npm testpytest 를 돌리는 이유가 이 verification loop를 밟기 위해서예요.

Retry Trigger

Reflection이 “실패를 감지하면 retry” 와 짝으로 돌아가야 의미가 있어요. 감지만 하고 고치지 않으면 그냥 로그 남기는 거잖아요. Retry trigger는 검증 실패 시 자동으로 다시 시도하는 장치예요.

여기서 설계 포인트가 있어요. 무한 retry는 위험 해요. 같은 방식으로 10번 retry하면 10번 실패하고 돈만 날려요. 좋은 retry는 다르게 시도 해요. 첫 실패 이후엔 LLM에게 “아까 이렇게 했더니 실패했어, 다른 접근을 써 봐” 라고 실패 원인을 포함해서 프롬프트를 다시 날려요. 이게 B1의 “적응 (adaptation)” 층의 정체예요. Reflection이 실패를 감지하고, retry가 다르게 다시 도는 거예요.

이 reflection 층이 다음 편 M5 Evaluation 으로 바로 이어져요. Evaluation은 agent를 외부에서 평가하는 프레임워크이고, reflection은 agent가 내부에서 자기 검증하는 장치예요. 둘이 같은 뿌리에서 출발해요. “답이 맞는지 어떻게 아는가” 라는 질문이요.

6. Multi-Agent — 여러 agent가 역할 분담

마지막 층이 multi-agent예요. B1에서는 없었던 층이에요. B1은 “한 대의 차” 얘기였지만, 현실에서는 차 여러 대가 협업하는 구조도 많이 쓰여요.

왜 여러 agent로 나누나

한 agent에게 모든 역할을 다 시키면 프롬프트가 비대 해져요. “너는 기획자이자 개발자이자 테스터이자 리뷰어야” 라고 쓰면 LLM이 매 순간 “지금 내 역할이 뭐지?” 를 재확인해야 해요. 이게 품질을 떨어뜨려요.

반대로 agent를 역할별로 분리하면 각 agent의 시스템 프롬프트가 명확 해져요. 기획자 agent는 기획만, 개발자 agent는 개발만, 리뷰어 agent는 리뷰만. 각자 자기 일만 집중해서 잘해요. Claude Code에서 subagent를 띄울 때 “이 subagent는 오직 파일 검색만 하는 역할” 같은 좁은 프롬프트를 주는 이유가 이거예요.

대표 구현체들

Claude subagent. Anthropic의 Task tool이 이 개념을 프레임워크에 박아 넣었어요. 상위 agent가 “이 작업을 할 subagent를 띄워” 라고 요청하면, 별도의 컨텍스트에서 하위 agent가 돌아요. 하위 agent가 끝나면 결과만 상위로 돌아와요. 컨텍스트가 격리된다는 게 핵심이에요. 하위 agent의 중간 생각이 상위 컨텍스트를 오염시키지 않아요.

CrewAI. 2024년에 뜬 프레임워크예요. 여러 agent에게 “역할, 목표, 도구” 를 지정하고 팀으로 묶어서 일하게 해요. 예를 들어 “리서처, 라이터, 편집자” 세 agent를 만들고 “이 주제로 블로그 기사를 써” 라고 지시하면, 셋이 자기 역할대로 협업해요. UX가 직관적이라 프로토타입에 인기 많아요.

LangGraph. LangChain이 만든 multi-agent 프레임워크예요. Agent 간 흐름을 그래프 로 정의해요. 어떤 조건에서 어느 agent로 넘어가는지를 노드와 엣지로 그려요. 좀 더 엔지니어링적인 접근이고 프로덕션에 적합해요. Auto-GPT가 직선 루프로 죽었다는 교훈을 받아서 “조건부 분기가 가능한 그래프” 로 진화한 거예요.

언제 효과, 언제 오버엔지니어링

Multi-agent는 양날의 검이에요. 효과 있는 경우는 역할이 명확히 갈라지는 작업 이에요. 기사 작성 (리서치 → 초안 → 편집), 코드 리뷰 (제안 → 비평 → 반영), 복잡한 연구 (탐색 → 합성 → 보고) 같은 것들이요.

오버엔지니어링이 되는 경우도 많아요. 단순한 작업을 굳이 3개 agent로 나누면 agent 간 커뮤니케이션 오버헤드 가 작업 자체보다 커져요. 한 agent가 다른 agent에게 “이게 필요해요” 라고 전달하는 메시지를 생성하는 데 토큰이 들고, 받는 agent가 그걸 해석하는 데 또 토큰이 들어요. 단순 작업은 한 agent가 끝까지 하는 게 훨씬 빨라요.

현실 팁 하나. 처음에는 무조건 single-agent로 시작하세요. Single-agent가 막히는 지점이 명확해졌을 때, 그 지점만 subagent로 분리하세요. 처음부터 multi-agent 구조를 설계하면 복잡성만 늘고 실제 품질은 안 올라오는 경우가 많아요. 이건 Anthropic 엔지니어들이 공개 블로그에서 반복해서 강조하는 포인트이기도 해요.

7. 실제 agent 제품을 5층으로 분해해보기

이제 4개 대표 제품을 이 5층으로 분해해볼게요. 한 줄 요약 표부터.

제품 Tool use State Planning Reflection Multi-agent
Claude Code 강 (workspace + TODO) 강 (ReAct + Task) 강 (test-driven) 중 (subagent 가능)
Cursor 중 (프로젝트 인덱스) 중 (Composer planning) 중 (lint/type check)
Devin 강 (전용 VM) 강 (Plan-Execute)
Auto-GPT 중 (불안정) 약 (파일 기반) 약 (직선 루프) 약 (없음에 가까움) 없음

한 제품씩 살을 붙여볼게요.

Claude Code

Tool use는 매우 정교해요. Read, Edit, Write, Bash, Grep, Glob, Task 같은 기본 도구가 있고, MCP로 수십 개가 더 붙어요. JSON schema가 엄격하게 정의돼 있고 permission 시스템으로 위험 행동을 걸러요.

State는 workspace (현재 디렉토리) + 세션 히스토리 + CLAUDE.md 라는 장기 기억 파일 + TODO.md scratchpad 의 4층 조합이에요. CLAUDE.md가 프로젝트별 규칙을 LLM 바깥에 두고 재주입되니까 세션이 끊겨도 프로젝트 맥락이 안 없어져요.

Planning은 ReAct가 기본이고, 복잡한 작업에선 Task tool로 subagent를 띄워서 hierarchical 분해가 돼요. “이 일은 내가 못 하겠다” 라고 스스로 판단해서 subagent를 띄우는 걸 봤을 때 “얘 진짜 지능이 있네” 싶은 순간이 있어요.

Reflection은 test-driven이에요. 코드 수정 후 자동으로 테스트를 돌리고, 실패 시 다시 수정하는 루프가 기본이에요. Lint, type check도 체크 단계에 들어와요.

Multi-agent는 subagent 패턴이 있지만 Devin처럼 완전히 독립된 에이전트 팀 구조는 아니에요. 중간 정도 수준.

Cursor

Tool use는 강해요. 파일 편집, 터미널, 검색 같은 기본 도구가 에디터에 직접 통합돼 있어요.

State는 프로젝트 인덱스 (파일 임베딩) 와 세션 히스토리가 중심이에요. Claude Code의 CLAUDE.md에 해당하는 장기 기억 장치는 .cursorrules 파일인데 운영 깊이가 Claude Code만큼은 아니에요.

Planning은 Composer에 간단한 planning이 들어가 있어요. 복잡한 작업을 받으면 여러 파일을 순서대로 편집하는 계획을 세워요. 하지만 hierarchical 분해나 명시적인 Plan-and-Execute는 약해요.

Reflection은 편집 결과를 lint, type check로 검증하는 건 있는데, test-driven 루프가 Claude Code만큼 강제되진 않아요. Cursor는 개발자가 직접 보면서 쓰는 제품이라, reflection의 일부를 개발자에게 맡기는 설계예요.

Multi-agent는 거의 없어요. 여러 agent 협업 구조는 Cursor의 초점이 아니에요.

Devin (Cognition)

Tool use는 자체 VM 환경 안에서 브라우저, 에디터, 터미널을 다 도구로 써요. 시각적으로 “Devin이 브라우저 여는 걸 볼 수 있는” 것이 큰 차별점이에요.

State는 전용 가상 머신 하나를 작업당 띄워요. 이 VM이 workspace이자 장기 기억 저장소예요. 작업이 며칠 걸려도 VM이 살아있어서 상태가 유지돼요.

Planning은 Plan-and-Execute가 강해요. UI에 10~30스텝 계획이 보이고 실시간으로 체크됩니다.

Reflection은 단계마다 검증 스텝이 들어가요. 코드 수정 후 테스트, UI 변경 후 스크린샷 비교 같은 식으로.

Multi-agent는 내부적으로 여러 agent가 협업하는 구조예요. 기획, 실행, 리뷰가 분리돼 있다고 알려졌어요.

단점은 비싸다 는 거예요. VM을 작업당 띄우는 게 토큰 비용 위에 인프라 비용이 얹혀서, 구독료가 높아요. 품질은 높지만 비용 대비 합리성은 사용자마다 평가가 갈려요.

Auto-GPT (2023년 초기 실패 사례)

Auto-GPT는 2023년 3월에 공개됐고 GitHub에서 스타 수십만을 받았어요. 완전 자율 agent 라는 개념을 대중에 처음 보여준 프로젝트예요. 그런데 실제로 써 본 사람들은 대부분 “뭔가 안 된다” 는 인상을 받았어요. 왜 그랬는지를 5층으로 진단해 볼게요.

Tool use는 불안정 했어요. 당시 GPT-4의 function calling이 나오기 전이라, LLM 출력을 정규식으로 파싱해서 도구를 불렀어요. 파싱 실패가 잦았고, 엉뚱한 함수를 부르는 일이 많았어요.

State는 얕았어요. 로컬 파일에 간단히 기록하긴 했는데 workspace 개념이 명확하지 않았어요. 세션이 길어지면 agent가 “내가 뭘 했더라” 를 자주 헷갈렸어요.

Planning은 직선 루프 였어요. ReAct처럼 한 스텝씩 돌면서 “다음에 뭐 할까” 만 골랐어요. Plan-and-Execute도 hierarchical도 없었어요. 그래서 큰 작업을 주면 5분 안에 탈선해서 엉뚱한 방향으로 갔어요.

Reflection은 거의 없었어요. Verification loop도 retry trigger도 제대로 없었고, agent가 “내가 지금 맞게 가고 있나?” 를 체크하는 장치가 빈약했어요.

Multi-agent는 전혀 없었어요. 한 agent가 혼자 다 하려고 했어요.

이 다섯 층이 다 빈약하니까 실패가 당연했어요. 그런데 Auto-GPT는 개념 증명 으로서는 엄청난 역할을 했어요. 2023년 이후 모든 agent 프레임워크가 “Auto-GPT가 왜 안 됐나” 를 교훈으로 해서 각 층을 보강하는 방향으로 진화했어요. Claude Code도 Devin도 LangGraph도 다 Auto-GPT의 실패 위에 서 있어요.

8. 왜 Auto-GPT는 실패했고 Claude Code는 성공했나

같은 질문을 거꾸로 봐요. Auto-GPT가 2023년에 실패한 게 2025년의 Claude Code에 어떤 교훈을 남겼나. 다섯 층을 비교하면 5개 층 전부 에서 차이가 나요.

Tool use의 안정성. Auto-GPT는 정규식 파싱, Claude Code는 Anthropic API의 tool_use 전용 타입. 포맷 에러율이 다른 차원이에요. 구조화된 function calling이 표준이 된 게 agent 실용화의 조용한 혁명이었어요.

State의 깊이. Auto-GPT는 파일 메모, Claude Code는 workspace + CLAUDE.md + TODO scratchpad + 세션 컨텍스트의 4층. 기억의 내구성이 다르고, 장기 작업의 탈선율이 다릅니다.

Planning의 구조화. Auto-GPT는 직선 ReAct, Claude Code는 ReAct + subagent + task decomposition의 조합. 작업 복잡도에 맞춰서 planning 깊이가 적응적으로 바뀌어요.

Reflection의 존재. Auto-GPT는 거의 없음, Claude Code는 test-driven loop + lint + type check. “내가 낸 답이 맞는지” 를 외부 신호로 계속 검증해요.

Tool 안전성. Auto-GPT는 권한 관리가 거의 없어서 위험한 명령도 그냥 실행했어요. Claude Code는 Permission 시스템으로 파일 삭제나 force push 같은 건 사용자 확인을 받아요. 이게 agent의 프로덕션 도입을 가능하게 한 요소예요.

정리하면 Auto-GPT는 5층 중 어느 것도 충분히 깊지 않았어요. Claude Code는 5층을 다 세심하게 설계했어요. 같은 기본 아이디어 (LLM + 도구 + 루프) 위에서, 각 층의 엔지니어링 품질이 실용화의 갈림길이었어요. 모델이 GPT-3.5에서 Claude 4.7로 올라간 것도 당연히 큰 영향이지만, harness 설계의 숙성 이 그만큼 혹은 그 이상의 비중을 차지해요. 이 얘기가 M4로 넘어가요.

9. 실무에서 agent 제품 평가할 때 물어야 하는 10가지

회장님이 agent 제품을 도입하거나 평가할 때 바로 써먹을 수 있는 체크리스트예요. B1의 5개 질문을 더 구체화한 10개입니다. 각 질문은 위에서 다룬 5층 중 어디에 해당하는지도 표시해둘게요.

1. Tool use — 이 agent는 내 도구를 쓸 수 있나?
MCP 같은 확장 프로토콜을 지원하나, 아니면 built-in 도구만 있나. 우리 환경에 맞는 도구를 추가할 수 있는 길이 있나.

2. Tool use — 도구 호출 실패율이 얼마나 되나?
→ 벤더에게 직접 물어보세요. 10% 이상이면 프로덕션에 쓰기 위험해요. 잘 만든 agent는 1~2% 이하예요.

3. State — 세션을 재개할 때 이전 맥락이 유지되나?
→ 세션을 일부러 끊고 며칠 뒤에 다시 열어 보세요. “지난번에 뭘 했었지” 를 agent가 기억하는지가 state 품질의 직접 증거예요.

4. State — Scratchpad나 TODO 같은 노트장이 있나?
→ Agent가 자기 계획을 파일로 적는지 보세요. 있으면 긴 작업의 탈선율이 낮아요.

5. Planning — 복잡한 작업을 받았을 때 먼저 계획을 보여주나?
→ 10스텝짜리 작업을 시켜 보세요. 바로 1스텝을 시작하는 agent보다, 먼저 계획을 보여주고 확인받는 agent가 신뢰할 만해요.

6. Planning — 중간 결과를 볼 수 있나?
→ Agent가 돌아가는 동안 내부 상태가 실시간으로 보이는지. 블랙박스에서 결과만 뱉는 agent는 실패 원인 추적이 어려워요.

7. Reflection — 실패하면 다시 시도하나?
→ 일부러 실패 케이스를 던지고 관찰하세요. 바로 “실패했습니다” 를 뱉고 끝나면 agent로 부르기 부족해요.

8. Reflection — Verification은 무엇으로 하나?
→ 테스트, lint, 외부 API 결과, 스크린샷 비교 중 뭐가 verification 신호로 쓰이는지. 자기 확신만으로 “완료” 를 선언하는 agent는 위험해요.

9. Multi-agent — Subagent를 띄울 수 있나?
→ 항상 필요한 건 아니지만, 복잡한 작업에 subagent 옵션이 있으면 확장성이 있어요.

10. 전체 — 이 agent의 harness는 누가 설계했나?
→ B1에서도 물었던 질문이에요. Agent 설계 경험이 있는 팀인지, 그냥 API wrapper 급인지. 답변에서 “OpenAI/Anthropic API에 프롬프트 붙였다” 수준이면 몇 달 뒤 경쟁력이 약해요.

이 10개를 던지면 대부분의 “agent” 제품이 어느 수준인지 빠르게 가려져요. 특히 2번 (도구 실패율), 4번 (scratchpad), 8번 (verification 신호) 이 제일 날카로운 질문이에요. 이 셋은 설계가 실제로 깊이 있는 팀 만 답할 수 있어요.

10. Agent는 왜 하네스 없이 못 사나 — M4 예고

5층을 다 뜯고 나니 보이는 게 있어요. 이 5층 전부가 LLM 바깥에서 돌아가요. Tool use의 JSON 왕복, state의 저장소 관리, planning의 계획 수립, reflection의 검증 루프, multi-agent의 오케스트레이션. 이게 다 LLM 본체가 하는 게 아니라 LLM을 둘러싼 코드 가 해요.

이 “둘러싼 코드 전체” 가 harness 예요. B1에서도 언급했지만 이번 편을 거쳐서 보니 더 분명해졌어요. Agent의 품질은 모델이 얼마나 좋은지보다 harness가 얼마나 정교한지 로 결정돼요. 같은 Claude Sonnet 4.7을 쓴다고 해도 Claude Code와 Auto-GPT는 완전히 다른 결과를 내요. 차이가 harness에 있어요.

다음 편 M4에서는 이 harness를 직접 뜯어봅니다. 도구 정의를 어떻게 쓰는가, permission 시스템을 어떻게 설계하는가, 컨텍스트를 어떻게 압축하는가, sandbox와 격리는 어떻게 하는가. Agent 제품 평가의 질문 10번 (“이 harness는 누가 설계했나”) 에 직접 답할 수 있게 될 거예요. Agent를 직접 만들거나 경쟁 제품을 뜯어보고 싶은 분들에게 M4가 제일 실전 편이 될 거예요.

닫는 한 문장

Agent는 tool use · state · planning · reflection · multi-agent 라는 5층으로 구성된 시스템이고, Claude Code와 Auto-GPT의 운명이 갈린 것도 결국 이 5층 각각의 엔지니어링 깊이였다. 이 5층을 체크리스트로 가지고 있으면 어떤 agent 제품도 공정하게 평가할 수 있다. 다음 편에서 이 5층을 떠받치는 harness 자체의 설계 원리 로 들어갑니다.

다음 읽기

  • M4 — Harness가 agent를 agent로 만드는 방식 [준비 중]
  • M5 — Evaluation이 agent 품질을 수치로 만드는 방식 [준비 중]

시리즈 처음부터: F1 — LLM이란 무엇인가 · B1 — Agent가 LLM과 다른 순간 · M2 — Long-context와 Memory

자주 묻는 질문 (FAQ)

Q1. Tool use와 function calling은 같은 말인가요?

거의 같은 말이에요. OpenAI가 2023년에 function calling 이라는 이름으로 API에 먼저 도입했고, Anthropic이 비슷한 기능을 tool use 라는 이름으로 냈어요. 개념은 같아요. “LLM이 JSON으로 도구 호출을 요청하고, 외부 코드가 실행 후 결과를 다시 LLM에 돌려주는 왕복 구조” 예요. 요즘은 tool use 가 더 일반적인 용어로 정착하는 중이에요. “function” 이 프로그래밍 함수에 한정된 느낌이라면 “tool” 은 검색, 계산, API 호출, 심지어 다른 agent 호출까지 포괄하는 상위 개념이거든요.

Q2. ReAct와 Chain of Thought는 뭐가 다른가요?

Chain of Thought (CoT) 는 LLM이 답을 내기 전에 중간 생각을 쓰도록 유도 하는 프롬프트 기법이에요. “단계별로 생각해 봐” 라고 지시하면 모델이 생각을 쓰면서 푸는 거죠. ReAct는 CoT에 도구 사용 (Acting) 을 결합한 거예요. CoT가 “생각만” 한다면 ReAct는 “생각하고, 도구 부르고, 결과 보고, 또 생각” 을 반복해요. Agent 환경에서는 CoT만으로는 부족하고 ReAct가 필요해요. 외부 세계와 상호작용이 있어야 agent거든요.

Q3. Multi-agent를 처음 도입하려면 어떤 프레임워크가 좋을까요?

용도에 따라 달라요. 빠르게 프로토타입을 만들고 싶으면 CrewAI. 역할 지정이 직관적이고 문서화가 잘 돼 있어요. 프로덕션 수준의 엔지니어링이 필요하면 LangGraph. 그래프 기반이라 조건 분기, 에러 핸들링, 디버깅이 깔끔해요. Claude 생태계에 이미 있으면 Claude의 Task tool. 별도 프레임워크 없이 subagent를 띄울 수 있고, 컨텍스트 격리가 자동이에요. 처음에는 무조건 single-agent로 시작하시고, single-agent가 막히는 지점이 명확해졌을 때 필요한 부분만 multi로 확장하시는 게 현명해요. 처음부터 multi-agent 구조를 설계하면 복잡성이 품질보다 빨리 늘어요.


뉴스레터 구독 안내

매주 월요일, AI · LLM · 에이전트 관련 실무 정리를 한 통씩 보내드립니다. Agent 제품을 뜯고 평가하는 이런 심화편을 차분히 쌓아가고 싶으시면 구독해 주세요.

뉴스레터 구독하기


시리즈 안내
– F1~F6: LLM 기초편
– B1: Agent가 LLM과 다른 순간
– B2~B6: Agent 심화 기초편
– M1: Retrieval Layer
– M2: Long-context와 Memory
M3: Agent 심화 — 5층으로 뜯어보기 (현재 글)
– M4: Harness Engineering [다음]
– M5: Evaluation
– M6: Context Management
– (이하 20편까지)

📍 AI 공부 지도 — 16/29편
이 글은 AI의 기초부터 Meta-Harness·응용 비교까지 순서대로 읽는 29편 시리즈의 16편입니다.
📚 전체 지도 보기
← 이전 편: M2. Long-context / Memory · 다음 편: M4. Harness

💡 이 편의 한 줄 요약

Agent를 5층으로 뜯으면 Claude Code·Cursor·Devin·Auto-GPT가 왜 다른 결과를 냈는지가 정확히 보인다. 10가지 평가 체크리스트.

소스 리스트


著者: 바이브코딩 태일러 (VibeCoding Tailor) — Lovable公式アンバサダー. AI·バイブコーディング専門メディアshuntailor.net運営.
本シリーズ “AI 공부 지도” 22편은 위키 자료와 공식 논문·공식 문서를 근거로 정리한 체계적 학습 커리큘럼입니다.

JAKO