Agent가 항상 정답은 아니다: Chain, RAG, Agent를 구분해서 선택하기

김민수·2026년 6월 11일

Agent를 기본 아키텍처로 두면 설계가 쉽게 과해진다.

"요즘은 Agent가 대세니까 이 기능도 Agent로 만들자"

이 접근은 위험하다. Agent는 특정 문제를 해결하는 구조이지, 모든 LLM 앱의 상위 호환이 아니다.

좋은 기준은 이것이다.

답변만 필요한가?
외부 정보를 검색해야 하는가?
실행할 Tool이 필요한가?
Tool 결과가 다음 행동을 바꾸는가?
사람 승인과 상태 관리가 필요한가?

1. Chain으로 충분한 경우

정해진 입력을 받아 정해진 방식으로 출력하면 chain이 낫다.

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

llm = ChatOpenAI(model="gpt-5-nano", temperature=0)

prompt = ChatPromptTemplate.from_messages([
    ("system", "기술 개념을 정의, 이유, 예시 순서로 설명하세요."),
    ("user", "{question}")
])

chain = prompt | llm | StrOutputParser()

이런 업무는 Agent가 필요 없다.

  • 문장 다듬기
  • 짧은 요약
  • 개념 설명
  • 템플릿 기반 초안 생성
  • 고정된 포맷의 보고서 섹션 작성

흐름이 고정되어 있으면 고정된 구조가 더 안정적이다.

2. Structured Output으로 충분한 경우

자연어에서 필드를 뽑아 다음 시스템에 넘기는 문제는 Agent보다 structured output이 핵심일 수 있다.

from typing import Literal
from pydantic import BaseModel, Field

class TicketRequest(BaseModel):
    equipment_id: str = Field(description="설비 ID")
    symptom: str = Field(description="이상 증상")
    priority: Literal["low", "medium", "high"]
    requested_action: str

필요한 것이 "행동 선택"이 아니라 "안정적인 구조화"라면 굳이 Agent loop를 만들 필요가 없다.

user text -> structured extraction -> deterministic handler

이 구조가 더 테스트하기 쉽고, 실패 지점도 선명하다.

3. RAG로 충분한 경우

문서 기반 Q&A는 기본 RAG로 충분한 경우가 많다.

def rag_answer(question: str) -> str:
    docs = retriever.invoke(question)
    return answer_chain.invoke({
        "question": question,
        "context": format_docs(docs),
    })

다음 조건이면 기본 RAG를 먼저 선택한다.

  • 질문 유형이 비슷하다.
  • 문서 범위가 명확하다.
  • 항상 같은 retriever를 써도 된다.
  • 검색 결과 평가에서 이미 충분한 recall이 나온다.
  • 응답 속도가 중요하다.

Agentic RAG는 검색 경로 선택, 재검색, fallback이 필요할 때 검토한다.

검색 품질이 낮은데 Agent부터 붙이면 원인을 가린다. 먼저 문서 파싱, chunking, embedding, retriever, 평가셋을 봐야 한다.

4. Tool-using chatbot과 Agent를 구분하기

Tool이 있다고 항상 Agent는 아니다.

단발 Tool 호출은 tool-using chatbot으로 충분할 수 있다.

user asks weather
-> call weather_api once
-> answer

반면 Tool 결과가 다음 행동을 바꾸면 Agent 설계가 필요해진다.

user request
-> lookup order
-> if delivered: check return policy
-> if return allowed: ask approval
-> if approved: create return ticket

기준은 Tool 존재가 아니라 control loop다.

decide -> act -> observe -> decide next

5. Agent가 필요한 조건

Agent를 검토할 만한 조건은 아래와 같다.

State가 필요하다

한 번의 요청으로 끝나지 않고 중간 상태를 들고 다녀야 한다.

from typing import Literal, NotRequired, TypedDict

class AgentState(TypedDict):
    request: str
    extracted_fields: NotRequired[dict]
    tool_result: NotRequired[dict]
    approval_status: NotRequired[Literal["pending", "approved", "rejected"]]
    retry_count: int
    final_answer: NotRequired[str]

Routing이 필요하다

질문 유형이나 Tool 결과에 따라 다음 경로가 달라진다.

def route(state: AgentState) -> str:
    if state.get("approval_status") == "pending":
        return "wait_for_human"
    if state["retry_count"] > 2:
        return "fallback"
    if state.get("tool_result"):
        return "generate"
    return "call_tool"

HITL이 필요하다

실제 업무 변경으로 이어지는 Tool은 승인 대기가 필요할 수 있다.

  • email send
  • refund
  • ticket creation
  • database write/delete
  • external API execution

Observability가 필요하다

최종 답변만으로는 원인을 알기 어렵다.

  • route selected
  • tool args
  • tool result
  • retry count
  • latency
  • token/cost
  • approval decision

Agent에는 trace가 거의 필수다.

6. Anti-patterns

1. 역할 경계 없는 multi-agent

Supervisor -> Planner -> Researcher -> Reviewer -> Writer

이 구조가 항상 나쁜 것은 아니다. 하지만 역할 경계가 흐리면 hop만 늘어난다.

징후:

  • 같은 질문을 여러 agent가 반복 처리한다.
  • delegation이 습관처럼 발생한다.
  • 응답이 서로 충돌한다.
  • latency가 커진다.
  • trace를 봐도 책임 지점이 흐리다.

2. 단순 분류에 Agent 사용

배송/환불/교환 분류

규칙이나 작은 classifier로 충분하면 Agent는 과하다.

3. 검색 품질 문제를 Agent로 덮기

문서가 잘못 파싱됐거나 chunking이 나쁘면 Agentic RAG가 해결해주지 않는다.

먼저 볼 것:

  • 문서 원문
  • chunk boundary
  • retrieval top-k
  • relevant doc id
  • Hit@K / Recall@K
  • Faithfulness

4. 승인 없는 실행 Agent

Tool이 외부 시스템을 변경한다면 권한, 승인, 로그가 필요하다.

LLM selected tool != safe to execute

7. 선택 기준 표

문제추천 구조
고정된 답변 생성Chain
자연어를 JSON으로 추출Structured Output
문서 기반 Q&ARAG
단발 외부 정보 조회Tool-using chatbot
Tool 결과에 따라 다음 행동 변경Agent
승인, 재시도, fallback 필요LangGraph/HITL Agent
역할 경계가 분명하고 병렬 이점 있음Multi-Agent

8. 구현 전 decision checklist

1. chain으로 해결 가능한가?
2. structured output만 있으면 되는가?
3. fixed RAG pipeline으로 충분한가?
4. Tool 호출이 단발성인가?
5. Tool result가 다음 action을 바꾸는가?
6. state를 여러 turn 또는 node에서 공유해야 하는가?
7. retry/fallback/stop condition이 필요한가?
8. human approval이 필요한가?
9. trace와 테스트를 준비했는가?
10. 복잡도가 늘어나는 만큼 품질 개선 근거가 있는가?

정리

Agent는 만능 패턴이 아니다.

Agent를 쓰면 유연성이 생기지만 동시에 비용, latency, test surface, observability requirement도 늘어난다.

단순한 문제는 단순하게 푸는 편이 낫다.

Chain -> Structured Output -> RAG -> Tool-using chatbot -> Agent -> Multi-Agent

이 순서로 필요한 만큼만 복잡도를 올리는 것이 실무적으로 더 안전하다.

profile
생성형 AI, RAG, AI Agent를 가르치는 강사 김민수입니다. 교육 현장과 실무에서 얻은 경험을 기록합니다. 강의 및 교육 문의는 rlaalstn1504@naver.com으로 연락 부탁드립니다.

0개의 댓글