File size: 4,354 Bytes
95a5cb0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2e3dc8a
 
 
 
 
 
95a5cb0
 
 
 
2e3dc8a
 
 
 
95a5cb0
 
d69ddeb
 
95a5cb0
 
d69ddeb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95a5cb0
d69ddeb
95a5cb0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2e3dc8a
 
 
95a5cb0
bcabbeb
95a5cb0
 
 
 
 
 
 
 
 
 
 
 
 
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
import asyncio
from helper import MODEL_NAME, AUTO_ANSWERS, ROLE_ASSISTANT
from typing import List
from huggingface_hub import InferenceClient
import os




class RAGModel:
    """ Class for model related functions, such as loading the model, API/model interaction and such."""

    def __init__(self, api_key: str, model_name: str = MODEL_NAME):
        self.api_key = api_key
        self.model_name = model_name
        self.client = InferenceClient(provider="nebius", token=api_key)

        # Backup (maybe)
        #try:
        #    self.tokenizer = AutoTokenizer.from_pretrained(model_name)
        #except Exception as e:
        #    print(f"Lokaler Tokenizer nicht verfügbar: {e}")
        #    self.tokenizer = None

    def get_auto_answer(self, reason: str): 
        return f"Apologies: {reason}"

    def generate_response(self, 
                               query: str, 
                               context: List[str],
                               temperature: float = 0.7,
                               max_tokens: int = 512,
                               top_p: float = 0.9,
                               top_k: int = None) -> str:
        """Generate an answer via Hugging Face API with configurable parameters
        
            Args: 
                query: User input string 
                context: Context retrieved from context DB
                temperature: Sampling temperature (0.0 to 2.0)
                max_tokens: Maximum tokens to generate
                top_p: Nucleus sampling parameter
                top_k: Top-k sampling parameter (not used in HF API)
        """
        
        if len(context) >= 10: 
            context_text = "\n".join(context[:10])  # limit to 10 most relevant chunks
        else: 
            context_text = "\n".join(context)

        UNIVERSITY_ASSISTANT_SYSTEM_PROMPT = """
        You are a university assistant that helps ONLY with university-related topics using the available database.

        ## APPROPRIATE RESPONSES
        You can help with:
        - "What courses is [student] taking?"
        - "Who teaches [course]?" 
        - "Which students are in [professor]'s class?"
        - "What is [professor]'s email?"
        - "What department is [faculty] in?"

        ## STRICT BOUNDARIES
        Never discuss:
        - Grades, academic performance, or GPA
        - Financial information, tuition, or payments
        - Sensitive student data beyond basic directory info
        - Any non-university topics (medical, legal, financial advice)

        ## RESPONSE STYLE
        - Be helpful and professional
        - Redirect inappropriate requests: "I can only help with university academic topics"
        - For sensitive data: "I don't have access to that information. Please contact [relevant office]"
        - Only share information appropriate for academic purposes

        ## KNOWLEDGE USAGE 
        Use the provided Context below to answer user requests.
        """
        
        prompt = f"{UNIVERSITY_ASSISTANT_SYSTEM_PROMPT} \n\nContext: {context_text}\nQuestion: {query}\nAnswer: Based on the given context,"

        try:   
            response = self.client.chat.completions.create(
                model=self.model_name,
                messages=[
                {
                    "role": ROLE_ASSISTANT,
                    "content": [
                        {
                            "type": "text",
                            "text": prompt
                        },
                    ]
                }
            ],
                max_tokens=max_tokens,      # Use configurable parameter
                temperature=temperature,     # Use configurable parameter
                top_p=top_p,                # Use configurable parameter
            )
                    
            if response: 
                return response.choices[0].message.content
            else:
                print(f"NO RESPONSE")
                return self.get_auto_answer(AUTO_ANSWERS.COULD_NOT_GENERATE.value)
                
        except asyncio.TimeoutError:
            print("API Timeout")
            return self.get_auto_answer(AUTO_ANSWERS.REQUEST_TIMED_OUT.value)
        except Exception as e:
            print(f"API Fehler: {e}")
            return self.get_auto_answer(AUTO_ANSWERS.UNEXPECTED_ERROR.value)