RAG vs Agent: 내 시스템을 망가뜨린 결정 (그리고 이제 내가 이를 사전에 강제하는 방법)
요약
RAG와 Agent 사이의 아키텍처 선택 오류로 인한 재구축 경험을 바탕으로, 올바른 기술 선택을 위한 결정 프레임워크를 제시합니다. 검색 중심의 RAG와 실행 중심의 Agent를 구분하는 기준을 통해 시스템 설계의 시행착오를 줄이는 방법을 설명합니다.
핵심 포인트
- RAG는 정보 검색(retrieval)에, Agent는 실행(execution)과 결정에 최적화됨
- 상태 유지(stateful)가 필요한 복잡한 워크플로우에는 Agent가 필수적임
- 단순 정보 제공을 넘어 상태 변화나 재계획이 필요하면 Agent를 선택해야 함
- 아키텍처 결정 시 검색 작업인지 실행 작업인지 먼저 진단할 것
대부분의 사람들은 RAG 대 Agent 문제를 기술적인 선호도의 문제로 취급합니다. 그냥 적절해 보이는 것을 선택하고, 나중에 조정하면 된다고 생각하죠.
저도 그렇게 했습니다. 그 대가로 두 번의 전체 재구축(rebuild)을 치러야 했습니다.
여기 제가 정착한 결정 프레임워크(decision framework)와, 코드 한 줄을 쓰기 전에 이를 강제하기 위해 제가 만든 도구가 있습니다.
실수: 아키텍처를 가역적인 것으로 취급함
저는 4개의 모듈로 구성된 내부 인재 개발 플랫폼인 GrowthOS를 구축하고 있었습니다. 세 번째 모듈인 '개인화된 학습 경로 생성(personalized learning path generation)' 단계에 도달했을 때, 저는 습관적으로 RAG를 선택했습니다. 모듈 1에서 이미 탄탄한 RAG 지식 베이스(knowledge base)를 구축했었기 때문입니다. 그 패턴은 익숙했습니다.
6일이 지났을 때, 저는 관련 학습 자료를 찾아낼 수 있는 검색 시스템(retrieval system)을 갖게 되었습니다. 하지만 다음과 같은 일들은 할 수 없었습니다:
- 직원의 현재 기술 프로필(skill profile) 읽기
- 어떤 구체적인 격차(gaps)를 메워야 하는지 분석하기
- 가용 시간을 고려하여 최적의 순서 결정하기
- 학습 경로를 완료한 후 직원의 행동이 변했는지 모니터링하기
- 기술이 변화했을 때 재계획(re-planning) 트리거하기
RAG는 문서를 반환했습니다. 하지만 이 작업에는 _시간에 따른 결정(decisions across time)_이 필요했습니다. 저는 잘못된 기본 요소(primitive)를 선택했고, 그 대가는 재구축이었습니다.
더 깊은 문제는, 구축하기 전에 아키텍처 질문에 답하도록 만드는 강제 기능(forcing function)이 제게 없었다는 점입니다.
결정 프레임워크
두 번의 재구축을 거친 후, 저는 RAG 대 Agent 결정을 세 가지 진단 질문으로 축소했습니다:
질문 1: 이것은 검색(retrieval) 작업인가, 실행(execution) 작업인가?
RAG는 근본적으로 검색 기본 요소(retrieval primitive)입니다. 쿼리(query)가 주어지면 관련 콘텐츠를 찾아 합성합니다. 출력값이 _정보(information)_일 때 매우 뛰어납니다.
Agent는 실행 기본 요소(execution primitive)입니다. 목표가 주어지면 도구(tools)를 사용하여 일련의 행동을 취합니다. 출력값이 _결정(decision) 또는 상태 변화(state change)_일 때 필요합니다.
혼란이 발생하는 이유는 현대의 RAG 파이프라인이 마치 에이전트처럼 느껴질 수 있기 때문입니다. 청킹(chunking), 임베딩(embedding), 검색(retrieval), 재순위화(rerank), 생성(generation) 과정을 거치니까요. 하지만 그 모든 복잡성은 워크플로우를 실행하는 것이 아니라, 질문에 답하기 위한 서비스일 뿐입니다.
질문 2: 작업이 여러 단계에 걸쳐 상태(state)를 유지해야 하는가?
만약 그렇다면, Agent가 필요합니다.
RAG는 설계상 무상태(stateless)입니다. 각 쿼리는 독립적입니다. 컨텍스트(context)를 저장하거나 쿼리를 체이닝(chaining)하는 등의 우회 방법을 만들 수는 있지만, 이는 아키텍처 자체와 싸우는 격입니다.
Agent는 설계상 상태 유지(stateful) 방식입니다. 컨텍스트를 유지하고, 중간 결과(intermediate results)를 추적하며, 발견한 내용에 따라 다시 루프(loop)를 돌 수 있습니다.
GrowthOS 모듈 3의 경우, 경로 생성 워크플로우(workflow)는 다음과 같았습니다:
read_profile(employee_id)
→ analyze_skill_gap(profile, target_role)
→ search_materials(gap_list)
→ generate_path(gaps, materials, available_time)
→ monitor_progress(employee_id, path) ← 지속적으로 실행
→ trigger_replan(if behavior_signal_detected)
각 화살표는 이전 단계의 결과에 의존하는 도구 호출(tool call)입니다. 이것은 RAG의 영역이 아니라 Agent의 영역입니다.
질문 3: 이를 잘못 결정했을 때의 비용은 얼마인가?
RAG의 실패 모드(failure modes)는 대개 눈에 띄며 복구가 가능합니다. 답변이 틀리거나 불완전하여 사용자가 이를 인지하면, 검색(retrieval) 과정을 수정하면 됩니다. 시간 비용이 발생할 뿐, 재앙적인 수준은 아닙니다.
Agent의 실패 모드는 조용히 발생하며 누적될 수 있습니다. 에이전트가 잘못된 행동을 취하고, 후속 단계들이 그 오류를 바탕으로 진행되며, 6단계가 지난 후에야 오류를 발견하게 됩니다. 혹은 사용자가 운영 환경(production)에서 이를 마주할 때까지 발견하지 못할 수도 있습니다.
이러한 비대칭성은 아키텍처 결정에 얼마나 많은 사전 엄밀성(rigor)을 적용할지에 직접적인 영향을 미쳐야 합니다. 실패 비용이 높을수록, 구축하기 전에 더 확실한 확신이 필요합니다.
GrowthOS 모듈 분석
이 프레임워크를 통해 네 가지 모듈 모두를 실행해 보면 패턴이 명확해집니다:
| 모듈 | 작업 유형 | 상태 유지 (Stateful)? | 실패 비용 | 결정 |
|---|---|---|---|---|
| 모듈 1: 지식 베이스 (Knowledge base) | 문서에 관한 질문에 답변 | 아니오 | 낮음 (가시적) | RAG |
| ... |
흥미로운 사례는 모듈 2입니다. 기술 태깅 (skill-tagging) 시스템이라면 RAG나 에이전트 (Agent)를 사용할 것이라고 예상할 수도 있겠지만, 이 작업은 실제로는 결정론적 (deterministic)입니다. 행동 이벤트 (behavior events)는 정의된 규칙을 통해 기술 가중치 (skill weights)로 매핑되며, 감쇠 (decay)는 정해진 일정에 따라 실행됩니다. LLM 추론 (inference)이 필요한 부분은 아무것도 없습니다. 모든 이벤트마다 LLM 호출을 하는 것보다 크론 잡 (cron job)을 활용한 규칙 엔진 (rules engine)을 사용하는 것이 더 신뢰할 수 있고 저렴합니다.
결정론적 로직 (deterministic logic)만으로 충분한 곳에 AI를 과도하게 적용하는 것은 프로덕션 시스템 (production systems)에서 가장 흔하고 비용이 많이 드는 실수 중 하나입니다. 질문은 "AI가 이것을 할 수 있는가?"가 아니라 "이 작업이 실제로 AI를 필요로 하는가?"가 되어야 합니다.
강제 적용의 문제 (The Enforcement Problem)
프레임워크를 알고 있더라도 적절한 시점에 적용하지 못한다면 도움이 되지 않습니다. 적절한 시점은 바로 _코드를 작성하기 전_입니다. 즉, 아키텍처 (architecture)가 매몰 비용 (sunk cost)이 아닌 하나의 결정 사항인 단계입니다.
실제로 대부분의 개발자(저를 포함하여)는 이미 구축을 시작한 후에야 아키텍처 문제에 직면합니다. 그 패턴은 다음과 같습니다:
- 기능 구현 시작
- 무언가 제대로 작동하지 않음을 깨달음
- 몇 시간 동안 디버깅 (debug)
- 결국 근본적인 아키텍처 불일치 (mismatch)를 진단
- 재구축
나에게 필요했던 것은 결정을 더 일찍 내리도록 강제하는 무언가였습니다. 이상적으로는 첫 번째 도구 호출 (tool call)을 하기 전, 새로운 모듈이나 기능을 설명하기 시작하는 바로 그 순간 말입니다.
이것이 바로 Rein이 해결하도록 설계된 문제입니다.
Rein이 사전 아키텍처 결정을 강제하는 방법
Rein은 Claude Code를 위한 오픈 소스 스킬 (Skill)로, 개발 대화를 모니터링하고 특정 진단 시점에 개입합니다.
아키텍처 결정에 있어, Rein의 Q1 레이어 (SPEC)는 다음과 같은 제약 조건을 강제합니다: 데이터 검색 (data retrieval) 또는 자동화된 의사 결정 (automated decision-making)을 포함하는 기능에 대해 구현 작업이 시작되기 전, SPEC은 반드시 다음 질문에 답해야 합니다:
- 출력 유형은 무엇인가? (정보 vs 결정 vs 상태 변경)
- 작업이 여러 단계에 걸쳐 상태(state)를 유지해야 하는가?
- 실패 모드(failure mode)는 무엇이며 그 비용은 얼마인가?
- 이것은 어떤 프리미티브(primitive)에 매핑되는가: 규칙 엔진 (rules engine) / RAG / 단일 에이전트 (single Agent) / 멀티 에이전트 (multi-Agent)?
이 질문들에 대한 답을 내리지 않은 채 구현(implementation) 설명을 시작하면, Rein이 이를 표면화합니다. 단순한 체크리스트로서가 아니라, 당신이 설명한 내용을 바탕으로 한 타겟팅된 질문으로서 말입니다.
두 번째 강제 지점은 Q4(검증 스크립트, verification scripts)입니다. 아키텍처 결정은 단순히 기록되는 것에 그치지 않고, 검증됩니다. 모듈 3이 "완료"된 것으로 간주되기 전에, verify.sh에는 다음이 포함되었습니다:
check "PathAgent 도구 목록이 SPEC과 일치하는지 확인" \
"grep -c 'def get_employee_profile\|def analyze_skill_gap\|def search_learning_materials\|def generate_learning_path\|def monitor_progress' agent/path_agent.py | grep -q '^5$'"
...
만약 구현이 SPEC에서 벗어나면, 게이트(gate)는 실패합니다. 당신은 이를 프로덕션(production) 환경이 아닌 즉시 알게 됩니다.
침묵의 규칙 (The Silence Rule)
주목할 만한 설계 원칙 하나는, Rein은 플래그(flag)를 세울 것이 없을 때는 침묵한다는 점입니다.
이것이 중요한 이유는 대부분의 Harness 툴링이 과도하게 장황해지는 경향이 있기 때문입니다. 모든 것에 대해 경고하고, 끊임없이 확인을 요청하며, 모든 결정에 개입하려 합니다. 이러한 오버헤드는 개발 경험을 저하시켜 결국 사용자가 이를 무시하게 만듭니다.
Rein의 트리거(trigger) 조건은 좁고 구체적입니다. 아키텍처 결정의 경우:
- 트리거 발생: 세 가지 진단 질문에 답하는 SPEC 없이, 검색(retrieval) 또는 자동화된 결정(automated decisions)을 포함하는 새로운 기능을 설명할 때
- 트리거 미발생: 이미 명확한 SPEC이 작성된 기능을 구현할 때
- 트리거 미발생: 디버깅, 리팩터링(refactoring), 또는 UI 작업을 할 때
16개 시나리오 벤치마크에서, Rein은 개입이 정당한 경우의 100%에서 트리거되었으며, 개입이 필요하지 않은 경우의 100%에서 침묵을 유지했습니다. 침묵 테스트는 트리거 테스트만큼이나 중요합니다.
실질적인 시사점 (The Practical Takeaway)
만약 당신이 AI 시스템을 구축하고 있으면서 모든 구성 요소에 대해 다음 세 가지 질문에 명시적으로 답하지 않았다면, 당신은 복리로 쌓여가는 아키텍처 부채 (architecture debt)를 축적하고 있는 것입니다:
- 출력값이 정보인가, 아니면 결정/상태 변화 (decision/state change)인가?
- 작업이 여러 단계에 걸쳐 상태 (state)를 유지해야 하는가?
- 이것이 틀렸을 경우 발생하는 비용은 무엇인가?
답변이 영구적일 필요는 없습니다. 요구사항이 변함에 따라 아키텍처는 진화합니다. 하지만 답변은 두 번이나 재구축한 후가 아니라, 구축하기 전에 존재해야 합니다.
RAG와 Agent는 연속적인 스펙트럼 상에서 서로 교체 가능한 도구가 아닙니다. 그것들은 서로 다른 문제 형태 (problem shapes)를 해결하기 위한 서로 다른 기본 요소 (primitives)입니다. 초기에 적절한 매칭을 찾는 것은 AI 시스템 설계에서 가장 레버리지가 높은 결정 중 하나입니다.
Rein은 오픈 소스입니다: github.com/DtoTHEmoon/rein-skill
설치:
git clone https://github.com/DtoTHEmoon/rein-skill.git ~/.claude/skills/rein
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기