File size: 3,297 Bytes
ce8d30d
9727059
ce8d30d
 
63b5b71
 
 
 
9727059
63b5b71
9727059
63b5b71
 
9185bb7
63b5b71
 
 
 
9727059
63b5b71
 
 
 
9185bb7
63b5b71
9185bb7
63b5b71
 
 
 
9185bb7
ce8d30d
63b5b71
 
 
 
ce8d30d
63b5b71
 
 
 
ce8d30d
63b5b71
9185bb7
63b5b71
 
 
 
 
 
69b6673
9185bb7
63b5b71
ce8d30d
69b6673
9727059
63b5b71
 
69b6673
9727059
63b5b71
 
9727059
63b5b71
 
 
9727059
63b5b71
9727059
63b5b71
ce8d30d
63b5b71
 
69b6673
63b5b71
 
 
ce8d30d
63b5b71
 
ce8d30d
63b5b71
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
import os
import gradio as gr
from langchain.chains import ConversationalRetrievalChain
from langchain.text_splitter import CharacterTextSplitter
from langchain.document_loaders import PyPDFLoader
from langchain.vectorstores import Chroma
from langchain.chat_models import ChatOpenAI
from langchain.embeddings.openai import OpenAIEmbeddings

vectordb = None

# 處理 PDF ζ–‡δ»ΆδΈ¦εˆε§‹εŒ–ε‘ι‡ζ•Έζ“šεΊ«
def load_and_process_pdf(pdf_file, api_key):
    try:
        loader = PyPDFLoader(pdf_file.name)
        documents = loader.load()
        text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
        docs = text_splitter.split_documents(documents)

        # ε‚³ιž API Key
        embeddings = OpenAIEmbeddings(openai_api_key=api_key)
        vectordb = Chroma.from_documents(docs, embedding=embeddings, persist_directory="./data")
        return vectordb
    except Exception as e:
        return f"η„‘ζ³•θ™•η†ζ–‡δ»ΆοΌŒιŒ―θͺ€: {str(e)}"

# ζŸ₯詒處理函數
def handle_query(api_key, user_message, pdf_vectordb, chat_history):
    if not pdf_vectordb or isinstance(pdf_vectordb, str):
        return chat_history, "θ«‹ε…ˆδΈŠε‚³ζœ‰ζ•ˆηš„ PDF 文仢。"

    try:
        retriever = pdf_vectordb.as_retriever(search_kwargs={"k": 5})
        pdf_qa_chain = ConversationalRetrievalChain.from_llm(
            ChatOpenAI(temperature=0.7, model_name="gpt-4", openai_api_key=api_key),
            retriever=retriever
        )
        result = pdf_qa_chain({"question": user_message, "chat_history": chat_history})
        answer = result.get("answer", "ζŠ±ζ­‰οΌŒζˆ‘η„‘ζ³•ζδΎ›η­”ζ‘ˆγ€‚")
        chat_history.append((user_message, answer))
        return chat_history, answer
    except Exception as e:
        return chat_history, f"ε‡ΊηΎιŒ―θͺ€: {str(e)}"

# η•Άη”¨ζˆΆδΈŠε‚³ PDF 時處理
def process_pdf_upload(api_key, pdf_file):
    global vectordb
    vectordb = load_and_process_pdf(pdf_file, api_key)
    if isinstance(vectordb, str):
        return vectordb
    return "ι£Ÿθ­œε·²ζˆεŠŸθΌ‰ε…₯οΌθ«‹ι–‹ε§‹ι»žθœγ€‚"

# 主程式 - Gradio 介青
with gr.Blocks() as demo:
    gr.Markdown("## πŸ“˜ εœ‹ιš›ε€§ε»šζ•™δ½ εšθœ ")

    with gr.Row():
        api_key = gr.Textbox(label="πŸ”‘ θ«‹θΌΈε…₯ζ‚¨ηš„ OpenAI API Key", type="password")
        pdf_file = gr.File(label="πŸ“‚ δΈŠε‚³ PDF 食譜", file_types=[".pdf"])

    chatbot = gr.Chatbot(label="πŸ’¬ θŠε€©ε€")
    state = gr.State([])

    with gr.Row():
        user_input = gr.Textbox(show_label=False, placeholder="θ«‹θΌΈε…₯ε•ι‘Œ...", lines=2)
        send_btn = gr.Button("ζδΊ€ε•ι‘Œ")

    response = gr.Textbox(label="πŸ“’ ε›žζ‡‰", interactive=False, lines=4)

    pdf_file.change(process_pdf_upload, inputs=[api_key, pdf_file], outputs=response)

    def handle_user_input(api_key, user_message, chat_history):
        if not vectordb:
            return chat_history, "θ«‹ε…ˆδΈŠε‚³ PDF ι£Ÿθ­œγ€‚"
        if user_message.strip().lower() == "謝謝":
            return chat_history, "加油~~~"
        return handle_query(api_key, user_message, vectordb, chat_history)

    send_btn.click(handle_user_input, inputs=[api_key, user_input, state], outputs=[chatbot, response])
    user_input.submit(handle_user_input, inputs=[api_key, user_input, state], outputs=[chatbot, response])

demo.launch()