منطق ایجنت‌ها › M6 — ساختن سیستم بدون کد
۶.۷ پایدار تدریسی ~۳۵ دقیقه

یک سیستم واقعی را باز می‌کنیم

قبل از این فصل: فصل ۶.۲ · فصل ۶.۴

در یک نگاه

درباره‌ی این فصل این سیستم واقعی است و مدت‌ها کار کرده — به همین دلیل انتخاب شده، چون درسِ یک سیستمِ کارکرده با یک نمونه‌ی ساختگی فرق دارد. ولی فقط ساختار و منطقش نشان داده می‌شود؛ نام‌ها و محتوای واقعی با نمونه‌ی ساختگی جایگزین شده‌اند — که خودش تمرینِ فصل ۵.۳.۵ است: ساختار می‌ماند، محتوا جایگزین می‌شود.
۶.۷.۱

چه مسئله‌ای را حل می‌کرد

مسئله از یک واقعیتِ M1 شروع می‌شود: ایجنت بین session‌ها هیچ‌چیز یادش نمی‌ماند (فصل ۱.۴.۱). پس هر بار که کاری شروع می‌شد، باید همه‌چیز از نو توضیح داده می‌شد: این پروژه چیست، قبلاً چه تصمیم‌هایی گرفته شد، کجا ماند.

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

و همین سومی، تصمیم معماریِ اصلی را ساخت: کسی که کار می‌کند، اجازه‌ی نوشتن در حافظه را ندارد.

۶.۷.۲

ساختار پوشه‌ها

سیستم دو اتاق دارد، و مرزشان جدی است:

معماری کامل: دو اتاق و مرزشان اتاق حافظه شامل یادداشت‌های موضوعی و فایل تغییرات و ورودی است و یک نگهبان دارد؛ اتاق کار شامل پوشه‌ی پروژه‌ها و فایل وضعیت و گزارش‌ها است و یک سازنده دارد. سازنده فقط گزارش می‌فرستد و حافظه را فقط می‌خواند. اتاق حافظه نگهبان — فقط او می‌نویسد یادداشت‌های موضوعی _تغییرات.md _ورودی.md حقیقتِ پایدار اتاق کار سازنده — می‌سازد، نمی‌نویسد پوشه‌ی هر پروژه _وضعیت.md _گزارش‌ها/ کارِ در جریان ← گزارش: تنها راهِ ورود چیزی به حافظه ← خواندن: آزاد، در هر دو جهت
دو اتاق، یک مرز. خطِ پُر تنها مسیری است که حافظه را عوض می‌کند؛ خطِ نقطه‌چین فقط خواندن است.

و حالا تصمیم‌های طراحی که در این تصویر پنهان‌اند:

۶.۷.۳

نقش هر فایل

آزمون «این فایل کِی عوض می‌شود؟» (فصل ۶.۳.۴) را روی هر فایل اجرا کن و ببین چطور جواب می‌دهد:

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

۶.۷.۴

قوانینش و چرا این‌طور نوشته شدند

قوانین این سیستم کم‌اند، و هر کدام از یک شکستِ واقعی درآمده — نه از پیش‌بینی. این خودش یک درس است: قانونِ خوب معمولاً پس از خرابی نوشته می‌شود، نه قبلش.

۶.۷.۵

چه چیزی کار کرد و چه چیزی نه

این بخش صادقانه‌ترین بخش فصل است، و مفیدترینش.

چه چیزی کار کرد:

و چه چیزی کار نکرد — سه شکست واقعی:

  1. گزارش‌نوشتن، آخرین قدم بود؛ پس حذف شد. این بدترینشان بود. چون گزارش انتهای کار بود، وقتی کار تمام می‌شد دیگر انگیزه‌ای نمانده بود. یک بار نُه روز کار پشت سر هم گزارش نشد و هیچ‌چیز متوجهش نشد — چون سیستم راهی برای دیدنِ نبودن نداشت. حل: یک بررسی که کارهای گزارش‌نشده را پیدا می‌کند و اول هر کار نشانشان می‌دهد. یعنی همان درس فصل ۶.۴.۴ — قانونی که رعایت نمی‌شد به بررسی تبدیل شد، نه به تأکید بیشتر.
  2. حافظه فقط اضافه می‌شد. هیچ‌وقت چیزی حذف نمی‌شد، پس یادداشت‌ها کم‌کم پر از چیزهای منقضی شدند — دقیقاً همان ضدالگوی فصل ۶.۳. این هنوز کامل حل نشده است؛ فقط یک مرورِ دوره‌ای اضافه شد.
  3. ورودی سریع‌تر از پردازش پر می‌شد. ثبت ارزان بود (که خوب است)، ولی پردازش وقتِ ثابت نداشت (که بد است) — و نتیجه‌اش انبوهی شد که خودش دلیلِ سراغ‌نرفتن شد. همان گیرِ شماره‌ی یکِ فصل ۶.۶.۴، عیناً.

و الگوی مشترکِ این سه: هر سه‌شان جاهایی بودند که سیستم به یادآوریِ انسان تکیه کرده بود. هر جا که سیستم گفت «یادت باشد که…»، دیر یا زود شکست. هر جا که به یک بررسی یا یک ساختار تبدیل شد، دوام آورد.

۶.۷.۶

و یک خط کد هم داخلش نیست

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

و یک صداقتِ لازم: آن «بررسیِ کارهای گزارش‌نشده» که در بخش قبل گفتیم، یک برنامه‌ی کوچک است — و این نقض این فصل نیست، بلکه دقیقاً همان الگویی است که فصل ۶.۱.۳ وعده داد:

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

اگر از اول با کد شروع شده بود، هیچ‌کدام از این سه شکست پیدا نمی‌شد — چون زیر پیچیدگیِ کد پنهان می‌ماندند.

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

تمرین (فکری)

یک تصمیم طراحی این سیستم را نقد کن و جایگزین پیشنهاد بده. لازم نیست مؤدب باشی؛ لازم است دلیل داشته باشی. برای نقدت بگو:

  1. کدام تصمیم؟
  2. چه هزینه‌ای دارد که در فصل گفته نشد؟
  3. جایگزینت چیست، و آن جایگزین چه چیزی را از دست می‌دهد؟
پاسخنامه — یک نقد جدی به مهم‌ترین تصمیم سیستم

تصمیم مورد نقد: «سازنده هیچ‌وقت در حافظه نمی‌نویسد.» همان تصمیمی که فصل گفت بیشترین ارزش را داشت.

هزینه‌ای که در فصل گفته نشد: این قاعده یک تأخیر می‌سازد. بین لحظه‌ای که چیزی فهمیده می‌شود و لحظه‌ای که وارد حافظه می‌شود، یک فاصله هست — و در آن فاصله دانش در گزارشی است که هنوز خوانده نشده. یعنی سیستم عملاً دو حافظه دارد: حافظه‌ی رسمی، و انبوهِ گزارش‌های خوانده‌نشده. و شکستِ شماره‌ی یک (نُه روز گزارش‌نشده) در واقع همین هزینه است، نه یک اتفاق جدا — چیزی که فصل به‌عنوان مسئله‌ی انگیزه توضیحش داد، ریشه‌اش معماری است.

جایگزین: بگذار سازنده در حافظه بنویسد، ولی فقط در یک بخشِ مشخص و علامت‌دار (مثلاً «ثبت‌های تأییدنشده») که نگهبان بعداً تأییدشان می‌کند. یعنی به‌جای ممنوعیتِ نوشتن، نوشتنِ قابل‌تشخیص.

و آن جایگزین چه چیزی را از دست می‌دهد: سادگیِ مرز. الان قاعده یک جمله است و هیچ حالت میانی ندارد — پس نمی‌شود بدفهمیدش. نسخه‌ی پیشنهادی یک حالت سوم می‌سازد («نوشته‌شده ولی تأییدنشده») و حالا هر خواننده‌ای باید بداند این حالت وجود دارد و با آن چه کند. و طبق فصل ۶.۴.۱، هر حالتِ اضافه یک جای تازه برای تفسیرِ بی‌صداست.

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

ذخیره شد