-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathanswer_fixer_cli.py
More file actions
253 lines (212 loc) · 7.68 KB
/
Copy pathanswer_fixer_cli.py
File metadata and controls
253 lines (212 loc) · 7.68 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
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
"""
Answer Fixer CLI Tool
Quick command-line interface for testing the strict RAG answer fixer.
Usage:
python answer_fixer_cli.py --interactive
python answer_fixer_cli.py --test-examples
python answer_fixer_cli.py --fix "question" "answer" --evidence "ev1" "ev2"
"""
import argparse
import sys
from typing import List
from utils.answer_fixer import fix_rag_answer
def interactive_mode():
"""Interactive mode for testing the fixer."""
print("=" * 80)
print("STRICT RAG ANSWER FIXER - Interactive Mode")
print("=" * 80)
print()
print("Enter question, answer, and evidence to see the fixer in action.")
print("Type 'quit' or 'exit' to quit.")
print()
while True:
print("-" * 80)
# Get question
question = input("Question: ").strip()
if question.lower() in ['quit', 'exit']:
break
if not question:
print("Question cannot be empty. Try again.")
continue
# Get answer
answer = input("Generated Answer: ").strip()
if answer.lower() in ['quit', 'exit']:
break
# Get evidence (multiple lines)
print("Evidence (enter each evidence line, press Enter twice when done):")
evidence_lines = []
while True:
line = input(" > ").strip()
if line.lower() in ['quit', 'exit']:
sys.exit(0)
if not line:
break
evidence_lines.append(line)
if not evidence_lines:
print("At least one evidence line is required. Try again.")
continue
# Build sources
sources = [
{"file": f"source_{i+1}.pdf", "evidence": ev}
for i, ev in enumerate(evidence_lines)
]
# Apply fixer
print()
print("Applying fixer...")
fixed = fix_rag_answer(question, sources, answer if answer else None)
# Display results
print()
print("RESULTS:")
print("-" * 80)
print(f"Original Answer: {answer if answer else '[Generated from evidence]'}")
print(f"Fixed Answer: {fixed}")
print()
if answer and answer != fixed:
print("✓ Corrections applied")
else:
print("✓ No corrections needed")
print()
def test_examples():
"""Run predefined test examples."""
print("=" * 80)
print("STRICT RAG ANSWER FIXER - Test Examples")
print("=" * 80)
print()
examples = [
{
"name": "Remove Incomplete Sentence",
"question": "Quel est le prix?",
"sources": [{"file": "doc.pdf", "evidence": "L'offre coûte 1990 DA par mois."}],
"answer": "L'offre coûte 1990 DA par mois. Ensuite..."
},
{
"name": "Remove Forbidden Addition (French)",
"question": "Qu'est-ce que l'upload?",
"sources": [{"file": "doc.pdf", "evidence": "L'upload est la vitesse d'envoi des données."}],
"answer": "L'upload est la vitesse d'envoi des données. Par exemple, pour les emails."
},
{
"name": "Remove Forbidden Addition (Arabic)",
"question": "ما معنى الرفع؟",
"sources": [{"file": "doc.pdf", "evidence": "الرفع هو سرعة إرسال البيانات"}],
"answer": "الرفع هو سرعة إرسال البيانات. مثل البريد الإلكتروني."
},
{
"name": "Fix False Unavailable",
"question": "Quel est le prix?",
"sources": [{"file": "doc.pdf", "evidence": "L'offre coûte 1990 DA par mois."}],
"answer": "Information non disponible dans les documents fournis."
},
{
"name": "Deduplicate Repeated Info",
"question": "Quel est le prix?",
"sources": [
{"file": "doc1.pdf", "evidence": "L'offre coûte 1990 DA."},
{"file": "doc2.pdf", "evidence": "L'offre coûte 1990 DA par mois."}
],
"answer": None # Will generate from sources
},
{
"name": "Empty Sources",
"question": "Quel est le prix?",
"sources": [],
"answer": "Le prix est 1990 DA."
},
{
"name": "Fix Wrong Numbers",
"question": "Quel est le prix?",
"sources": [{"file": "doc.pdf", "evidence": "L'offre coûte 1990 DA."}],
"answer": "L'offre coûte 2500 DA."
}
]
for i, example in enumerate(examples, 1):
print(f"Example {i}: {example['name']}")
print("-" * 80)
print(f"Question: {example['question']}")
print(f"Sources: {len(example['sources'])} sources")
for j, src in enumerate(example['sources'], 1):
print(f" [{j}] {src.get('evidence', '')}")
print(f"Original: {example['answer'] if example['answer'] else '[Generate from sources]'}")
# Apply fixer
fixed = fix_rag_answer(
example['question'],
example['sources'],
example['answer']
)
print(f"Fixed: {fixed}")
# Show if changes made
if example['answer'] and example['answer'] != fixed:
print("✓ Corrections applied")
elif not example['answer']:
print("✓ Generated from sources")
else:
print("✓ No corrections needed")
print()
print("=" * 80)
print(f"Completed {len(examples)} examples")
print("=" * 80)
def fix_command(question: str, answer: str, evidence_list: List[str]):
"""Fix a single answer via command line."""
sources = [
{"file": f"source_{i+1}.pdf", "evidence": ev}
for i, ev in enumerate(evidence_list)
]
fixed = fix_rag_answer(question, sources, answer if answer else None)
print("FIXED ANSWER:")
print(fixed)
def main():
parser = argparse.ArgumentParser(
description="Strict RAG Answer Fixer CLI",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
# Interactive mode
python answer_fixer_cli.py --interactive
# Test predefined examples
python answer_fixer_cli.py --test-examples
# Fix a specific answer
python answer_fixer_cli.py --fix "Quel est le prix?" "Le prix est 1990 DA. Ensuite..." \\
--evidence "L'offre coûte 1990 DA par mois."
"""
)
parser.add_argument(
'--interactive', '-i',
action='store_true',
help='Run in interactive mode'
)
parser.add_argument(
'--test-examples', '-t',
action='store_true',
help='Run predefined test examples'
)
parser.add_argument(
'--fix', '-f',
nargs=2,
metavar=('QUESTION', 'ANSWER'),
help='Fix a specific question and answer'
)
parser.add_argument(
'--evidence', '-e',
nargs='+',
metavar='EVIDENCE',
help='Evidence texts (required with --fix)'
)
args = parser.parse_args()
# Determine which mode to run
if args.interactive:
interactive_mode()
elif args.test_examples:
test_examples()
elif args.fix:
if not args.evidence:
print("Error: --evidence is required when using --fix")
sys.exit(1)
question, answer = args.fix
fix_command(question, answer, args.evidence)
else:
# Default: show help
parser.print_help()
print()
print("Tip: Try 'python answer_fixer_cli.py --test-examples' to see examples")
if __name__ == "__main__":
main()