چیزی که Ruff و mypy تو کد ایجنتها نمیبینن
خلاصهٔ کاملتر
نویسنده تعریف میکنه که ماجرا از یه code review شروع نشد، از این شروع شد که دید ایجنت تو کد خودش گم شده. هر بار به یه helper نیاز داشته یکی نوشته، و چندتاش تقریباً کپی همونهایی بودن که چند سشن قبل نوشته بود، با یه اسم کمی فرقدار و یه پارامتر اضافه. وقتی خواسته نحوهٔ نرمالسازی یه مقدار رو عوض کنه، چهار تابع پیدا شد که تقریباً همون کارو میکردن و آخرش سه تاشون تغییر کرد. نه ایجنت مطمئن بود کدوم اصلیه، نه خودش.
به گفتهٔ نویسنده مشکل جای دیگهایه: Ruff قواعد سطح کد رو میگیره مثل import بیاستفاده و اسم سایهانداز، mypy شکل دادههایی که بین توابع رد و بدل میشن رو با امضاها میسنجه، و pytest رفتار رو. هیچکدوم بین توابع رو نگاه نمیکنن. Ruff قاعدهای برای «این بلوک تو یه فایل دیگه هم هست» نداره، هیچچیز تو خط لوله نمیدونه کدوم ماژول اجازه داره کدوم رو import کنه، و helperی که دیگه صداش نمیزنن هم لینت رو پاس میکنه هم mypy رو.
قبل از ایجنتها این چیزها رو آدمی که diff رو میخوند میگرفت، ولی ایجنتها diff رو سریعتر از خوندن آدم تولید میکنن و اون بخش از review بیصدا تعطیل شده. نویسنده میگه کد تکراری تو کدبیس ایجنتنوشته فقط برای آدمها هزینه نداره؛ هر بار که ایجنت برمیگرده باید همهٔ کپیها رو دوباره بخونه و حدس بزنه کدوم اصلیه.
برای اندازهگیری، تحلیل ساختاری با pyscn (ابزار خود نویسنده برای پیدا کردن کد کلون، کد مرده و چرخهٔ وابستگی) روی پنج نقطه از تاریخ یه ریپوی چندهزارخطی NumPy و SciPy اجرا شد. نمره تو همهٔ اسنپشاتها حدود A موند، ولی میانگین پیچیدگی از ۶.۹ به ۸.۵ رسید. سر HEAD هشت تابع از ۳۲ تا پیچیدگی ۱۰ یا بالاتر داشتن و pyscn check با آستانهٔ پیشفرضش روی همهشون fail میشد، ولی این پروژه هیچوقت check رو تو CI اجرا نمیکرد و فقط نمره رو میدید.
چیزی که تکرار رو کم کرد یه gate تو CI نبود؛ به گفتهٔ نویسنده این بود که خود چکر بهعنوان ابزار MCP دست ایجنت باشه تا همون سشن، قبل از اینکه آدم diff رو ببینه، صداش بزنه و کپیها رو جمع کنه. اونوقت هنوز یادشه هر کپی چرا ساخته شده؛ بعدش اون context رفته و رفع تکرار میشه یه کار حوصلهسربر. توصیههای دیگهش هم سادهست: تو CI روی delta گیت بذار، میانگین پیچیدگی رو در طول زمان ردیابی کن، و قواعد وابستگی رو تو contract ابزاری مثل import-linter بنویس نه تو یه پاراگراف از CLAUDE.md.
نکات کلیدی:
- میانگین پیچیدگی از ۶.۹ به ۸.۵ رفت ولی نمرهٔ کلی روی A ثابت موند: نمره خط روند نیست
- سر HEAD هشت تابع از ۳۲ تا پیچیدگی ۱۰ یا بالاتر داشتن؛ pyscn زیر ۱۰ رو کم، ۱۰ تا ۱۹ رو متوسط و ۲۰ به بالا رو زیاد حساب میکنه
- پیچیدهترین تابع سر HEAD روی ۱۹ بود و نویسنده دست نزدش: یه متریک دلیلیه برای نگاه کردن، نه حکم
- تو لودر CSV دو شرط با بدنهٔ یکسان پیدا شد، و پکیج MCP لایهٔ وسط رو رد میکرد و مستقیم از ماژولهای عددی import میکرد
- radon و vulture معادل پیچیدگی و کد مرده رو میدن و import-linter قواعد وابستگی رو، ولی تشخیص کد کلون تو پایتون جواب استاندارد جدا نداره
- تو CI روی delta گیت بذار نه کل ریپو، وگرنه اجرای اول ۲۰۰ ایراد میده و تا ناهار چک خاموش میشه




