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

@@ -8,15 +8,52 @@
نسخه‌ی رسمی و به‌روزِ کتاب‌ها: <https://irtextbook.ir>
(از خارج ایران در دسترس نیست؛ دانلود باید از داخل ایران انجام شود.)
## نام‌گذاری پیشنهادی
## اولویت (به‌روزشده ۱۴۰۵/۰۶/۲۱)
math-grade1.pdf ریاضی اول دبستان
math-grade2.pdf ریاضی دوم دبستان
math-grade4.pdf ریاضی چهارم دبستان
math-grade5.pdf ریاضی پنجم دبستان
سینیور اولویت را عوض کرد: **از پایه ششم به بالا**، با تمرکز روی پایه‌های
ترانزیشنی ۶، ۷، ۹ و ۱۰. کتاب‌های ابتدایی (اول/دوم/چهارم/پنجم) که قبلاً
دانلود شده‌اند فعلاً در نوبت نیستند.
پایه‌های سوم و ششم لازم نیستند: محتوایشان از قبل روی Qdrant موجود است
(collectionهای «ریاضی سوم» و «ریاضی ششم» ساخته‌ی تیم دیگر).
| پایه | وضعیت |
|---|---|
| ششم، هفتم | از قبل روی Qdrant موجود است (ساخته‌ی تیم دیگر) |
| نهم، دهم | PDF موجود است؛ ingest با `rag_ingest_book` |
| هشتم | PDF موجود است، هنوز در `textbooks.py` ثبت نشده |
| اول، دوم، چهارم، پنجم | PDF موجود است، خارج از اولویتِ فعلی |
## نام‌گذاری
نامِ فایل باید دقیقاً با `filename` در `rag/services/textbooks.py` یکی باشد،
مثلاً `ریاضی نهم.pdf`.
## چطور ingest کنیم
```bash
# اول ببینید چه چیزی قرار است پردازش شود (رایگان، هیچ فراخوانیِ مدلی ندارد)
python manage.py rag_ingest_book --grade نهم --plan
# یک فصل، با سقفِ صفحه برای کنترلِ هزینه
python manage.py rag_ingest_book --grade نهم --chapters 1 --max-pages 5
# کلِ کتاب (از جایی که مانده ادامه می‌دهد)
python manage.py rag_ingest_book --grade نهم
```
هر اجرا صفحه‌هایی را که قبلاً chunk ساخته‌اند رد می‌کند، پس قطع کردنش با
Ctrl-C بی‌خطر است و اجرای دوباره هزینه‌ی رفته را دوباره نمی‌پردازد.
## افزودنِ کتابِ جدید
در `rag/services/textbooks.py` یک `Textbook` بسازید با:
- `page_offset` — اختلافِ شماره‌ی صفحه‌ی چاپ‌شده با شماره‌ی صفحه در PDF
(جلد و فهرست جلوترند). از روی فهرستِ کتاب و بازبینیِ یک صفحه‌ی مرزی درمی‌آید.
- `chapters` — بازه‌ی صفحه‌ی هر فصل بر اساسِ شماره‌ی چاپ‌شده. بازه‌ها باید
پشتِ‌هم و بدونِ حفره باشند (تستِ `TextbookLayoutTests` همین را چک می‌کند).
- `grade_label` — همان رشته‌ای که در payloadِ `grade` می‌نشیند.
عنوانِ فصل‌ها خودکار در `known_collections.MATH_CHAPTERS` ثبت می‌شود، پس
جستجو بلافاصله می‌تواند شماره‌ی فصل را به رشته‌ی دقیق تبدیل کند.
## بعدش چه اتفاقی می‌افتد