make the tutor grade-aware and its answers measurable
مهمترین خواستهی سینیور این بود که بسنجیم پاسخِ AI واقعاً یاد میدهد یا نه. برای سنجیدن، اول باید پاسخها قابلِ ردیابی میشدند. پرامپتها پایهآگاه شدند: تا پیش از این «معلمِ دبستانی» برای پایه نهم هاردکد بود، هم در تولیدِ پاسخ و هم در vision — یعنی دانشآموزِ نهم لحنِ ابتدایی میگرفت. PROMPT_VERSION حالا روی هر پیام ذخیره میشود. هر پاسخ حاشیهنویسی میشود: مدل، نسخهی پرامپت، پایه، collection، مقدارِ فیلتر، تعداد chunk، توکن، تأخیر و from_cache. فیدبک reason اختیاری گرفت تا لایک/دیسلایک بعداً قابلِ تحلیل باشد («بشه چک کرد کدوم بهتر بوده»). ai_feedback_report --by prompt_version نسبتِ رضایت را کنارِ مصرف/هزینه میگذارد. rag_eval سوالهای واقعی را از مسیرِ واقعی میپرسد، با --retrieval-only برای اجرای ارزان. rag/services/lesson_context.py از lessonId تنها پایه و فصل را درمیآورد؛ normalize_grade_title هم اختلافِ «پایه نهم» در دیتابیس با «ریاضی نهم» در نامِ collection را میبندد — بدونِ آن مسیرِ gradeId بیسروصدا خالی برمیگشت. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
کشِ پاسخِ RAG برای سوالِ عیناً تکراری.
|
||||
|
||||
کلید = هشِ (collection + مقدارِ فیلترِ درس/فصل + متنِ نرمالشدهی سوال).
|
||||
کلید = هشِ (collection + مقدارِ فیلترِ درس/فصل + پایه + متنِ نرمالشدهی سوال).
|
||||
فقط مرحلهی گران (embedding + جستجوی Qdrant + تولیدِ GPT) رو رد میکنه؛
|
||||
کوتای روزانه، idempotency و ثبتِ Message همچنان در view اجرا میشن.
|
||||
"""
|
||||
@@ -10,7 +10,9 @@ import hashlib
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
|
||||
_PREFIX = 'rag:ans:v1:'
|
||||
# v2: پایه هم واردِ کلید شد (پایین را ببینید). نسخهی prefix عمداً جلو رفت تا
|
||||
# کلیدهای v1 که پایه در آنها نبود، خودبهخود بیاثر شوند.
|
||||
_PREFIX = 'rag:ans:v2:'
|
||||
|
||||
|
||||
def ttl() -> int:
|
||||
@@ -25,8 +27,15 @@ def _norm(text: str) -> str:
|
||||
return ' '.join((text or '').split()).strip().lower()
|
||||
|
||||
|
||||
def make_key(collection, filter_value, question: str) -> str:
|
||||
raw = f'{collection}|{filter_value}|{_norm(question)}'
|
||||
def make_key(collection, filter_value, question: str, grade_title: str = '') -> str:
|
||||
"""
|
||||
⚠️ `grade_title` جزءِ کلید است چون تولیدِ پاسخ از این به بعد پایهآگاه است
|
||||
(لحن و سطحِ توضیح از پایه میآید). بدونِ آن، وقتی subject/فصل مشخص نیست
|
||||
collection و filter هر دو None میشوند و کلید فقط به متنِ سوال میماند —
|
||||
یعنی پاسخی که برای دانشآموزِ نهم ساخته شده عیناً به دانشآموزِ سوم
|
||||
برمیگشت.
|
||||
"""
|
||||
raw = f'{collection}|{filter_value}|{(grade_title or "").strip()}|{_norm(question)}'
|
||||
return _PREFIX + hashlib.sha1(raw.encode('utf-8')).hexdigest()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user