Bedrock RAG: 콘솔부터 직접 구현까지
과정 개요
챗봇 과정에서 만든 챗봇은 모델이 학습한 지식만 답했습니다. 이 과정에서는 모델이 우리 문서를 근거로 답하게 만듭니다. 이것이 RAG(Retrieval-Augmented Generation, 검색 증강 생성)입니다.
이 과정의 설계는 한 가지 의도를 따릅니다. 먼저 콘솔에서 관리형 RAG의 “마법”을 체험하고(클릭 몇 번으로 문서 기반 챗봇이 완성됩니다), 그 마법이 내부에서 무슨 일을 하는지 이론으로 역추적한 뒤, 마지막에 코드로 직접 구현해 봅니다. 끝에 도달하면 한 문장이 남습니다. “RAG는 마법이 아니라 임베딩 + 벡터검색 + 프롬프트 조립의 합이다.”
| Lab | 제목 | 핵심 내용 |
|---|---|---|
| 01 | 콘솔 관리형 RAG | Knowledge Bases + S3 Vectors로 클릭만으로 RAG 구축 |
| 02 | Guardrail | 콘텐츠 필터 · 금지 주제로 입력/출력 안전장치 적용 |
| 03 | RAG 이론 | 임베딩 · 벡터 검색 · 청킹 · 메타데이터와 한계 |
| 04 | 관리형 KB 코드 호출 | bedrock-agent-runtime으로 retrieve / retrieve_and_generate |
| 05 | from-scratch 미니 RAG | Titan 임베딩 + 코사인 검색 + Converse를 순수 Python으로 |
데이터는 2019–2022 아마존 주주서한을 사용합니다. 챗봇 과정에서 만든 콘솔 챗봇 UI 모듈(chat_ui.py)을 그대로 재사용하며, 학습자는 boto3 호출 함수만 구현합니다.
RAG란
RAG는 AI가 답변을 생성할 때 외부 문서에서 관련 정보를 검색해 참고하는 방식입니다. 모델이 학습하지 않은 최신 정보나 내부 문서를 근거로 정확한 답변을 만들 수 있습니다.
- 검색(Retrieval) — 질문과 비슷한 문서 조각을 벡터 유사도로 찾아냅니다
- 증강(Augmented) — 찾아낸 문서 내용을 모델 프롬프트에 끼워 넣습니다
- 생성(Generation) — 모델이 그 문서 내용을 근거로 답변을 생성합니다
핵심을 한 문장으로 줄이면 이렇습니다. “질문과 비슷한 내 문서 조각을 찾아(retrieve), 그걸 근거로 모델이 답을 쓰게(generate) 하는 것.” 챗봇은 “아는 것”만 답하지만, RAG는 “찾아온 것”을 근거로 답합니다. 그래서 최신 사내 규정, 특정 도메인 문서, 어제 추가된 자료처럼 모델이 학습할 기회가 없었던 정보도 다룰 수 있습니다.
왜 콘솔부터 시작하는가
대부분의 RAG 강의는 코드부터 시작합니다. 그러나 임베딩·벡터검색·청킹을 처음 보는 사람에게 코드를 먼저 들이밀면, 각 부품이 무슨 역할인지 모른 채 타이핑만 따라 하게 됩니다.
이 과정은 순서를 뒤집습니다.
- 체험 먼저 (Lab 01~02) — 콘솔에서 Knowledge Base를 만들고 질문을 던지면, 모델이 내 문서를 근거로 답하고 출처(citation)까지 보여줍니다. “어떻게 이게 되지?”라는 궁금증이 먼저 생깁니다.
- 이론으로 역추적 (Lab 03) — 방금 콘솔이 자동으로 해 준 일(청킹·임베딩·벡터검색·생성)을 칠판에서 거꾸로 분해합니다. 콘솔의 각 설정 화면이 이론의 어느 개념이었는지 연결됩니다.
- 코드로 직접 (Lab 04~05) — 콘솔이 대신 해 주던 일을 boto3로 한 줄씩 펼쳐 봅니다. 임베딩은
embed()함수가, 벡터검색은cosine()한 줄이 됩니다.
이 흐름이 끝나면 RAG의 각 부품이 또렷해집니다. 콘솔 Test 패널이 사실은 retrieve / retrieve_and_generate API의 GUI였다는 것, S3 Vectors가 사실은 메모리 속 INDEX = [(청크, 벡터)...]의 영구 저장판이었다는 것을 몸으로 알게 됩니다.
Lab별 학습 내용
Lab 01: 콘솔 관리형 RAG
| 단계 | 상세 |
|---|---|
| 데이터 업로드 | 2019–2022 아마존 주주서한 PDF를 S3 버킷에 업로드 |
| KB 생성 | Knowledge Base with vector store → S3 데이터소스 → Fixed-size 청킹 |
| 임베딩 + 벡터저장 | Titan Text Embeddings V2(1024차원) → Quick create / Amazon S3 Vectors |
| Sync + Test | 동기화 실행 → Retrieval only vs Retrieval+Generation 비교, 출처 클릭으로 근거 확인 |
콘솔이 자동으로 처리하는 청킹·임베딩·벡터저장이, 오후에 코드로 직접 할 일이라는 점을 짚습니다. 산출물로 본인 KB ID를 메모합니다(Lab 04에서 사용).
Lab 02: Guardrail
| 단계 | 상세 |
|---|---|
| 개념 | Guardrail = 입력/출력 안전장치(유해 콘텐츠 · 금지 주제 · PII · 환각 억제). “정책으로, 코드 없이” |
| 생성 | Standard 티어 → 콘텐츠 필터 5범주(Hate/Insults/Sexual/Violence/Misconduct) Medium → 금지 주제(투자 조언) → 버전 생성 |
| 적용 + 전/후 비교 | KB Test에 Guardrail 선택 → 같은 질문을 적용 전/후로 비교 |
정상 질문은 통과하고 금지/유해 질문만 차단되는지, 과차단(false positive)은 없는지 관찰합니다.
Lab 03: RAG 이론
| 주제 | 핵심 |
|---|---|
| 임베딩 | 텍스트 → 의미를 담은 숫자 벡터. “비슷한 뜻 = 가까운 벡터” (Titan V2 = 1024차원) |
| 벡터 검색 | 질문도 벡터로 변환 → 코사인 유사도로 가장 가까운 청크 top-k. “검색 = 거리 계산” |
| 청킹 | 문서를 왜 자르나(너무 길면 정확도·비용↑). 고정 크기 vs 의미 단위 |
| 메타데이터 & 한계 | 출처/날짜 필터링. “청크가 답을 안 담으면 못 찾는다, 검색이 틀리면 답도 틀린다” |
코드 없이 슬라이드/칠판으로, 콘솔에서 일어난 일을 역추적합니다.
Lab 04: 관리형 KB 코드 호출
| 단계 | 상세 |
|---|---|
| 클라이언트 구분 | 모델 호출은 bedrock-runtime, KB 호출은 bedrock-agent-runtime |
retrieve() | 검색만 — 점수와 함께 원본 청크 반환 (콘솔 Retrieval only와 동일) |
retrieve_and_generate() | 검색 + 생성 — 답변과 인용을 함께 반환 (콘솔 Retrieval+Generation과 동일) |
“콘솔 Test = 이 API들의 GUI였다”를 코드로 확인합니다.
Lab 05: from-scratch 미니 RAG
| 단계 | 상세 |
|---|---|
embed() | Titan을 invoke_model로 호출(body {"inputText": ...}) → 텍스트를 벡터로 |
cosine() | 내적 / (크기·크기) — 이론의 ‘거리’가 코드 한 줄로 |
build_index() + search() | 청크-벡터 목록 INDEX 구축 → 질문과 가까운 청크 top-k 검색 |
rag_answer() | 검색된 청크를 ‘참고 문서’로 묶어, “문서 근거로만 답하라” 프롬프트로 Converse 생성 |
챗봇 과정의 chat_ui 모듈을 재사용해 대화를 실행합니다. 마지막으로 일부러 무너뜨려 봅니다 — 문서에 없는 질문, 검색이 엉뚱한 청크를 집는 경우, top-k를 1로 줄이는 경우 등 “어디서 무너지나”를 관찰합니다.
사용하는 AWS 서비스
| 서비스 | 용도 | 사용 Lab |
|---|---|---|
| Amazon Bedrock Knowledge Bases | 관리형 RAG (청킹·임베딩·벡터저장·검색을 자동 처리) | Lab 01, 04 |
| Amazon S3 | 원본 문서 저장소 | Lab 01 |
| Amazon S3 Vectors | KB가 자동 생성하는 벡터 저장소/인덱스 | Lab 01 |
| Titan Text Embeddings V2 | 텍스트 → 1024차원 벡터 (임베딩) | Lab 01, 05 |
| Amazon Bedrock Guardrails | 입력/출력 안전장치 (콘텐츠 필터·금지 주제·PII) | Lab 02 |
| Amazon Bedrock (Claude) | 답변 생성 (Haiku 4.5) | Lab 01~05 |
💡 왜 S3인가? KB는 “원본 문서가 어디 있는지”만 가리키면, 그 문서를 잘라(chunk) 임베딩으로 바꿔 벡터 저장소에 넣는 일을 대신 해 줍니다. 그 원본의 자리가 S3입니다.
콘솔과 코드의 대응 관계
이 과정의 핵심 통찰은 “오전 콘솔이 자동으로 해 준 일”과 “오후 코드가 직접 하는 일”이 정확히 1:1로 대응한다는 점입니다. 같은 일을 두 번 — 한 번은 콘솔이 대신, 한 번은 내 손으로 — 하기 때문에 각 부품의 정체가 또렷해집니다.
| 오전 (콘솔, 자동) | 오후 (코드, 직접) |
|---|---|
| 문서 청킹 (Fixed-size) | Lab 05 — 문단 단위로 자르기 |
| Titan 임베딩 | Lab 05 embed() — invoke_model로 벡터 생성 |
| S3 Vectors 저장/검색 | Lab 05 INDEX + cosine() — 메모리 벡터검색 |
| RetrieveAndGenerate | Lab 04 — 같은 이름의 API를 boto3로 호출 |
“콘솔이 대신 해 주던 일”을 코드로 펼쳐 보면, RAG가 마법이 아니라 임베딩 + 벡터검색 + 프롬프트 조립의 합임이 드러납니다.
다음 단계
먼저 콘솔에서 “마법”을 체험합니다. Lab 01에서 클릭 몇 번으로 Knowledge Base를 만들고, 2019–2022 아마존 주주서한을 근거로 답하는 RAG 챗봇을 완성한 뒤, 답변의 출처가 실제 문서 문장과 연결되는 것을 직접 눈으로 확인합니다.
NxtCloud Workshop