CPN 한국어 자습서 · 러닝패스 2 / 4 — Building with the Claude API
RAG
The full RAG flow
지금까지 다룬 큰 그림 · 텍스트 청킹 · 텍스트 임베딩을 하나로 합쳐, RAG 파이프라인 전체를 처음부터 끝까지 따라갑니다. 가상의 “완벽한 2차원 임베딩 모델”을 가정해 정규화 · 벡터 데이터베이스 · 코사인 유사도까지 단계별로, 뒤에서 도는 약간의 수학과 함께 이해합니다.
Stephen Grider · Anthropic 기술 스태프
이 모듈의 이 지점에서, RAG 파이프라인이 어떻게 동작하는지 큰 그림을 한 번 보여 드렸습니다. 텍스트 청킹을 조금 이야기했고, 텍스트 임베딩도 살짝 맛봤습니다. 이제 이 세 가지 — RAG 과정의 큰 그림, 텍스트 임베딩, 텍스트 청킹 — 를 한데 합쳐 전체 RAG 파이프라인을 제대로 이해해 봅니다. 완전한 RAG 예시를 처음부터 끝까지, 아주 상세히, 단계별로 따라갑니다.
1단계. 앞서처럼 원본 문서를 가져와 여러 개의 텍스트 조각으로 청킹합니다. 이 예시에서는 텍스트 조각이 딱 둘만 있다고 가정합니다 — 섹션 1 의료 연구(medical research), 섹션 2 소프트웨어 공학(software engineering).
2단계. 각 청크에 대해 임베딩을 생성합니다. 이 예시에서는 가상의 완벽한 임베딩 모델이 있다고 칩니다. 이 모델은 두 가지 중요한 성질이 있습니다. 첫째, 항상 길이 2의 임베딩(숫자 두 개)을 돌려줍니다. 둘째, 각 숫자가 원본 텍스트의 무엇을 점수화하는지 우리가 정확히 안다고 가정합니다. 현실에서는 그렇지 않지만, 여기서는 첫 번째 숫자는 텍스트가 의료 분야를 얼마나 이야기하는지, 두 번째 숫자는 소프트웨어 공학을 얼마나 이야기하는지라고 정합니다.
첫 번째 청크를 임베딩하면, 이건 분명히 의료 연구를 이야기하므로 의료 점수 0.97을 줍니다. 그런데 bug라는 용어도 쓰는데 이건 소프트웨어 공학의 뉘앙스가 살짝 있습니다. 그래서 소프트웨어 0.344를 줍니다. 두 번째 텍스트는 분명히 소프트웨어 공학을 이야기하므로 0.97을 주고, infection vectors(감염 경로)도 언급해 의료의 뉘앙스가 있으니 의료 점수도 약간 높여 0.3을 줍니다.
이렇게 임베딩을 만든 뒤, 정규화(normalization)라는 약간의 수학 단계를 거칩니다. 정규화를 깊이 이해할 필요는 거의 없습니다 — 대부분의 경우 사용하는 임베딩 API가 알아서 해 줍니다. 이 단계는 각 벡터의 크기(magnitude)를 1.0으로 스케일하는 것입니다. 용어가 낯설어도 괜찮습니다. 그냥 각 숫자의 크기를 살짝 조정한다고만 이해하면 됩니다.
임베딩을 만들고 정규화하면, 이렇게 평면에 시각화할 수 있습니다. 단위원(unit circle)을 그리면, 두 임베딩을 나타내는 점이 길이가 정확히 1로 정규화됐기 때문에 원 위에 정확히 놓입니다. 위쪽에 소프트웨어 공학 섹션, 옆쪽에 의료 연구가 있습니다.
다음 단계로, 이 임베딩들을 벡터 데이터베이스(vector database)라는 것에 저장합니다. 임베딩처럼 긴 숫자 리스트를 저장·비교·조회하는 데 최적화된 데이터베이스입니다. 이 시점에서 우리는 잠시 멈춥니다. 여기까지가 미리 해 두는 사전처리(pre-processing)였기 때문입니다. 이제 사용자가 실제로 질의를 보낼 때까지 기다립니다.
마침내 사용자가 앱에 와서 챗봇 같은 데 질문을 입력합니다. 예를 들어 “이 회사가 궁금한데, 특히 소프트웨어 공학 부서가 올해 뭘 했어?” 이 질문을 똑같은 가상 임베딩 모델에 넣습니다. 질문이 소프트웨어 공학을 특정해 묻고 있으니 소프트웨어 점수 0.89, 회사·의료가 약간 얽혀 있으니 의료 점수도 아주 살짝 0.1을 줍니다. 그리고 다시 정규화합니다.
이제 벡터 데이터베이스를 씁니다. 사용자 질의를 넣고 “네 안에 저장된 모든 벡터 중 이것과 가장 가까운 벡터를 줘”라고 요청합니다. 이 경우 사용자가 소프트웨어 공학을 물었으니 섹션 2가 돌아올 거라 기대합니다. 그런데 벡터 데이터베이스 안에서 정확히 무슨 일이 일어나는지 봅시다.
사용자 질의를 차트에 얹으면, 시각적으로 질의가 소프트웨어 공학에 아주 가깝다는 걸 바로 알 수 있습니다. 사람인 우리는 차트를 보고 “아, 이 둘이 가깝다”고 말할 수 있죠. 하지만 컴퓨터는 차트를 그려 눈으로 보는 게 아니라, 뒤에서 실제 계산을 합니다. 그 계산이 무엇인지 봅시다 — 나중에 벡터 데이터베이스를 쓸 때 이 수학과 관련된 용어가 많이 나오기 때문에 기본은 알아 두는 게 좋습니다.
사용자 질의와 가장 비슷한 임베딩을 찾으려면 코사인 유사도(cosine similarity)를 계산합니다. 이것은 사용자 질의와, 데이터베이스에 저장된 각 임베딩 사이 각의 코사인입니다. 여기 각 A를 찾아 코사인을 취하고, 각 B를 찾아 코사인을 취합니다. 결과는 −1에서 1 사이의 숫자입니다. 1에 가까우면 질의와 매우 비슷한 임베딩을 찾은 것이고, −1에 가까우면 전혀 비슷하지 않은 것입니다. 우리 경우 질의와 소프트웨어 공학 청크의 코사인 유사도는 0.983 — 매우 비슷합니다. 그러니 소프트웨어 공학 청크를 사용자 질문과 함께 프롬프트에 넣어야겠다는 신호입니다.
넘어가기 전에 한 가지 더. 지금은 살짝 헷갈리지만 나중에 벡터 데이터베이스를 다룰 때 아주 유용합니다. 많은 벡터 데이터베이스 문서에서 코사인 거리(cosine distance)라는 용어를 보게 됩니다. 이것은 코사인 유사도와 다릅니다. 1에서 코사인 유사도를 뺀 값(1 − 코사인 유사도)으로 계산합니다. 해석하기 쉬운 숫자로 만들기 위한 조정이죠. 코사인 거리는 0에 가까울수록 유사도가 크고, 값이 클수록 덜 비슷합니다. 벡터 데이터베이스 문서에 아주 자주 나오니 이 용어를 보면 떠올리세요.
이제 이 수학을 큰 그림에서 이해했으니, 다시 본 줄기로 돌아옵니다. 사용자 질문과 유사도가 높은 텍스트 청크를 찾으면, 사용자 질문과 그 가장 관련 있는 청크를 함께 프롬프트에 넣습니다. 그 프롬프트를 Claude에 보냅니다. 이것이 전체 과정 — 뒤에서 도는 기술과 약간의 수학까지 — 의 아주 상세한 전부입니다. 이제 이 흐름을 잠시 뒤 노트북에서 직접 구현해 봅니다.
이 장에서 배우는 것What you'll learn
약 9분청킹 · 임베딩 · 큰 그림을 합쳐 RAG 전 과정을 한 번에
가상 2차원 임베딩 모델(1번=의료, 2번=소프트웨어)로 직관 잡기
정규화로 크기를 1.0으로 — 임베딩이 단위원 위에 놓인다
벡터 데이터베이스에 저장하고 사용자 질의를 기다린다
코사인 유사도(각의 cos, −1~1)로 가장 가까운 청크를 찾는다
코사인 거리 = 1 − 유사도 — 벡터DB 문서에 자주 나오는 용어
앞서 RAG의 큰 그림을 보고, 텍스트 청킹과 텍스트 임베딩을 맛봤습니다. 이제 셋을 합쳐 전체 파이프라인을 처음부터 끝까지, 아주 상세히 따라갑니다. 단계를 눌러 무슨 일이 일어나는지 확인해 보세요.
앞의 1~3단계는 미리 해 두는 사전처리입니다. 4~5단계는 사용자 질의가 들어온 뒤 실행됩니다.
1단계로 원본 문서를 청크로 나눕니다. 여기서는 청크가 둘뿐이라고 가정합니다 — ① 의료 연구, ② 소프트웨어 공학. 2단계로 각 청크를 임베딩하는데, 설명을 위해 완벽한 2차원 임베딩 모델을 상상합니다.
이 가상 모델은 ⑴ 항상 숫자 두 개짜리 임베딩을 돌려주고, ⑵ 각 숫자의 의미를 우리가 안다고 칩니다 — 1번 = 의료 분야를 얼마나 이야기하나, 2번 = 소프트웨어 공학을 얼마나 이야기하나. (현실에서는 각 숫자의 의미를 알 수 없습니다. 어디까지나 직관을 위한 가정입니다.)
임베딩을 만든 뒤 정규화(normalization)라는 작은 수학 단계를 거칩니다. 각 벡터의 크기(magnitude)를 1.0으로 스케일하는 것입니다. 깊이 이해할 필요는 없습니다 — 대부분의 임베딩 API가 알아서 해 줍니다.
길이를 정확히 1로 맞추면, 2차원 임베딩은 모두 반지름 1인 원(단위원) 위의 한 점으로 놓입니다. 위쪽으로 갈수록 소프트웨어, 오른쪽으로 갈수록 의료 — 이렇게 시각화하면 두 임베딩의 방향만으로 비교할 수 있습니다.
정규화한 임베딩을 벡터 데이터베이스(vector database)에 저장합니다. 임베딩처럼 긴 숫자 리스트를 저장·비교·조회하는 데 최적화된 데이터베이스입니다. 여기까지가 미리 해 두는 사전처리입니다 — 이제 사용자가 질의를 보낼 때까지 기다립니다.
사용자가 질문합니다 — “소프트웨어 공학 부서가 올해 뭐 했어?” 이 질문을 똑같은 임베딩 모델에 넣어 임베딩하고([0.1 의료, 0.89 소프트]), 다시 정규화한 뒤 벡터DB에 “이것과 가장 가까운 벡터를 줘”라고 요청합니다.
벡터DB는 차트를 눈으로 보지 않습니다. 뒤에서 코사인 유사도(cosine similarity)를 계산합니다 — 사용자 질의와 각 임베딩 사이 각의 코사인입니다. 아래에서 슬라이더로 질의를 돌리며 각 A(의료까지)와 B(소프트웨어까지)가 어떻게 바뀌는지, 그리고 유사도가 어떻게 움직이는지 직접 확인해 보세요.
유사도 = 두 정규화 벡터의 점곱(dot product) = 두 벡터가 이루는 각의 cos. 슬라이더로 질의를 돌리면 두 청크와의 각이 바뀌고, 유사도 · 코사인 거리가 실시간으로 갱신됩니다. 더 가까운(각이 작은) 청크가 강조됩니다.
한 가지 용어를 더 알아 둡니다. 벡터DB 문서에 자주 나오는 코사인 거리(cosine distance)입니다. 코사인 유사도와 다릅니다.
해석하기 쉽게 만든 조정입니다. 0에 가까울수록 유사도가 큽니다(가깝다). 값이 클수록 덜 비슷합니다. 위 위젯의 각 청크 카드에 유사도와 함께 코사인 거리도 표시됩니다 — 유사도 0.98이면 거리 0.02처럼, 둘은 1을 기준으로 뒤집힌 값입니다.
유사도가 높은 청크를 찾았으면, 마지막으로 사용자 질문 + 그 청크를 함께 프롬프트에 넣어 Claude에 보냅니다. 이것이 전체 RAG 과정 — 뒤에서 도는 약간의 수학까지 포함한 — 의 전부입니다.
Q1정규화(normalization)는 무엇을 하나요?
정규화는 크기를 1.0으로 스케일합니다. 대부분 임베딩 API가 알아서 해 주며, 정규화하면 모든 임베딩이 단위원 위의 점이 됩니다.
Q2코사인 유사도 값의 의미로 맞는 것은?
코사인 유사도는 두 벡터 각의 코사인으로 −1~1입니다. 1에 가까우면 비슷, −1에 가까우면 안 비슷합니다.
Q3코사인 거리(cosine distance)는?
코사인 거리 = 1 − 코사인 유사도. 해석하기 쉽게 만든 조정으로, 0에 가까울수록 더 비슷합니다. 벡터DB 문서에 자주 나옵니다.
이제 이 흐름을 노트북에서 직접 구현합니다 — 청킹·임베딩·벡터DB 저장·검색을 코드로. → RAG 흐름 구현하기
전 코스는 계속 무료입니다. 등록하면 이 코스의 남은 76개 레슨을 끝까지 읽을 수 있습니다.
이미 등록하셨다면 그때 쓰신 이메일을 넣어 주세요.