| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- web
- MIPS
- DS
- computer
- data structure
- Rag
- system
- DB
- control
- javascript
- php
- python
- Linux
- github
- openai
- Java
- AI
- Algorithm
- react
- mysql
- function
- architecture
- XML
- for
- instruction
- Class
- CSS
- html
- DATAPATH
- Pipelining
- Today
- Total
YYYEJI
[MAC] Naive RAG 구현 코드 구현하기 본문
간단한 형태의 RAG 모델로,
외부 문서(지식베이스)에서 정보를 검색하고,
그 정보를 기반으로 답변을 생성하는 방식으로 코드를 구현해보겠습니다!!
문서 임베딩 및 저장: 문서들을 임베딩 벡터로 변환해 저장
질문 임베딩: 질문을 임베딩벡터로 변환
검색(Retrieval): 질문 벡터와 문서 벡터 간 유사도를 계산해 가장 관련 있는 문서 선택
생성(Generation): 선택된 문서를 참고하여 답변 생성
약간의 Naive RAG 개념을 요약해봤고 진짜 코드를 구현해봅시다!

1) 벡터 저장소 로드
from langchain_chroma import Chroma
from langchain_openai import AzureOpenAIEmbeddings
# OpenAI 임베딩 모델 생성
embeddings_openai = AzureOpenAIEmbeddings(
model="text-embedding-3-small", # 사용할 모델 이름
)
# 저장된 벡터 저장소를 가져오기
chroma_db = Chroma(
persist_directory="./chroma_db",
embedding_function=embeddings_openai
)
# 문서 개수 확인
print(f"백터 저장소의 문서 개수: {chroma_db._collection.count()}")
AzureOpenAIEnbeddings()에서 모델은 text-embedding-3-small을 사용합니다!
persist_directory="./chroma_db" 폴더에서 이미 저장된 벡터를 불러옵니다.
[MAC] 벡터 저장소 ChromaDB 사용한 코드 살펴보기
벡터 저장소(Vector Store)이란?벡터 저장소란!!비정형 데이터를 벡터(숫자 배열)형태로 저장하고,빠르게 검색할 수 있게 해주는 특수한 데이터베이스에요!단순한 키워드 검색이 아니라 의미 기반
yyyeji.tistory.com
2) 검색기(Retriever) 초기화
# mmr 검색기 생성
retriever = chroma_db.as_retriever(
search_type="mmr",
search_kwargs={"k": 5,
"fetch_k": 10,
"lambda_mult": 0.3},
)
[MAC] 벡터 저장소 기반 RAG 검색기 사용하기
RAG란?검색(Retrieval)과 생성(Generation)을 결합해, LLM이 더 정확하고 최신 정보로 답변하게 하는 방식입니다! RAG 개념 알아보기RAG란 무엇일까요??Retrieval-Augmented Geteration의 줄임말이며,LLM의 한계를 보
yyyeji.tistory.com
mmr 검색을 사용하여 다양성을 높이는 설정을 했습니다!!
# 검색 테스트
query = "탄소 제로 정책에 대해 알려줘"
# 쿼리와 유사한 문서 검색
retrieved_docs = retriever.invoke(query)
print(f"쿼리: {query}")
print("검색 결과: ")
for i, doc in enumerate(retrieved_docs, 1):
print(f"-{i}-\n{doc.page_content}\n[출처: {doc.metadata['source']}]")
print("-" * 100)

retriever.invoke(query)로 검색기에 질문을 던져주고 관련 문서 리스트를 받아옵니다!
retrieved_docs는 문서 객체들의 리스트이고,
각 문서의 내용은 doc.page_content에
출처 정보는 doc.metadata['source']에 담겨 있으며
문서별로 번호와 함께 내용, 출처를 출력하는 코드입니다!!
3) RAG 프롬프트 구성
LangChain의 ChatPromptTembpate 클래스를 사용해 {context}, {question} 변수를 포함하는 예제를 살펴보겠습니다!
# Prompt 템플릿 (커스텀 예시)
from langchain_core.prompts import ChatPromptTemplate
template = """주어진 컨텍스트를 기반으로 질문에 답변하시오.
[지침]
- 컨텍스트에 있는 정보만을 사용하여 답변할 것
- 외부 지식이나 정보를 사용하지 말 것
- 컨텍스트에서 답을 찾을 수 없는 경우 "주어진 정보만으로는 답변하기 어렵습니다."라고 응답할 것
- 불확실한 경우 명확히 그 불확실성을 표현할 것
- 답변은 논리적이고 구조화된 형태로 제공할 것
- 답변은 한국어를 사용할 것
[컨텍스트]
{context}
[질문]
{question}
[답변 형식]
1. 핵심 답변: (질문에 대한 직접적인 답변)
2. 근거: (컨텍스트에서 발견된 관련 정보)
3. 추가 설명: (필요한 경우 부연 설명 제공)
[답변]
"""
prompt = ChatPromptTemplate.from_template(template)
# 템플릿 출력
prompt.pretty_print()
프롬프트 구성요소
- 작업 지침
- 컨텍스트 영역
- 질문 영역
- 답변 형식 가이드
작업 지침
- 컨텍스트 기반 답변 원칙
- 외부 지식 사용 제한
- 불확실성 처리 방법
- 답변 불가능한 경우의 처리 방법
답변 형식
- 핵심 답변 섹션
- 근거 제시 섹션
- 추가 설명 섹션
제약사항 반영
- 답변은 사실에 기반해야 해야한다!
- 추측이나 가정을 최소화해야 한다!
- 명확한 근거 제시가 필요하다!
- 구조화된 형태로 작성되어야 한다!
템플릿을 왜 사용하는가?
- 일관성 유지
- 효율성 향상 (변수를 통해 재활용)
- 명확한 지침 제공
- 유연성 제공!! 합니당
4) RAG 체인 구성
from langchain_core.runnables import RunnablePassthrough, RunnableParallel # RunnableParallel -> 한 번에 병렬 처리
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import AzureChatOpenAI
# LLM 설정
llm = AzureChatOpenAI(
deployment_name="gpt-4o-mini",
temperature=0.7)
# 문서 포맷팅
def format_docs(docs):
return "\n\n".join([f"{doc.page_content}" for doc in docs])
# RAG 체인 생성
rag_chain = (
RunnableParallel(
{
"context": retriever | format_docs,
"question": RunnablePassthrough() # 니가 뭘 하지 말고 받은 그대로 뒤로 넘겨라
}
)
| prompt
| llm
| StrOutputParser()
)
# 체인 실행
query = "탄소 제로 정책에 대해서 알려줘 "
output = rag_chain.invoke(query)
print(f"쿼리: {query}")
print("답변:")
print(output)
retriever를 통해 질문에 맞는 문서들을 검색하고,
format_docs 함수로 문서 내용을 연결해 context로 만들고,
question은 그대로 LLM에게 변경없이 전달합니다!!
| prompt
| llm
| StrOutputParser()
prompt: 앞서 만든 프롬프트 텝플릿에 context와 question을 채우고
llm: GPT 모델에 프롬프트를 전달해 답변을 생성하고
StrOutputParser(): 결과를 문자열로 깔끔하게 파싱합니다!!
이제 체인을 실행해보면
output = rag_chain.invoke(query)

템플릿에 맞춰 답변을 받아보신 것을 확인할 수 있습니다!!

'인공지능 챗봇' 카테고리의 다른 글
| [MAC] 키워드 검색(Keyword Search)을 기반으로 한 RAG 살펴보기 (4) | 2025.08.06 |
|---|---|
| [MAC] 의미론적 검색(Semantic Search)을 기반으로 한 RAG 살펴보기 (4) | 2025.08.06 |
| [MAC] 벡터 저장소 기반 RAG 검색기 사용하기 (6) | 2025.08.05 |
| [MAC] 벡터 저장소 FAISS(Facebook AI Similarity Search) 사용한 코드 살펴보기 (2) | 2025.08.05 |
| [MAC] 벡터 저장소 ChromaDB 사용한 코드 살펴보기 (2) | 2025.08.05 |