Repository navigation
Expand file tree
/
Copy pathfaq_processor.py
More file actions
100 lines (77 loc) · 3.71 KB
/
Copy pathfaq_processor.py
File metadata and controls
100 lines (77 loc) · 3.71 KB
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
import os
import glob
import re
from text_processor import TextProcessor
from config import FAQ_FOLDER, MIN_SIMILARITY_THRESHOLD, MAX_FAQ_RESULTS
class FAQProcessor:
def __init__(self):
self.text_processor = TextProcessor()
self.faq_data = []
self.load_faq_files()
def load_faq_files(self):
"""Load all FAQ files from the specified folder"""
if not os.path.exists(FAQ_FOLDER):
print(f"FAQ folder not found: {FAQ_FOLDER}")
return
txt_files = glob.glob(os.path.join(FAQ_FOLDER, "*.txt"))
for file_path in txt_files:
try:
with open(file_path, 'r', encoding='utf-8') as file:
content = file.read()
# Split content into Q&A pairs
qa_pairs = self.parse_faq_content(content, file_path)
self.faq_data.extend(qa_pairs)
except Exception as e:
print(f"Error loading {file_path}: {e}")
print(f"Loaded {len(self.faq_data)} FAQ entries from {len(txt_files)} files")
def parse_faq_content(self, content, file_path):
"""Parse FAQ content into question-answer pairs"""
qa_pairs = []
filename = os.path.basename(file_path)
# Split by double newlines to separate entries
entries = [entry.strip() for entry in content.split('\n\n') if entry.strip()]
for entry in entries:
lines = entry.split('\n')
if len(lines) >= 2:
question = lines[0].strip()
answer = '\n'.join(lines[1:]).strip()
# Remove Q: and A: prefixes if present
question = re.sub(r'^Q:\s*', '', question, flags=re.IGNORECASE)
answer = re.sub(r'^A:\s*', '', answer, flags=re.IGNORECASE)
qa_pairs.append({
'question': question,
'answer': answer,
'source': filename
})
return qa_pairs
def search_faq(self, query):
"""Search FAQ entries for the best matches"""
if not self.faq_data:
return "No FAQ data available. Please check the FAQ folder."
# Extract questions for similarity calculation
questions = [item['question'] for item in self.faq_data]
# Calculate similarities
similarities = self.text_processor.calculate_similarity(query, questions)
# Get top matches
top_indices = similarities.argsort()[-MAX_FAQ_RESULTS:][::-1]
results = []
for idx in top_indices:
if similarities[idx] >= MIN_SIMILARITY_THRESHOLD:
results.append({
'question': self.faq_data[idx]['question'],
'answer': self.faq_data[idx]['answer'],
'source': self.faq_data[idx]['source'],
'similarity': similarities[idx]
})
return self.format_faq_response(results, query)
def format_faq_response(self, results, query):
"""Format FAQ search results"""
if not results:
return f"I couldn't find a good match for '{query}' in the FAQ. Try rephrasing your question."
response = f"Here's what I found for '{query}':\n\n"
for i, result in enumerate(results, 1):
response += f"📋 Match #{i} (from {result['source']}):\n"
response += f"Q: {result['question']}\n"
response += f"A: {result['answer']}\n"
response += f"Confidence: {result['similarity']:.2%}\n\n"
return response.rstrip()