فاز 19 · درس 54

تولید خودکار مقاله در LaTeX: معماری مبتنی بر اسکلت و مانیفست

نوع
ساختنی
زمان
حدود 90 دقیقه
زبان‌ها
Python
یک ماکت یا اسکلت سیمی فلزی و هندسی از ساختار یک سند چاپی و چند کتاب و فرمول روی میز کار مهندسی
فهرست مطالب
  1. اهداف یادگیری
  2. چرا اول اسکلت؟
  3. ساختار داده‌ی Paper
  4. قرارداد رندر
  5. تزریق شکل‌ها از آزمایش‌ها
  6. تولیدکننده‌ی ساختگی متن
  7. خروجی مانیفست
  8. گیت‌های کنترلی اعتبارسنجی
  9. راهنمای خواندن کدها
  10. گام‌های بعدی

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

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

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

اسکلت LaTeX در واقع قراردادی میان پژوهشگر و حروف‌چین (typesetter) است. اگر این قرارداد نقض شود، سند کامپایل نخواهد شد و شکست آن کاملاً پر سر و صدا خواهد بود. اول اسکلت را بسازید، سپس درونش را پر کنید.

اهداف یادگیری

  • نگاه به مقاله‌ی پژوهشی به‌عنوان یک دست‌سازه (Artifact) ساختاریافته با گرافی مشخص از بخش‌ها، نه متنی آزاد و بی‌ساختار.
  • تولید یک اسکلت LaTeX که چکیده، بخش‌ها، جایگاه شکل‌ها و کلیدهای کتاب‌شناسی را پیش از نگارش حتی یک جمله از متن مشخص می‌کند.
  • تزریق شکل‌ها از خروجی‌های آزمایش (مسیرها و زیرنویس‌ها) به درون اسکلت از طریق یک سازوکار قطعی برای جایگاه‌ها (slots).
  • اتصال یک تولیدکننده‌ی متن ساختگی (mocked) که هر بخش را بر اساس طرحی کلی و ساختاریافته پر می‌کند تا بستر آزمایشی (harness) بدون نیاز به مدل هم قابل آزمایش باشد.
  • تولید یک فایل مجزای paper.tex به‌همراه references.bib و یک مانیفست (Manifest) که تمام شکل‌های ارجاع‌شده و ارجاعاتِ به‌کاررفته را فهرست می‌کند.
اسکلت مقالهاول ساختار، سپس متن
PAPER SKELETONThe skeleton declares sections, figure slots, and bibliography keys as data before any prose exists. The harness validates that contract first: every referenced figure has a slot, every citation has an entry, every section lands in the table of contents. Only then does the generator write prose into each slot, so structural debt never accumulates.چکیدهبخش: مقدمهبخش: روشجایگاه شکل: results.pngمنابع: 3 کلیداعتبارسنجی پیش از متن:okهر شکل یک جایگاه داردokهر استناد یک مدخل داردokهمه بخش‌ها در فهرستسپس متن جایگاه‌ها را پر می‌کند،هر بار یک بخش
اسکلت مقاله، بخش‌ها، جایگاه شکل‌ها و کلیدهای کتاب‌شناسی را پیش از وجود هرگونه متن به‌عنوان داده تعریف می‌کند. بستر آزمایشی ابتدا این قرارداد را اعتبارسنجی می‌کند: هر شکل ارجاع‌شده یک جایگاه دارد، هر استناد یک مدخل دارد، و هر بخش در فهرست مطالب قرار می‌گیرد. تنها پس از آن، مولد متن را در هر جایگاه می‌نویسد تا بدهی ساختاری هرگز انباشته نشود.

چرا اول اسکلت؟

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

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

این دقیقاً همان نظمی است که در درس‌های قبلی برای برنامه‌ها، فراخوانی ابزار (Tool call) و ردگیری محاسبات (Trace) به کار رفت. ساختار، همان قرارداد است.

ساختار داده‌ی Paper

مقالهفرادادهفهرست بخش‌هافهرست شکل‌هافهرست منابععنواننویسندگانچکیدهبخش: id, title, body, citesشکل: id, path, caption, labelمدخل کتاب‌شناسی: key, fields

تک‌تک فیلدها داده‌های معمولی پایتون هستند. رندرر (renderer) یک تابع خالص (Pure Function) از Paper به رشته‌ای در قالب LaTeX است. بستر آزمایشی می‌تواند پیش از رندر کردن، ساختار مقاله را تحلیل کند: تعداد بخش‌ها را بشمارد، فایل‌های مفقود تصاویر را فهرست کند و مطمئن شود که به ازای هر \cite{key} یک BibEntry متناظر وجود دارد.

قرارداد رندر

رندرر سه ویژگی را تضمین می‌کند. اول، به ازای هر جایگاه تصویر در اسکلت، یک بلوک \begin{figure} با برچسبی پایدار به‌فرم fig:<id> تولید می‌شود. دوم، هر بخش یک \section{} با برچسبی پایدار به‌فرم sec:<id> تولید می‌کند تا ارجاع‌های متقابل درست کار کنند. سوم، بخش کتاب‌شناسی یک بلوک \bibliography تولید می‌کند که فایل references.bib آن دقیقاً شامل مدخل‌های اعلام‌شده در ساختار مقاله باشد؛ نه یک مورد بیشتر و نه کمتر.

نقض هر یک از این موارد یک خطای رندر به‌شمار می‌رود، نه یک هشدار ساده. اسکلت، همان قرارداد است؛ رندری که به‌طور ضمنی و بی‌صدا شکلی را حذف کند، این قرارداد را نقض کرده است.

تزریق شکل‌ها از آزمایش‌ها

درس‌های پیشین این مسیر، خروجی‌های آزمایش را در قالب مانیفست‌های JSON تولید می‌کردند. هر مانیفست فهرستی از دست‌سازه‌ها را همراه با مسیرها و زیرنویس‌های کوتاه در بر دارد. نویسنده‌ی مقاله (paper writer) این مانیفست را می‌خواند و رکوردهای Figure را تولید می‌کند.

experiment.jsonread_experiment_manifestفهرست شکل‌هاPaper.figuresrender_latexpaper.tex

این تزریق کاملاً قطعی (deterministic) است. شناسه‌های تصویر از نام آزمایش به‌همراه یک شمارنده‌ی صعودی به‌دست می‌آیند. زیرنویس‌ها از مانیفست خوانده می‌شوند. مسیرها نسبت به دایرکتوری خروجیِ مقاله یکسان‌سازی (نرمالایز) می‌شوند تا حتی اگر خروجی‌های آزمایش در جای دیگری از دیسک باشند، فایل LaTeX بدون مشکل کامپایل شود.

تولیدکننده‌ی ساختگی متن

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

همین برای آزمودن تمام رفتارهای نویسنده کافی است. در پیاده‌سازی واقعی می‌توان به‌سادگی این تولیدکننده را با یک فراخوانی مدل زبانی جایگزین کرد؛ بستر آزمایشیِ پیرامون آن هیچ تغییری نخواهد کرد. ارزشِ تعریف تولیدکننده‌ی متن به‌صورت یک موجودیت فراخوان‌پذیر (callable) در همین است: در آزمون یک نسخه‌ی قطعی می‌گذارید و در محیط عملیاتی (پروداکشن) یک مدل واقعی، در حالی که باقی پایپ‌لاین کاملاً دست‌نخورده باقی می‌ماند.

خروجی مانیفست

نویسنده سه فایل در دایرکتوری خروجی می‌سازد.

PaperWriter.writepaper.texreferences.bibmanifest.jsonشکل‌های ارجاع‌شدهارجاعات استفاده‌شدهبخش‌های رندرشده

مانیفست همان چیزی است که ارزیاب‌ها یا چرخه‌ی ناقد (Critic) بعدی آن را می‌خوانند. این ابزارها LaTeX را تجزیه (parse) نمی‌کنند، بلکه مانیفست را می‌خوانند. در درس بعدی، یعنی چرخه‌ی ناقد، این مانیفست ورودی کار خواهد بود تا فهرستی از بازخوردها تولید شود. دقیقاً به همین دلیل مانیفست بخشی از قرارداد است، اما خودِ LaTeX جزو قرارداد نیست.

گیت‌های کنترلی اعتبارسنجی

نویسنده پیش از نوشتن هر فایلی، چهار گیت کنترلی (Gates) را بررسی می‌کند:

  1. شناسه‌ی هر شکل در سراسر مقاله یکتا باشد.
  2. فیلد cites در هر بخش، به کلید کتاب‌شناسی معتبری اشاره کند که در سند مقاله تعریف شده است.
  3. چکیده خالی نباشد.
  4. عنوان مقاله خالی نباشد.

رد شدن در هر گیت با اعلام خطای PaperValidationError و ذکر دقیق علت همراه است. بستر آزمایشی این دلیل را به‌عنوان حالت شکست (failure mode) منعکس می‌کند. نوشتن ناقص یا بخشی از فایل‌ها معنا ندارد: یا هر سه فایل کامل نوشته می‌شوند، یا هیچ‌کدام.

راهنمای خواندن کدها

فایل code/main.py کلاس‌های Paper، Section، Figure، BibEntry، PaperValidationError، MockProseGenerator، PaperWriter و تابع render_latex را تعریف می‌کند. متد write یک دایرکتوری خروجی می‌گیرد و سه فایل paper.tex، references.bib و manifest.json را تولید می‌کند. تابع کمکی read_experiment_manifest هم فهرستی از مانیفست‌های آزمایش را به رکوردهای Figure تبدیل می‌کند.

فایل code/tests/test_paper_writer.py این سناریوها را پوشش می‌دهد: رندر اسکلت بدون هیچ بخشی، رندر کامل با 2 بخش و 2 شکل، گیت ارجاع ناموجود، گیت شناسه‌ی تکراری شکل، محتوای مانیفست و قرارداد ساختار LaTeX (اینکه هر بخش حتماً یک \section{} و هر شکل یک \begin{figure} تولید کند).

گام‌های بعدی

در یک پیاده‌سازی واقعی، دو قابلیت اضافه بسیار کارآمد خواهد بود. اول، رندر به فرمت‌های گوناگون: اینکه همان ساختار Paper برای پست‌های وبلاگی به Markdown و برای پیش‌نمایش به HTML تبدیل شود. با این کار، رندرر به یک استراتژی روی Paper تبدیل می‌شود. دوم، غنی‌سازی ارجاعات: نویسنده با تکیه بر کش محلیِ DOIها، مدخل‌های BibTeX را از روی کلید ارجاع استخراج کند. هر دوی این قابلیت‌ها ارزش بالایی دارند و هر دو را می‌توان بدون دست زدن به قرارداد پایه‌ای اسکلت اضافه کرد.

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

خودآزمایی

به سؤال‌ها جواب بدهید تا ببینید چقدر از درس در ذهنتان مانده است.

  1. پیش از درسچرا نویسنده قبل از نوشتن متن، بخش‌ها، شکل‌ها و استنادها را به عنوان داده تعریف می‌کند؟
  2. پیش از درسمرحله تزریق شکل از مانیفست آزمایش چه چیزی تولید می‌کند؟
  3. حین درسکدام شکست در اعتبارسنجی پیش از نوشته شدن هر فایلی خطای PaperValidationError را ایجاد می‌کند؟
  4. حین درسچرا مولد متن به جای یک متد در PaperWriter، یک موجودیت قابل فراخوانی (callable) است که به آن تزریق می‌شود؟
  5. پس از درسمتد PaperWriter.write در صورت موفقیت چه سه فایلی را تولید می‌کند؟
  6. پس از درسچرا مانیفست به جای اینکه فقط فایل LaTeX باشد، بخشی از قرارداد نویسنده است؟

سؤالات متداول

چرا در تولید خودکار مقاله باید ابتدا اسکلت LaTeX ساخته شود؟

چون اسکلت ساختار را مانند یک قرارداد قطعی تثبیت می‌کند؛ پیش از نگارش متن تضمین می‌شود که تمام شکل‌ها جایگاه مشخص، تمام ارجاعات شناسه معتبر و تمام بخش‌ها ترتیب درستی دارند تا از بدهی ساختاری و خطای کامپایل جلوگیری شود.

چرا به جای ارسال مستقیم فایل LaTeX به چرخه‌های بعدی، مانیفست JSON تولید می‌شود؟

تجزیه (parse) کردن فایل‌های LaTeX برای مدل‌ها یا ارزیاب‌های خودکار سخت و شکننده است، اما مانیفست ساختاریافته تمام بخش‌ها، شکل‌ها و مراجع را به‌شکل داده خالص و خوانا در اختیار ابزارهای بعدی قرار می‌دهد.

گیت‌های اعتبارسنجی (Validation Gates) چه خطاهایی را قبل از نوشتن فایل‌ها مهار می‌کنند؟

این گیت‌ها مواردی چون یکتا بودن شناسه‌ی شکل‌ها، معتبر بودن کلیدهای کتاب‌شناسیِ ارجاع‌شده در هر بخش، و خالی نبودن عنوان و چکیده را بررسی می‌کنند و در صورت نقض هرکدام، مانع ذخیره ناقص فایل‌ها می‌شوند.

ما رو توی گوگل بیشتر ببین

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