File size: 6,315 Bytes
587c522
ba964ad
dfabed7
d802f7b
e0f269f
d802f7b
e0f269f
07b2dc9
c104d72
e0f269f
 
1c71475
e0f269f
d802f7b
c56e053
62319f5
2bd39e5
97feed9
 
587c522
 
c56e053
62319f5
e4cfcd3
1c71475
c56e053
1c71475
 
 
 
 
d1ab55d
1c71475
 
 
 
 
 
 
 
 
 
 
 
d1ab55d
1c71475
d1ab55d
1c71475
 
 
 
 
 
d1ab55d
1c71475
d1ab55d
 
1c71475
237299a
1c71475
 
 
 
 
c56e053
e4cfcd3
237299a
c56e053
 
5ffcb10
 
c56e053
 
 
237299a
c56e053
 
 
 
5ffcb10
c56e053
d6823a3
1c71475
556fb16
237299a
c56e053
 
 
 
556fb16
237299a
c56e053
 
237299a
c56e053
 
 
 
 
 
 
 
e4cfcd3
237299a
 
 
 
e4cfcd3
 
 
 
 
 
 
 
 
237299a
5ffcb10
 
 
 
587c522
 
 
e4cfcd3
556fb16
 
 
e4cfcd3
237299a
 
1c71475
 
237299a
e4cfcd3
 
556fb16
e4cfcd3
 
 
 
587c522
68d8ac5
237299a
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import os
import subprocess
import gradio as gr
import json
from tqdm import tqdm
from langchain_community.vectorstores import FAISS
from langchain_google_genai import GoogleGenerativeAIEmbeddings
import google.generativeai as genai
# from playwright._impl._driver import get_driver_dir

from helpers import (
    list_docx_files, get_splits, get_json_splits_only, prompt_order, log_message, extract_metadata
)

from file_loader import get_vectorstore
# import asyncio

# key = "AIzaSyDJ4vIKuIBIPNHATLxnoHlagXWbsAz-vRs"
key = os.getenv("GOOGLE_API_KEY")
# Cấu hình API key cho Google GenAI
genai.configure(api_key=key)

vectorstore = get_vectorstore()
last_vector_docs = None  # Lưu kết quả docs từ vectorstore.invoke trong lần gọi get_answer gần nhất
see_metadata = None

def augment_prompt(query: str, k: int = 5):
    #define metadata
    messages = [
        {"role": "user", "parts": [{"text": """
        {}
'Tai lieu ve': ['Chương trình đào tạo', 'Đề án', 'Đề cương']
'Nganh': ['Trí tuệ nhân tạo', 
                  'Toán kinh tế', 
                  'Thống kê kinh tế', 
                  'Phân tích dữ liệu trong Kinh tế', 
                  'Kỹ thuật phần mềm', 
                  'Khoa học máy tính', 
                  'Khoa học dữ liệu', 
                  'Hệ thống thông tin quản lý',
                  'Hệ thống thông tin', 
                  'Định phí bảo hiểm và Quản trị rủi ro', 
                  'Chương trình Công nghệ thông tin', 
                  'An toàn thông tin']

Nhiệm vụ của bạn là viết output dưới dạng dict để xác thực metadata, output có dạng: 
{'Tai lieu ve': '<write here>', 'Nganh': <write here>}, nếu không có theo 2 lists bên trên thì trả về dict rỗng, nếu có nhiều kết quả cùng một key thì trả về dict rỗng.
        """}]},
        {"role": "user", "parts": [{"text": f'Câu hỏi như sau: {query}'}]},
    ]
    genai.configure(api_key=key)
    model = genai.GenerativeModel("gemini-2.0-flash")

    response = model.generate_content(contents=messages)
    global see_metadata
    metadata = extract_metadata(response)
    see_metadata = metadata
    #retrieve
    global last_vector_docs
    if metadata == {}:
        retriever = vectorstore.as_retriever(search_kwargs={"k": 50})
    else:
        retriever = vectorstore.as_retriever(search_kwargs={"k": k, "fetch_k": 50, "filter": metadata})
    
    results = retriever.invoke(query)
    # Lưu kết quả để dùng cho log và lọc sau này
    last_vector_docs = results  
    if results:
        source_knowledge = "\n\n".join([doc.page_content for doc in results])
        return f"""Dữ liệu dưới đây liên quan đến Trường Công Nghệ (NCT) thuộc Đại học Kinh tế Quốc dân (NEU), dựa vào đó trả lời câu hỏi.
Dữ liệu:
{source_knowledge}
"""
    else:
        return "Không có thông tin liên quan.\n."

def get_answer(query, queries_list=None):
    if queries_list is None:
        queries_list = []
    
    messages = [
        {"role": "user", "parts": [{"text": "IMPORTANT: You are a super helpful, polite, Vietnamese-speaking assistant to give information of an university. If you cannot see the answer in contexts, tell user to make a more detailed question."}]},
        {"role": "user", "parts": [{"text": augment_prompt(query=query)}]}
    ]
    
    queries_list.append(query)
    queries = {"role": "user", "parts": [{"text": prompt_order(queries_list)}]}
    messages_with_queries = messages.copy()
    messages_with_queries.append(queries)
    
    # Cấu hình API key và khởi tạo model Gemini
    genai.configure(api_key=key)
    model = genai.GenerativeModel("gemini-2.0-flash")
    
    response = model.generate_content(contents=messages_with_queries, stream=True)
    response_text = ""
    for chunk in response:
        response_text += chunk.text
        yield response_text
    messages.append({"role": "model", "parts": [{"text": response_text}]})
    log_message(messages)

def filter_vector_docs(keyword: str):
    global last_vector_docs
    if last_vector_docs is None:
        return "Chưa có dữ liệu vectorstore được gọi từ get_answer."
    else:
        if not keyword.strip():
            # Nếu không nhập gì, trả về tất cả
            filtered = [doc.page_content for doc in last_vector_docs]
        else:
            # Lọc các chunk chứa từ khoá (không phân biệt chữ hoa thường)
            filtered = [doc.page_content for doc in last_vector_docs if keyword.lower() in doc.page_content.lower()]
        if not filtered:
            return f"Không có kết quả chứa từ khoá '{keyword}'."
        return "\n\n".join(filtered)

institutions = ['Tất cả', 'Trường Công Nghệ']
categories = ['Tất cả', 'Đề án', 'Chương trình đào tạo']

print("Launching on space... This may take some time...")

with gr.Blocks() as demo:
    with gr.Row():
        # Dropdown category nếu cần
        category1 = gr.Dropdown(choices=institutions, label="Trường", value=None)
        category2 = gr.Dropdown(choices=categories, label="Bạn quan tâm tới", value=None)
    
    # Chat Interface sử dụng ô nhập chung
    shared_query = gr.Textbox(placeholder="Đặt câu hỏi tại đây", container=False, autoscroll=True, scale=7)
    chat_interface = gr.ChatInterface(get_answer, textbox=shared_query, type="messages")

    metadata_box = gr.Textbox(label="Metadata", value=str(see_metadata), interactive=False)
    
    # Phần lọc các chunk: ô prompt nhập từ khoá và nút "Tìm trích xuất" nằm cùng hàng,
    # kết quả sẽ hiển thị ở ô bên dưới. Nếu để trống, hiển thị toàn bộ.
    with gr.Row():
        filter_prompt = gr.Textbox(label="Nhập từ khoá", placeholder="Nhập từ khoá để lọc (để trống để hiển thị tất cả)", interactive=True)
        filter_button = gr.Button("Tìm trích xuất")
    filter_output = gr.Textbox(label="Content", interactive=False)
    filter_button.click(fn=filter_vector_docs, inputs=filter_prompt, outputs=filter_output)

if __name__ == "__main__":
    demo.launch()