자작 RAG vs Bedrock Knowledge Base — 직접 만들 때와 사서 쓸 때의 경계
시리즈: AWS 자격증, 실무로 되짚기
1 / 3편
- 11편 - Gen AI 자격증과 자작 RAG지금 읽는 중
- 22편 - 아키텍트 자격증과 Multi-AZ 운영
- 33편 - DevOps 자격증과 자동 복구
목차
TL;DR
- 계기: 날짜 검색이 자꾸 틀리던 자작 RAG를 고쳐놓고 나서, 같은 해법이 시험에 한 문장으로 적혀 있는 걸 봤습니다
- 관리형 vs 자작: 시험은 Bedrock Knowledge Base(완성품)를 답으로 주고 저는 LanceDB로 검색·청킹·병합을 직접 짰습니다
- 겹친 것: 청킹 전략과 하이브리드 검색입니다. 제가 두 번 갈아엎으며 잡은 걸 시험은 한 줄 개념으로 정리해뒀습니다
- 시험이 안 알려주는 것: “왜 이게 정답인지”. 그건 직접 만들어본 쪽이 압니다
- 한계: 자격증은 카탈로그를 넓혀줄 뿐, 트레이드오프 감각은 결국 손으로 만들어봐야 생깁니다
“3월 15일 미팅 뭐였지?”라고 물으면 4월이 나왔습니다
제가 만들어 쓰는 개인 AI 비서에 이렇게 물으면 4월 7일 미팅을 꺼내왔습니다. 한두 번이 아니라, 날짜를 물을 때마다 거의 매번 그랬습니다.
버그는 아니었습니다. 벡터 검색은 “3월 15일 팀 미팅”과 “4월 7일 팀 미팅”을 의미가 거의 같다고 봅니다. 날짜 숫자는 의미에서 차지하는 비중이 작아서 맥락이 더 비슷한 다른 날 기록한테 밀립니다. 설계상 그렇게 도는 겁니다. 이걸 알기까지 한참 걸렸습니다.
얼마 뒤 AWS Generative AI 자격증(AIP-C01)을 준비하다가 이 문장을 만났습니다.
시맨틱 검색(벡터)은 의미가 비슷한 걸 찾고, 키워드 검색은 단어가 일치하는 걸 찾는다. 둘을 합친 하이브리드가 정확도를 높인다.
한 줄이었습니다. 제가 검색 결과를 하나씩 뒤져가며 도착한 결론이 시험에서는 외워야 할 문장 하나였습니다. 그래서 자격증을 딴 뒤 제 코드를 처음부터 다시 열어봤습니다. 시험이 정답이라고 한 구조와 제가 실제로 만든 구조를 나란히 놓고 보고 싶었습니다.
이 글은 세 편짜리 시리즈의 첫 편입니다. AWS 프로페셔널 자격증 세 개를 각각 제가 직접 만든 시스템 하나에 붙여서 시험이 그린 그림과 제 코드가 어디서 만나고 갈라지는지 봅니다.
- 1편(지금): Gen AI 자격증(AIP-C01) ↔ 자작 RAG — 관리형 Bedrock과 LanceDB 사이
- 2편: 아키텍트 자격증(SAP-C02) ↔ 실제 운영한 Multi-AZ 고가용성 — 재해 복구 전략과 현실의 거리
- 3편: DevOps 자격증(DOP-C02) ↔ 밤새 혼자 도는 개인 시스템의 자동 복구
자격증이 종이 한 장으로 안 남으려면, 그 지식이 내 손에서 뭘 만들었는지 되짚어보는 게 낫겠다 싶었습니다.
한 가지 먼저 밝혀둡니다. 저는 Bedrock을 사이드로 한 번 갈아끼워본 정도지, 프로덕션으로 오래 운영한 적은 없습니다. 그러니 아래는 “관리형을 깊게 써본 사람의 평가”가 아니라, 자작으로 굴려본 사람이 시험 속 관리형 정답을 되짚어본 대조입니다.
시험이 답으로 준 완성품을 저는 부품으로 조립했습니다
시험의 RAG 파트는 이런 식으로 묻습니다.
“사내 문서를 근거로 답하는 챗봇을 만들려 한다. 인프라 관리는 최소화하고 싶다. 어떤 조합이 가장 적합한가?”
정답은 대개 Bedrock Knowledge Base + 관리형 벡터 스토어 + 파운데이션 모델의 조합으로 좁혀집니다. 문서를 넣으면 청킹·임베딩·검색·생성까지 알아서 엮어주는 완성품입니다.
문제를 풀다가 묘한 기분이 들었습니다. 저는 이걸 반년 전에 직접 만들어서 매일 굴리고 있었기 때문입니다. Jarvis라는 개인 AI 비서에 장기 기억을 붙이려고 LanceDB로 벡터 검색을 짰고, 청크 크기 때문에 두 번 갈아엎었고, 앞서 말한 날짜 문제 때문에 BM25까지 붙였습니다.
시험이 미는 그림과 제가 만든 그림을 나란히 두면 이렇습니다.
graph LR
subgraph M["시험 정답 — 관리형"]
direction TB
M1["문서 업로드"] --> M2["Bedrock<br/>Knowledge Base"]
M2 --> M3["관리형<br/>벡터 스토어"]
M3 --> M4["파운데이션 모델<br/>응답"]
end
subgraph S["내 자작 — Jarvis"]
direction TB
S1["대화 → 청크"] --> S2["Ollama<br/>로컬 임베딩"]
S2 --> S3["LanceDB<br/>벡터 + BM25"]
S3 --> S4["Claude API<br/>응답"]
end같은 자리에 뭐가 들어가는지 비교하면 트레이드오프가 선명해집니다.
| 구성 요소 | 시험 정답 (관리형) | 내 자작 (Jarvis) | 뭘 얻고 뭘 잃나 |
|---|---|---|---|
| 청킹·인덱싱 | Knowledge Base가 자동 | 청크 기준 직접 결정 | 자동은 편하지만, 청크 단위를 내 데이터에 맞게 못 바꿈 |
| 임베딩 | Titan 등 관리형(유료) | Ollama 로컬(무료) | 관리형이 정확도 높음. 대신 호출마다 비용 |
| 벡터 스토어 | OpenSearch·Aurora 등 | LanceDB(파일 기반) | 관리형은 확장 쉬움. 자작은 맥미니 한 대로 충분 |
| 검색 병합 | 관리형 하이브리드 | RRF 직접 구현 | 직접 짜면 k값·가중치를 내가 만짐 |
시험은 “관리를 최소화하려면 관리형을 골라라”라고 가르칩니다. 맞는 말입니다. 그런데 제 경우는 반대 이유로 자작을 골랐습니다. 개인이 매일 쓰는 비서라 비용이 0에 수렴해야 했고, 데이터가 사적인 대화라 로컬 밖으로 내보내고 싶지 않았습니다. 임베딩을 Ollama 로컬로 돌린 것도 이 두 가지 때문입니다.
시험은 “인프라 관리 최소화”라는 한 축만 봅니다. 실제 선택은 비용·프라이버시·확장성이 얽힌 다축 문제입니다. 이 감각은 문제집이 아니라 요금 청구서와 맥미니 발열이 가르쳐줬습니다.
청크 크기는 두 번 갈아엎었습니다
시험에서 청킹은 이렇게 나옵니다. “고정 크기 청킹, 시맨틱 청킹, 계층형 청킹 중 이 상황에 맞는 것은?” 보기 하나를 고르면 끝입니다.
저는 이 한 줄을 두 번 실패하고서야 이해했습니다. Jarvis 초기에 청크 크기를 잡는 데 예상보다 오래 걸렸습니다.
- 문장 단위로 잘랐더니 검색 결과가 파편으로 쪼개졌습니다
- 일정 토큰 수로 잘랐더니 대화 흐름이 중간에 끊겼습니다
- 결국 대화 한 덩어리(질문 하나 + 답변 하나)를 청크 한 개로 잡고서야 안정됐습니다
이 기준으로 저장한 결과가 지금의 18만 개 가까운 청크입니다. 시험 보기의 “시맨틱 청킹”이 왜 고정 크기보다 나은 경우가 있는지, 저는 검색이 엉뚱한 맥락을 꺼내오는 걸 눈으로 보고 나서 납득했습니다.
시험이 준 건 선택지의 이름이고 제가 가진 건 그 선택지가 왜 필요한지 겪어본 감각입니다. 둘 다 있으면 좋습니다. 이름을 알면 남한테 설명할 때 편하고, 겪어봤으면 새 상황에서 어떤 이름을 골라야 할지 감이 옵니다.
BM25를 얹으니 4월 미팅이 사라졌습니다
앞에서 말한 날짜 문제로 돌아갑니다. 벡터 검색이 구조적으로 못 잡는 거라면, 단어가 실제로 박혀 있는지만 보는 검색을 옆에 세우면 됩니다. 그래서 BM25를 붙였습니다. LanceDB가 전문 검색(FTS)을 기본으로 지원해서 쓰던 벡터 DB에 인덱스만 하나 더 얹으면 됐습니다.
async function hybridSearch(queryText, queryEmbedding, limit = 10) {
// 순서대로 돌리면 두 배로 기다리니까 동시에 던짐
const [vectorResults, ftsResults] = await Promise.all([
table.search(queryEmbedding).distanceType('cosine').limit(limit * 2).toArray(),
table.search(queryText, 'fts').limit(limit * 2).toArray()
]);
return mergeResults(vectorResults, ftsResults, limit);
}두 결과를 합치는 건 RRF(Reciprocal Rank Fusion)로 했습니다. 양쪽 검색에서 모두 위에 오른 문서를 우대하는 방식입니다. k값은 원논문 기본값 60을 그대로 썼는데, 바꿔봐도 체감 차이가 없어서 그냥 뒀습니다.
시험이 “하이브리드 검색이 정확도를 높인다”고 한 줄로 정리한 그 문장이, 저한테는 날짜 검색을 거의 다 맞게 돌려놓은 실제 개선이었습니다. 응답은 한 50ms쯤 느려졌는데, 1초도 안 되는 차이라 쓰면서는 모릅니다.
시험 개념과 제 경험이 정확히 같은 지점에서 만난 셈입니다. 다른 건 하나뿐입니다. 시험은 결론만 주고 저는 그 결론에 닿으려고 청크 크기와 날짜 필터와 프롬프트를 차례로 갈아봤습니다.
Guardrails, Agents, 임베딩 선택 기준
여기까지만 보면 “이미 다 아는 걸 시험이 뒤늦게 확인해준 것 아니냐”고 할 수 있습니다. 절반은 맞습니다.
검색과 청킹은 손으로 팠지만 그 옆의 것들은 이름만 흐릿하게 알고 있었습니다. 이쪽은 시험 준비하면서 처음 정리했습니다.
- Guardrails: 모델 출력에서 민감 정보나 유해 표현을 거르는 관리형 장치. 저는 Jarvis에서 개인정보 마스킹을 직접 규칙으로 짰는데, 관리형은 이걸 서비스로 제공한다는 걸 시험에서 정리했습니다
- Agents: 모델이 도구를 호출하며 다단계로 일하는 구조. Jarvis도 비슷하게 굴러가지만, 관리형이 이걸 어떤 추상화로 묶는지는 시험으로 봤습니다
- 임베딩 모델 선택 기준: 저는 무료라서 로컬 모델을 골랐을 뿐인데, 시험은 차원 수·언어 지원·비용을 기준으로 어떻게 고르는지 축을 정리해줬습니다
제가 만든 시스템은 검색만 깊고 나머지는 얕은 모양이었습니다. 특히 Guardrails는 좀 허탈했습니다. 개인정보 마스킹 규칙을 며칠 붙잡고 짰는데 그게 이미 서비스로 나와 있었습니다.
관리형 전환을 저울질할 때 짚어볼 다섯 가지
자작 RAG를 굴리면서 관리형 전환을 저울질하고 있다면 아래를 짚어보면 됩니다.
- 임베딩 비용을 계산해봤는가? (호출량이 적으면 로컬, 많으면 관리형이 갈림)
- 데이터가 밖으로 나가도 되는가? (사적·민감 데이터면 로컬 임베딩이 안전)
- 청크 단위를 내 데이터에 맞게 바꿔야 하는가? (자동 청킹으로 충분한지 검색 품질로 확인)
- 날짜·고유명사 검색이 자주 틀리는가? (벡터만이면 BM25 하이브리드가 필요할 수 있음)
- 검색 밖 기능(가드레일·에이전트)이 필요한가? (직접 짜는 비용 vs 관리형 도입 비용 비교)
다시 만든다면 BM25부터 깔고 시작합니다
다음에 RAG를 또 만들 일이 있으면 저는 벡터 검색을 띄우기 전에 BM25부터 깔고 시작할 겁니다. 이건 객관식으로 얻은 게 아닙니다. 4월 미팅을 잘못 가져오는 자비스를 며 칠 붙잡고 있다가 얻었습니다.
시험 덕에 알게 된 것도 있습니다. Guardrails처럼 제가 며칠 걸려 규칙으로 짠 걸 이미 서비스로 파는 곳이 있다는 것. 다음에 비슷한 걸 또 손으로 짜기 전에 한 번은 찾아보겠습니다.
다음 편은 AWS Solutions Architect 자격증(SAP-C02)으로 갑니다. 시험이 그리는 재해 복구·다중 리전 전략과, 제가 실제로 운영해본 Multi-AZ 고가용성 사이에서 어디까지가 손에 익은 범위였는지 정리해보려 합니다.
