๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŒŸ AI & ML Tech/LLM

[LLM] RAG ์„ค๋ช… ๋ฐ ์‹ค์Šต | OpenAI ๋ชจ๋ธ๊ณผ ChromaDB๋ฅผ ์ด์šฉํ•œ RAG ์‹ค์Šต

by ๋ญ…์ฆค 2024. 9. 16.
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š”! ๋ญ…์ฆค์ž…๋‹ˆ๋‹ค.

 

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” OpenAI์˜ Chat API์™€ ChromaDB๋ฅผ ํ™œ์šฉํ•œ RAG(Retrieval-Augmented Generation)์— ๋Œ€ํ•ด ์„ค๋ช…๋“œ๋ฆด๊ฒŒ์š”. ์‹ค์Šต ์ฝ”๋“œ๋„ ์žˆ๋‹ต๋‹ˆ๋‹ค ๐Ÿ˜Š

 

RAG๋Š” ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ์™€ ์–ธ์–ด ๋ชจ๋ธ์„ ๊ฒฐํ•ฉํ•ด ์ข€ ๋” ์ •ํ™•ํ•˜๊ณ  ๋งฅ๋ฝ์— ๋งž๋Š” ๋‹ต๋ณ€์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ผ์š” ๐Ÿค—


๐Ÿ“Œ RAG (Retrieval-Augmented Generation)

RAG๋Š” Retrieval-Augmented Generation์˜ ์•ฝ์ž๋กœ, ์ •๋ณด ๊ฒ€์ƒ‰๊ณผ ์ƒ์„ฑํ˜• AI๋ฅผ ๊ฒฐํ•ฉํ•œ ๋ฐฉ๋ฒ•์ด์—์š”. GPT์™€ ๊ฐ™์€ ์–ธ์–ด ๋ชจ๋ธ์€ ์ž์ฒด์ ์œผ๋กœ ๋‹ค์–‘ํ•œ ์ง€์‹์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ, ์ตœ์‹  ์ •๋ณด๋‚˜ ํŠน์ • ๋„๋ฉ”์ธ์— ๋Œ€ํ•œ ์ƒ์„ธํ•œ ๋‚ด์šฉ์„ ์•Œ์ง€ ๋ชปํ•  ๋•Œ๋„ ์žˆ์–ด์š”. ์ด๋Ÿฐ ๊ฒฝ์šฐ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด RAG๋ฅผ ์‚ฌ์šฉํ•ด์š”.

  • Retrieval: ์ฃผ์–ด์ง„ ์งˆ๋ฌธ์— ๋Œ€ํ•ด ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๊ด€๋ จ ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ณผ์ •์ด์—์š”. ์ด ๋‹จ๊ณ„์—์„œ๋Š” ๊ฒ€์ƒ‰๋œ ๋ฌธ์„œ๋‚˜ ํ…์ŠคํŠธ ์กฐ๊ฐ์ด ๋‹ต๋ณ€์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ผ์š”.
  • Augmented Generation: ๊ฒ€์ƒ‰์„ ํ†ตํ•ด ์–ป์€ ์ •๋ณด๋ฅผ ์–ธ์–ด ๋ชจ๋ธ์— ์ถ”๊ฐ€ํ•˜์—ฌ ๋” ์ •ํ™•ํ•˜๊ณ  ๋งฅ๋ฝ์— ๋งž๋Š” ๋‹ต๋ณ€์„ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์ด์—์š”.

 

โœ… ์™œ RAG๋ฅผ ์‚ฌ์šฉํ•˜๋‚˜์š”?

  1. ์ตœ์‹  ์ •๋ณด ์ œ๊ณต: ์–ธ์–ด ๋ชจ๋ธ ์ž์ฒด๊ฐ€ ๊ฐ–๊ณ  ์žˆ๋Š” ์ง€์‹์€ ํ›ˆ๋ จ ์‹œ์  ์ดํ›„์˜ ์ •๋ณด๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ์ตœ์‹  ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜์—ฌ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.
  2. ์ •ํ™•ํ•œ ๋„๋ฉ”์ธ ์ง€์‹: ํŠน์ • ๋ถ„์•ผ๋‚˜ ์ „๋ฌธ ์ง€์‹์„ ํฌํ•จํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ฐธ์กฐํ•ด ๋ณด๋‹ค ์ •ํ™•ํ•œ ๋‹ต๋ณ€์„ ์–ป์„ ์ˆ˜ ์žˆ์–ด์š”.
  3. ์ง€์‹ ํ™•์žฅ: ์–ธ์–ด ๋ชจ๋ธ์ด ์ง์ ‘ ํ›ˆ๋ จ๋˜์ง€ ์•Š์€ ๋‚ด์šฉ๋„ ์™ธ๋ถ€ ๋ฌธ์„œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์ฐธ์กฐํ•˜์—ฌ ๋‹ต๋ณ€ํ•  ์ˆ˜ ์žˆ์–ด์š”.

 

โœ… RAG์˜ ์ „์ฒด์ ์ธ ํ๋ฆ„

  1. ๋ฌธ์„œ ์ค€๋น„: ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์ •๋ณด๊ฐ€ ๋‹ด๊ธด ๋ฌธ์„œ๋ฅผ ์ค€๋น„ํ•ด์š”. ์ด ๋ฌธ์„œ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋  ์ž๋ฃŒ๊ฐ€ ๋ผ์š”.
  2. ๋ฌธ์„œ ์ž„๋ฒ ๋”ฉ: ChromaDB๋ฅผ ์‚ฌ์šฉํ•ด ์ค€๋น„๋œ ๋ฌธ์„œ๋ฅผ ๋ฒกํ„ฐ ์ž„๋ฒ ๋”ฉํ•˜์—ฌ ์ €์žฅํ•ด์š”.
  3. ์งˆ๋ฌธ ์ž„๋ฒ ๋”ฉ ๋ฐ ๊ฒ€์ƒ‰: ์‚ฌ์šฉ์ž๊ฐ€ ์งˆ๋ฌธ์„ ์ž…๋ ฅํ•˜๋ฉด, ํ•ด๋‹น ์งˆ๋ฌธ๋„ ๋ฒกํ„ฐ๋กœ ์ž„๋ฒ ๋”ฉ๋˜์–ด ChromaDB์— ์ €์žฅ๋œ ๋ฌธ์„œ๋“ค๊ณผ ์œ ์‚ฌ๋„๋ฅผ ๋น„๊ตํ•ด์š”.
  4. ๋ฌธ์„œ ๊ฒฐํ•ฉ ๋ฐ ๋‹ต๋ณ€ ์ƒ์„ฑ: ๊ฒ€์ƒ‰๋œ ๋ฌธ์„œ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ์ž์˜ ์งˆ๋ฌธ์„ ์–ธ์–ด ๋ชจ๋ธ์— ์ž…๋ ฅํ•ด ๋‹ต๋ณ€์„ ์ƒ์„ฑํ•ด์š”. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ณด๋‹ค ์ •ํ™•ํ•œ ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ต๋ณ€์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์–ด์š”.

๐Ÿ“Œ ChromaDB์˜ ์—ญํ• 

ChromaDB๋Š” RAG๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ ์ค‘์š”ํ•œ ์š”์†Œ์ธ ๊ฒ€์ƒ‰ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ญํ• ์„ ํ•ด์š”. ์‰ฝ๊ฒŒ ๋งํ•ด, ์‚ฌ์šฉ์ž๊ฐ€ ์งˆ๋ฌธํ•  ๋•Œ ์ฐธ๊ณ ํ•  ์ˆ˜ ์žˆ๋Š” ์ง€์‹ ์ €์žฅ์†Œ์ธ ๊ฑฐ์ฃ ! ๐Ÿ—‚๏ธ

  • ๋ฌธ์„œ ์ž„๋ฒ ๋”ฉ: ChromaDB๋Š” ๋ฌธ์„œ๋ฅผ ๋ฒกํ„ฐ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ์ €์žฅํ•ด์š”. ์ด ๋ฒกํ„ฐ๋Š” ๋ฌธ์„œ์˜ ์˜๋ฏธ๋ฅผ ๋‹ด๊ณ  ์žˆ์–ด ๊ฒ€์ƒ‰ ๋‹จ๊ณ„์—์„œ ํ™œ์šฉ๋ผ์š”. ๋ฌธ์„œ ์ž„๋ฒ ๋”ฉ์€ OpenAI์˜ ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ์ด๋‚˜ ๋‹ค๋ฅธ ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ด ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”.
  • ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰: ์‚ฌ์šฉ์ž๊ฐ€ ์งˆ๋ฌธ์„ ํ•  ๋•Œ, ์งˆ๋ฌธ์— ๋Œ€ํ•œ ์ž„๋ฒ ๋”ฉ์„ ์ƒ์„ฑํ•˜๊ณ  ์ €์žฅ๋œ ๋ฌธ์„œ ์ž„๋ฒ ๋”ฉ๊ณผ ๋น„๊ตํ•˜์—ฌ ๊ฐ€์žฅ ๊ด€๋ จ์„ฑ ๋†’์€ ๋ฌธ์„œ๋ฅผ ์ฐพ์•„์š”.
  • ์ž„์‹œ ๋ฐ ์˜๊ตฌ ์ €์žฅ: ChromaDB๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜๋„ ์žˆ๊ณ , ์˜๊ตฌ์ ์œผ๋กœ ๋ฌธ์„œ๋ฅผ ์ €์žฅํ•ด๋‘˜ ์ˆ˜๋„ ์žˆ์–ด์š”.

์ž„๋ฒ ๋”ฉ์€ ํ…์ŠคํŠธ๋ฅผ ์ˆ˜์น˜ ๋ฒกํ„ฐ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ž‘์—…์„ ์˜๋ฏธํ•ด์š”.

ChromaDB๋Š” ๊ฐ ๋ฌธ์„œ๋ฅผ ์ž„๋ฒ ๋”ฉํ•œ ํ›„ ์ €์žฅํ•˜๊ณ , ์‚ฌ์šฉ์ž์˜ ์งˆ๋ฌธ์„ ์ž„๋ฒ ๋”ฉํ•˜์—ฌ ๊ทธ ๋ฒกํ„ฐ์™€ ๊ฐ€์žฅ ์œ ์‚ฌํ•œ ๋ฌธ์„œ๋ฅผ ์ฐพ์•„๋‚ด์š”. ์ด ๊ณผ์ •์ด ๋ฌธ์„œ ๊ฒ€์ƒ‰ ๋‹จ๊ณ„์—์„œ ํ•ต์‹ฌ ์—ญํ• ์„ ํ•ด์š”. ๐Ÿ’ก


 

๐Ÿ“Œ RAG ์ฝ”๋“œ ์‹ค์Šต

์ž! ์ด์ œ ์‹ค์Šต์ธ๋ฐ์š”! ์ด๋ฒˆ ์‹ค์Šต์€ OpenAI์˜ ์–ธ์–ด ๋ชจ๋ธ๊ณผ ChromaDB๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ„๋‹จํ•œ RAG ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์ฐธ์กฐ ๋ฐ์ดํ„ฐ๋Š” ์›น ํŽ˜์ด์ง€๋ฅผ html๋กœ ์ €์žฅํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ–ˆ์œผ๋‹ˆ, ์—ฌ๋Ÿฌ๋ถ„์ด ์ฐธ์กฐ ๋ฐ์ดํ„ฐ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ์›นํŽ˜์ด์ง€๋ฅผ html ํŒŒ์ผ๋กœ ์ €์žฅ๋ฉด ํ•ด๋‘๋ฉด ๋ฐ”๋กœ ์‹ค์Šตํ•ด ๋ณผ ์ˆ˜ ์žˆ์–ด์š”!

 

 

LLM-Tutorials/OpenAI/OpenAI_RAG_ChatAPI.ipynb at main · mov-z/LLM-Tutorials

๋‹ค์–‘ํ•œ LLM ํŠœํ† ๋ฆฌ์–ผ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. . Contribute to mov-z/LLM-Tutorials development by creating an account on GitHub.

github.com

 

 

์•„๋ž˜์—์„œ ์„ค๋ช…ํ•˜๋Š” ์ฝ”๋“œ๋Š” ์ค‘์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์„ค๋ช…ํ•˜๋‹ˆ, ์‹ค์Šต ์ „์ฒด ์ฝ”๋“œ๋Š” ์œ„ Colab ์„ ์ฐธ๊ณ  ๋ถ€ํƒ๋“œ๋ ค์š” !

 

โœ… ์ฐธ์กฐ ๋ฐ์ดํ„ฐ HTML ํŒŒ์ผ๋กœ ์ €์žฅํ•˜๊ธฐ

 

  • RAG ์ฐธ์กฐ ๋ฐ์ดํ„ฐ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์€ ์›นํŽ˜์ด์ง€์— ๋“ค์–ด๊ฐ€ ํŽ˜์ด์ง€๋ฅผ HTML ํŒŒ์ผ๋กœ ์ €์žฅํ•ด ๋‘๊ณ ,
  • ๊ตฌ๊ธ€ ๋“œ๋ผ์ด๋ธŒ์— ์—…๋กœ๋“œํ•ด๋‘๋ฉด ์‹ค์Šต์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

โœ… ํ•„์š” ํ•จ์ˆ˜ ์„ ์–ธ 

# HTML ํŒŒ์ผ์—์„œ ํ…์ŠคํŠธ ์ถ”์ถœ ํ•จ์ˆ˜
def extract_text_from_html(html_path):
    with open(html_path, 'r', encoding='utf-8') as file:
        soup = BeautifulSoup(file, 'html.parser')

        # ๋ชจ๋“  ํ…์ŠคํŠธ๋ฅผ ์ถ”์ถœํ•˜๋ฉฐ, ํ•„์š”์— ๋”ฐ๋ผ ํŠน์ • ํƒœ๊ทธ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Œ
        text = ' '.join(soup.stripped_strings)
    return text

# ํ…์ŠคํŠธ๋ฅผ ๊ธธ์ด์— ๋”ฐ๋ผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ถ„ํ• ํ•˜๋Š” ํ•จ์ˆ˜
def smart_chunk_splitter(text, max_chunk_size=500):
    sentences = text.split('. ')
    chunks = []
    current_chunk = ""

    for sentence in sentences:
        if len(current_chunk) + len(sentence) + 1 <= max_chunk_size:
            current_chunk += sentence + '. '
        else:
            chunks.append(current_chunk.strip())
            current_chunk = sentence + '. '

    if current_chunk:  # ๋‚จ์•„ ์žˆ๋Š” ํ…์ŠคํŠธ ์ถ”๊ฐ€
        chunks.append(current_chunk.strip())

    return chunks

# ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ ํ•จ์ˆ˜
def create_chat_prompt(system_prompt, user_query, context_documents):
    # context_documents๊ฐ€ ์ค‘์ฒฉ ๋ฆฌ์ŠคํŠธ์ผ ๊ฒฝ์šฐ ํ‰ํƒ„ํ™”
    if isinstance(context_documents[0], list):
        context_documents = [item for sublist in context_documents for item in sublist]

    return [
        {'role': 'system', 'content': system_prompt},
        {'role': 'user', 'content': f"""
            Context:
            {" ".join(context_documents)}

            Context๋ฅผ ์ฐธ์กฐํ•ด์„œ ์•„๋ž˜ ์งˆ๋ฌธ์— ๋‹ตํ•ด์ฃผ์„ธ์š”.

            Question:
            {user_query}

            Answer:
        """}
    ]

# OpenAI API๋ฅผ ํ†ตํ•œ ์‘๋‹ต ์ƒ์„ฑ ํ•จ์ˆ˜
def generate_response(system_prompt, user_query, context_documents):
    response = client.chat.completions.create(
        model=GPT_MODEL,
        messages=create_chat_prompt(system_prompt=system_prompt, user_query=user_query, context_documents=context_documents),
        max_tokens=1500  # ํ•„์š”ํ•œ ๋งŒํผ ํ† ํฐ ์ˆ˜ ์กฐ์ •
    )
    return response.choices[0].message.content

# RAG ๊ธฐ๋ฐ˜ ์‘๋‹ต ์ƒ์„ฑ ํ•จ์ˆ˜
def chat_with_rag(system_prompt, user_query):
    query_result = corpus_collection.query(query_texts=[user_query], n_results=8)
    print(query_result['documents'])
    response = generate_response(system_prompt, user_query, query_result['documents'])
    return response
  • extract_text_from_html : HTML ํŒŒ์ผ์—์„œ ํ…์ŠคํŠธ๋ฅผ ์ถ”์ถœ
    • ์‹ค์Šต์—์„œ๋Š” RAG ์ฐธ์กฐ ๋ฐ์ดํ„ฐ๋ฅผ HTML ํŒŒ์ผ์—์„œ ํ…์ŠคํŠธ๋ฅผ ์ถ”์ถœํ•ด์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • PDF ํŒŒ์ผ์„ ์ฝ๊ฑฐ๋‚˜ ์ง์ ‘ ํ…์ŠคํŠธ๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ๊ณ ๋ คํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • smart_chunk_splitter : ํ…์ŠคํŠธ ๊ธธ์ด์— ๋”ฐ๋ผ ๋ถ„ํ• ํ•˜๋Š” ํ•จ์ˆ˜
    • ์‹ค์Šต์—์„œ๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ…์ŠคํŠธ์˜ ๊ธธ์ด์— ๋”ฐ๋ผ chunk๋ฅผ ๋ถ„ํ• ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ์–ด์š”.
    • ์‹ค์ œ๋กœ๋Š” ์กฐ๊ธˆ ๋” ์Šค๋งˆํŠธํ•œ ๋ฐฉ๋ฒ•๋“ค์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
  • create_chat_prompt : ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ ํ•จ์ˆ˜
  • generate_response : OpenAI API ์‘๋‹ต ์ƒ์„ฑ
  • chat_with_rag : RAG ๊ธฐ๋ฐ˜ ์‘๋‹ต ์ƒ์„ฑ ํ•จ์ˆ˜

 

โœ… ๋ชจ๋ธ ์„ ์–ธ

# models
EMBEDDING_MODEL = "text-embedding-3-small"
GPT_MODEL = "gpt-4o-mini"

# ChromaDB ์ž„๋ฒ ๋”ฉ ํ•จ์ˆ˜ ์ดˆ๊ธฐํ™”
embedding_function = OpenAIEmbeddingFunction(
    api_key=os.getenv("OPENAI_API_KEY"),
    model_name=EMBEDDING_MODEL
)

client = OpenAI()
  • RAG ๊ฒ€์ƒ‰์— ํ™œ์šฉํ•  ํ…์ŠคํŠธ ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ๊ณผ ์‚ฌ์šฉํ•  LLM ์„ ์„ ์–ธ
  • ChromaDB์˜ ์ž„๋ฒ ๋”ฉ ํ•จ์ˆ˜ ์ดˆ๊ธฐํ™” ์ง„ํ–‰

 

โœ… RAG ์ฐธ์กฐ ๋ฐ์ดํ„ฐ ์„ธํŒ…

# HTML ํŒŒ์ผ ๊ฒฝ๋กœ
html_path = "/content/drive/MyDrive/แ„แ…ฉแ„ƒแ…ณ แ„‹แ…จแ„Œแ…ฆ/LLM/ref_docs/KBO_แ„…แ…ตแ„€แ…ณ.html"

# ํ…์ŠคํŠธ ์ถ”์ถœ ๋ฐ ๋ถ„ํ• 
text = extract_text_from_html(html_path)
chunks = smart_chunk_splitter(text, max_chunk_size=2000)

# ๋ถ„ํ• ๋œ ํ…์ŠคํŠธ ์ถœ๋ ฅ
for i, chunk in enumerate(chunks):
    print(f"Chunk {i+1}:\n{chunk}\n")
    
# ChromaDB ํด๋ผ์ด์–ธํŠธ ๋ฐ ์ปฌ๋ ‰์…˜ ์ดˆ๊ธฐํ™”
chroma_client = chromadb.Client()  # ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฐ˜ ์ƒํƒœ๋กœ ์‹คํ–‰
corpus_collection = chroma_client.create_collection(
    name='KBO',
    embedding_function=embedding_function
)

# ๊ฐ ํ…์ŠคํŠธ ์ฒญํฌ๋ฅผ ์ปฌ๋ ‰์…˜์— ์ถ”๊ฐ€
for i, chunk in enumerate(chunks):
    corpus_collection.add(ids=[str(i)], documents=[chunk])

 

- HTML ํŒŒ์ผ์—์„œ ํ…์ŠคํŠธ ์ถ”์ถœํ•˜๊ธฐ

  • ์›น ํŽ˜์ด์ง€์—์„œ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด HTML ํŒŒ์ผ์—์„œ ํ…์ŠคํŠธ๋ฅผ ์ถ”์ถœ
  • ์ด๋•Œ BeautifulSoup ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด HTML ๊ตฌ์กฐ๋ฅผ ํŒŒ์‹ฑํ•˜๊ณ , ํ…์ŠคํŠธ๋ฅผ ์ถ”์ถœํ•ด์š”.

 

- ํ…์ŠคํŠธ ๋ถ„ํ•  (Chunking)

  • OpenAI ๋ชจ๋ธ์€ ์ž…๋ ฅ ๊ธธ์ด์— ์ œํ•œ์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ธด ํ…์ŠคํŠธ๋ฅผ ์ ์ ˆํ•˜๊ฒŒ ๋ถ„ํ• ํ•˜๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•ด์š”.
  • smart_chunk_splitter ํ•จ์ˆ˜๋Š” ๋ฌธ์žฅ์„ ๊ธฐ์ค€์œผ๋กœ ํ…์ŠคํŠธ๋ฅผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋‚˜๋ˆ„๋Š” ์—ญํ• ์„ ํ•ด์š”.

 

- ChromaDB ์„ค์ • ๋ฐ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€

  • ChromaDB๋Š” RAG ๊ตฌํ˜„์—์„œ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ, ๋ฌธ์„œ ์ž„๋ฒ ๋”ฉ์„ ์ €์žฅํ•˜๊ณ  ๊ฒ€์ƒ‰ํ•ด์š”.
  • ์—ฌ๊ธฐ์„œ๋Š” OpenAI์˜ ์ž„๋ฒ ๋”ฉ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ด์š”.
  • ChromaDB ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฐ˜ ์ƒํƒœ๋กœ ์‹คํ–‰ํ•˜๊ณ , ์ž„๋ฒ ๋”ฉ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์ปฌ๋ ‰์…˜์„ ์ƒ์„ฑํ•ด์š”.
  • ์•ž์„œ ์ถ”์ถœํ•˜๊ณ  ๋ถ„ํ• ํ•œ ํ…์ŠคํŠธ๋ฅผ ChromaDB์— ์ถ”๊ฐ€ํ•ด์š”.

 

โœ… RAG ๊ธฐ๋ฐ˜ ์‘๋‹ต ์ƒ์„ฑ

# system prompt ์„ค์ •
system_prompt = "KBO ๊ด€๋ จ ์งˆ๋ฌธ์— ์‚ฌ์‹ค ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ต๋ณ€ํ•˜๋Š” ์–ด์‹œ์Šคํ„ดํŠธ์ž…๋‹ˆ๋‹ค."

# ์˜ˆ์ œ ์งˆ๋ฌธ์— ๋Œ€ํ•œ RAG ์‘๋‹ต ์ƒ์„ฑ
user_query = "KBO ๊ตฌ๋‹จ๋ณ„ ๋งค์ถœ์— ๋Œ€ํ•ด ๊ฐ„๋žตํ•˜๊ฒŒ ์š”์•ฝํ•ด์ค˜"
response = chat_with_rag(system_prompt, user_query)
print(response)

 

  • ์•ž์„œ ์„ ์–ธํ•œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ์‚ฌ์šฉ์ž ์งˆ๋ฌธ์— ๋งž๋Š” ๋ฌธ์„œ๋ฅผ ChromaDB์—์„œ ๊ฒ€์ƒ‰ํ•˜๊ณ , ํ•ด๋‹น ๋ฌธ์„œ์™€ ํ•จ๊ป˜ OpenAI ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ด ๋‹ต๋ณ€์„ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์ด์—์š”.
  • ์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ChromaDB์—์„œ ๊ด€๋ จ ๋ฌธ์„œ๋ฅผ ์ฐพ๊ณ , ๊ทธ ๋ฌธ์„œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ OpenAI ๋ชจ๋ธ์ด ๋‹ต๋ณ€์„ ์ƒ์„ฑํ•ด์š”. 

 

์‹ค์Šต ๊ฒฐ๊ณผ

 

์‹ค์ œ๋กœ ์‹ค์Šตํ•ด ๋ณด๋ฉด ์œ„์™€ ๊ฐ™์ด ์ฐธ์กฐ ๋ฐ์ดํ„ฐ์— ๊ธฐ๋ฐ˜ํ•œ ์‘๋‹ต์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”!๐Ÿ˜ƒ


 

์ด๋ ‡๊ฒŒ RAG ๊ธฐ๋Šฅ๊ณผ ChromaDB๋ฅผ ์ด์šฉํ•ด OpenAI ๋ชจ๋ธ์˜ ์„ฑ๋Šฅ์„ ํ•œ์ธต ๋” ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด์š”. ์—ฌ๋Ÿฌ๋ถ„๋งŒ์˜ ์ฐธ์กฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด์„œ ํŠน์ • ๋ฐ์ดํ„ฐ์— ํŠนํ™”๋œ ์ฑ—๋ด‡์„ ๋งŒ๋“ค์–ด๋ณด๋ฉด ์–ด๋–จ๊นŒ์š”!?

 

๋” ์ž์„ธํ•œ ๋‚ด์šฉ์ด๋‚˜ ์ถ”๊ฐ€์ ์ธ ์ฝ”๋“œ ์„ค๋ช…์ด ํ•„์š”ํ•˜๋ฉด ์–ธ์ œ๋“ ์ง€ ์•Œ๋ ค์ฃผ์„ธ์š”! ๐Ÿ˜Š

๋ฐ˜์‘ํ˜•