홍드로이드의 야매코딩

내 문서로 답하는 AI 챗봇 만들기 — 무료 RAG 실전 예제 본문

AI & Vibe Coding

내 문서로 답하는 AI 챗봇 만들기 — 무료 RAG 실전 예제

홍드로이드 2026. 7. 4. 21:05

 

일반 챗봇에게 "우리 회사 휴가 규정 알려줘" 하면? 모르니까 그럴듯하게 지어냅니다(환각). AI가 진짜 내 문서를 읽고 답하게 하는 기술이 바로 RAG예요. 이번엔 지난 무료 챗봇에 이어, 무료 API + numpy만으로 RAG 챗봇을 처음부터 만들어봅니다. 벡터DB 설치도 없이, 복붙하면 도는 최소 예제로 갑니다.

📌 30초 요약 — RAG 4단계
① 문서를 조각(chunk)으로 자른다
② 각 조각을 임베딩(숫자 벡터)으로 바꿔 저장
③ 질문과 가장 비슷한 조각을 유사도로 찾는다
④ 그 조각을 프롬프트에 넣어 LLM에게 답하게 한다
→ 전부 무료 API + numpy로, 벡터DB 없이 구현

RAG가 뭐고 왜 필요한가

LLM은 학습 시점 이후의 일이나 내 개인 문서를 모릅니다. 그렇다고 문서 전체를 매번 프롬프트에 다 넣으면 비싸고 느리고, 길면 잘려요. 그래서 쓰는 게 RAG(검색 증강 생성). 질문에 관련 있는 부분만 콕 집어 AI에게 건네고 "이걸 근거로 답해"라고 시키는 방식이에요.

🔑 핵심 아이디어 — 문장을 숫자 벡터(임베딩)로 바꾸면, "의미가 비슷한 문장"은 벡터도 가까워집니다. 그래서 질문 벡터와 가장 가까운 문서 조각을 수학(코사인 유사도)으로 찾을 수 있어요. 이게 RAG의 전부입니다.

준비물 (전부 무료)

NVIDIA Build 무료 API 키 — 발급법은 지난 글 /151 2분 컷 (카드 X)

임베딩 모델도 무료 — 채팅용 LLM과 같은 키·같은 주소로 사용

✅ 라이브러리 2개면 끝 →

pip install openai numpy

STEP 1. 문서를 조각내고 임베딩하기

먼저 문서를 의미 단위 조각으로 나눕니다(여기선 간단히 문단 단위). 그리고 각 조각을 임베딩 벡터로 바꿔 저장해요. NVIDIA 임베딩 모델은 문서/질문 구분이 필요해서 input_type을 넘깁니다.

import numpy as np
from openai import OpenAI

client = OpenAI(
    base_url="https://integrate.api.nvidia.com/v1",
    api_key="nvapi-여기에_발급받은_키",
)

EMBED_MODEL = "nvidia/nv-embedqa-e5-v5"

def embed(text, is_query=False):
    resp = client.embeddings.create(
        model=EMBED_MODEL,
        input=[text],
        extra_body={
            "input_type": "query" if is_query else "passage",
            "truncate": "END",
        },
    )
    return np.array(resp.data[0].embedding)

# 내 문서 (여기에 회사 규정, 매뉴얼, 노트 등을 조각으로 넣으세요)
docs = [
    "우리 회사 연차 휴가는 입사 1년 후 15일이 부여된다.",
    "재택근무는 주 2회까지 팀장 승인 하에 가능하다.",
    "경비 처리는 매월 25일까지 영수증을 제출해야 한다.",
    "점심시간은 12시부터 1시까지이며 유연근무제를 운영한다.",
]

# 모든 문서 조각을 미리 임베딩해 저장 (문서가 많으면 한 번만 해두면 됨)
doc_vecs = [embed(d) for d in docs]
print(f"{len(docs)}개 조각 임베딩 완료")

STEP 2. 질문과 가장 비슷한 조각 찾기

질문도 임베딩한 뒤, 코사인 유사도로 가장 가까운 조각 몇 개(top-k)를 골라냅니다. 벡터DB 없이 numpy 한 줄이면 돼요.

def cosine(a, b):
    return a @ b / (np.linalg.norm(a) * np.linalg.norm(b))

def search(question, k=2):
    q_vec = embed(question, is_query=True)
    scores = [cosine(q_vec, dv) for dv in doc_vecs]
    # 점수 높은 순으로 top-k 조각의 원문을 반환
    top = np.argsort(scores)[::-1][:k]
    return [docs[i] for i in top]

print(search("연차 며칠 나와?"))
# → ['우리 회사 연차 휴가는 입사 1년 후 15일이 부여된다.', ...]
포인트 — "연차 며칠 나와?"라는 질문에 '연차'라는 단어가 정확히 없어도, 의미가 비슷한 조각을 찾아냅니다. 이게 단순 키워드 검색과 다른 의미 기반 검색의 힘이에요.

STEP 3. 찾은 조각으로 답하게 하기 (RAG 완성)

마지막. 찾아낸 조각을 프롬프트에 근거로 넣고 LLM에게 답을 시킵니다. "이 자료 안에서만 답해"라고 못박는 게 환각을 줄이는 핵심이에요.

def ask(question):
    context = "\n".join(search(question, k=2))   # 관련 조각 검색

    resp = client.chat.completions.create(
        model="meta/llama-3.1-8b-instruct",
        messages=[
            {"role": "system",
             "content": "아래 [자료]만 근거로 답해. 자료에 없으면 '모른다'고 해."},
            {"role": "user",
             "content": f"[자료]\n{context}\n\n[질문] {question}"},
        ],
    )
    return resp.choices[0].message.content

print(ask("연차는 며칠이고 언제부터 쓸 수 있어?"))
# → "입사 1년 후부터 연차 15일을 쓸 수 있습니다." (내 문서 기반!)

🎉 완성! 이 세 함수(embed · search · ask)가 RAG의 전부입니다. docs 리스트에 내 문서를 넣기만 하면, 그 내용으로 답하는 챗봇이 돼요.

실전으로 키우는 법

상황 이렇게 확장
문서가 수백 개↑ numpy 대신 Chroma·FAISS 같은 벡터DB로 (검색이 빨라짐)
PDF·워드 파일 먼저 텍스트로 추출(pypdf 등) → docs에 넣기
긴 문서 문단이 길면 300~500자 단위로 겹쳐서 잘게 쪼개기
답변 품질↑ k값(가져올 조각 수)을 3~5로 늘리거나 모델 교체

여기서부터는 직접 짜지 말고 Claude Code에 위 코드를 던지고 "이 RAG 코드에 PDF 업로드 기능이랑 Streamlit 채팅 UI를 붙여줘"라고 요청하세요. 핵심 로직은 내가 이해했으니, 살은 바이브코딩으로 붙이면 됩니다.

주의사항

⚠️ RAG도 환각을 100% 막지 못합니다. "자료에 없으면 모른다고 해"를 system에 넣고, 답변에 근거 조각을 함께 표시해 사람이 검증하게 하세요.

🔑 API 키는 .env로 분리, 문서에 민감정보가 있으면 외부 API 전송 여부를 반드시 확인하세요.

자주 묻는 질문

Q. 파인튜닝이랑 뭐가 다른가요?

파인튜닝은 모델 자체를 다시 학습시켜 비싸고 오래 걸려요. RAG는 문서만 갈아 끼우면 되니 즉시 반영·저비용입니다. 자주 바뀌는 사내 문서엔 RAG가 정답.

Q. 벡터DB 꼭 써야 하나요?

문서가 수십~수백 개면 이 글처럼 numpy로 충분합니다. 수천 개를 넘어가 검색이 느려지면 그때 Chroma·FAISS로 옮기면 돼요. 작게 시작하세요.

Q. 임베딩도 무료 크레딧을 쓰나요?

채팅과 같은 무료 티어로 돌아갑니다. 임베딩은 요청당 비용이 아주 낮아 학습·프로토타입엔 부담이 없어요. 문서 임베딩은 한 번만 해두면 재사용됩니다.

정리조각내기 → 임베딩 → 유사도 검색 → 근거로 답변. 이 4단계가 RAG의 본질이고, 무료 API와 numpy만으로 오늘 완성할 수 있습니다. 내 문서를 아는 AI, 생각보다 가깝습니다.


출처: NVIDIA Build 임베딩 모델 문서(nv-embedqa-e5-v5, integrate.api.nvidia.com), OpenAI 파이썬 라이브러리 임베딩 API. 모델·크레딧 정책은 바뀔 수 있으니 발급 시점 공식 페이지 확인. 예제는 학습용 최소 구현으로, 실서비스는 벡터DB·청킹·보안을 보강하세요.

Comments