LangChanin RAG ์‚ฌ์šฉํ•˜๊ธฐ ๐Ÿฆœ๏ธ๐Ÿ”—

udonehnยท2024๋…„ 1์›” 25์ผ
3
post-thumbnail

๊ฐœ์š” ๐Ÿฆœ๏ธ๐Ÿ”—

์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ๋Š” Model I/O, LCEL, Prompt, Memory ๋“ฑ์— ๋Œ€ํ•ด ์ •๋ฆฌํ•˜์˜€๋‹ค. ์ด๋ฒˆ์—๋Š” RAG ๋ฐฉ์‹์„ ํ†ตํ•ด ์™ธ๋ถ€ ๋ฌธ์„œ๋ฅผ ์ œ๊ณตํ•˜๊ณ , ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ •๋ณด๋ฅผ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ๋Š” ์ฑ„ํŒ… ๋ชจ๋ธ์„ ๋งŒ๋“ค์–ด ๋ณธ๋‹ค.

RAG๋ž€?

RAG(Retrieval-Augmented Generation, ๊ฒ€์ƒ‰ ์ฆ๊ฐ• ์ƒ์„ฑ)๋ž€ AI๋ชจ๋ธ์˜ ์ •ํ™•์„ฑ๊ณผ ์‹ ๋ขฐ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด Pre-training(์‚ฌ์ „ ํ•™์Šต) ๋ฐ์ดํ„ฐ ์ด์™ธ์˜ ์™ธ๋ถ€ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ํ•˜๋Š” ๊ธฐ์ˆ ์„ ์˜๋ฏธํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด AI๋Š” ์ตœ์‹  ์ •๋ณด๋‚˜ ์‚ฌ์šฉ์ž ๋งž์ถค์˜ ์ •ํ™•ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

LangChain์—์„œ๋Š” ํฌ๊ฒŒ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ณผ์ •์„ ํ†ตํ•ด RAG๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

์›๋ณธ ๋ฐ์ดํ„ฐ -> ์ ์žฌ(load) -> ๋ถ„ํ• (split) -> ์ž„๋ฒ ๋”ฉ -> ๋ฒกํ„ฐ ๊ณต๊ฐ„ ์ €์žฅ(vector store & retriever)

์ฝ”๋“œ

from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import UnstructuredFileLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings, CacheBackedEmbeddings
from langchain.vectorstores import FAISS
from langchain.storage import LocalFileStore
from langchain.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnablePassthrough, RunnableLambda

llm = ChatOpenAI(
    temperature=0.1,
)

cache_dir = LocalFileStore("./.cache/practice/")

splitter = CharacterTextSplitter.from_tiktoken_encoder(
    separator="\n",
    chunk_size=600,
    chunk_overlap=100,
)

loader = UnstructuredFileLoader("./files/์šด์ˆ˜ ์ข‹์€ ๋‚ .txt")

docs = loader.load_and_split(text_splitter=splitter)

embeddings = OpenAIEmbeddings()

cached_embeddings = CacheBackedEmbeddings.from_bytes_store(embeddings, cache_dir)

vectorstore = FAISS.from_documents(docs, cached_embeddings)

retriever = vectorstore.as_retriever()

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            """
            You are a helpful assistant. 
            Answer questions using only the following context. 
            If you don't know the answer just say you don't know, don't make it up:
            \n\n
            {context}",
            """
        ),
        ("human", "{question}"),
    ]
)

chain = (
    {
        "context": retriever,
        "question": RunnablePassthrough(),
    }
    | prompt
    | llm
)

result = chain.invoke("๊น€์ฒจ์ง€๋Š” ํ•™์ƒ์„ ์–ด๋””๋กœ ๋ฐ๋ ค๋‹ค ์ฃผ์—ˆ๋‚˜?")
print(result)

์ถœ๋ ฅ

content='๊น€์ฒจ์ง€๋Š” ํ•™์ƒ์„ ๋‚จ๋Œ€๋ฌธ ์ •๊ฑฐ์žฅ๊นŒ์ง€ ๋ฐ๋ ค๋‹ค ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.'

Loading & Splitting

LLM์— ๋ฌธ์„œ๋ฅผ ์ œ๊ณตํ•  ๋•Œ ๋ฌธ์„œ ์ „๋ฌธ(ๅ…จๆ–‡)์„ LLM์— ์ „๋‹ฌํ•œ๋‹ค๋ฉด ํ”„๋กฌํ”„ํŠธ๊ฐ€ ๊ณผ๋„ํ•˜๊ฒŒ ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์ •ํ™•๋„๊ฐ€ ๋–จ์–ด์ง€๊ณ  ๋‹ต๋ณ€์ด ๋Š๋ฆฌ๋ฉฐ ๋น„์šฉ ์†Œ๋ชจ๊ฐ€ ๋งŽ์•„์ง€๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฌธ์„œ๋ฅผ ๋ถ„ํ• ํ•˜์—ฌ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์ „๋‹ฌํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. ๋‹จ, ๋ฌธ๋งฅ์ด๋‚˜ ์˜๋ฏธ๋ฅผ ์†์ƒํ•  ๋งŒํผ ์ž‘์€ ๋‹จ์œ„์˜ ๋ถ„ํ• ์€ ์ข‹์ง€ ์•Š๊ธฐ์— ์ ์ ˆํ•œ ํฌ๊ธฐ๋กœ ๋ถ„ํ• ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

splitter = CharacterTextSplitter.from_tiktoken_encoder(
    separator="\n",
    chunk_size=600,
    chunk_overlap=100,
)
loader = UnstructuredFileLoader("./files/์šด์ˆ˜ ์ข‹์€ ๋‚ .txt")
docs = loader.load_and_split(text_splitter=splitter)

CharacterTextSplitter

๋ฌธ์„œ๋ฅผ ๋ถ„ํ• ํ•  ๋•Œ ์‚ฌ์šฉ๋  splitter์„ ์„ ์–ธํ•œ๋‹ค. LangChain์—์„œ ์ œ๊ณตํ•˜๋Š” splitter์˜ ์ข…๋ฅ˜์—๋Š” Recursive, HTML, Markdown ๋“ฑ ์—ฌ๋Ÿฌ๊ฐ€์ง€๊ฐ€ ์žˆ์ง€๋งŒ ์—ฌ๊ธฐ์„œ๋Š” Character๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. CharacterTextSplitter๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ง€์ •ํ•œ ๋ฌธ์ž๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ฌธ์„œ๋ฅผ ๋ถ„ํ• ํ•œ๋‹ค.

ํŒŒ๋ผ๋ฏธํ„ฐ

  • separator: ํ•ด๋‹น ๋ฌธ์ž๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ฌธ์„œ๋ฅผ ๋ถ„ํ• ํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” "\n(์ค„ ๋ฐ”๊ฟˆ)"์„ ๊ธฐ์ค€์œผ๋กœ ๋ฌธ์„œ๋ฅผ ๋ถ„ํ• ํ•œ๋‹ค.
  • chunk_size: ๋ถ„ํ• ๋œ ํ•œ ๋ฌธ์„œ์˜ ์ตœ๋Œ€ ์ฒญํฌ ํฌ๊ธฐ๋ฅผ ์ง€์ •ํ•œ๋‹ค.
  • chunk_overlap: ๋ฌธ์„œ ๋ถ„ํ•  ์‹œ ์•ž๋’ค ๋ฌธ์„œ์˜ 100์ž๋ฅผ ์ค‘๋ณต์œผ๋กœ ์ถ”๊ฐ€ํ•˜์—ฌ ์ƒ์„ฑํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฌธ๋งฅ์ƒ ์ ์ ˆํ•˜์ง€ ์•Š์€ ๋ถ€๋ถ„์—์„œ ๋ฌธ์„œ๊ฐ€ ๋ถ„ํ• ๋˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

UnstructuredFileLoader

ํŒŒ์ผ ๋กœ๋”ฉ์— ์‚ฌ์šฉ๋  Loader๋ฅผ ์„ ์–ธํ•œ๋‹ค. LangChain์€ TextLoader, PyPDFLoader ๋“ฑ ๋‹ค์–‘ํ•œ ํŒŒ์ผ ํ˜•์‹์— ๋งž์ถ˜ Loader๋ฅผ ์ œ๊ณตํ•œ๋‹ค. UnstructuredFileLoader๋Š” text files, powerpoints, html, pdfs, images๋“ฑ ์—ฌ๋Ÿฌ ํ˜•์‹์˜ ํŒŒ์ผ์„ ์ง€์›ํ•˜๊ธฐ์— ํŽธ๋ฆฌํ•˜๋‹ค. ๋ฌธ์„œ๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๊ฒฝ๋กœ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค.

loader.load_and_split()

ํŒŒ์ผ์„ ๋กœ๋”ฉํ•˜๋Š” ๋™์‹œ์— ๋ถ„ํ• ์„ ์ง„ํ–‰ํ•œ๋‹ค. splitter๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌํ•˜๋ฉฐ, ๋ถ„ํ• ๋œ ๋ฌธ์„œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. (return type: list)

Embedding

Embedding์ด๋ž€ ์‚ฌ๋žŒ์ด ์ฝ๋Š” ์ž์—ฐ์–ด๋ฅผ ์ปดํ“จํ„ฐ๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ์ˆซ์ž์˜ ๋‚˜์—ด์ธ vector๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ž‘์—…์„ ์˜๋ฏธํ•œ๋‹ค. ๊ฐ„๋‹จํžˆ ์„ค๋ช…ํ•˜์ž๋ฉด, text์— ์˜๋ฏธ๋ณ„๋กœ ์ ์ ˆํ•œ ์ ์ˆ˜๋ฅผ ๋ถ€์—ฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰๋œ๋‹ค.

Embedding์„ ํ†ตํ•ด ๋ณ€ํ™˜๋œ ๋ฌธ์„œ๋Š” vector store(๋ฒกํ„ฐ ๊ณต๊ฐ„)์— ์ €์žฅ๋œ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ฟผ๋ฆฌ๋ฅผ ์ž…๋ ฅํ•˜๋ฉด Retriever๋Š” ์ฟผ๋ฆฌ์™€ ์—ฐ๊ด€์„ฑ์ด ๋†’์€ ๋ฌธ์„œ๋“ค์„ vector store์—์„œ ์ฐพ์•„์˜ค๊ณ , ์ด ๋ฌธ์„œ๋“ค์„ LLM์— ์ „๋‹ฌํ•  ํ”„๋กฌํ”„ํŠธ์— ํฌํ•จํ•จ์œผ๋กœ์จ ์ •ํ™•๋„๊ฐ€ ๋†’์€ ๋‹ต๋ณ€์„ ๊ธฐ๋Œ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

embeddings = OpenAIEmbeddings()
cache_dir = LocalFileStore("./.cache/practice/")
cached_embeddings = CacheBackedEmbeddings.from_bytes_store(embeddings, cache_dir)

OpenAIEmbeddings

OpenAI๋Š” Embedding ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

CacheBackedEmbeddings

Embedding์€ ๋น„์šฉ์ด ๋ถ€๊ณผ๋˜๋Š” ์„œ๋น„์Šค์ด๋‹ค. ๊ฐ™์€ ๋ฌธ์„œ๋ฅผ ๋งค๋ฒˆ ์ž„๋ฒ ๋”ฉํ•˜๋Š” ๊ฒƒ์€ ํšจ์œจ์ ์ด์ง€ ์•Š๊ธฐ์—, Cache Memory๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ํšจ๊ณผ์ ์ด๋‹ค.

Embedding ๊ฐ์ฒด์™€ ์บ์‹œ๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ๋Š” ์œ„์น˜๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌํ•œ๋‹ค. ์ถ”ํ›„ embedding ๊ฐ์ฒด๊ฐ€ ํ˜ธ์ถœ๋  ์ผ์ด ์žˆ์„ ๋•Œ cached_embeddings๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์ด ๋•Œ ๋งŒ์•ฝ ์ด๋ฏธ ์บ์‹œ๋˜์–ด ์žˆ๋‹ค๋ฉด ์ €์žฅ๋œ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด embedding์„ ์ง„ํ–‰ํ•˜์—ฌ ์บ์‹œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

Vector store & Retriever

vectorstore = FAISS.from_documents(docs, cached_embeddings)
retriever = vectorstore.as_retriever()

LangChain์€ ์—ฌ๋Ÿฌ vector sotre๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ๋กœ์ปฌ์—์„œ ์ง์ ‘ ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•œ ๋ฌด๋ฃŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ FAISS๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋‹ค. ๋น„์Šทํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ Chroma๋„ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

Retriever

Retriever๋ž€ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ Query๋ฅผ ํ•ด์„ํ•˜์—ฌ ๊ทธ์™€ ๊ด€๋ จ์ด ์žˆ๋Š” ๋ฌธ์„œ๋ฅผ ์ฐพ์•„์™€์„œ(retrieve) ๋ฐ˜ํ™˜ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. ์ฝ”๋“œ์—์„œ๋Š” vector store๋ฅผ retriever๋กœ ์‚ฌ์šฉํ•˜์˜€์ง€๋งŒ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ํด๋ผ์šฐ๋“œ ๋“ฑ ์—ฌ๋Ÿฌ ์œ ํ˜•์˜ ์ €์žฅ์†Œ๋ฅผ retriever๋กœ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
(ex: retriever = WikipediaRetriever(top_k_results=5))

Prompt

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            """
            You are a helpful assistant. 
            Answer questions using only the following context. 
            If you don't know the answer just say you don't know, 
            don't make it up:
            \n\n
            {context}
            """,
        ),
        ("human", "{question}"),
    ]
)

LLM์— ์ „๋‹ฌ๋  ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค. LLM์˜ hallucination(ํ™˜๊ฐ) ํ˜„์ƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๋ฌธ๊ตฌ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. (If you don't know the answer just say you don't know, don't make it up)

Chain

Retriever๋กœ๋ถ€ํ„ฐ ๊ฐ€์ ธ์˜จ ๋ถ„ํ•  ๋ฌธ์„œ๋“ค์„ LLM์— ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

Stuff

๊ด€๋ จ๋œ ๋ฌธ์„œ๋“ค์„ ๋ชจ๋‘ prompt์— ์ฑ„์›Œ ๋„ฃ์–ด(stuff) ์ „๋‹ฌํ•œ๋‹ค. ํ”„๋กฌํ”„ํŠธ๊ฐ€ ๊ณผ๋„ํ•˜๊ฒŒ ๊ธธ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

Map reduce

๊ฐ๊ฐ์˜ ๋ฌธ์„œ๋“ค์„ ์š”์•ฝํ•˜๊ณ , ์š”์•ฝ๋œ ๋ฌธ์„œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ตœ์ข… ์š”์•ฝ๋ณธ์„ ๋งŒ๋“ค์–ด๋‚ธ๋‹ค. ํ† ํฐ ์ด์Šˆ(ํ”„๋กฌํ”„ํŠธ๊ฐ€ ์ œํ•œ ํ† ํฐ ์ˆ˜ ์ด์ƒ์œผ๋กœ ๊ธธ์–ด์ง)๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์ง€๋งŒ, ๋ชจ๋“  ๋ฌธ์„œ๋ฅผ ์š”์•ฝํ•˜๊ธฐ์— ์†๋„๊ฐ€ ๋Š๋ฆฌ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

Refine

๋ฌธ์„œ๋“ค์„ ์ˆœํšŒํ•˜๋ฉฐ ์ค‘๊ฐ„ ๋‹ต๋ณ€(Intermediate Answer)์ƒ์„ฑํ•˜๊ณ , ์ด๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉฐ ์ ์  ๋‹ต๋ณ€์„ ์ •์ œ(refine)ํ•œ๋‹ค. ์ตœ์ข…์ ์œผ๋กœ ์–‘์งˆ์˜ ๋‹ต๋ณ€์ด ๋งŒ๋“ค์–ด์ง€๊ฒŒ ๋œ๋‹ค. ์†๋„๊ฐ€ ๋Š๋ฆฌ๊ณ  ๋น„์šฉ์ด ๋น„์‹ธ์ง€๋งŒ ๊ฒฐ๊ณผ๋ฌผ์ด ๋›ฐ์–ด๋‚˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

Map re-rank

๊ฐ๊ฐ ๋ฌธ์„œ์— ๋Œ€ํ•ด ๊ฐ๊ฐ์˜ ๋‹ต๋ณ€์„ ๋งŒ๋“ค์–ด ๋‚ด๊ณ , ์ด์— ์ ์ˆ˜๋ฅผ ๋ถ€์—ฌํ•œ๋‹ค. ๊ฐ€์žฅ ๋†’์€ ์ ์ˆ˜๋ฅผ ๋ฐ›์€ ๋‹ต๋ณ€์„ ์ตœ์ข… ๋‹ต๋ณ€์œผ๋กœ ์„ค์ •ํ•œ๋‹ค. ๋ฌธ์„œ๊ฐ€ ๊ตฌ๋ถ„๋˜์–ด ์žˆ๊ณ  ๋†’์€ ์œ ์‚ฌ์„ฑ์„ ์š”๊ตฌํ•  ๋•Œ(ํ•˜๋‚˜์˜ ๋ฌธ์„œ์—๋งŒ ์›ํ•˜๋Š” ์ •๋ณด๊ฐ€ ์žˆ์„ ๋•Œ) ์œ ์šฉํ•˜๋‹ค.

์—ฌ๊ธฐ์„œ๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๊ตฌ์กฐ์ธ Stuff ๋ฐฉ์‹์„ LCEL๋กœ ๊ตฌํ˜„ํ•ด ๋ณธ๋‹ค.

llm = ChatOpenAI(temperature=0.1)
chain = (
    {
        "context": retriever,
        "question": RunnablePassthrough(),
    }
    | prompt
    | llm
)
result = chain.invoke("๊น€์ฒจ์ง€๋Š” ํ•™์ƒ์„ ์–ด๋””๋กœ ๋ฐ๋ ค๋‹ค ์ฃผ์—ˆ๋‚˜?")
print(result)
  • chain.invoke()๋ฅผ ํ†ตํ•ด ์ „๋‹ฌ๋œ ์ฟผ๋ฆฌ๋Š” retriever์— ์ „๋‹ฌ๋˜๊ณ , ๋ฐ˜ํ™˜๋œ ๋ฌธ์„œ๋ฅผ {context}์— ๋„ฃ๋Š”๋‹ค.
  • RunnablePassthrough()๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž์˜ ์งˆ๋ฌธ ๋˜ํ•œ {question}์— ๊ทธ๋Œ€๋กœ ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค.
  • ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ๋”•์…”๋„ˆ๋ฆฌ ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ํ”„๋กฌํ”„ํŠธ๊ฐ€ ์™„์„ฑ๋˜๊ณ , LLM์— ์ „๋‹ฌ๋˜์–ด ์ตœ์ข… ๋‹ต๋ณ€์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

์‹คํ–‰ ๊ฒฐ๊ณผ

๊น€์ฒจ์ง€๋Š” ํ•™์ƒ์„ ์–ด๋””๋กœ ๋ฐ๋ ค๋‹ค ์ฃผ์—ˆ๋‚˜?
-> ๊น€์ฒจ์ง€๋Š” ํ•™์ƒ์„ ๋‚จ๋Œ€๋ฌธ ์ •๊ฑฐ์žฅ๊นŒ์ง€ ๋ฐ๋ ค๋‹ค ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

๊น€์ฒจ์ง€๋Š” ํ•™์ƒ์„ ์–ด๋””๋กœ ๋ฐ๋ ค๋‹ค ์ฃผ์—ˆ๋‚˜? ํ•ด๋‹น ๋ถ€๋ถ„์˜ ์›๋ฌธ๊ณผ ํ•จ๊ป˜ ์ถœ๋ ฅํ•˜์‹œ์˜ค. 
-> ๊น€์ฒจ์ง€๋Š” ํ•™์ƒ์„ ๋‚จ๋Œ€๋ฌธ ์ •๊ฑฐ์žฅ๊นŒ์ง€ ๋ฐ๋ ค๋‹ค ์ฃผ์—ˆ๋‹ค. 
   ํ•ด๋‹น ๋ถ€๋ถ„์˜ ์›๋ฌธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค:\n\n"๋‚จ๋Œ€๋ฌธ ์ •๊ฑฐ์žฅ๊นŒ์ง€ ์–ผ๋งˆ์š”?

RetrievalQA

off-the-shelf chain ํด๋ž˜์Šค์ธ RetrievalQA๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๊ฐ„๋‹จํ•˜๊ฒŒ Chain์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์›๋ฆฌ๊ฐ€ ๋ชจํ˜ธํ•˜๊ณ  ์ปค์Šคํ…€ํ•˜๊ธฐ ์–ด๋ ต๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค. ๋˜ํ•œ ์ด๋Š” legacy๋กœ ๊ณต์‹์ ์œผ๋กœ LCEL๋กœ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ์‹์ด ๊ถŒ์žฅ๋œ๋‹ค.

chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="map_rerank",
    retriever=retriever,
)

result = chain.run("๊น€์ฒจ์ง€๋Š” ํ•™์ƒ์„ ์–ด๋””๋กœ ๋ฐ๋ ค๋‹ค ์ฃผ์—ˆ๋‚˜?")
print(result)

chain_type์— ์›ํ•˜๋Š” ๋ฐฉ์‹์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ธฐํƒ€

  • ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ์šด์ˆ˜ ์ข‹์€ ๋‚ .txt ๋ฌธ์„œ๋Š” ์ด 41๊ฐœ์˜ ๋ฌธ์„œ๋กœ ๋ถ„ํ• ๋˜๋ฉฐ, 4๊ฐœ์˜ ๋ฌธ์„œ๊ฐ€ LLM์— ์ „๋‹ฌ๋œ๋‹ค.
  • ๋ฌธ์„œ์™€ ์ฟผ๋ฆฌ, ํ”„๋กฌํ”„ํŠธ ์ง€์‹œ๋ฌธ ๋“ฑ์€ ๋ชจ๋‘ ์˜์–ด๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ํ•œ๊ตญ์–ด๋Š” ์ •ํ™•๋„๊ฐ€ ๋–จ์–ด์ง€๋Š” ๊ฒƒ ๊ฐ™๋‹ค.
  • embedding๊ณผ retriever์˜ ์›๋ฆฌ๋Š” ์ข€ ๋” ๊ณต๋ถ€๊ฐ€ ํ•„์š”ํ•  ๋“ฏ ํ•˜๋‹ค..

์ถœ์ฒ˜ ๋ฐ ์ฐธ๊ณ ์ž๋ฃŒ

https://python.langchain.com/docs
https://github.com/nomadcoders/fullstack-gpt
https://www.youtube.com/watch?v=tQUtBR3K1TI

profile
์•ˆ๋…•ํ•˜์„ธ์š”. ๋งŒ๋‚˜์„œ ๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค.

1๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2024๋…„ 2์›” 3์ผ
๋‹ต๊ธ€ ๋‹ฌ๊ธฐ

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด