ingest whole textbooks chapter by chapter, resumably

نقشه‌ی فیزیکیِ کتاب‌ها (افستِ صفحه، بازه‌ی هر فصل، درس‌های داخلِ فصل از
فهرستِ خودِ کتاب) در rag/services/textbooks.py ثبت شد تا عنوانِ فصل از
کتاب بیاید نه از حدسِ مدل — رشته‌ی فصل باید دقیقاً بینِ ingest و retrieval
یکی باشد وگرنه نتیجه بی‌سروصدا خالی برمی‌گردد.

rag_ingest_book کتاب را فصل‌به‌فصل ingest می‌کند و قابلِ ازسرگیری است:
rag.IngestedPage نشانه‌ی «این صفحه پردازش شد» را نگه می‌دارد حتی وقتی
صفحه chunkی نساخته، وگرنه هر بار اجرای دوباره بابتِ صفحه‌های بی‌مسئله
دوباره پول می‌گرفت. --plan هزینه را رایگان برآورد می‌کند.

rag_import_collection نقاطِ موجودِ Qdrant را در LessonChunk می‌ریزد —
فقط می‌خواند، رایگان و idempotent، برای پایه‌هایی که تیمِ دیگر ingest
کرده بود.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-13 18:59:03 +03:30
parent 52d9694583
commit c79be0a336
11 changed files with 1139 additions and 35 deletions

View File

@@ -10,6 +10,8 @@
اگه تیمِ دیگه collection جدید اضافه/تغییر داد، فقط همین فایل به‌روز بشه.
"""
from .textbooks import TEXTBOOKS, chapter_titles
# --- درس‌های متنی: payload کلیدِ `lesson_number` (رشته) + `summary` دارد ---
# نامِ collection = f"{subject} {grade}".lower()
TEXT_SUBJECT_LESSON_FILTER_KEY = 'lesson_number'
@@ -22,6 +24,11 @@ MATH_SUBJECTS = {'ریاضی'}
# فصول ریاضی به تفکیکِ (subject, grade) — کلیدِ داخلی هم شماره‌ی فصل و هم
# رشته‌ی کامل رو می‌پذیره.
#
# پایه‌های سوم/ششم/هفتم را تیمِ دیگر آپلود کرده بود و این جدول از روی دادهٔ
# زنده‌ی Qdrant درآمده. پایه‌های نهم/دهم را خودمان ingest می‌کنیم، پس عنوانِ
# فصلشان از rag/services/textbooks.py می‌آید تا رشته‌ای که ingest می‌نویسد و
# رشته‌ای که retrieval رویش فیلتر می‌کند نتوانند از هم جدا بیفتند.
MATH_CHAPTERS = {
('ریاضی', 'سوم'): {
1: 'فصل ۱: الگوها',
@@ -55,6 +62,10 @@ MATH_CHAPTERS = {
},
}
MATH_CHAPTERS.update({
(b.subject, b.grade): chapter_titles(b) for b in TEXTBOOKS.values()
})
# درس‌های علوم/اجتماعی — فقط برای مرجع/اعتبارسنجی (lesson_number → عنوان).
TEXT_LESSONS = {
('علوم تجربی', 'سوم'): {
@@ -72,7 +83,7 @@ TEXT_LESSONS = {
KNOWN_COLLECTIONS = {
'ریاضی سوم', 'ریاضی ششم', 'ریاضی هفتم',
'علوم تجربی سوم', 'مطالعات اجتماعی ششم', 'مطالعات اجتماعی چهارم',
}
} | {b.key for b in TEXTBOOKS.values()}
def is_math_subject(subject: str) -> bool: