label every textbook solution, and build quizzes at the level the app plays
سه کارِ بههمپیوسته که از یک کشف شروع شدند: راهحلهایی که vision از کتاب
درآورده گاهی غلطاند، و این خطا در بازیابی دیده نمیشود — فقط وقتی کسی به
`solution` اعتماد کند خودش را نشان میدهد.
۱) بازبینیِ راهحلها (rag_verify_solutions)
هر chunk دوباره حل میشود و با کتاب مقایسه. نتیجه سهحالته است، نه بله/خیر:
اجرای اول با بولی ۱۹٪ خطا گزارش کرد؛ خواندنِ دستیِ نمونهها نشان داد ۳۵٪ از
آنها مسئلههایی بودند که به شکلِ کتاب ارجاع میدادند و اصلاً قابلِ قضاوت
نبودند، و ۲۴٪ موردی که «۳/۱۰۴» را کسرِ ۳÷۱۰۴ خوانده بود نه عددِ ۳٫۱۰۴. با دو
حالت، «نمیدانم» ناچار به «غلط است» ترجمه میشد.
با سه حالت و پرامپتی که این دو تله را میشناسد: ۲٬۱۱۹ chunk بررسی شد،
۱٬۱۱۲ درست، ۱۲۳ غلط (۵٫۸٪)، ۸۸۱ غیرقابلِ قضاوت. آن ۸۸۱ رایگان برچسب خوردند
چون پیشفیلتر قبل از هر فراخوانی کنارشان گذاشت.
`solution` هرگز بازنویسی نمیشود — کتاب باید کتاب بماند. برچسب در payloadِ
Qdrant هم مینشیند، ولی با نامی که `retrieval._payload_text` نمیخواند: یک
نویسه هم به متنی که به مدل میرسد اضافه نشد.
نمونهی خطاهای واقعیِ کتاب که پیدا شد:
BMI = ۱۰۰/(۲٫۷۴)² کتاب: ۳۳٫۲ درست: ۱۳٫۳
۱۶ آبی + ۲۴ صورتی کتاب: «کل ۵۰» درست: ۴۰
بزرگترین عددِ ۴رقمیِ بیتکرار کتاب: ۸۵۳۲ درست: ۹۸۷۶
g(x) = x³ − ۲ کتاب: «نمایی» درست: چندجملهای
۲) سوالها فقط از راهحلهای تأییدشده
۱٬۱۹۹ سوال در content/seed/questions.json، همه از chunkهایی که برچسبِ
«درست» گرفتهاند. هر شش پایه برنامهی درسی دارند (۱٬۹۲۸ درس) — هشتم و دهم
تازه ساخته شدند.
۳) GET /api/nodes/{id}/quiz
واحدِ بازی در اپ «مبحث» است ولی سوالها به «درس» بستهاند، و درس اینجا
ریزترین دانه است: یک نوعِ مسئله، نه یک جلسه. نتیجهاش این بود که اپ برای یک
آزمونِ چهارسوالی باید دهها درخواست میزد. این اندپوینت از همهی درسهای مبحث
نمونه برمیدارد، حداکثر یکی از هر درس تا آزمون روی یک مهارت گیر نکند.
درهمریزی با بذرِ nodeId:userId پایدار است: رفرشِ صفحه همان آزمون را میدهد،
نه مجموعهی تازهای که پیشرفت را بیمعنا کند. `questionCount` جدا از
`requested` میآید تا مبحثِ کمسوال وانمود نکند کامل است.
──────────
اصلاحاتِ جانبی که سرِ راه لازم شدند:
• QDRANT_TIMEOUT_SECONDS: کلاینت بدونِ timeout ساخته میشد و پیشفرضِ ۵
ثانیهایِ کتابخانه ingestِ کتابِ هشتم را روی اولین فراخوانی کشت.
• پاکسازیِ نقاطِ نیمهنوشته: upsert با wait=True ممکن است نوشته باشد و فقط
جوابش تایماوت شده باشد؛ مسیرِ جبران فقط ردیفهای DB را پس میگرفت و هر
retry یک نسخهی تکراری در Qdrant جا میگذاشت (۸ مورد در پایه نهم، پاک شد).
• تشخیصِ سقفِ حساب: «insufficient user quota» با فاصله میآید نه زیرخط، و
محافظِ اول نمیگرفتش — یک اجرا ۷۷۰ فراخوانیِ محکومبهشکست زد.
• پرامپتِ vision حالا میخواهد محتوای شکل داخلِ متنِ مسئله نوشته شود. ۴۲٪ از
محتوای موجود به شکلی ارجاع میدهد که در متن نیست؛ مدل آن را دیده بود ولی
از او خواسته نشده بود بنویسدش. کتابهای موجود قبل از این قاعده وارد شدهاند.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -103,6 +103,16 @@ def extract_problem_types(image, grade: str, chapter_name: str) -> dict:
|
||||
"""
|
||||
یک عکسِ صفحهی کتاب → ساختارِ JSONِ انواعِ مسئله (فارسی)، با مدلِ vision.
|
||||
خروجی همون شکلیست که uploadِ ریاضیِ تیمِ دیگه هم تولید میکرد.
|
||||
|
||||
⚠️ قاعدهی «self-contained» در پرامپت تازه اضافه شده و کتابهایی که تا امروز
|
||||
وارد شدهاند بدونِ آن استخراج شدهاند. اثرش با عدد: از ۲٬۱۱۹ مسئلهی موجود،
|
||||
۸۸۱ تا (۴۲٪) به «شکلِ زیر» یا «جدولِ روبهرو» ارجاع میدهند و بدونِ آن تصویر
|
||||
قابلِ حل نیستند — نه برای دانشآموز، نه برای دستیار، نه برای ساختِ سؤال.
|
||||
|
||||
نکته این است که مدل آن شکل را **دیده بود**؛ محدودیتِ vision نبود، فقط از او
|
||||
خواسته نشده بود آنچه میبیند را بنویسد. برای همین با ingestِ دوبارهی همان
|
||||
صفحهها قابلِ جبران است، ولی چون هزینه دارد فعلاً انجام نشده. هر کتابِ
|
||||
تازهای که از این پس وارد شود این مشکل را ندارد.
|
||||
"""
|
||||
prompt = f"""
|
||||
You are {teacher_persona(grade)}.
|
||||
@@ -121,6 +131,15 @@ Rules:
|
||||
- exampleFromImage must be a real problem from the image (not invented).
|
||||
- Keep the mathematical notation of the textbook; do not simplify the concept
|
||||
to a lower grade level than "{grade}".
|
||||
- SELF-CONTAINED PROBLEMS. You can see the figures, tables and diagrams on this
|
||||
page, but the reader of your output cannot. Whenever a problem refers to one
|
||||
("the shape below", "the table opposite", "the given diagram"), write what it
|
||||
shows INTO the problem text itself: the measurements, the vertex labels, the
|
||||
angles, the table's values, what is shaded. Someone with only your text must
|
||||
be able to solve it. If a figure genuinely cannot be put into words (a freehand
|
||||
drawing task, a colouring exercise), skip that problem instead of writing a
|
||||
reference to something the reader will never see.
|
||||
- The same applies to the solution: no step may depend on looking at the page.
|
||||
- If the page has no math problem at all (cover, foreword, table of contents,
|
||||
a page of pure text), return an empty "problemTypes" list instead of inventing one.
|
||||
- Output ONLY the JSON object. No markdown, no backticks.
|
||||
|
||||
Reference in New Issue
Block a user