docs/
Outline
---
title: سه تا قانون کد تمیز واسه agentها، با چک ابزار
slug: clean-code-rules
lang: fa
published: 2026-10-31
words: 445
lines: 75
size: 3.4 KB
read: 3 min read
reel: توی دوران agentها، کد تمیز از همیشه مهمتره
---
قبلاً خودت کد رو مینوشتی و دلیل تکتک تصمیمها یادت بود. ولی agent هر session از صفر شروع میکنه و هر الگویی ببینه همونو کپی میکنه. ریپوی شلوغ هر session برات token میسوزونه و خروجیش هم شلوغتر میشه.
واسه همین سه تا قانون سفت دارم و هرکدوم رو یه ابزار چک میکنه. قانونی که کسی چکش نکنه فقط یه آرزوئه.
قانون ۱: هر بخش کار خودشو میکنه
agent واسه یه تغییر کوچیک باید فقط چندتا فایل بخونه. توی بکاند من جهت هر import مشخصه و کد فقط از یه سمت لایهها رو رد میکنه:
api > schemas > services > selectors > models
اگه لایهای از جهت اشتباه چیزی برداره، import-linter بیلد رو fail میکنه. این قرارداد واقعی از pyproject.toml منه:
[[tool.importlinter.contracts]]
name = "inside each app: api > schemas > services > selectors > models"
type = "layers"
containers = ["apps.accounts", "apps.content"]
layers = ["(api)", "(schemas)", "(services)", "(selectors)", "(models)"]
PYTHONPATH=src uv run lint-imports
Contracts: 5 kept, 0 broken.
قانون ۲: کامنتا درستن و هر function یه docstring داره
agent به هرچی بخونه اعتماد میکنه. کامنت غلط میفرستدش راه غلط. پس کامنت دلیل رو توضیح میده و هر function عمومی یه docstring به سبک Google داره:
def minutes(self, body_en: str, body_fa: str) -> int:
"""Return the reading time of the longer body.
Args:
body_en: English Markdown source.
body_fa: Persian Markdown source.
Returns:
Whole minutes, at least 1.
"""
Ruff اینو چک میکنه، با هر چیز دیگهای که بتونه:
[tool.ruff.lint]
select = ["ALL"]
قانون ۳: dead code نداریم
agent وقتی یه login قدیمی کنار login فعلی ببینه، باید حدس بزنه کدوم واقعیه و گاهی اشتباه حدس میزنه. کدی که حذف شده واقعاً پاک میشه، نه کامنت میشه نه پشت flag میمونه. Git یادش میمونه. قانونهای ERA توی Ruff هم کد کامنتشده رو میگیرن و select = ["ALL"] روشنشون کرده.
یه بار هزینه بده
قبلاً تمیز نگه داشتن ریپو گرون بود و همه با شلوغیش میساختن. الان agent تمیزش میکنه. یه بار هزینه میدی و هر session بعدی کمتر میخونه و بیشتر درست میزنه.
اینو بذار توی CLAUDE.md
## Code rules
- Each module does one job. Respect the import direction: api > services > selectors > models.
- Every public function, class and module has a Google style docstring.
- Comments explain why, never what. Fix or delete a comment that is wrong.
- No dead code. Delete what is unused, including old versions. Git keeps the history.
- Before you finish, run the linters and the tests, and report their real output.
همین چکها رو توی CI هم بذار تا هیچ sessionی نتونه ازشون رد بشه.
| قبلاً خودت کد رو مینوشتی و دلیل تکتک تصمیمها یادت بود. ولی agent هر session از صفر شروع میکنه و هر الگویی ببینه همونو کپی میکنه. ریپوی شلوغ هر session برات token میسوزونه و خروجیش هم شلوغتر میشه. |
| واسه همین سه تا قانون سفت دارم و هرکدوم رو یه ابزار چک میکنه. قانونی که کسی چکش نکنه فقط یه آرزوئه. |
| ## قانون ۱: هر بخش کار خودشو میکنه |
| agent واسه یه تغییر کوچیک باید فقط چندتا فایل بخونه. توی بکاند من جهت هر import مشخصه و کد فقط از یه سمت لایهها رو رد میکنه: |
| ```text |
| api > schemas > services > selectors > models |
| ``` |
| اگه لایهای از جهت اشتباه چیزی برداره، `import-linter` بیلد رو fail میکنه. این قرارداد واقعی از `pyproject.toml` منه: |
| ```toml |
| [[tool.importlinter.contracts]] |
| name = "inside each app: api > schemas > services > selectors > models" |
| type = "layers" |
| containers = ["apps.accounts", "apps.content"] |
| layers = ["(api)", "(schemas)", "(services)", "(selectors)", "(models)"] |
| ``` |
| ```bash |
| PYTHONPATH=src uv run lint-imports |
| ``` |
| ```text |
| Contracts: 5 kept, 0 broken. |
| ``` |
| ## قانون ۲: کامنتا درستن و هر function یه docstring داره |
| agent به هرچی بخونه اعتماد میکنه. کامنت غلط میفرستدش راه غلط. پس کامنت دلیل رو توضیح میده و هر function عمومی یه docstring به سبک Google داره: |
| ```python |
| def minutes(self, body_en: str, body_fa: str) -> int: |
| """Return the reading time of the longer body. |
| Args: |
| body_en: English Markdown source. |
| body_fa: Persian Markdown source. |
| Returns: |
| Whole minutes, at least 1. |
| """ |
| ``` |
| Ruff اینو چک میکنه، با هر چیز دیگهای که بتونه: |
| ```toml |
| [tool.ruff.lint] |
| select = ["ALL"] |
| ``` |
| ## قانون ۳: dead code نداریم |
| agent وقتی یه login قدیمی کنار login فعلی ببینه، باید حدس بزنه کدوم واقعیه و گاهی اشتباه حدس میزنه. کدی که حذف شده واقعاً پاک میشه، نه کامنت میشه نه پشت flag میمونه. Git یادش میمونه. قانونهای `ERA` توی Ruff هم کد کامنتشده رو میگیرن و `select = ["ALL"]` روشنشون کرده. |
| ## یه بار هزینه بده |
| قبلاً تمیز نگه داشتن ریپو گرون بود و همه با شلوغیش میساختن. الان agent تمیزش میکنه. یه بار هزینه میدی و هر session بعدی کمتر میخونه و بیشتر درست میزنه. |
| ## اینو بذار توی CLAUDE.md |
| ```markdown |
| ## Code rules |
| - Each module does one job. Respect the import direction: api > services > selectors > models. |
| - Every public function, class and module has a Google style docstring. |
| - Comments explain why, never what. Fix or delete a comment that is wrong. |
| - No dead code. Delete what is unused, including old versions. Git keeps the history. |
| - Before you finish, run the linters and the tests, and report their real output. |
| ``` |
| همین چکها رو توی CI هم بذار تا هیچ sessionی نتونه ازشون رد بشه. |





