Agentic RAG
에이전트 자율 검색 전략
Agentic RAG
검색의 도구화 · 소스 라우팅 · 자기 평가 루프
파이프라인에서 판단으로
에이전트가 언제 · 어디서 · 몇 번 검색할지 스스로 결정하는 RAG
왜 Agentic RAG인가
고정 파이프라인의 한계 · 판단하는 검색
Agentic RAG
검색을 에이전트가 자율 제어 — 부족하면 다시, 불필요하면 건너뛰고, 여러 소스를 교차 검증
Agentic RAG
일반 RAG는 "검색 → 생성" 1회 — Agentic RAG는 에이전트가 검색 전략을 스스로 결정합니다
- 검색 여부 — 불필요하면 건너뛰기
- 소스 선택 — Knowledge Base·API 중 라우팅
- 재검색 — 부족하면 쿼리 변형 후 재시도
- 교차 검증 — 여러 소스 결과 종합
바뀌는 것은 검색 기술이 아니라 결정의 주체입니다.
파이프라인이 정한 순서대로가 아니라, 에이전트가 상황을 보고 결정합니다.
고정 파이프라인이 놓치는 것
단순 RAG는 성실함 — 문제는 어떤 질문이 와도 똑같이 성실하다는 것
-
1
질문 수신
"안녕하세요" 같은 인사도, 여러 소스가 필요한 복합 질문도 같은 길로 들어갑니다.
-
2
항상 검색
검색이 불필요한 질문에도 벡터 검색을 실행 — 비용과 레이턴시를 낭비합니다.
-
3
무조건 삽입
관련 없는 결과도 그대로 프롬프트에 삽입 — 검색이 실패했다는 사실을 인지하지 못합니다.
-
4
생성
부족한 컨텍스트로도 답변을 생성 — 검색 누락은 할루시네이션(환각)으로 이어집니다.
파이프라인은 성실하지만 판단하지 않습니다.
검색 여부·소스·횟수를 판단하는 주체가 필요합니다 — 그 주체가 에이전트입니다.
Naive RAG vs Agentic RAG
항상 검색 vs 판단 후 검색 — 기준은 질문의 복잡도와 실패 비용
Naive RAG
항상 검색 — 파이프라인 고정
- 모든 질문에 벡터 검색 실행
- 검색 결과를 무조건 프롬프트에 삽입
- 검색 실패 시 대응 없음
- 흐름이 단순해 레이턴시·비용 예측 가능
단일 Knowledge Base에 질문 패턴이 단순하고 낮은 레이턴시가 중요하다면 이쪽으로 충분합니다 — 단순 FAQ 봇에 Agentic은 오버 엔지니어링입니다.
Agentic RAG
판단 후 검색 — 에이전트 제어
- 질문 분석 → 검색 필요 여부 결정
- 소스·횟수를 상황에 따라 선택
- 결과 품질 자체 평가 — 부족하면 재검색
- "찾을 수 없습니다"라는 정직한 응답도 가능
멀티 소스·복합 질문·검색 실패 자동 대응이 필요할 때 — 단, 토큰 소비가 몇 배로 늘 수 있어 복잡한 질문에만 선택 적용합니다.
전부 바꾸는 결정이 아닙니다 — 실패가 잦은 질문 유형에만 Agentic을 얹는 점진 도입이 정석입니다.
같은 질문, 두 갈래 여정
첫 검색이 빗나간 순간 — 그대로 생성하는 파이프라인과 고쳐서 다시 검색하는 에이전트
러닝 예제
"예약금 환불 규정이 어떻게 되나요?"
Knowledge Base 문서 — restaurant-policy.pdf
NAIVE RAG
검색 1회 — 결과가 부실해도 그대로 진행
검색 — 질문 문장 그대로
→
1위 청크 — "본 정책의 목적과 용어 정의…" (서문만 적중)
→
무조건 삽입 → 생성
→
근거 부실 답변 — 할루시네이션 위험
AGENTIC RAG
결과를 평가하고 — 부족하면 쿼리를 고쳐 다시
같은 검색 · 같은 청크
→
평가 — 부족 (관련성 0.34 · 예시 수치)
→
재작성 — "취소 수수료 환불 절차 기한"
→
재검색 — restaurant-policy.pdf §3 적중
→
근거 있는 답변
재검색으로도 부족하면 다른 소스(웹 검색 · API 도구)로 라우팅 — 소스 선택도 에이전트의 판단입니다
검색 기술은 두 쪽이 같습니다 — 다른 것은 빗나간 뒤의 행동입니다.
그 행동을 만드는 재료는 도구화 · 라우팅 · 자기 평가 세 가지입니다.
검색을 도구로
@tool · Bedrock Knowledge Bases Retrieve · docstring
검색의 도구화
에이전트에게 검색을 맡기는 방법 — Knowledge Base 검색을 @tool 하나로 감싸기
검색 = @tool 하나
Bedrock Knowledge Base의 Retrieve API를 함수로 감싸면, 검색은 에이전트가 골라 쓰는 도구가 됩니다
- @tool — 함수 하나가 곧 도구
- bedrock-agent-runtime — Knowledge Base Retrieve API
- docstring — 에이전트의 도구 선택 기준
- Agent(tools=[...]) — 장착하면 끝
새 프레임워크가 아닙니다 — Strands SDK 모듈에서 배운 Agent와 @tool 그대로, 이번에는 도구가 검색일 뿐입니다.
strands-agents-tools의 빌트인 retrieve 도구(Bedrock Knowledge Bases)도 있습니다 — 여기서는 원리가 보이도록 직접 감쌉니다.
Knowledge Base 검색을 @tool로
Retrieve API 호출을 함수로 감싸고 @tool을 붙이면 — 에이전트가 필요할 때만 호출하는 검색 도구
from strands import tool
import boto3
bedrock_rt = boto3.client("bedrock-agent-runtime", region_name="us-east-1")
# ① 도구명 + @tool — 함수 하나가 곧 검색 도구
@tool
def search_terms(query: str) -> str:
# ② docstring — 에이전트가 도구를 고르는 유일한 근거
"""레스토랑 정보를 검색합니다. 메뉴, 예약, 위치 관련 질문에 사용합니다."""
response = bedrock_rt.retrieve(
knowledgeBaseId="KB-RESTAURANT-001",
retrievalQuery={"text": query},
retrievalConfiguration={"vectorSearchConfiguration": {
# ③ 상위 3개 청크만 + 하이브리드 검색
"numberOfResults": 3,
"overrideSearchType": "HYBRID",
}},
)
# ④ 반환 문자열이 그대로 에이전트 컨텍스트에 들어간다
return "\n\n".join(r["content"]["text"] for r in response["retrievalResults"])
- @tool + 도구명 — 함수 하나가 곧 도구. search_terms라는 이름도 선택 근거의 일부
- docstring — 그대로 도구 설명이 됨. "언제 사용하는지"까지 적어야 정확히 선택
- retrieve 설정 — bedrock-agent-runtime 클라이언트로 Knowledge Base 호출. HYBRID(시맨틱+키워드) · 상위 3개만으로 토큰 절약
- 반환 — 청크 텍스트를 이어붙인 문자열이 toolResult로 컨텍스트에 합류
에이전트가 보는 것은 docstring뿐
도구 선택의 유일한 근거 — 모호한 설명은 잘못된 도구 선택과 비용 낭비로 직결
나쁜 도구 설명
"데이터를 가져옵니다"
- 어떤 데이터인지 불명확
- 언제 써야 하는지 단서가 없음
- 잘못된 도구 선택 → 검색 실패
- 불필요한 호출 → 비용 낭비
에이전트 입장에서는 이름이 다른 블랙박스가 여러 개 놓인 셈 — 추측으로 고를 수밖에 없습니다.
좋은 도구 설명
"레스토랑 정보를 검색합니다. 메뉴, 예약, 위치 관련 질문에 사용합니다."
- 무엇을 검색하는지 명확
- 적용되는 질문 유형을 예시로 제시
- 에이전트가 올바른 도구를 선택
- 라우팅 정확도가 설명 품질에 비례
"무엇을 + 어떤 질문에" 두 가지를 담는 것이 규칙입니다 — 멀티 소스 라우팅의 정확도가 이 품질에 비례합니다.
에이전트는 함수 코드를 읽지 않습니다 — docstring만 보고 도구를 고릅니다.
도구 설명이 곧 라우팅 규칙입니다.
소스 라우팅
멀티 소스 · 판단 기준 · 복합 질문
소스 지도 — 질문별 담당 소스
소스마다 도구 하나 — 정적 문서는 Knowledge Base로, 실시간 데이터는 API로 분리
이 질문, 어디로
검색 생략까지 포함해 네 갈래 — 코드 분기가 아니라 docstring과 시스템 프롬프트가 만드는 판단 기준, 실행은 에이전트의 몫
멀티 소스 에이전트
도구 3개와 선택 기준을 주면 — 복합 질문은 에이전트가 순서대로 호출해 종합
설계 원칙
- 1 도구 = 1 소스
- Knowledge Base 전용·API 전용으로 책임 분리 — 도구가 곧 소스의 경계
- system_prompt
- 도구 선택 기준과 폴백을 명시해야 에이전트가 따릅니다.
- 복합 질문
- 에이전트가 여러 도구를 순서대로 호출 → 결과 종합
- 도구 수 제한
- 10개 이하 권장 — 많아지면 선택 정확도 하락
코드
# 멀티 소스 에이전트 — 도구 3개를 주면 선택은 에이전트가 한다
agent = Agent(
model=model,
system_prompt="""레스토랑 추천 컨시어지입니다.
도구 선택 기준:
1. 메뉴/정책/규정 → search_terms
2. 레스토랑 상품/가격/혜택 → search_restaurants
3. 실시간 좌석/예약 현황 → check_reservations
복합 질문은 여러 도구를 순서대로 호출하세요.""",
tools=[search_terms, search_restaurants, check_reservations],
)
# 복합 질문 — "지금 레스토랑보다 싼 곳 있어? 바꾸면 취소 규정은?"
# → check_reservations(현재 예약 확인)
# → search_restaurants(더 저렴한 레스토랑)
# → search_terms(변경 취소 수수료) → 종합 답변 생성
자기 평가 루프
Self-RAG · 쿼리 재작성 · 에스컬레이션
자기 평가
첫 검색이 빗나가도 끝이 아니게 — 결과를 스스로 평가하고 부족하면 재검색
검색하고, 평가하고, 부족하면 다시
검색 실패에 대응하는 Agentic RAG 패턴 가족 — 이름은 많지만 공통 뼈대는 하나입니다
- Self-RAG — 검색 필요·품질 자체 판단
- Corrective RAG — 쿼리 변형 후 재시도
- Adaptive RAG — 질문 유형별 전략 분기
- Router RAG — 멀티 소스 자동 라우팅
라우팅(Router·Adaptive)은 앞 파트에서 이미 만들었습니다.
이번 파트는 나머지 반쪽 — 검색 결과가 부족할 때의 자기 교정 루프입니다.
Self-RAG 루프
검색 → 평가 → 재작성 — 충분해질 때까지, 그러나 무한히는 아니게
루프 한 바퀴 — 실제 장면
"예약금 환불 규정이 어떻게 되나요?"가 답이 되기까지 — 검색 두 번 · 평가 두 번 · 재작성 한 번
시도 1 — 질문 그대로 검색
"예약금 환불 규정이 어떻게 되나요?"
"본 정책은 환불의 목적과 용어를 정의한다…" — 서문만 적중
쿼리 재작성
→
동의어 · 구체화
시도 2 — 재작성 쿼리로 재검색
"취소 수수료 환불 절차 기한"
"예약금은 이용일 3일 전까지 취소하면 전액 환불, 이용일 1~2일 전 취소는 50% 공제…" (예시 문서)
답변 생성
"예약금은 이용일 3일 전까지 취소하시면 전액 환불되며, 1~2일 전에는 50%가 공제됩니다." — 근거: restaurant-policy.pdf §3
관련성 수치는 예시 — 재시도 한계(1~2회) 초과 시 best effort 전환
이 트레이스의 판정·재작성 기준은 코드 분기가 아니라 시스템 프롬프트의 규칙입니다 — 별도 파이프라인 없이 지시문만으로 만들어집니다.
판단 규칙을 프롬프트에
별도 파이프라인 없이 — 결과 품질 판단과 재검색 규칙을 시스템 프롬프트로 지시
핵심 포인트
- 판단 규칙
- 관련 · 부분 관련 · 무관 — 검색 결과 품질을 3단계로 자기 평가
- 재검색
- 무관하면 쿼리를 바꿔 재시도 — 횟수 제한으로 무한 루프 방지
- 폴백 응답
- 재검색 후에도 없으면 추측 대신 정직한 안내로 전환
- 추측 금지
- 검색 결과에 없는 내용 생성 차단 — 할루시네이션(환각) 방어선
코드
# 검색 결과 판단 규칙 — 자기 평가를 시스템 프롬프트로 지시
agent = Agent(
model=model,
system_prompt="""레스토랑 추천 컨시어지입니다.
검색 결과 판단 규칙:
1. 질문과 직접 관련 있으면 → 답변
2. 부분적으로만 관련 있으면 → 담당 팀 연결 안내
3. 전혀 관련 없으면 → 쿼리를 바꿔서 재검색 (최대 1회)
4. 재검색 후에도 없으면 → "전문 상담원 연결이 필요합니다"
절대 금지: 검색 결과에 없는 내용을 추측하여 답변""",
tools=[search_terms, search_restaurants, check_reservations],
)
# "글루텐프리 메뉴" → 검색 0건 → 쿼리 변형 재검색
# → 여전히 없음 → "셰프에게 직접 문의가 필요합니다. 연결해드릴까요?"
그래도 못 찾으면 — 에스컬레이션 4레벨
자동 재시도에서 사람 연결까지 — 에이전트가 따르도록 각 레벨의 진입 조건을 프롬프트에 명시
구현과 운영
전체 조립 · Strands vs AgentCore Gateway · 가드레일
전체 조립 — 도구화·라우팅·자기 평가를 한 에이전트로
새 개념 없이 조립만 — 세 재료가 Agent 생성자 하나에 담기는 완성형
# Agentic RAG 완성형 — 파트 2~4의 재료를 에이전트 하나로 조립
agent = Agent(
model=model,
# ① 도구 장착 — PART 2 검색의 도구화
tools=[search_terms, search_restaurants, check_reservations],
# ② 시스템 프롬프트 — PART 3 라우팅 기준 + PART 4 판단 규칙
system_prompt="""레스토랑 추천 컨시어지입니다.
도구 선택 기준:
1. 메뉴/정책/규정 → search_terms
2. 상품/가격/혜택 → search_restaurants
3. 실시간 좌석/예약 → check_reservations
검색 결과 판단 규칙:
- 무관하면 쿼리를 바꿔 재검색 (최대 1회)
- 재검색 후에도 없으면 상담원 연결 안내
절대 금지: 검색 결과에 없는 내용을 추측하여 답변""",
)
# ③ 호출 상한 — 판단을 맡긴 대가로 한도를 건다 (운영 가드레일의 시작)
result = agent("예약금 환불 규정이 어떻게 되나요?",
limits={"turns": 6, "total_tokens": 20_000})
- tools — PART 2에서 만든 검색 도구 3개. docstring이 그대로 선택 근거
- 도구 선택 기준 — PART 3의 소스 라우팅. 코드 분기 없이 프롬프트가 규칙
- 판단 규칙 — PART 4의 자기 평가·에스컬레이션. 재검색과 폴백까지 지시
- limits — 턴·토큰 상한을 호출 시 지정, 초과하면 stop_reason 반환. 판단을 맡긴 대가로 한도를 겁니다
구현 경로 — Strands vs AgentCore Gateway
조립한 에이전트를 어디에 올릴까 — 신규 Agentic RAG의 두 가지 권장 경로, 제어의 깊이로 선택
Strands Agents
@tool + Knowledge Base Retrieve API
- 검색 도구를 코드로 완전 제어
- Corrective RAG 등 커스텀 재검색 로직 자유
- 이 모듈의 모든 예제가 이 경로
- AgentCore Runtime으로 그대로 배포
재검색 규칙·폴백·캐싱을 직접 설계해야 하는 워크로드라면 이 경로 — 오늘 본 코드가 곧 프로덕션 뼈대입니다.
AgentCore Gateway
Knowledge Bases 커넥터
- Knowledge Base를 에이전트 도구로 노출 — 검색 코드 불필요
- 도구 스키마 · 인증을 Gateway가 관리
- 여러 에이전트가 같은 Knowledge Base 도구를 공유
- Retrieve / AgenticRetrieveStream 유형 선택
검색 도구를 조직 공용 자산으로 관리하고 싶을 때 — 커넥터 설정만으로 Knowledge Base가 도구가 됩니다.
유지보수 모드로 전환되어 2026-07-30부터 신규 고객 접근이 차단됩니다. 신규 구현은 Strands 또는 AgentCore 경로로, 기존 Bedrock Agents Classic + Knowledge Base 구성은 AgentCore로 마이그레이션이 필요합니다.
운영 가드레일
판단을 맡겼다면 판단을 감시하는 장치까지가 설계 — 비용 · 품질 · 도입 순서의 안전장치
호출 제한
검색 남발을 구조적으로 차단
- 도구 호출 3~5회 · 재시도 1~2회 · 타임아웃 10~30초
- Strands는 Hooks로 구현 — BeforeToolCallEvent에서 초과 호출을 event.cancel_tool로 차단
- CloudWatch Invocations · Throttles로 호출 빈도 감시
검색 결과 캐싱
반복 질문의 검색·LLM 비용 절감
- 동일 쿼리 TTL 5분 캐시 (DynamoDB · ElastiCache)
- 시맨틱 캐시 — 임베딩 유사도 0.95 이상은 동일 취급
- 문서 업데이트 시 메타데이터 태그로 무효화
평가 메트릭
에이전트 판단의 품질을 숫자로
- Tool Selection Accuracy — 예시 목표 90% 이상
- Unnecessary Retrieval Rate — 예시 목표 10% 미만
- Answer Completeness · Escalation Rate 함께 추적
점진 도입
전면 전환이 아니라 선택 적용
- 단순 RAG로 시작 → 검색 실패 로그 분석
- 실패 빈도 높은 질문 유형에만 Agentic 적용
- 질문당 토큰 비용을 사전 계산해 허용 범위 확인
Agentic RAG 실습
Strands Agents로 Self-RAG와 Corrective RAG 패턴을 직접 구현합니다
학습 목표
- Self-RAG 패턴으로 검색 결과 관련성을 자동 평가하고 재검색
- Corrective RAG 패턴으로 검색 품질이 낮을 때 웹 검색 폴백
- @tool로 검색 → 평가 → 재생성 루프 구현
- Adaptive RAG 패턴으로 질문 복잡도에 따라 전략 선택
@tool 하나로 시작하는 Agentic RAG — 라우팅 · 자기 평가 · 에스컬레이션까지