File size: 2,728 Bytes
cfb9fa3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# rag.py
from transformers import pipeline
from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma
from langchain_huggingface import HuggingFaceEmbeddings

from langchain_core.runnables import RunnableLambda, RunnablePassthrough

DB_PATH = "chroma_db"

chatbot = None
vectorstore = None

def get_chatbot():
    global chatbot

    if chatbot is None:
        chatbot = pipeline(
            task="text-generation",
            model="Qwen/Qwen2.5-0.5B-Instruct",
            return_full_text=False,
        )
    
    return chatbot

def get_vectorstore():
    global vectorstore
    
    if vectorstore is None:
        embeddings = HuggingFaceEmbeddings(
            model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
        )
    
        vectorstore = Chroma(persist_directory=DB_PATH, embedding_function=embeddings)

    return vectorstore

def get_answer_rag(question: str) -> tuple[str, str]:
    vectorstore = get_vectorstore()
    retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
    chatbot = get_chatbot()

    def format_docs(docs):
        return "\n\n".join(
            doc.page_content for doc in docs
        )
        
    def generate(inputs):
        prompt = [
            {
                "role": "system",
                "content": """
                    ์‚ฌ์šฉ์ž์˜ ์งˆ๋ฌธ์— ๋Œ€ํ•ด ํ•œ๊ตญ์–ด๋กœ ํ•œ ๋ฌธ์žฅ์œผ๋กœ ๋‹ต๋ณ€ํ•˜์„ธ์š”.
                    ๋ฐ˜๋“œ์‹œ ์ œ๊ณต๋œ ๋ฌธ์„œ ๋‚ด์šฉ๋งŒ ๊ทผ๊ฑฐ๋กœ ๋‹ต๋ณ€ํ•˜์„ธ์š”.
                    ์ œ๊ณต๋œ ๋ฌธ์„œ ๋‚ด์šฉ์—์„œ ๋‹ต์„ ์ฐพ์„ ์ˆ˜ ์—†์œผ๋ฉด, '๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค'๋ผ๊ณ  ๋‹ต๋ณ€ํ•˜์„ธ์š”.
                """
            },
            {
                "role": "user",
                "content": f"[๋ฌธ์„œ ๋‚ด์šฉ] {inputs['context']} [์งˆ๋ฌธ] {inputs['question']}"
            },
        ]

        result = chatbot(prompt, max_new_tokens=100, do_sample=False)
        return str(result[0]['generated_text'])
            
    rag_chain = (
        {
            "context": retriever | RunnableLambda(format_docs),
            "question": RunnablePassthrough(),
        }
        | RunnablePassthrough.assign(answer=RunnableLambda(generate))
    )
    
    result = rag_chain.invoke(question)
    return str(result["answer"]), str(result["context"])

def add_pdf_to_vectorstore(pdf_path: str):
    vectorstore = get_vectorstore()

    loader = PyPDFLoader(pdf_path)
    documents = loader.load()
    splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=100)
    split_docs = splitter.split_documents(documents)
    
    vectorstore.add_documents(split_docs)
    
    return len(split_docs)