
๐ GitHub repository
ํ๋ก์ ํธ ๊ธฐ๊ฐ: ย 2025.06.30 - 2025.07.03 ย (4์ธ ํ๋ก์ ํธ)
์ต๊ทผ ๋ช ๋ ์ฌ์ด ๊ฑด๊ฐ๊ธฐ๋ฅ์ํ ์์ฅ์ ํธ๋ ๋๋ฅผ ๋์ด ์ผ์ ์๋น๋ก ์ ์ฐฉ๋์๋ค. ๊ทธ๋ฌ๋ ์๋ฐฑ ๊ฐ์ ๋ธ๋๋์ ์ฑ๋ถ, ์ ํ๊ตฐ์ด ๋์์ ์์์ง๋ ์ํฉ์์ ์๋น์๋ ์ฌ์ ํ ์ด๋ค ์์์ ๋ฅผ ์ด๋ป๊ฒ ์ ํํด์ผ ํ ์ง ๋ช ํํ ๊ธฐ์ค์ ๊ฐ๊ธฐ ์ด๋ ต๋ค.
๊ฒ๋ค๊ฐ ์ต๊ทผ์๋ ๊ฒ์๋ณด๋ค ChatGPT, Gemini์ ๊ฐ์ ๋ํ ์ธ์ด๋ชจ๋ธ(Large Language Model, LLM) ๊ธฐ๋ฐ ์ฑ๋ด์๊ฒ ์ง์ ์ง๋ฌธํ์ฌ ์ ๋ณด๋ฅผ ์ป๋ ๊ฒ ์์ฐ์ค๋ฌ์ด ์๋๊ฐ ๋์๋ค.
โ๋ฌด์จ ์์์ ๋ฅผ ๋จน๋ ๊ฒ ์ข์๊น?โ, โ๋ฃจํ ์ธ์ ๋์ ์ง์ง ํจ๊ณผ ์์ด?โ, โ์ด ์ ํ์ ๋น๋จ ํ์๋ ๋จน์ ์ ์์ด?โ ๊ฐ์ ์ง๋ฌธ๋ ์ ๋ฌธ๊ฐ๊ฐ ์๋๋ผ ์ฑ๋ด์๊ฒ ๋จผ์ ๋ฌป๊ณ ๋ ํ๋ค.
๊ทธ๋ฐ๋ฐ "๊ทธ ์ ๋ณด, ๊ทธ๋๋ก ๋ฏฟ์ด๋ ๋ ๊น?" ํ๋ ์๋ฌธ๋ ๊ฐ์ง๊ณ ์์ ๊ฒ์ด๋ค.
์ค์ ๋ก ๊ฑด๊ฐ ์ ๋ณด๋ ์ฑ๋ถ ์ถ์ฒ์ ๋ํด ์ด๋ค ์ฑ๋ด์ด ์ ๊ณตํ๋ ์๋ต์ ๊ณผ๊ฑฐ์ ๋นํด ์๋นํ ์ ํํ๊ณ ์์ฐ์ค๋ฝ๊ฒ ๋ณด์ด์ง๋ง, ์ฌ์ ํ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ์ ์ธ ๋ฌธ์ ๊ฐ ์กด์ฌํ๋ค.
์ด๋ฌํ ๋ฐฐ๊ฒฝ์์ ๋ณธ ํ๋ก์ ํธ๋ '์์์ ์ถ์ฒ ์์คํ '์ ๋ง๋๋ ๊ฒ์ด ์๋๋ผ, LLM์ ๋ถํ์คํ ์๋ต ๊ตฌ์กฐ ์์ฒด๋ฅผ ์ ๋ขฐ ๊ฐ๋ฅํ ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํ๊ธฐ ์ํ ๊ธฐ์ ์ ์คํ์ผ๋ก ์์๋์๋ค.
" GPT๋ณด๋ค ๋ฏฟ์ ์ ์๋, ์ค์ ๋ก ๋์์ด ๋๋ ย ์์์ ์ถ์ฒ ์์คํ โ
์ฐ๋ฆฌ ํ์ ํ๋์ ๋ฐฉํฅ ์์์ ์ธ ๊ฐ์ง์ ๋ชฉํ๋ฅผ ์ ํํ๊ฒ ์ก์๋ค.
ํ๋ก์ ํธ์ ๋ฐฉํฅ ์ค์ ํ, ์๋์ ๊ฐ์ด ์ญํ ์ ๋ถ๋ฐฐํ์๋ค.
| ํ์ฅ A | ํ์ B (๋ณธ์ธ) | ํ์ C | ํ์ D |
|---|---|---|---|
| โธฐ PM โธฐ ์์ด๋์ด ๊ธฐํ โธฐ ๊ธฐ์ ์กฐ์ฌ | โธฐ ํ๋กฌํํธ ์์ง๋์ด๋ง โธฐ 1์ฐจ RAG ์ค๊ณ โธฐ ์๋ต ์ ๋ฐ๋ ๊ฐ์ | โธฐ ํ์ ๋
ผ๋ฌธ ์กฐ์ฌ โธฐ ๋ฌธ์ ์ ์ โธฐ ์๋๋ฆฌ์ค ๊ธฐ๋ฐ ํ ์คํธ | โธฐ ๊ณต๊ณต๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ ๊ตฌ์ถ โธฐ 2์ฐจ RAG ์ค๊ณ โธฐ ๋ฒกํฐ DB ๊ตฌ์ถ |
GPT-4๋ ๊ฐ๋ ฅํ ๋ฌธ์ฅ ์์ฑ ๋ฅ๋ ฅ์ ๊ฐ์ถ์์ง๋ง, ์ ํด์ง ์ง์ ๋ฒ์ ๋ด์์๋ง ์๋ํ์ง ์๋๋ค. ํนํ ๊ฑด๊ฐ ๋๋ฉ์ธ์์๋ ์กด์ฌํ์ง ์๋ ์ฑ๋ถ์ด๋ ์ ํ๋ช ์ ์ ์ํ๋ 'ํ๊ฐ(Hallucination)' ๋ฌธ์ ๊ฐ ์น๋ช ์ ์ด๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, ๋ณธ ํ๋ก์ ํธ์์ RAG (Retrieval-Augmented Generation) ๊ตฌ์กฐ๋ฅผ ์ฑํํ๋ ๊ฒ์ด ์ ์ ํ๋ค๊ณ ํ๋จํ์๋ค.
RAG๋ ์ธ๋ถ ๋ฌธ์์์ ์ ๋ณด๋ฅผ ๊ฒ์ํ๊ณ ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก LLM์ด ์๋ต์ ์์ฑํ๋ ๋ฐฉ์์ผ๋ก,"๋ฌธ์ ๊ธฐ๋ฐ ์ง์์ ํต์ " ์ "LLM ์๋ต์ ์ ํ์ฑ" ์ ๋์์ ํ๋ณดํ ์ ์๋ ๊ตฌ์กฐ์ด๋ค.
- Hallucination์ ์์ฒ์ ์ผ๋ก ์ฐจ๋จ ๊ฐ๋ฅ (๋ฌธ์ ์ธ ์ ๋ณด ์ฌ์ฉ ์ ํ)
- ์๋ต ์ ๋ขฐ๋ ํฅ์ ๋ฐ ์ถ์ฒ ๋ช ์ ๊ฐ๋ฅ
- LangChain ๊ธฐ๋ฐ์ผ๋ก RAG ์ฒด์ธ์ ๊ตฌ์ฑํ๊ธฐ ์ฉ์ดํจ
๋ฌธ์ ๊ฒ์ ๊ณผ์ ์์ ํต์ฌ์ด ๋๋ ๊ฒ์ ์ฌ์ฉ์์ ์ง๋ฌธ๊ณผ ๊ฐ์ฅ ์ ์ฌํ ๋ฌธ๋จ์ ๋น ๋ฅด๊ฒ ์ฐพ์๋ด๋ ๊ฒ์ด๋ค. ์ด๋ฅผ ์ํด
OpenAI Embedding + FAISS ์ธ๋ฑ์ฑ ๊ตฌ์กฐ๋ฅผ ์ ํํ์๋ค.
FAISS(Facebook AI Similarity Search)๋ ๊ณ ์ฐจ์ ๋ฒกํฐ ๊ฐ ์ ์ฌ๋ ๊ณ์ฐ์ ํนํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก, ์์ฒ~์๋ง ๊ฐ์ ๋ฒกํฐ์์ ์ ์ฌํ ๊ฒฐ๊ณผ๋ฅผ ๋น ๋ฅด๊ฒ ์ฐพ์๋ด๋ ๋ฐ ์ ํฉํ๋ค.
Document ๊ฐ์ฒด์ ๋ฉํ ์ ๋ณด๋ฅผ ํจ๊ป ์ ์ฅํ๋ฏ๋ก ๊ฒ์ ํ ์๋ฌธ ์ถ์ฒ, ๋ฌธ์๋ช , ์ถํ์ฐ๋ ๋ฑ๋ ํจ๊ป ์ถ์ถ ๊ฐ๋ฅํ๋ค๋ ์ ์์ ํ๋ก์ ํธ์ ๋ฐฉํฅ์ฑ์ ๋ถํฉํ๋ค.
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
embedding = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(documents, embedding)
vectorstore.save_local("faiss_db/")
- 1๋ง ๊ฑด ์ด์์ ๋ฌธ์๋ฅผ ๋ฒกํฐํํ์ฌ๋ ๊ฒ์ ์๋๊ฐ ๋น ๋ฆ
- Local ํ๊ฒฝ์์ ์ ์ฅ, ๋ก๋, ์ถ๊ฐ ์ฝ์ (add_documents) ๊ฐ๋ฅ
- LangChain๊ณผ ํตํฉ ๊ฐ๋ฅ (FAISS.from_documents(), load_local() ๋ฑ)
๋ฌธ์ ๊ธฐ๋ฐ ์ฑ๋ถ ์ถ์ฒ๋ง์ผ๋ก๋ ์ค์ ์ฌ์ฉ์ ์ก์ ์ผ๋ก ์ด์ด์ง๊ธฐ ์ด๋ ต๋ค.
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ํ์์ฝํ์์ ์ฒ ๊ฑด๊ฐ๊ธฐ๋ฅ์ํ์ ๋ณด Open API ๋ฅผ ์ฌ์ฉํ์๋ค.
์ด API๋ ์ฝ 10,000๊ฑด์ ์์์ ์ ํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ฉฐ ๊ธฐ๋ฅ์ฑ, ์ฑ๋ถ, ์ฃผ์์ฌํญ, ์ญ์ทจ๋ฐฉ๋ฒ ๋ฑ์ ์ ๋ณด๋ฅผ ํฌํจํ๊ณ ์๋ค.
- ๊ณต๊ณต๊ธฐ๊ด์ด ์ ๊ณตํ๋ ์ ๋ขฐ ๊ฐ๋ฅํ ์ ํ ์ ๋ณด
- ์ผ์ผ 10,000๊ฑด ํธ์ถ ๊ฐ๋ฅ
- ์ ํ๋ช , ๊ธฐ๋ฅ์ฑ, ์ฃผ์์ฌํญ, ์ญ์ทจ๋ ๋ฑ์ ํ๋๊ฐ ์กด์ฌํ์ฌ ์ถ์ฒ ํ ์ฐ๊ณ ๊ฐ๋ฅ
์ฌ์ฉ๋ ๋ฌธํ์ ์ด 46ํธ์ ํ์ ๋ ผ๋ฌธ, ๊ฑด๊ฐ๊ธฐ๋ฅ์ํ ๊ฐ์ด๋๋ผ์ธ, ์์ฝ์ฒ ์๋ฃ๋ก ๊ตฌ์ฑ๋์ด ์๋ค. ์ด ๋ฌธํ๋ค์ PDF ํ์์ผ๋ก ์์ง๋์๊ณ , ๋ฌธ๋จ ๋จ์๋ก ๋ถํ ํ๊ณ ๋ฒกํฐํํ๊ธฐ ์ํ ์ฌ์ ์ ์ ์์ ์ด ํ์ํ์๋ค.
์๋์ ๊ณผ์ ์ผ๋ก ์ ์ฒ๋ฆฌ๋ฅผ ์ํํ์๋ค.
PyMuPDF ๊ธฐ๋ฐ์ผ๋ก PDF์์ ๋ณธ๋ฌธ ํ
์คํธ ์ถ์ถDocument ๊ฐ์ฒด๋ก ๋ณํ (๋ฉํ ์ ๋ณด ํฌํจ: ์ถ์ฒ, ์ ๋ชฉ, ๋ฌธ์ ์ ํ ๋ฑ)๋ฌธ์ ๋ถํ ์ ๋จ์ ๊ธธ์ด ๊ธฐ์ค์ด ์๋ ๋ฌธ๋งฅ ๋ณด์กด์ ์ํ chunk overlap ๊ธฐ๋ฒ์ ์ ์ฉํ์์ผ๋ฉฐ ์ดํ Embedding ๊ณผ์ ์ผ๋ก ์ฐ๊ฒฐ๋๋ค.
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
loader = PyPDFLoader("๊ฐ๊ฑด๊ฐ_๊ฐ์ด๋๋ผ์ธ.pdf")
pages = loader.load()
splitter = RecursiveCharacterTextSplitter(chunk_size=700, chunk_overlap=100)
documents = splitter.split_documents(pages)
RAG(Retrieval-Augmented Generation)๋ฅผ ๋ ๋ฒ ํ์ฉํด ์ ๋ขฐ์ฑ๊ณผ ์ ๋ฐ๋๋ฅผ ๋์์ ํ๋ณดํฉ๋๋ค.
์ด๋ ๊ฒ 2๋จ๊ณ๋ก ๋ถ๋ฆฌ๋ ๊ตฌ์กฐ๋ "์ ์ด ์ฑ๋ถ์ ์ถ์ฒํ๋๊ฐ" ์ "๊ทธ ์ฑ๋ถ์ด ํฌํจ๋ ์ ํ์ ๋ฌด์์ธ๊ฐ" ๋ฅผ ์ฐ๊ฒฐํ ์ ์๋ค.

์ฌ์ฉ์ ์
๋ ฅ์ ๋จ์ผ ์ฆ์์ด ์๋ ์ฌ๋ฌ ๊ฑด๊ฐ ์์ญ์ ํฌํจํ ์ ์๋ค.
ย ย ย ย ย ex. ๋ ๊ฑด๊ฐ + ํผ๋ก + ์ปคํผ ๊ณผ๋ค ์ญ์ทจ
์ด๋ฅผ ๊ณ ๋ คํ์ฌ ๋ฌธ์ ๋ฒกํฐ DB๋ฅผ ์งํ/์ด์๋ณ ์๋๋ฆฌ์ค ์ผ์ด์ค๋ฅผ ๋ถ๋ฆฌ ์ ์ฅํ์์ผ๋ฉฐ, LangChain์ EnsembleRetriever๋ฅผ ํตํด ๋ค์ค ๊ฒ์์ด ๊ฐ๋ฅํ๋๋ก ๊ตฌ์ฑํ์๋ค.
retriever1 = FAISS.load_local("faiss_db/case_A", embedding)
retriever2 = FAISS.load_local("faiss_db/case_b", embedding)
ensemble_retriever = EnsembleRetriever(
retrievers=[retriever1, retriever2],
weights=[0.5, 0.5]
)
์ฌ์ฉ์ ์ ๋ ฅ ํค์๋ ์ถ์ถ ํ, ์๋๋ฆฌ์ค๋ณ Case๋ฅผ ๋ถ๋ฅํ์ฌ ํ์ดํธ๋ฆฌ์คํธ ๊ธฐ๋ฐ ํ๋กฌํํธ๋ฅผ ์ค๊ณํ์๋ค.
>> ย 6. ์ฌ์ฉ์ ์ ๋ ฅ ์ฒ๋ฆฌ ๋ฐ Case ๋ถ๋ฅ ๋ก์ง ์ฐธ๊ณ
>> ย 7. ๊ณต๊ณต๋ฐ์ดํฐ ๊ธฐ๋ฐ ์ ํ ์ถ์ฒ ํ์ดํ๋ผ์ธ ์ฐธ๊ณ
์๋ฃยท์์ ๋๋ฉ์ธ์ "์ฐฝ์์ฑ" ๋ณด๋ค ์์ ์ฑยท๊ทผ๊ฑฐ ๊ธฐ๋ฐ์ด ์ต์ฐ์ ์ด๋ค.
์ค์ ๋
ผ๋ฌธ๋ง๋ค ๊ฒฐ๊ณผ๊ฐ ์๊ฐ๋ฆฌ๊ณ , ์ ๋ฌธ๊ฐ๋ค์กฐ์ฐจ ๋จ์ผ ์ ๋ต์ ๋ด๋ฆฌ๊ธฐ ์ด๋ ค์ด ์์ญ์ด๋ฏ๋ก, "๋ชจ๋ ์ํฉ์ ๋ง๋ ๋ต๋ณ" ๋์ ์๋๋ฆฌ์ค(case) ๋จ์๋ก ๊ฒ์ฆ๋ ์ฑ๋ถ๋ง ์ ๊ณตํ๋๋ก ๊ตฌํํ์๋ค. ์ด ๊ณผ์ ์์ ๋
ผ๋ฌธ/์ฐ๊ตฌ ์๋ฃ ๋ฑ ์ ๋น์ฑ ์๋ ์๋ฃ ์กฐ์ฌ๋ฅผ ํตํด ๋๋ฉ์ธ์ ๋ํ ์ ํํ ์ดํด๊ฐ ํ์ํ๋ค.
๋ณธ ํ๋ก์ ํธ๋ ์ฌ์ฉ์์๊ฒ ๋ค์ ํญ๋ชฉ์ ์ ๋ ฅ์ ์๊ตฌํ๋ค.
์ด ์ ๋ ฅ์ ๋จ์ํ ๋ฌธ์์ด๋ก ๊ตฌ์ฑ๋์ด ์์ผ๋, ์ดํ ์ ์ฒด ํ์ดํ๋ผ์ธ์์ ํต์ฌ์ ์ธ ์ญํ ์ ํ๊ฒ ๋๋ฉฐ
ํนํ "์ฌ์ฉ์ ์ํ ๋ถ๋ฅ โ case๋ณ ์ฒ๋ฐฉ ๋ถ๊ธฐ" ์ ๊ธฐ์ค์ด ๋๋ค.
์ด๊ธฐ ์ค๊ณ ๋จ๊ณ์์ ๊ตฌ์ฒด์ ์ธ ํ๋ฅด์๋๋ฅผ ์ง์ ํ์ฌ ์ฌ์ฉ์ ์๊ตฌ๋ฅผ ๋ช ๊ฐ์ง ์ ํ์ผ๋ก ๋ถ๋ฅํ์๋ค.
์ด๋ ์ง๋ฌธ์ ํํ๋ฅผ ์ ํํ๊ธฐ ์ํจ์ด ์๋๋ผ, LLM์ ํ๋กฌํํธ ์์ ์ฑ๊ณผ ์๋ต ํ์ง์ ํ๋ณดํ๊ธฐ ์ํ ๊ตฌ์กฐ์ ์ฅ์น์ด๋ค. ์์ ์ธ๊ธํ ๊ฒ์ฒ๋ผ ๋๋ฉ์ธ ํน์ฑ ์ "๋ชจ๋ ์ํฉ์ ๋ง๋ ๋ต๋ณ" ๋ณด๋ค๋ ํ์ ๋ ๋์์ด๋ผ๋ ๊ฒ์ฆ๋ ์ฑ๋ถ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ์ค์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ฌ์ฉ์์ ์์ ์ ๋ ฅ์ ์ฌ์ ์ ์๋ Case์ ๋งคํํ๊ธฐ ์ํ ํจ์๋ฅผ ๊ตฌ์ฑํ์๋ค.
def categorize_user_query(user_input: str) -> list:
case_list = []
if "๊ฐ" in user_input or "์์ฃผ" in user_input or "ํ์" in user_input:
case_list.append("A")
if "์ปคํผ" in user_input or "์นดํ์ธ" in user_input:
case_list.append("B")
if "๋" in user_input or "๋ฃจํ
์ธ" in user_input:
case_list.append("C")
if "์ฝ" in user_input or "๋ณต์ฉ" in user_input:
case_list.append("D")
return case_list
ํด๋น ํจ์๋ ์์ ์ ๋ ฅ์ ๋ถ์ํ์ฌ ์ค์ฒฉ๋ case๋ฅผ ๋ค์ค ๋ฐํํ๋ค.
์ฆ, ํ ์ฌ์ฉ์๊ฐ ๋์์ ๊ฐ ๊ฑด๊ฐ + ๋ ๊ฑด๊ฐ + ์ฝ๋ฌผ ๋ณต์ฉ ์ ๋ณด๋ฅผ ์ ๋ ฅํ ๊ฒฝ์ฐ, ์ธ ๊ฐ์ง ์ฒ๋ฐฉ ๋ ผ๋ฆฌ๋ฅผ ๋ชจ๋ ํ๋กฌํํธ์ ๋ฐ์ํ ์ ์๋๋ก ์ค๊ณํ์๋ค.
๊ฐ case์๋ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ์ JSON ์๋ต ํ ํ๋ฆฟ์ด ์ฌ์ ์ ์ ์๋์ด ์๋ค.
{
"recommended": [...],
"avoid": [...],
"caution": [...],
"reference": [...]
}
์ด ํ ํ๋ฆฟ์ ๊ฐ case๋ณ๋ก ๋ค๋ฅด๊ฒ ์ ์๋๊ณ , ์ฌ์ฉ์์ ์ ๋ ฅ์ด ์ฌ๋ฌ case์ ํด๋น๋ ๊ฒฝ์ฐ ํด๋น ํ ํ๋ฆฟ์ ๋ณํฉํ์ฌ LLM ํ๋กฌํํธ๋ก ์ ๋ฌํ๋ค.
ํ๋ก์ ํธ ์งํ ๊ณผ์ ์์
ํ๋กฌํํธ๋ "ํ์ฉ๋ ์ฑ๋ถ๋ง ์ฌ์ฉํ๋ผ" ๋ whitelist ๊ตฌ์กฐ๋ฅผ ๊ฐ์ถ๋๋ก ์ค๊ณ ๋ฐฉํฅ์ ์ก๊ฒ ๋์๋ค. ์ด ๊ตฌ์กฐ ๋๋ถ์ ๊ตฌ์กฐํ๋ ์๋ต, ์ผ๊ด๋ ํ๋, ์์ ์ ์ธ ํ์ฑ์ด ๊ฐ๋ฅํด์ก๋ค.
์ฌ์ฉ๋ ๋ฐ์ดํฐ๋ ์์ฝ์ฒ ๊ฑด๊ฐ๊ธฐ๋ฅ์ํ์ ๋ณด ๊ณต๊ณต API๋ก, ์ด 10,000๊ฑด์ ์์์ ์ ํ ์ ๋ณด๋ฅผ ์ฌ์ฉํ์๋ค.

๋ณธ ํ๋ก์ ํธ์์๋ ๋ค์ 5๊ฐ์ง ํ๋๋ง ์ ์งํ์ฌ ๋ฒกํฐํ ๋์ ๋ฌธ์๋ฅผ ๊ตฌ์ฑํ์๋ค.
[์ฐธ๊ณ ] ์ํ์์ฝํ์์ ์ฒ_๊ฑด๊ฐ๊ธฐ๋ฅ์ํ์ ๋ณด Open API
์ฌ์ฉํ ์์ฝ์ฒ API์ ์๋๊ณผ ๊ฐ์ ์ ์ฝ์ด ์กด์ฌํ๋ ๊ฒ์ ํ์ธํ์๋ค.
numOfRows ์ต๋๊ฐ: 100์ด๋ฅผ ๊ณ ๋ คํ์ฌ ๋ค์ ์ ๋ต์ผ๋ก ์์ง์ ์งํํ์๋ค.
| ๋จ๊ณ | ์ฒ๋ฆฌ ๋ฐฉ์ | ๋ชฉ์ |
|---|---|---|
| โ 1,000๊ฑด ํ๋กํ ํ์ | 500 + 500๊ฑด์ ํธ์ถํ์ฌ ํ ์คํธ | ์๋ต ํ์ ๋ถ์, ํ์ฑ ํ ์คํธ |
| โก ์๋ฒ ๋ฉ ํ ํฐ ์ด๊ณผ ๋์ | 500๊ฑด์ฉ ์์ง โ ๋ค์ 100๊ฐ์ฉ ๋๋์ด ์๋ฒ ๋ฉ | OpenAI ์๋ฒ ๋ฉ ํ ํฐ ์ ํ ํํผ |
| โข ์ ์ฒด ์์ง | 100ํ์ด์ง ร 100๊ฐ = 10,000๊ฑด ์์ง ์๋ฃ | ์ ์ฒด ๋ฐ์ดํฐ ํ๋ณด |
| โฃ ๋ฌธ์ํ | ํ์ํ ํ๋๋ง LangChain Document๋ก ์ ์ฅ | ์๋ฒ ๋ฉ ๋ถํ ์ต์ํ, ๊ฒ์ ์ ํ๋ ํฅ์ |
์ ํ ์ถ์ฒ์ recommended ์ฑ๋ถ ๋ฆฌ์คํธ๋ฅผ ๊ธฐ์ค์ผ๋ก FAISS ๊ฒ์์ ์ํํ๊ณ ,
๋์์ avoid ์ฑ๋ถ ๋ฆฌ์คํธ์ ํด๋นํ๋ ์ ํ์ ํํฐ๋งํ์ฌ ์ ์ธํ๋ค.
def filter_avoid_products(results, avoid_list):
return [
r for r in results
if not any(avoid in r.page_content for avoid in avoid_list)
]
์ต์ข ์ ์ผ๋ก 5๊ฐ ์ ํ๋ง ์ถ๋ ค์ ์ฌ์ฉ์์๊ฒ ์นด๋ ํํ๋ก ์ ์ํ๊ณ , ์ ํ ์ ๋ณด๋ UI ์์์ ํ์ฅ ๊ฐ๋ฅ(expandable)ํ๊ฒ ๊ตฌ์ฑํ์๋ค.
UI๋ Streamlit ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑํ์์ผ๋ฉฐ, ์ฌ์ฉ์๋ ํ ํ๋ฉด ๋ด์์ ๋ค์๊ณผ ๊ฐ์ ํ๋ฆ์ ๊ฒฝํํ๊ฒ ๋๋ค.
์ด๋ฌํ ๊ตฌ์ฑ์ ์ฌ์ฉ์๊ฐ ์๋ต ์ ๋ขฐ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ค์๊ฐ ์ ํ ๋น๊ต ํ๋์ผ๋ก ์ด์ด์ง ์ ์๋๋ก UX ํ๋ฆ์ ์ค๊ณํ์๋ค.
LLM์ ์๋ต์ JSON์ผ๋ก ์ ํ๋์ด ์์ง๋ง,
์๋ต์ด ๋๋ฝ๋๊ฑฐ๋ ํฌ๋งท ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ ๋๋นํ์ฌ ๋ค์๊ณผ ๊ฐ์ ์์ ์ฅ์น๋ฅผ ๋ง๋ จํ์๋ค.
json.loads() ์คํจ ์ ์ฆ์ ์ค๋ฅ ๋ฉ์์ง ์ถ๋ ฅ์๋๋ ์ต์ข ์ ์ผ๋ก ์์ฑ๋ "์์์ Check!" ์๋น์ค๋ฅผ ์คํํ ํ๋ฉด์ด๋ค.
์ฌ์ฉ์๊ฐ ์ ๋ณด๋ฅผ ์ ๋ ฅํ๋ฉด, ์ถ์ฒ ์ฑ๋ถ๊ณผ ํผํด์ผ ํ ์ฑ๋ถ, ์ฃผ์์ฌํญ, ์ค์ ์ ํ๊น์ง ์์ฐจ์ ์ผ๋ก ์ถ๋ ฅ๋๊ณ , ๊ฐ ๊ฒฐ๊ณผ๋ ๋ชจ๋ ๋ ผ๋ฌธ ๋๋ ๊ณต๊ณต๋ฐ์ดํฐ์ ๊ธฐ๋ฐํ ๊ฒ์ฆ๋ ์ ๋ณด๋ง์ ์ฌ์ฉํ๋ค.
์ฌ์ฉ์๋ ์์ ์ ์ํ์ ๋ฐ๋ผ ๋ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๊ฒ ๋๋ฉฐ, ๊ทธ ์ฐจ์ด๋ฅผ ๋ช ํํ ์ฒด๊ฐํ ์ ์๋ค.


์คํ ๊ฒฐ๊ณผ๋ฅผ ํด์ํ ๋ ๊ฐ์ฅ ์ค์ํ๋ ๊ฑด, ์ ์๋ ์ฑ๋ถ์ด ์ค์ ๋ก ํด๋น ์ฌ์ฉ์์๊ฒ ์ ์ ํ๊ฐ๋ฅผ ๋๋ฉ์ธ ๊ธฐ์ค์์ ๊ฒ์ฆํ๋ ๊ฒ์ด์๋ค.
๊ณต๋ถํ๊ณ ์ดํดํ ๋๋ฉ์ธ ์ง์์ ๋ฐํ์ผ๋ก ๋์์ผ ํ ์ฑ๋ถ์ด ๋น ์ง๊ฑฐ๋ ๋์ค๋ฉด ์ ๋๋ ์ฑ๋ถ์ด ํฌํจ๋ ๊ฒฝ์ฐ๋ฅผ ๊ตฌ๋ถํ ์ ์์๊ณ , ์ด ๊ณผ์ ์ ํตํด ํ์ฌ ๋ก์ง์ ์ด๋ค ๋ฌธ์ ๊ฐ ์๋์ง ์ง์ด๋ด๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค.
๊ถ๊ทน์ ์ผ๋ก๋ โ๊ทธ๋ด๋ฏํ ๋ต๋ณโ ์ด ์๋๋ผ ์ ํํ๊ณ ์ ๋ขฐ ๊ฐ๋ฅํ ๊ฒฐ๊ณผ๋ง์ ์ฌ์ฉ์์๊ฒ ์ ๊ณตํ๋ ๊ฒ์ ๊ฐ๊น์์ง ์ ์์๋ค.
์๋ต ์ ๋ฐ๋ ๊ฐ์ ์ ๋ต ๋ฐ ํ์ ๊ฐ์ ๋ฐฉํฅ
๋ญ์ฒด์ธํค ๋ฐํ ํ,
ํผ์ค๋์ ํผ๋๋ฐฑ์ ํตํด ์ป์ ์ธ์ฌ์ดํธ๋ก ๊ฐ์ ๋ฐฉํฅ์ ์๊ฐํด ๋ณผ ์ ์์๋ค.
๋ณธ ํ๋ก์ ํธ๋ RAG๋ฅผ ๋ ๋จ๊ณ๋ก ๊ตฌ์ฑํ์ฌ ์ฌ์ฉ์ ์ง๋ฌธ์ ๋ํ ์ง์์๋ต๊ณผ, ์ดํ ์กฐ๊ฑด ๊ธฐ๋ฐ ์์์ ์ถ์ฒ๊น์ง ๋ชจ๋ ์ธ์ด ๋ชจ๋ธ ๊ธฐ๋ฐ ์ ์ฌ๋ ๊ฒ์์ ํ์ฉํ์๋ค. ๊ทธ๋ฌ๋ ์ฑ๋ถ ๊ฐ ์ ์ฌ์ฑ์ด ๋์ ์ํฉ์์๋ ๋ฒกํฐ ์ ์ฌ๋ ๊ธฐ๋ฐ์ ์ ๋ ฌ์ด ๊ธฐ๋๋งํผ ๋ช ํํ ์ฐ์ ์์๋ฅผ ์ ๊ณตํ์ง ๋ชปํ ๊ฐ๋ฅ์ฑ๋ ์๋ค.
์ ์ฌํ ํจ๋ฅ์ ์ง๋ ์ฑ๋ถ๋ค์ด ๋ค์ ์กด์ฌํ ๋, ์ ์ฌ๋ ๊ธฐ๋ฐ ๊ฒ์์ด ์ค์ ์ถ์ฒ์ ์ฐ์ ์์์ ๋ค๋ฅด๊ฒ ์๋ํ ์ ์์ผ๋ฉฐ ์ด ๊ฒฝ์ฐ ์ ํํ๋ ๊ตฌ์กฐ์ RDB(Relational Database)๋ฅผ ํ์ฉํ ์ ๋ ฌ ๋ฐฉ์์ด ๋ ํจ๊ณผ์ ์ผ ์ ์๋ค. ํฅํ์๋ RAG ๊ธฐ๋ฐ ์ถ์ฒ๊ณผ RDB ๊ธฐ๋ฐ ์ ๋ ฌ์ ์ฑ๋ฅ์ ๋น๊ตํ์ฌ ์ถ์ฒ ์ ํ๋ ๋ฐ ์ฌ์ฉ์ ๋ง์กฑ๋๋ฅผ ๊ธฐ์ค์ผ๋ก ํ์ด๋ธ๋ฆฌ๋ ๊ตฌ์กฐ ๋์ ๋ ๊ณ ๋ คํ ์ ์๋ค.
์ฌ์ฉ์์๊ฒ "์ถ์ฒ ์ฑ๋ถ" ๋๋ "ํผํด์ผ ํ ์ฑ๋ถ"์ ์ ์ํ ๋, ํด๋น ๋ด์ฉ์ ๋ท๋ฐ์นจํ๋ ์ฐ๊ตฌ ๊ฒฐ๊ณผ๋ ์์ ๊ทผ๊ฑฐ(๋ ผ๋ฌธ, ๊ฐ์ด๋๋ผ์ธ ๋ฑ)๋ฅผ ํจ๊ป ์ ์ํ๋ฉด ์ ๋ณด์ ์ ๋ขฐ๋์ ์ ๋ฌธ์ฑ์ด ํ์ธต ๋์์ง ์ ์๋ค. RAG์ ์๋ต ๊ฒฐ๊ณผ์ ๋ ผ๋ฌธ ์ถ์ฒ ๋๋ ํต์ฌ ๋ฌธ์ฅ์ ์ธ์ฉํ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ฑฐ๋, ๊ทผ๊ฑฐ ๊ธฐ๋ฐ ์์ฝ ๊ธฐ๋ฅ์ ๋ณด์ํ๋ ๋ฐฉํฅ์ผ๋ก๋ ๊ฐ์ ์ด ๊ฐ๋ฅํ๋ค.
๐ ย ๋ค์ ๊ธ