Digisky
پژوهش حقوقی۱۴۰۵ — شش روز تحویلِ سکو، روی پیکره‌ای که پیش‌تر ساخته شده بود

ساخت پیکرهٔ ۱٫۸ گیگابایتی حقوق ایران

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

مسئله

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

۱,۸۲۶ MBحجم پیکره روی دیسک
۱۸۳,۷۲۵صفحهٔ خزش‌شده
۱۵۱,۲۱۶ / ۰واحد جست‌وجو / واحد بردارشده
۲۴,۵۱۷ of ۳۴,۷۷۳یال استنادی قرنطینه‌شده
۵۶ (۱۸ critical)یافتهٔ پاک‌سازی در هفت دور
۳,۰۴۳آزمون خودکار

این پروژه قرار نبود دستیار حقوقی باشد

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

جواب این پرسش از پیکره می‌آید، نه از مدل. پس پیکره خودِ پروژه شد.

«این متن از کجا می‌آید و آیا در روزی که موکل من اقدام کرده هنوز معتبر بوده؟»

خزش: ۱۸۳٬۷۲۵ صفحه در حدود ۸۰ دقیقه

هشت دراپلت از ارزان‌ترین‌ها، صفر بن، یک تا دو دلار هزینهٔ کل.

نکتهٔ جالب سرعت نیست. دو ثابتی است که ناوگان حولشان ساخته شد:

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

هیچ‌چیز این طراحی هوشمندانه نیست. فقط صادقانه است، و صداقت همان چیزی است که تکرارپذیرش می‌کند.

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

آنچه در پیکره هست

محتوا تعداد سطر
قانون، شامل قانون اساسی ۱٬۰۲۰
ماده، شامل ۱۷۷ اصل قانون اساسی ۳۲٬۱۰۳
تبصره، به‌عنوان موجودیت مستقل ۱۴٬۴۷۱
رأی قضایی ۳۵٬۱۸۵
نظریهٔ مشورتی ۱۳٬۴۶۲
نشست قضایی ۶٬۴۰۶
اثر پژوهشی ۲۱٬۸۷۰
شرح و تفسیر ۸۲٬۵۴۰
موضوع · پیوند موضوعی ۲۳٬۵۶۷ · ۳۶۱٬۱۶۷
قاضی ۱٬۴۰۱
یال ماده‑به‑ماده · یال ماده‑به‑رأی ۳۴٬۷۷۳ · ۳۹٬۷۱۲
واحد جست‌وجو در استخر بازیابی ۱۵۱٬۲۱۶
واحد جست‌وجوی دارای بردار ۰

و پیرامون آن یک سکوی عملیاتی: احراز هویت، بسته‌های اشتراک، دو درگاه پرداخت پشت یک واسط، پنل مدیریت و دفتر رویداد — ۳۳ دکوریتور مسیر روی ۱۱ روتر، ۱۴ جدول اپلیکیشن، و حدود ۳٬۰۴۳ آزمون خودکار. بیست کامیت در شش روز، شانزده وظیفهٔ برنامه‌ریزی‌شده، هر شانزده سبز.

هفت دور، ۵۶ یافته

حکم دربارهٔ بارگذاری اول همان موقع نوشته شد: پیش‌نویس اول خوبی است و هنوز در حد محصول نیست. هفت دور «ممیزی، سپس اصلاح» ۵۶ یافته داد که ۱۸ تای آن بحرانی بود. نمونه‌ای از آنچه یک پیکرهٔ حقوقی واقعاً غلط دارد:

  • قانون اساسی کلاً غایب بود. تجزیه‌گر «مادهٔ N» را می‌شناخت و «اصل N» را نه، پس همهٔ اصول بی‌صدا افتاده بودند. از آرشیو خام بازیابی شد؛ بدون جای خالی.
  • رتبهٔ اعتبار کاملاً تخت بود. همهٔ آرا در یک سطح بارگذاری شده و هیچ‌کدام لازم‌الاتباع علامت نخورده بود، پس رأی وحدت رویه دقیقاً هم‌رتبهٔ رأی بدوی می‌نشست.
  • گراف استناد بیشتر ناوبری بود. ۲۴٬۵۱۷ یال از ۳۴٬۷۷۳ یال، همان الگوی «مادهٔ قبلی / مادهٔ بعدی» بود.
  • سند در طبقهٔ اشتباه. پایان‌نامه‌هایی که به‌عنوان قانون با شمارهٔ مادهٔ ساختگی وارد شده بودند؛ قانون اساسی یک کشور دیگر که به‌عنوان قانون داخلی نشسته بود؛ صفحه‌های جانگهدارِ ویکی که به‌عنوان رأی بارگذاری شده بودند.
  • باقی‌ماندهٔ لایه‌لایهٔ نشانه‌گذاری در ستون‌های متنی، از جمله کدگذاری نیم‌فاصله که رندر فارسی را می‌شکست — با چهار تابع SQL خودتوان و قابل‌استفادهٔ مجدد تمیز شد، نه با یک اسکریپت یک‌بارمصرف.

دور چهارم: تشخیص ما غلط بود

دور چهارم «تکه‌تکه بودن قوانین» را نقص ثبت کرده بود — یک قانون که ظاهراً میان چند رکورد پخش شده — و برایش ادغام تعریف کرده بود. بررسی پیش از اجرا خلافش را نشان داد: دو رکوردی که همهٔ شماره‌مواد را مشترک داشتند، تقریباً هیچ‌کدام از متن مواد را مشترک نداشتند. این‌ها دو نسخهٔ متوالی از یک قانون بودند که درست هم ذخیره شده بودند. یازده قانونی هم که «خالی» علامت خورده بودند، قوانین واقعی با محتوای مفقود بودند؛ یعنی مسئله‌ای دیگر با راه‌حلی دیگر.

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

بازیابی، به‌عنوان طراحی و نه ادعا

طراحی بازیابی به شکل یک تابع PostgreSQL و یک اسکیما تحویل شده، نه به شکل یک قابلیت در حال اجرا: دو بازو — یکی چگال روی بردار نیم‌دقتِ ۱۰۲۴‑بعدی با ایندکس HNSW و یکی واژگانی روی tsvector با پیکربندی simple — که با RRF و k=۶۰ ترکیب می‌شوند، هر بازو ۱۵۰ نامزد بیش‌واکشی می‌کند، فیلترهای «لازم‌الاجرا» و «قابل‌استناد» در خودِ تابع تنیده‌اند، و گره رتبه با سطح اعتبار باز می‌شود.

سه نکته در آن تصمیم است، نه پیش‌فرض:

  • پرس‌وجوی واژگانی با OR ساخته می‌شود، چون معنای AND برای شرح پرونده‌های واقعی صفر سطر برمی‌گرداند. نتیجهٔ کمتر ولی مرتب‌شده، از هیچ بهتر است.
  • PostgreSQL ریشه‌یاب فارسی ندارد. نه در پیکربندی‌های استاندارد و نه در افزونه‌های رایج. پس نرمال‌سازی در لایهٔ ورود انجام و در ستون‌های اختصاصی مادی می‌شود — و همان نرمال‌ساز باید هنگام پرس‌وجو هم اجرا شود، وگرنه بازوی واژگانی یک دروغ است.
  • بردارها خودمیزبان‌اند، روی مدلی با مجوز آزاد و ۱۰۲۴ بعد؛ همان مدل و همان بُعدی که مستقلاً برای سکوی تحلیل داده‌مان هم انتخاب شد. سرویس‌های ابری بردارسازی روی کیفیت ارزیابی نشدند؛ آن‌ها در دسترس نبودند، که گفت‌وگوی کوتاه‌تری است.

برای خریدار

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

ما می‌توانیم همهٔ این‌ها را دربارهٔ این پیکره جواب بدهیم، از جمله جواب‌هایی که به نفعمان نیست. کل دلیل انتشار این پرونده در همین مرحله — و نه بعد از انتشار صفحهٔ گفت‌وگو — همین است.

تصمیم‌ها

یال‌های آلودهٔ گراف استناد با یک پرچم قرنطینه شدند، نه با DELETE.

گزینه‌های دیگر: حذف ۲۴٬۵۱۷ سطر مشکوک، رها کردن گراف به همان شکل واردشده

حدود هفت یال از هر ده یال گراف، محصول پیوندهای ناوبری «مادهٔ قبلی/بعدی» بود و در همان جدولی نشسته بود که حدود ده هزار یال واقعی در آن است. DELETE تشخیص را ابطال‌ناپذیر می‌کند: اگر دربارهٔ الگو اشتباه کرده باشیم، شاهدی برای بازگشت نمانده. علامت‌گذاری اجازه می‌دهد امروز بازیابی آن‌ها را فیلتر کند و فردا بتوان دربارهٔ همان تصمیم دوباره بحث کرد.

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

ادغام قوانینی که «تکه‌تکه» به نظر می‌رسیدند لغو شد، چون تشخیص اولیه غلط از آب درآمد.

گزینه‌های دیگر: اجرای همان ادغامِ برنامه‌ریزی‌شده روی رکوردهای به‌ظاهر تکراری

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

در همان دور، یک فیلتر حذف برای آرای به‌ظاهر تکراری هم رد شد، چون بیشتر سطرهای نمونه آرای واقعی و مختومه بودند.

رتبه‌بندی روی اعتبار منبع، نه فقط روی شباهت برداری.

گزینه‌های دیگر: شباهت برداری خالص، شباهت به‌علاوهٔ تازگی

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

سطر ممیزی در همان تراکنشی نوشته می‌شود که خودِ عمل را ثبت می‌کند.

گزینه‌های دیگر: قلاب پس از commit، الگوی outbox، ثبت بهترین‌تلاش با هشدار در صورت خطا

هر سه جایگزین، همان شکستی را برمی‌گردانند که قرار بوده جلویش را بگیرند: عملی که اتفاق افتاده و ردی از آن نیست. نوشتن ممیزی فقط به session اضافه می‌شود؛ پس اگر و تنها اگر خودِ عمل commit شود، ممیزی هم commit می‌شود. یک تریگر پایگاه‌داده UPDATE و DELETE روی این جدول را به خطا تبدیل می‌کند و یک آزمون پوشش، جدول مسیرهای زنده را می‌پیماید و هر نقطهٔ پایانی تغییردهندهٔ تازه‌ای را که رویدادهایش را اعلام نکرده باشد قرمز می‌کند. در هیچ محیطی کلید خاموش‌کردن ندارد.

۱۵۱٬۲۱۶ بردار فعلاً تولید نمی‌شود.

گزینه‌های دیگر: تولید بردارها و انتشار صفحهٔ گفت‌وگو

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

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

محدودیت‌ها

  • بازیابی روشن نیست. استخر بازیابی ۱۵۱٬۲۱۶ واحد جست‌وجو دارد و صفر بردار. این یک پیکره و یک سکوست، نه دستیار حقوقی در حال کار؛ و توصیف آن به‌عنوان دستیار حقوقی نادرست است.
  • هیچ عدد تأخیر، دقت، nDCG یا فراخوانی برای این سامانه در هیچ جایی وجود ندارد. مجموعهٔ طلایی ارزیابی یک قلم تحویل‌شدنیِ زمان‌بندی‌شده است، نه یک نتیجه. هر عددی که دربارهٔ کیفیت بازیابی این سامانه به شما گفته شود، ساخته شده است.
  • پیکره از منابع عمومی مرجع حقوقی گردآوری شده و وضعیت مجوز آن تعیین‌تکلیف نشده است. انتقال متن اولیه به منابع رسمی در برنامه است و خود پیکره توزیع نمی‌شود.
  • بخشی از صفحه‌های منبع، خلاصه‌های ماشین‌تولید خودِ منبع را حمل می‌کنند. این‌ها ثبت، پرچم‌گذاری و به‌صورت پیش‌فرض از مجموعهٔ قابل‌استناد کنار گذاشته شده‌اند — اما این یک فیلتر روی برچسبی است که منبع خودش زده، نه تضمینی که ما تولید کرده باشیم.
  • بیشتر یال‌های میان مواد و آرا، بازتاب پیوند سطح صفحه‌اند نه استناد در متن رأی. این یال‌ها فقط به‌عنوان ویژگی رتبه‌بندی به کار می‌روند و هرگز خودبه‌خود به نتایج اضافه نمی‌شوند.
  • قانونِ نقطه‌ای‌در‌زمان دقیقاً به اندازهٔ تاریخچهٔ نسخه‌های پشت آن کامل است. هرجا تاریخچه به‌طور شناخته‌شده ناقص باشد، تابع به‌جای جا زدن متن امروز به‌جای متن آن روز، هیچ برمی‌گرداند — که درست است و در عمل یعنی اغلب هیچ برمی‌گرداند.