DaJulster commited on
Commit
9f3d685
·
1 Parent(s): 2cc47df

better adapted for interview questions

Browse files
Files changed (5) hide show
  1. README.md +42 -4
  2. app_hf.py +1 -1
  3. queryrun.py +139 -11
  4. requirements_downloader.txt +1 -0
  5. test_interview_questions.py +89 -0
README.md CHANGED
@@ -8,9 +8,16 @@ app_file: app_hf.py
8
  pinned: false
9
  ---
10
 
11
- # RAG API with Hugging Face Spaces
12
 
13
- This is a RAG (Retrieval-Augmented Generation) API deployed on Hugging Face Spaces.
 
 
 
 
 
 
 
14
 
15
  ## API Endpoints
16
 
@@ -24,8 +31,39 @@ This is a RAG (Retrieval-Augmented Generation) API deployed on Hugging Face Spac
24
  }
25
  ```
26
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  ## Local Development
 
28
  1. Clone this repository
29
  2. Install dependencies: `pip install -r requirements_hf.txt`
30
- 3. Set up environment variables in `.env`
31
- 4. Run: `python app_hf.py`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  pinned: false
9
  ---
10
 
11
+ # Enhanced RAG API with Interview-Style Question Support
12
 
13
+ This is an enhanced RAG (Retrieval-Augmented Generation) API deployed on Hugging Face Spaces with hybrid AI support for interview-style questions.
14
+
15
+ ## Features
16
+
17
+ - **DeepSeek-Powered**: Uses DeepSeek as the primary response generator for all questions
18
+ - **Enhanced Responses**: DeepSeek provides more engaging, first-person responses
19
+ - **Fallback Support**: Gracefully falls back to Cohere if DeepSeek is unavailable
20
+ - **Context-Aware**: Uses retrieved documents to provide specific examples and details
21
 
22
  ## API Endpoints
23
 
 
31
  }
32
  ```
33
 
34
+ ## Environment Variables
35
+
36
+ Create a `.env` file with the following variables:
37
+
38
+ ```env
39
+ # Cohere API key (required for basic RAG functionality)
40
+ COHEREAPIKEY=your_cohere_api_key_here
41
+
42
+ # DeepSeek API key (required for enhanced interview-style question handling)
43
+ DEEPKEY=your_deepseek_api_key_here
44
+ ```
45
+
46
  ## Local Development
47
+
48
  1. Clone this repository
49
  2. Install dependencies: `pip install -r requirements_hf.txt`
50
+ 3. Set up environment variables in `.env` (see above)
51
+ 4. Run the main application: `python app_hf.py`
52
+ 5. Or test the system: `python test_interview_questions.py`
53
+
54
+ ## Response Generation
55
+
56
+ The system uses DeepSeek as the primary response generator for all questions, providing:
57
+
58
+ - **Engaging First-Person Responses**: Answers as if Julien is speaking directly
59
+ - **Context-Aware Answers**: Uses retrieved documents for specific examples
60
+ - **Professional Tone**: Maintains appropriate level of formality
61
+ - **Comprehensive Coverage**: Handles technical, personal, and general questions
62
+
63
+ ### Question Examples:
64
+ - "What is your educational background?"
65
+ - "Tell me about a challenging project you worked on..."
66
+ - "What programming languages do you know?"
67
+ - "Describe your experience with machine learning..."
68
+ - "What are your research interests?"
69
+ - "Walk me through your journey in computer science..."
app_hf.py CHANGED
@@ -43,7 +43,7 @@ def handle_query():
43
  print(f"Received query: {query}")
44
 
45
  search_results = query_system.search(query, k=5)
46
- response_text = query_system.generate_response(query, search_results)
47
 
48
  sources_for_response = [
49
  {
 
43
  print(f"Received query: {query}")
44
 
45
  search_results = query_system.search(query, k=5)
46
+ response_text = query_system.generate_hybrid_response(query, search_results)
47
 
48
  sources_for_response = [
49
  {
queryrun.py CHANGED
@@ -8,18 +8,22 @@ from dotenv import load_dotenv
8
  from langchain_community.docstore.document import Document
9
  # Corrected import based on the deprecation warning
10
  from langchain_community.docstore.in_memory import InMemoryDocstore
11
- # from openai import OpenAI # DeepSeek API no longer used
12
 
13
  # Load environment variables
14
  load_dotenv()
15
  cohere_api_key = os.getenv("COHEREAPIKEY")
16
- # api_key = os.getenv("DEEPKEY") # DeepSeek API key no longer needed
17
-
18
- # DeepSeek client initialization commented out
19
- # client = OpenAI(
20
- # api_key=api_key,
21
- # base_url="https://api.deepseek.com/v1"
22
- # )
 
 
 
 
23
 
24
  # Initialize Cohere client
25
  if not cohere_api_key:
@@ -238,6 +242,44 @@ class FAISSQuerySystem:
238
  traceback.print_exc()
239
  raise
240
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  def preprocess_query(self, query):
242
  """Preprocess query to improve retrieval and context understanding"""
243
  if not isinstance(query, str):
@@ -329,6 +371,92 @@ class FAISSQuerySystem:
329
  results.sort(key=lambda x: x['score'], reverse=True)
330
  return results
331
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  def generate_response(self, query, context_docs):
333
  """Generate RAG response using Cohere's chat API"""
334
  if not context_docs:
@@ -412,7 +540,7 @@ def main():
412
 
413
  if not docs:
414
  print("Could not find relevant documents in the knowledge base.")
415
- response = query_system.generate_response(query, [])
416
  print("\nResponse:")
417
  print("-" * 50)
418
  print(response)
@@ -421,9 +549,9 @@ def main():
421
 
422
  print(f"Found {len(docs)} relevant document chunks.")
423
 
424
- # 2. Generate and display response using RAG
425
  print("Generating response based on documents...")
426
- response = query_system.generate_response(query, docs)
427
  print("\nResponse:")
428
  print("-" * 50)
429
  print(response)
 
8
  from langchain_community.docstore.document import Document
9
  # Corrected import based on the deprecation warning
10
  from langchain_community.docstore.in_memory import InMemoryDocstore
11
+ from openai import OpenAI # DeepSeek API for interview-style questions
12
 
13
  # Load environment variables
14
  load_dotenv()
15
  cohere_api_key = os.getenv("COHEREAPIKEY")
16
+ deepseek_api_key = os.getenv("DEEPKEY") # DeepSeek API key for enhanced responses
17
+
18
+ # DeepSeek client initialization
19
+ if deepseek_api_key:
20
+ deepseek_client = OpenAI(
21
+ api_key=deepseek_api_key,
22
+ base_url="https://api.deepseek.com/v1"
23
+ )
24
+ else:
25
+ deepseek_client = None
26
+ print("Warning: DEEPKEY not found. DeepSeek features will be disabled.")
27
 
28
  # Initialize Cohere client
29
  if not cohere_api_key:
 
242
  traceback.print_exc()
243
  raise
244
 
245
+ def is_interview_style_question(self, query):
246
+ """Detect if the query is an interview-style question that would benefit from DeepSeek"""
247
+ query_lower = query.lower()
248
+
249
+ # Interview-style question patterns
250
+ interview_patterns = [
251
+ "tell me about", "can you tell me", "describe", "explain",
252
+ "what makes you", "why did you", "how did you", "what inspired",
253
+ "walk me through", "give me an example", "share a story",
254
+ "what was your role", "what challenges", "what was it like",
255
+ "how do you approach", "what's your experience with",
256
+ "what skills", "what technologies", "what projects",
257
+ "what's your background", "what's your journey",
258
+ "what are your strengths", "what are you passionate about",
259
+ "what motivates you", "what's your philosophy",
260
+ "how would you", "what would you do if",
261
+ "describe a time when", "tell me about a project where"
262
+ ]
263
+
264
+ # Check for interview patterns
265
+ for pattern in interview_patterns:
266
+ if pattern in query_lower:
267
+ return True
268
+
269
+ # Check for question words that suggest interview context
270
+ question_words = ["why", "how", "what", "when", "where", "which", "who"]
271
+ if any(query_lower.startswith(word) for word in question_words):
272
+ # Additional context clues for interview questions
273
+ interview_context = [
274
+ "experience", "project", "work", "study", "research", "develop",
275
+ "create", "build", "learn", "achieve", "accomplish", "solve",
276
+ "challenge", "problem", "team", "collaborate", "lead", "manage"
277
+ ]
278
+ if any(context in query_lower for context in interview_context):
279
+ return True
280
+
281
+ return False
282
+
283
  def preprocess_query(self, query):
284
  """Preprocess query to improve retrieval and context understanding"""
285
  if not isinstance(query, str):
 
371
  results.sort(key=lambda x: x['score'], reverse=True)
372
  return results
373
 
374
+ def generate_deepseek_response(self, query, context_docs):
375
+ """Generate response using DeepSeek as the primary response generator"""
376
+ if not deepseek_client:
377
+ print("DeepSeek client not available, falling back to Cohere")
378
+ return self.generate_response(query, context_docs)
379
+
380
+ if not context_docs:
381
+ try:
382
+ response = deepseek_client.chat.completions.create(
383
+ model="deepseek-chat",
384
+ messages=[
385
+ {
386
+ "role": "system",
387
+ "content": "You are Julien Serbanescu, a computer science student and AI researcher. Answer questions about your background, projects, and experience in a professional, engaging manner. Be specific and provide concrete examples when possible. If you don't have specific information, acknowledge this and suggest how the user might rephrase their question."
388
+ },
389
+ {
390
+ "role": "user",
391
+ "content": f"I could not find relevant documents in my knowledge base to answer your question: '{query}'. Please provide a general response about your background and suggest how the user might rephrase their question."
392
+ }
393
+ ],
394
+ temperature=0.7,
395
+ max_tokens=1000
396
+ )
397
+ return response.choices[0].message.content
398
+ except Exception as e:
399
+ print(f"Error calling DeepSeek without documents: {e}")
400
+ return "I could not find relevant documents and encountered an error trying to respond."
401
+
402
+ # Format context documents for DeepSeek
403
+ context_text = ""
404
+ for i, doc in enumerate(context_docs[:5]): # Limit to top 5 docs for DeepSeek
405
+ content = doc['content']
406
+ if not isinstance(content, str):
407
+ try:
408
+ content = str(content)
409
+ except UnicodeEncodeError:
410
+ import unicodedata
411
+ content = unicodedata.normalize('NFKD', str(content))
412
+
413
+ source = doc['metadata'].get('source', 'Unknown')
414
+ context_text += f"\n--- Source {i+1} ({source}) ---\n{content[:2000]}\n"
415
+
416
+ try:
417
+ response = deepseek_client.chat.completions.create(
418
+ model="deepseek-chat",
419
+ messages=[
420
+ {
421
+ "role": "system",
422
+ "content": f"""You are Julien Serbanescu, a computer engineering student and AI researcher. Answer the user's question based on the provided context documents about your background, projects, and experience.
423
+
424
+ Context about Julien Serbanescu:
425
+ {context_text}
426
+
427
+ Guidelines:
428
+ - Answer as if you are Julien speaking in first person
429
+ - Be specific and provide concrete examples from the context
430
+ - Use a professional but engaging tone
431
+ - If the context doesn't contain enough information, acknowledge this and provide what you can
432
+ - Structure your response clearly with specific examples
433
+ - Show enthusiasm and passion for your work
434
+ - For technical questions, provide detailed explanations
435
+ - For general questions, give comprehensive but concise answers"""
436
+ },
437
+ {
438
+ "role": "user",
439
+ "content": query
440
+ }
441
+ ],
442
+ temperature=0.7,
443
+ max_tokens=1500
444
+ )
445
+ return response.choices[0].message.content
446
+ except Exception as e:
447
+ print(f"Error calling DeepSeek: {e}")
448
+ # Fallback to Cohere
449
+ return self.generate_response(query, context_docs)
450
+
451
+ def generate_hybrid_response(self, query, context_docs):
452
+ """Generate response using DeepSeek as primary, with Cohere fallback"""
453
+ if deepseek_client:
454
+ print("Using DeepSeek for enhanced response...")
455
+ return self.generate_deepseek_response(query, context_docs)
456
+ else:
457
+ print("DeepSeek not available, using Cohere fallback...")
458
+ return self.generate_response(query, context_docs)
459
+
460
  def generate_response(self, query, context_docs):
461
  """Generate RAG response using Cohere's chat API"""
462
  if not context_docs:
 
540
 
541
  if not docs:
542
  print("Could not find relevant documents in the knowledge base.")
543
+ response = query_system.generate_hybrid_response(query, [])
544
  print("\nResponse:")
545
  print("-" * 50)
546
  print(response)
 
549
 
550
  print(f"Found {len(docs)} relevant document chunks.")
551
 
552
+ # 2. Generate and display response using hybrid RAG
553
  print("Generating response based on documents...")
554
+ response = query_system.generate_hybrid_response(query, docs)
555
  print("\nResponse:")
556
  print("-" * 50)
557
  print(response)
requirements_downloader.txt CHANGED
@@ -5,3 +5,4 @@ requests>=2.31.0
5
  pathlib2>=2.3.7; python_version < "3.4"
6
 
7
 
 
 
5
  pathlib2>=2.3.7; python_version < "3.4"
6
 
7
 
8
+
test_interview_questions.py ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test script to demonstrate the enhanced QA system with interview-style question handling.
4
+ This script tests both regular questions and interview-style questions to show the difference.
5
+ """
6
+
7
+ import os
8
+ import sys
9
+ from dotenv import load_dotenv
10
+
11
+ # Add the current directory to Python path
12
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
13
+
14
+ from queryrun import FAISSQuerySystem
15
+
16
+ def test_questions():
17
+ """Test various types of questions to demonstrate the DeepSeek-enhanced system"""
18
+
19
+ # Load environment variables
20
+ load_dotenv()
21
+
22
+ # Test questions
23
+ test_cases = [
24
+ {
25
+ "type": "General Question",
26
+ "question": "What is Julien's educational background?"
27
+ },
28
+ {
29
+ "type": "Interview Question",
30
+ "question": "Tell me about a challenging project you worked on and how you overcame the difficulties."
31
+ },
32
+ {
33
+ "type": "Technical Question",
34
+ "question": "What programming languages does Julien know?"
35
+ },
36
+ {
37
+ "type": "Experience Question",
38
+ "question": "Describe your experience with machine learning and what excites you most about AI research."
39
+ },
40
+ {
41
+ "type": "Research Question",
42
+ "question": "What are Julien's research interests?"
43
+ },
44
+ {
45
+ "type": "Personal Question",
46
+ "question": "Walk me through your journey in computer science and what motivated you to pursue this field."
47
+ }
48
+ ]
49
+
50
+ try:
51
+ print("Initializing RAG system...")
52
+ query_system = FAISSQuerySystem()
53
+ print("RAG system ready!\n")
54
+
55
+ for i, test_case in enumerate(test_cases, 1):
56
+ print(f"{'='*80}")
57
+ print(f"TEST CASE {i}: {test_case['type']}")
58
+ print(f"Question: {test_case['question']}")
59
+ print(f"{'='*80}")
60
+
61
+ # Search for relevant documents
62
+ print("\nSearching for relevant documents...")
63
+ docs = query_system.search(test_case['question'], k=5)
64
+ print(f"Found {len(docs)} relevant documents")
65
+
66
+ # Generate response using DeepSeek (with Cohere fallback)
67
+ print("\nGenerating response with DeepSeek...")
68
+ response = query_system.generate_hybrid_response(test_case['question'], docs)
69
+
70
+ print(f"\nResponse:")
71
+ print("-" * 60)
72
+ print(response)
73
+ print("-" * 60)
74
+
75
+ # Show sources
76
+ if docs:
77
+ print(f"\nSources used:")
78
+ for j, doc in enumerate(docs[:3], 1): # Show top 3 sources
79
+ print(f" {j}. {doc['metadata'].get('source', 'Unknown')} (score: {doc['score']:.4f})")
80
+
81
+ print(f"\n{'-'*80}\n")
82
+
83
+ except Exception as e:
84
+ print(f"Error during testing: {e}")
85
+ import traceback
86
+ traceback.print_exc()
87
+
88
+ if __name__ == "__main__":
89
+ test_questions()