اگر یک PDF، کتاب یا جزوه دارید و می‌خواهید ایجنت آن را به یک صفحه‌ی آموزشی قابل جست‌وجو و قابل ارجاع تبدیل کند، اسکیل learn-from-materials همین کار را می‌کند. در این پست نصب واقعی، اجرای واقعی روی یک فایل ۸ کیلوبایتی و خطای واقعیِ یک PDF را می‌بینید.

لحظه‌ی خواندن: ۲۷ سپتامبر ۲۰۲۶. ریپو در همین لحظه ۶۰۸ ستاره، ۵۹ فورک و ۰ ایشوی باز دارد، و زبان اصلی‌اش پایتون است. نسخه‌ی اعلام‌شده در فایل SKILL.md برابر 0.2.0 است و همین نسخه در تاریخچه با تاریخ ۲۰ سپتامبر ۲۰۲۶ ثبت شده.

این اسکیل چه کاری انجام می‌دهد

این پروژه یک دستورالعمل متنی برای ایجنت نیست که فقط متن را خلاصه کند. یک بسته‌ی کامل است که کار را به دو بخش تقسیم می‌کند: مدل فقط می‌فهمد و توضیح می‌دهد، و اسکریپت‌ها فقط استخراج، اعتبارسنجی و رندر را انجام می‌دهند. همین تفکیک در فایل SKILL.md به‌صراحت نوشته شده است.

آنچه این اسکیل را از یک خلاصه‌ساز معمولی جدا می‌کند، سه چیزی است که در ریپو واقعاً پیاده شده‌اند، نه فقط در توضیح آمده‌اند:

  1. نگاشت منبع. هر ادعا باید به یک بازه‌ی دقیق در فایل اصلی وصل شود. اسکریپت برای هر منبع یک شناسه‌ی پایدار می‌سازد و بازه‌ی نویسه‌ای آن را ذخیره می‌کند.
  2. جدا نگه‌داشتنِ آنچه ماده پوشش نداده. آنچه ماده می‌گوید، آنچه در ماده نبوده و آنچه خودِ مدل اضافه کرده، سه برچسب جدا هستند و در خروجی قابل تفکیک‌اند.
  3. دروازه‌ی پوشش. پیش از تحویل، یک اسکریپت بررسی می‌کند که آیا هر بخش از ماده واقعاً در صفحه آمده یا نه.

این پروژه روی دو ریپوی دیگر ساخته شده است: book-to-skill برای ساختار دانش و book-to-webpage برای صفحه‌ی تعاملی. فهرست کامل وابستگی‌های کاری در فایل NOTICE.md آمده است.

نصب و گزارش وابستگی‌ها

نصب این اسکیل با نصب یک پکیج پایتون فرق دارد. این یک بسته‌ی مهارت است و تنها کاری که لازم دارد این است که در مسیر جست‌وجوی اسکیل‌های ایجنت شما بنشیند. دستور زیر همان چیزی است که خودِ ریپو در بخش نصب نوشته است:

cd ~/src
# ریپو را می‌گیریم و کنار بقیه‌ی اسکیل‌ها می‌گذاریم
git clone https://github.com/dmoshehun-prog/learn-from-materials.git \
    ~/.claude/skills/learn-from-materials

# ساختار ریپو را می‌بینیم
ls ~/.claude/skills/learn-from-materials/scripts | head -8

خروجی واقعی این دستور روی همین سرور هشت اسکریپت اول است:

$ ls ~/.claude/skills/learn-from-materials/scripts | head -8
action_rules.py
audit_reverse_coverage.py
benchmark_pipeline.py
delivery.py
extract.py
finalize.py
localization.py
methodology.py

عدد بیست را دست کم نگیرید. یعنی بیست اسکریپت پایتون، هفده سند مرجع و ده فایل قالب در همین ریپو هست، و این‌ها قبل از آنکه ایجنت شما یک خط کد بنویسد کار می‌کنند.

این اسکیل یک تصمیم طراحی دارد که باید بدانیدش: هرگز خودش وابستگی نصب نمی‌کند. یعنی اگر کتابخانه‌ای نباشد، نمی‌رود pip install بزند و محیط شما را عوض کند. برای همین کار درست این است که اول وضعیت را بپرسید:

$ cd ~/.claude/skills/learn-from-materials
$ python3 scripts/extract.py --check
知识学习助手 — 依赖检查(只读)

  PPTX / PPTM
      → 可用:使用标准库解析器,可保留幻灯片编号和演讲者备注

  PDF(文字型)
      ✗ python: PyPDF2
      ✗ python: pdfminer.six
      ✗ system: pdftotext
      → 可选增强缺失,存在回退或可跳过

  PDF(表格/公式/代码密集)
      ✗ python: docling

این گزارش را بخوانید، نه اینکه از آن رد شوید. جمع‌بندی همین خروجی روی این سرور در جدول زیر آمده است:

قالب مادهمسیر پارس روی این سرور
PPTX و PPTMپارسر کتابخانه‌ی استاندارد، بدون وابستگی
PDF متنینیازمند pdftotext یا PyPDF2 یا pdfminer.six؛ هر سه غایب
PDF با جدول و فرمولنیازمند docling در حالت technical؛ غایب
PDF اسکن‌شدهنیازمند ocrmypdf؛ غایب
Markdown و متنبدون وابستگی، همان مسیری که در این پست اجرا شد

سطر اول مهم است: برای PowerPoint نیازی به نصب چیزی ندارید و شماره‌ی اسلاید و یادداشت سخنران حفظ می‌شود. سطرهای میانی می‌گویند اگر ماده‌ی شما PDF است، تا وقتی این وضعیت را نبینید در مرحله‌ی بعد غافلگیر می‌شوید.

اجرای واقعی، کش و تفسیر خروجی

حالا استخراج را روی یک فایل واقعی اجرا می‌کنیم. برای اینکه نتیجه قابل دفاع باشد، ماده را از خودِ همین ریپو برداشتیم: فایل references/method-library.md با ۸۰۰۳ بایت متن. این آزمون عمداً ساده است تا بتوانیم دقیقاً ببینیم خروجی چه چیزی می‌سازد.

$ python3 scripts/extract.py ../material.md --mode text --output-dir ../work
Extracting text document: /root/lfm/material.md

Extraction complete:
   Sources : 1 processed
   Size    : 0.01 MB
   Pages/slides: 0
   Words   : 1,059
   Tokens  : ~1K
   Chapters: 0 explicit chapter heading(s) detected
   Text -> .../work/full_text.txt
   Meta -> .../work/metadata.json
   Safety-> .../work/material-security-report.json
   Perf  -> .../work/performance-report.json
   Cache -> 0 hit(s), 1 miss(es)

چهار نکته در همین چند خط خروجی هست که باید بدانیدشان:

  • نگاشت منبع ساخته شد. فایل source_map.json شناسه‌ای مثل src-06b56969fc44-document-00001 را به بازه‌ی ۲۰۵ تا ۸۲۰۸ نویسه وصل می‌کند. هر ادعایی در صفحه‌ی نهایی می‌تواند به همین بازه برگردد.
  • اثر انگشت متن ثبت شد. همان sha256 در metadata.json و source_manifest.json تکرار می‌شود. این عدد پایه‌ی تشخیص تغییر ماده است.
  • گزارش امنیتی صفر یافته دارد. فایل material-security-report.json وضعیت را clear و تعداد یافته‌ها را ۰ ثبت کرده است.
  • برآورد توکن صریح برچسب خورده. عدد ۱۴۷۶ با روش cjk-aware-mixed محاسبه شده و خودِ فایل تصریح می‌کند که این یک تخمین است، نه شمارش دقیق.

تفسیر عددِ کلمه مهم است. فایل اصلی ۱۰۵۳ کلمه دارد و گزارش نهایی ۱۰۵۹ را چاپ می‌کند. این شش کلمه اختلاف از عنوان فایل و سربرگ است که خودِ ابزار اضافه می‌کند. یعنی عدد گزارش، شمارشِ متن استخراج‌شده است و شمارشِ خودِ فایل نیست.

رفتار بعدی برای کار تکراری مهم است: اگر فایل عوض نشده باشد، دوباره پردازش نمی‌شود. همان دستور را دوباره اجرا کنید:

$ python3 scripts/extract.py ../material.md --mode text --output-dir ../work
Reusing unchanged source: material.md

Extraction complete:
   Sources : 1 processed
   Words   : 1,059
   Cache -> 1 hit(s), 0 miss(es)

تغییرِ واقعی در دو جای خروجی دیده می‌شود: جمله‌ی اول از Extracting text document به Reusing unchanged source تبدیل می‌شود، و شمارنده‌ی کش از ۰ ضربه و ۱ اصابت به ۱ ضربه و ۰ اصابت می‌رسد. مبنای این تصمیم همان sha256 است که در اجرای قبل ذخیره شد.

فایل کش هم قابل بازرسی است و نامش همان اثر انگشت محتواست: work/.extraction-cache/57102676b9d3....json. اگر ماده عوض شود نام فایل کش عوض می‌شود و کش قدیمی بی‌اثر می‌ماند، بدون اینکه لازم باشد چیزی را دستی پاک کنید.

وقتی PDF شکست بخورد

قسمتی که این پست را می‌ارزد، همین شکست است. همان PDF مقاله‌ی ترنسفورمر را دادیم و ابزار در چند ثانیه متوقف شد:

$ python3 scripts/extract.py ../attention.pdf --mode text --ocr auto --output-dir ../work
PDF 文字提取 可使用可选包:PyPDF2, pdfminer.six。当前将使用回退方案
Trying pdftotext... not available
Trying PyPDF2... not available
Trying pdfminer.six... not available
Trying macOS PDFKit... unavailable or no text layer
Text extraction was empty; trying OCRmyPDF... WARNING: Skipping attention.pdf
ERROR: All 1 source(s) failed extraction

عدد پشت این شکست ساده است. گزارش --check سه مسیر را نام برده بود: pdftotext، PyPDF2 و pdfminer.six. هر سه روی این ماشین نبودند، و مسیر چهارم یعنی PDFKit فقط روی مک وجود دارد. نتیجه همان چیزی است که می‌بینید: خطا، بدون نصب چیزی.

راه درست، نصب کورکورانه نیست. سند امنیت این ریپو صریح می‌گوید که با حداقل دسترسی اجرا شود و وابستگی‌ها را خودکار نصب نکند. اگر PDF بخش اصلی کار شماست، یکی از آن سه کتابخانه را در یک محیط جدا نصب کنید و به اسکریپت بدهید. اگر ماده‌ی شما PDF نیست، همین الان با Markdown یا متن از بخش قبل ادامه دهید.

نکته‌ی عملی دیگر در همان سند امنیتی هست: ورودی همیشه داده‌ی بی‌اعتماد شمرده می‌شود، نه دستور. یعنی اگر داخل ماده‌ی شما نوشته باشند یک فایل را پاک کن، ابزار آن را اجرا نمی‌کند. برای کسی که PDF ناشناس دانلود می‌کند، این مهم‌ترین ویژگی این ریپو است.

محدودیت‌ها و جمع‌بندی

سه محدودیت را باید قبل از انتخاب بدانید، و همه از متن خودِ ریپو آمده‌اند نه از حدس من.

اول، زبان خروجی. نسخه‌ی بتا فقط en و zh-CN را پشتیبانی می‌کند. اگر می‌خواهید صفحه‌ی فارسی بگیرید، ریپو صریح می‌گوید باید بگویید کدام زبان پشتیبانی‌شده را استفاده کنید. این را قبل از شروع بدانید، نه بعد از یک ساعت کار.

دوم، دامنه‌ی پوشش. حالت systematic برای کتاب بلند پروژه‌ی چندروزه است: دفترچه‌ی قواعد، حسابرسی پوشش دوطرفه و نگاشت معکوس دارد. حالت quick در سند عمق یادگیری فقط هسته و شرایط لازم را درمی‌آورد. اگر هدفت یک مرور سریع است، quick را انتخاب کنید و انتظار فهرست کامل واژه‌نامه را نداشته باشید.

سوم، OCR. اسکریپت برای PDF اسکن‌شده می‌گوید پیش از رفتن به مسیر OCR از کاربر تأیید بگیر. یعنی برای جزوه‌ی اسکن‌شده، این ابزار به‌تنهایی کافی نیست و شما به یک لایه‌ی OCR جداگانه نیاز دارید.

جمع‌بندی: این اسکیل برای یک کار مشخص ساخته شده، تبدیل ماده به خروجی‌ای که بتوان به هر جمله‌اش برگشت. اگر خروجی شما فقط خلاصه باشد ابزارهای ساده‌تر کافی‌اند. اگر خروجی شما باید قابل ممیزی و قابل ارجاع باشد، همین نگاشت منبع دلیل کافی برای نصب است.

نکته‌ای که باید از این پست بگیرید این است: ابزاری که بی‌صدا وابستگی نصب کند، در پروژه‌ی واقعی دردسر است. این ابزار به‌جای آن خطا داد و گفت چه چیزی کم است. همین رفتار است، نه خروجی زیبا، که آن را قابل اعتماد می‌کند.

اگر می‌خواهید بدانید چرا خروجی HTML را دستی نمی‌نویسیم، به قرارداد محتوا نگاه کنید؛ برای جریان سریع، دستورهای واقعی حالت quick در سند جریان سریع آمده است. اگر هم می‌خواهید ببینید یک ایجنت روی یک هم‌بسته‌ی واقعی چطور کار می‌کند، پست بودجه‌ی کانتکست همان سمت دیگر همین موضوع است: هزینه‌ی پنهان هر لایه.

منابع

  1. ریپوی learn-from-materials — آمار، خوانده‌شده در ۲۷ سپتامبر ۲۰۲۶
  2. فایل SKILL.md — نسخه‌ی 0.2.0 و تفکیک مدل از اسکریپت
  3. تاریخچه — نسخه‌ی v0.2.0 در ۲۰ سپتامبر ۲۰۲۶
  4. سند امنیت — عدم نصب خودکار و رفتار با ماده‌ی بی‌اعتماد
  5. سند NOTICE — وابستگی به دو ریپوی پایه
  6. سند عمق یادگیری — تفاوت systematic و quick
  7. سند کتابخانه‌ی روش‌ها — ماده‌ی آزمون این پست
  8. قرارداد محتوا 4.3 — ساختار فیلدهای صفحه
  9. جریان سریع — دستورهای prepare_quick و render_page
  10. نمونه‌ی overview — ساختار JSON
  11. ریپوی book-to-skill — پایه‌ی ساختار دانش
  12. ریپوی book-to-webpage — پایه‌ی صفحه‌ی تعاملی