مقدمه: من هم فقط به AI میگفتم «این Feature رو بساز»
اگه مدتی با ابزارهایی مثل Codex، Claude Code، GitHub Copilot یا بقیه Coding Agentها کار کرده باشین، احتمالاً این سناریو براتون آشناست.
پروژه رو باز میکنیم، Agent رو اجرا میکنیم و خیلی ساده میگیم:
یه صفحه لاگین بساز.
Agent هم شروع میکنه به گشتن توی پروژه، چندتا فایل رو بررسی میکنه، Component میسازه، Form رو پیاده میکنه و در نهایت یه چیزی تحویلمون میده که حداقل در نگاه اول درست به نظر میرسه.
تا اینجای کار همهچیز خوبه.
Feature بعدی رو هم همینطوری میسازیم. بعدی رو هم میدیم به Agent. یه Bug پیدا میکنیم و میگیم درستش کن. بعد یه Refactor کوچیک، یه API جدید و همینطور ادامه میدیم.
در ظاهر همهچیز خوبه. اما بعد از چندتا Feature متوجه میشیم Agent بعضی جاها الگوی جدید ساخته، بعضی تصمیمهای قبلی پروژه رو نمیدونه و گاهی فایلهایی را تغییر داده که اصلاً قرار نبوده دست بزنه.
مثلاً توی یه بخش از پروژه یه الگوی مشخص برای Formها داریم، ولی Agent برای Feature جدید یه روش دیگه پیاده کرده. یا قبلاً تصمیم گرفتیم Refresh Token داخل HttpOnly Cookie باشه، ولی چند هفته بعد یه Agent دیگه پیشنهاد میده بفرستیمش داخل localStorage.
اینجاست که یه سؤال مهم واسمون پیش میاد:
مشکل از Prompt ماست؟ مدل AI ضعیفه؟ یا اصلاً روش کار ما با Agent درست نیست؟
جواب معمولاً ترکیبی از اینهاست، ولی یه بخش خیلی مهم ماجرا چیز دیگهایه:
Agent کدنویسی بلده، ولی پروژه ما رو نمیشناسه.
مشکل Vibe Coding دقیقاً چیه؟
Vibe Coding برای شروع واقعاً جذابه.
بهجای اینکه خودمون چند ساعت درگیر یه Feature بشیم، چیزی که میخوایم رو توضیح میدیم و AI بخش زیادی از کار رو انجام میده.
مثلاً:
<div class="dir-rtl">
یه صفحه لاگین بساز که شماره موبایل بگیره و OTP ارسال کنه.
</div>
برای یه Prototype یا پروژه کوچیک، همین روش ممکنه کاملاً جواب بده.
مشکل از جایی شروع میشه که پروژه بزرگتر میشه.
Agent خیلی چیزهایی رو که برای ما بدیهیه، نمیدونه.
نمیدونه معماری مورد قبول پروژه چیه.
نمیدونه برای Formها چه Patternی داریم.
نمیدونه چه Componentهایی باید Reuse بشن.
نمیدونه چه فایلهایی اجازه تغییر دارن.
نمیدونه Business Ruleهایی که چند ماه پیش دربارهشون تصمیم گرفتیم چی بودن.
حتی ممکنه ندونه Definition of Done ما برای یه Feature چیه.
فرض کنیم فقط بهش بگیم:
Implement authentication.
Agent حالا باید کلی تصمیم بگیره.
JWT استفاده کنه یا Session؟
Authentication با Password باشه یا OTP؟
Refresh Token کجا ذخیره بشه؟
Token Rotation داشته باشیم؟
Rate Limit چی؟
Logout دقیقاً چه کاری انجام بده؟
Backend فعلی رو تغییر بده یا نه؟
اگه جواب این سؤالها جایی ثبت نشده باشه، Agent مجبور میشه بخشی از اونها رو از روی Codebase حدس بزنه و بخشی رو هم خودش تصمیم بگیره.
گاهی درست تصمیم میگیره.
گاهی هم نه.
و هرچقدر پروژه بزرگتر بشه، هزینه همین «گاهی نه» بیشتر میشه.
Prompt Engineering کافی نیست
وقتی خروجی AI خوب نیست، اولین چیزی که معمولاً به ذهنمون میرسه اینه که:
باید Prompt بهتری بنویسم.
این حرف اشتباه نیست.
Prompt Engineering هنوز مهمه.
ولی همه ماجرا نیست.
فرض کنیم یه Prompt خیلی کامل بنویسیم:
Create an OTP authentication system using NestJS.
Use JWT access tokens.
Store refresh tokens in HttpOnly cookies.
Follow our existing architecture.
Reuse existing utilities.
Don't modify unrelated modules.
Add tests.
...
این Prompt احتمالاً نتیجه خیلی بهتری نسبت به «Authentication بساز» میده.
ولی یه مشکل داریم.
برای Feature بعدی چی؟
دوباره باید همه این چیزها رو توضیح بدیم؟
برای Session بعدی چی؟
اگه یه Agent دیگه وارد پروژه شد چی؟
اینجا تفاوت Prompt Engineering و Context Engineering مهم میشه.
Prompt Engineering بیشتر درباره اینه که:
درخواستمون رو چطور بهتر به AI بگیم؟
ولی Context Engineering یه سؤال بزرگتر میپرسه:
Agent برای انجام درست این کار به چه اطلاعاتی نیاز داره و چطور باید به اون اطلاعات دسترسی پیدا کنه؟
این تفاوت کوچیک به نظر میرسه، ولی در پروژههای واقعی خیلی مهمه.
Context Engineering چیه؟
Context Engineering رو خیلی ساده میشه اینطوری تعریف کرد:
بهجای اینکه فقط روی چیزی که به Agent میگیم تمرکز کنیم، روی چیزهایی که Agent قبل و حین انجام کار باید بدونه هم فکر کنیم.
این Context میتونه شامل چیزهای مختلفی باشه:
- معماری پروژه
- Coding Conventionها
- Business Ruleها
- تصمیمهای معماری قبلی
- Feature Spec
- Task فعلی
- محدودیتهای پروژه
- کدهای مشابه موجود
- تستها
- Definition of Done
مثلاً وقتی از Agent میخوایم یه Form جدید بسازه، شاید لازم نباشه کل معماری Database رو بخونه.
ولی احتمالاً لازمه بدونه:
- پروژه از Reactive Forms استفاده میکنه.
- Validation Messageها چطور نمایش داده میشن.
- چه Input Componentهایی از قبل داریم.
- Localization چطور انجام میشه.
- یه Form سالم و مشابه توی پروژه کجاست.
اینجا یه نکته خیلی مهم وجود داره:
Context خوب یعنی اطلاعات مرتبط، نه بیشترین اطلاعات ممکن.
اینکه ۵۰تا فایل Markdown داشته باشیم و قبل از هر Task به Agent بگیم همه رو بخون، لزوماً Context Engineering خوبی نیست.
حتی ممکنه نتیجه رو بدتر کنه.
جلوتر به این موضوع برمیگردیم.
Repository Instructions؛ یه README برای Agent
یکی از سادهترین کارهایی که میتونیم انجام بدیم اینه که یه نقطه ورود مشخص برای Agent داشته باشیم.
مثلاً:
project/
├── src/
├── tests/
├── AGENTS.md
└── README.md
فایل README.md معمولاً پروژه رو برای Developer توضیح میده.
AGENTS.md رو میتونیم یه جور README برای Coding Agent در نظر بگیریم.
مثلاً:
# Agent Instructions
## Stack
- Angular
- TypeScript
- NestJS
- PostgreSQL
## Rules
- Reuse existing components before creating new ones.
- Do not modify backend unless explicitly requested.
- Do not hard-code translatable strings.
- Follow existing project patterns.
- Run tests before finishing.
این فایل قرار نیست تمام دانش پروژه رو داخل خودش داشته باشه.
اتفاقاً اگه AGENTS.md تبدیل به یه فایل ۵۰۰۰ خطی بشه، احتمالاً داریم اشتباه ازش استفاده میکنیم.
بهتره چیزهایی داخلش باشن که Agent تقریباً همیشه باید بدونه.
مثلاً:
- Stack اصلی پروژه
- دستور Build و Test
- قوانین مهم پروژه
- محدودیتهای تغییر
- Conventionهای اصلی
- مسیر Documentationهای مرتبط
- Definition of Done عمومی
بعد برای جزئیات بیشتر، Agent رو به فایلهای تخصصیتر هدایت کنیم.
آیا .ai، docs، AGENTS.md و .github استاندارد هستن؟
اینجا یه نکته مهم وجود داره، چون ممکنه با دیدن Repositoryهای مختلف فکر کنیم همه این اسمها استاندارد خاصی دارن.
اینطور نیست.
مثلاً خودمون میتونیم تصمیم بگیریم یه فولدر داشته باشیم:
.ai/
و داخلش بنویسیم:
.ai/
├── tasks.md
├── progress.md
└── handoff.md
این ساختار میتونه خیلی مفید باشه، ولی .ai بهخودیخود یه استاندارد جهانی نیست.
Agent فقط به خاطر اینکه اسم فولدر .ai هست، الزاماً نمیفهمه باید تمام فایلهای داخلش رو بخونه.
از طرف دیگه، بعضی فایلها توسط ابزارهای مشخص شناخته میشن.
مثلاً ممکنه در پروژههای مختلف با اینها روبهرو بشیم:
AGENTS.md
CLAUDE.md
GEMINI.md
.github/copilot-instructions.md
بعضی از اینها عمومیتر شدن و بعضی کاملاً Tool-specific هستن.
پس بهتره این سه دسته رو از هم جدا کنیم:
Convention شخصی یا تیمی
مثل:
.ai/
docs/
Agent Instructions شناختهشده
مثل:
AGENTS.md
فایلهای مخصوص یه ابزار
مثل:
.github/copilot-instructions.md
CLAUDE.md
GEMINI.md
نکته مهم اینه که اسم فایل یا فولدر جادو نمیکنه.
باید بدونیم Agent مورد استفادهمون چه فایلهایی رو واقعاً میشناسه و برای ساختارهای شخصی خودمون هم یه مسیر مشخص تعریف کنیم.
مثلاً داخل AGENTS.md بگیم:
Before implementing a feature:
1. Read the relevant documents under docs/.
2. Read the current feature spec.
3. Check relevant architectural decisions.
4. Find a similar existing implementation.
5. Run tests before finishing.
حالا Agent میدونه برای پیدا کردن Context بیشتر باید کجا بره.
Project Knowledge Base؛ حافظه بلندمدت پروژه
حالا میرسیم به docs/.
من دوست دارم به این بخش به چشم حافظه بلندمدت پروژه نگاه کنم.
مثلاً:
docs/
├── product/
│ ├── vision.md
│ ├── glossary.md
│ └── business-rules.md
│
├── architecture/
│ ├── overview.md
│ ├── frontend.md
│ ├── backend.md
│ └── database.md
│
└── standards/
├── frontend.md
├── backend.md
└── testing.md
داخل product/ چیزهایی قرار میگیرن که توضیح میدن اصلاً چی داریم میسازیم.
داخل architecture/ توضیح میدیم سیستم چطور طراحی شده.
داخل standards/ هم Patternها و قواعدی رو میذاریم که موقع توسعه باید رعایت بشن.
یه نکته خوب درباره این Documentationها اینه که فقط برای AI نیستن.
اگه فردا یه Developer جدید وارد تیم بشه، همین فایلها میتونن کمک زیادی به Onboarding اون هم بکنن.
در واقع اگه Documentation ما فقط برای AI قابل فهم باشه و برای Developer هیچ ارزشی نداشته باشه، شاید بهتر باشه یه بار دیگه ساختارش رو بررسی کنیم.
Spec-Driven Development؛ قبل از کدنویسی مشخص کن چی میخوای
یکی از مشکلاتی که موقع کار با Agentها خیلی زود خودش رو نشون میده، درخواستهای مبهمه.
مثلاً:
Add authentication.
این جمله برای شروع Implementation خیلی بازه.
بهجاش میتونیم قبل از Implementation یه Spec کوچیک داشته باشیم.
مثلاً:
# Authentication
## Goal
Users should authenticate using OTP.
## Requirements
- OTP expires after 2 minutes.
- Maximum 5 attempts.
- Refresh tokens must rotate.
## API
POST /auth/request-otp
POST /auth/verify-otp
POST /auth/refresh
POST /auth/logout
## Acceptance Criteria
- Expired OTP cannot be used.
- OTP cannot be replayed.
- Logout revokes the active session.
حالا Agent خیلی کمتر مجبور میشه حدس بزنه.
نکته مهم اینه که Spec قرار نیست حتماً یه سند ۵۰ صفحهای باشه.
برای یه Feature کوچیک ممکنه حتی ۳۰ خط کافی باشه.
هدف اصلی اینه که قبل از Implementation، چیزهایی که مبهم هستن مشخص بشن.
در واقع Spec یه قرارداد بین چیزی که ما میخوایم و چیزی که Agent قراره پیاده کنه میسازه.
Plan-Driven Development؛ نذار Agent یهدفعه کل پروژه رو تغییر بده
یه مشکل دیگه Coding Agentها اینه که اگه Scope مشخص نباشه، بعضی وقتها زیادی کمک میکنن!
مثلاً ازش میخوای یه Feature رو اضافه کنه و میبینی:
- یه Module رو Refactor کرده.
- چندتا Utility جدید ساخته.
- یه Package نصب کرده.
- Routing رو تغییر داده.
- چندتا فایل غیرمرتبط رو هم تمیز کرده.
ممکنه تکتک این تغییرات حتی منطقی باشن.
ولی سؤال اینه:
آیا الان قرار بود این کارها انجام بشن؟
برای Featureهای بزرگ بهتره کار رو به Phase و Task تقسیم کنیم.
مثلاً:
Phase 0 — Foundation
↓
Phase 1 — Authentication
↓
Phase 2 — Customers
↓
Phase 3 — Services
و داخل هر Phase:
Understand
↓
Plan
↓
Implement
↓
Test
↓
Verify
این روش دو تا مزیت مهم داره.
اول اینکه Scope کار برای Agent مشخصتر میشه.
دوم اینکه خودمون هم میتونیم بعد از هر مرحله نتیجه رو بررسی کنیم و بعد بریم سراغ مرحله بعدی.
بهجای اینکه بگیم:
کل سیستم Authentication رو کامل کن.
میتونیم اول Contract رو مشخص کنیم، بعد Database Model، بعد API، بعد UI و در نهایت تستها رو جلو ببریم.
ADR؛ کاری کنیم تصمیمهای قبلی پروژه فراموش نشن
فرض کنیم چند ماه پیش درباره محل نگهداری Refresh Token تحقیق کردیم و در نهایت تصمیم گرفتیم از HttpOnly Cookie استفاده کنیم.
چند ماه بعد یه Agent جدید وارد پروژه میشه و میگه:
بهتره Refresh Token رو داخل localStorage نگه داریم.
مشکل این نیست که Agent لزوماً پیشنهاد بدی داده.
مشکل اینه که نمیدونه ما قبلاً این بحث رو انجام دادیم و به یه نتیجه رسیدیم.
اینجا ADR یا Architecture Decision Record خیلی کاربردی میشه.
مثلاً:
docs/
└── decisions/
├── ADR-001-use-postgresql.md
├── ADR-002-use-otp-auth.md
└── ADR-003-refresh-token-cookie.md
داخل ADR میتونیم چیزی شبیه این داشته باشیم:
# ADR-003: Store Refresh Tokens in HttpOnly Cookies
## Status
Accepted
## Decision
Refresh tokens will be stored in HttpOnly cookies.
## Alternatives
- localStorage
- sessionStorage
## Reason
Reduce exposure of refresh tokens to client-side JavaScript.
ارزش ADR فقط این نیست که میگه:
چه تصمیمی گرفتیم؟
قسمت مهمترش اینه که میگه:
چرا این تصمیم رو گرفتیم؟
این موضوع هم برای Agent آینده مفیده و هم برای خودمون.
چون واقعیت اینه که سه ماه بعد ممکنه خودمون هم یادمون نباشه چرا یه تصمیم خاص گرفته بودیم.
Working Memory و Handoff؛ حافظه کوتاهمدت Agent
همه اطلاعات پروژه قرار نیست دائمی باشن.
مثلاً فرض کنیم Agent الان داره روی Phase 4 کار میکنه.
یه بخشی انجام شده، یه بخشی مونده و دو تا مشکل هم پیدا شده که باید بعداً بررسی بشن.
این اطلاعات شاید مناسب docs/architecture/ نباشن.
اینجاست که میتونیم یه فضای جدا برای وضعیت فعلی کار داشته باشیم.
مثلاً:
.ai/
├── tasks.md
├── progress.md
└── handoff.md
داخل tasks.md میتونیم Task فعلی رو نگه داریم.
progress.md مشخص کنه تا کجا پیش رفتیم.
و handoff.md هم برای زمانی مفیده که Session تموم میشه یا Agent بعدی قراره ادامه کار رو بگیره.
مثلاً:
# Current Task
Phase 4 - Customer Management
## Completed
- Customer entity
- Customer repository
- Create customer API
## Remaining
- Update customer
- Delete customer
- Tests
## Known Issues
- Phone normalization needs review.
اینجا تفاوت docs/ و .ai/ بهتر مشخص میشه.
docs/ |
.ai/ |
|---|---|
| دانش نسبتاً پایدار | وضعیت فعلی کار |
| Architecture | Current Task |
| Business Rules | Progress |
| Standards | Remaining Work |
| Decisions | Handoff |
باز هم باید تأکید کنم که .ai/ یه استاندارد رسمی نیست.
این فقط یه ساختار پیشنهادی و قابل فهم برای جدا کردن حافظه کوتاهمدت Agent از Documentation اصلی پروژهست.
میتونیم اسم دیگهای هم براش انتخاب کنیم.
اشتباه رایج: هرچی Markdown بیشتر، بهتر!
وقتی اهمیت Context رو میفهمیم، ممکنه بریم سمت یه اشتباه دیگه.
شروع میکنیم برای همهچیز فایل ساختن.
بعد از مدتی Repository این شکلی میشه:
.ai/
├── architecture-v1.md
├── architecture-new.md
├── architecture-final.md
├── architecture-final-2.md
├── old-rules.md
├── new-rules.md
├── tasks.md
├── tasks-old.md
└── ...
حالا Agent یه مشکل جدید داره.
کدوم فایل درسته؟
architecture-final.md یا architecture-final-2.md؟
old-rules.md هنوز معتبره؟
کدوم تصمیم نهایی شده و کدوم فقط یه Proposal بوده؟
اینجا به چیزی میرسیم که میشه بهش Context Pollution گفت.
یعنی Context داریم، ولی Contextمون پر از اطلاعات قدیمی، تکراری یا متناقضه.
پس هدف این نیست که تا جایی که میتونیم Documentation تولید کنیم.
هدف اینه که Documentation کم، مرتبط، قابل پیدا کردن و بهروز داشته باشیم.
Progressive Disclosure؛ همهچیز رو یهجا به Agent نده
یکی از راههای خوب برای مدیریت Context اینه که Agent مجبور نباشه از همون اول همه Documentation پروژه رو بخونه.
مثلاً میتونیم یه مسیر شبیه این داشته باشیم:
AGENTS.md
↓
What kind of task?
↓
Frontend Task
↓
docs/standards/frontend.md
↓
Current Feature Spec
↓
Closest Existing Implementation
↓
Implementation
Agent اول قوانین عمومی پروژه رو میخونه.
بعد متوجه میشه Task مربوط به Frontendه.
پس Standardهای Frontend رو بررسی میکنه.
بعد Spec مربوط به Feature رو میخونه.
بعد یه Implementation سالم و مشابه توی Codebase پیدا میکنه.
و تازه بعد از اینها شروع به کدنویسی میکنه.
این خیلی بهتر از اینه که قبل از هر Task بهش بگیم:
تمام فایلهای docs رو بخون.
در واقع Context رو مرحلهبهمرحله و بر اساس نیاز Agent در اختیارش میذاریم.
ساختار پیشنهادی یه Repository واقعی
حالا اگه بخوایم همه چیزهایی که تا اینجا گفتیم رو کنار هم بذاریم، میتونیم به یه ساختار شبیه این برسیم:
project/
│
├── AGENTS.md
├── README.md
│
├── docs/
│ ├── product/
│ │ ├── vision.md
│ │ ├── glossary.md
│ │ └── business-rules.md
│ │
│ ├── architecture/
│ │ ├── overview.md
│ │ ├── frontend.md
│ │ ├── backend.md
│ │ └── database.md
│ │
│ ├── standards/
│ │ ├── coding.md
│ │ ├── frontend.md
│ │ └── testing.md
│ │
│ ├── specs/
│ │
│ ├── decisions/
│ │ ├── ADR-001.md
│ │ └── ADR-002.md
│ │
│ └── phases/
│ ├── phase-00.md
│ ├── phase-01.md
│ └── phase-02.md
│
└── .ai/
├── tasks.md
└── handoff.md
هر قسمت مسئولیت مشخصی داره.
README.md پروژه رو برای آدمها معرفی میکنه.
AGENTS.md نقطه ورود Agent و قوانین عمومی کار با پروژهست.
docs/product/ توضیح میده چی داریم میسازیم و Business Ruleها چی هستن.
docs/architecture/ ساختار فنی سیستم رو توضیح میده.
docs/standards/ مشخص میکنه کد جدید باید از چه Patternهایی پیروی کنه.
docs/specs/ قرارداد Featureهایی که قراره ساخته بشن رو نگه میداره.
docs/decisions/ تصمیمهای مهم و دلیلشون رو ثبت میکنه.
docs/phases/ مسیر توسعه پروژه رو مشخص میکنه.
و .ai/ هم میتونه وضعیت فعلی کار Agent رو نگه داره.
ولی این ساختار یه Template اجباری نیست.
برای یه پروژه کوچیک شاید فقط این کافی باشه:
AGENTS.md
docs/
└── architecture.md
قرار نیست برای یه Todo App بیستتا Documentation درست کنیم!
ساختار باید همراه با نیاز پروژه رشد کنه.
یه Workflow واقعی؛ از ایده تا Merge
تا اینجا درباره فایلها زیاد حرف زدیم، ولی اصل ماجرا خود فایلها نیستن.
چیزی که مهمتره Workflowیه که دور اونها میسازیم.
مثلاً:
Idea
↓
Spec
↓
Plan
↓
Load Relevant Context
↓
Implementation
↓
Tests
↓
Review
↓
Update Docs / ADR if needed
↓
Done
فرض کنیم میخوایم قابلیت حذف Account رو اضافه کنیم.
اول مشخص میکنیم دقیقاً چه رفتاری میخوایم.
Hard Delete یا Soft Delete؟
Sessionهای کاربر چی بشن؟
اطلاعات وابسته چی؟
آیا عملیات قابل برگشته؟
این میشه Spec.
بعد کار رو به Taskهای کوچیک تقسیم میکنیم.
Agent قبل از Implementation، Architecture و Standardهای مرتبط رو بررسی میکنه.
یه Feature مشابه پیدا میکنه.
کد رو مینویسه.
تستها اجرا میشن.
خروجی Review میشه.
و اگه وسط این Feature یه تصمیم معماری جدید گرفتیم، ADR مربوط به اون رو هم ثبت میکنیم.
اینجا AI دیگه فقط یه Code Generator نیست.
تبدیل شده به بخشی از Workflow توسعه.
Vibe Coding در برابر Agentic Development
اگه بخوایم تفاوت این دو مدل رو خیلی خلاصه کنار هم بذاریم:
| Vibe Coding | Agentic Development |
|---|---|
| Prompt محوره | Context محوره |
| مستقیم میریم سراغ Implementation | Spec و Plan قبل از Implementation داریم |
| تصمیمها ممکنه داخل Chat بمونن | تصمیمهای مهم ثبت میشن |
| به Chat History وابستهایم | دانش مهم داخل Repository قرار داره |
| Scope ممکنه باز باشه | Scope مشخصتره |
| Review ممکنه اتفاقی باشه | Validation بخشی از Workflow هستش |
| برای Prototype عالیه | برای پروژههای بلندمدت مناسبتره |
البته مرز بین این دوتا صفر و یکی نیست.
ممکنه یه بخش پروژه رو خیلی سریع با Vibe Coding جلو ببریم و برای بخش حساستری مثل Authentication از Spec، ADR و Validation دقیق استفاده کنیم.
مهم اینه که بدونیم داریم کدوم مدل رو انتخاب میکنیم و چرا.
یعنی Vibe Coding بده؟
نه.
اتفاقاً Vibe Coding یکی از جذابترین روشها برای سریع ساختن چیزهای جدیده.
برای این کارها میتونه عالی باشه:
- Prototype
- Proof of Concept
- پروژههای کوچیک
- Scriptهای یکبارمصرف
- تست کردن یه ایده
- ساخت یه ابزار شخصی ساده
قرار نیست برای یه Script صد خطی اول architecture.md و ADR و Roadmap درست کنیم.
مشکل زمانی شروع میشه که پروژهای که قرار بوده آخر هفته تموم بشه، شش ماه بعد تبدیل شده به یه محصول واقعی با چند ده Feature، Database، Authentication، Payment و کلی Business Rule؛ ولی روش کارمون با Agent هنوز همونه:
این Feature رو هم بساز.
هرچقدر عمر و پیچیدگی پروژه بیشتر میشه، Context و نظم مهندسی هم مهمتر میشن.
از فردا چطور شروع کنیم؟
اگه الان یه پروژه داریم که تقریباً هیچ ساختاری برای Agent نداره، لازم نیست بریم ۳۰تا فایل Markdown بسازیم.
میتونیم خیلی ساده شروع کنیم.
اول:
AGENTS.md
قوانین مهم، دستور Build/Test و مسیر Documentation رو داخلش مشخص کنیم.
بعد یه Architecture ساده:
docs/
└── architecture.md
وقتی Patternهای پروژه زیاد شدن:
docs/
└── standards/
وقتی Feature پیچیده داریم، براش Spec بنویسیم.
وقتی Task بزرگ داریم، Plan یا Phase درست کنیم.
و وقتی یه تصمیم معماری مهم گرفتیم، ADR ثبت کنیم.
یعنی ساختار میتونه تقریباً اینطوری رشد کنه:
1. AGENTS.md
↓
2. Architecture
↓
3. Coding Standards
↓
4. Feature Specs
↓
5. Tasks / Plans
↓
6. ADRs when needed
لازم نیست همه اینها از روز اول وجود داشته باشن.
هر فایل باید یه مشکل واقعی رو حل کنه.
جمعبندی؛ هدف فقط Prompt بهتر نیست، محیط بهتره
اگه چند وقت پیش درباره استفاده بهتر از AI برای برنامهنویسی حرف میزدیم، احتمالاً بیشتر بحثمون درباره Prompt Engineering بود.
چطور Prompt دقیقتری بنویسیم؟
چطور Role تعریف کنیم؟
چطور Context بیشتری داخل Prompt بذاریم؟
این چیزها هنوز مهمن.
ولی وقتی AI از یه Chat ساده تبدیل میشه به Agentی که Repository رو میخونه، فایل تغییر میده، Command اجرا میکنه، تست مینویسه و چند مرحله روی یه Task کار میکنه، مسئله یه مقدار متفاوت میشه.
دیگه سؤال فقط این نیست:
چطور Prompt بهتری بنویسم؟
شاید سؤال بهتر این باشه:
چطور کاری کنم Agent قبل از تغییر پروژه، چیزهایی رو بدونه که یه Developer خوب تیم من باید بدونه؟
معماری پروژه چیه؟
چه تصمیمهایی قبلاً گرفتیم؟
چه چیزهایی نباید تغییر کنن؟
Feature دقیقاً چه شرایطی داره؟
چه چیزی Done محسوب میشه؟
و برای انجام Task فعلی، کدوم بخش از Context پروژه واقعاً لازمه؟
اینجاست که چیزهایی مثل AGENTS.md، Project Documentation، Spec، Plan، ADR و Working Memory کنار هم معنی پیدا میکنن.
هدف این نیست که Repository رو پر از Markdown کنیم.
هدف اینه که Agent مجبور نباشه هر بار پروژهمون رو از صفر حدس بزنه.
شاید تفاوت اصلی Vibe Coding و یه روش مهندسیشدهتر برای کار با Agentها هم دقیقاً همین باشه:
در Vibe Coding بیشتر به Agent میگیم چی بسازه؛ در Agentic Development سعی میکنیم محیطی بسازیم که Agent بفهمه چی بسازه، چرا بسازه و چطور باید با پروژه ما هماهنگ بمونه.
منابع و مطالعه بیشتر
برای اینکه این مفاهیم رو عمیقتر بررسی کنین، این موضوعات و مستندات نقطه شروع خوبی هستن:
- مستندات OpenAI Codex و
AGENTS.md - مستندات GitHub Copilot درباره Repository Custom Instructions
- مستندات ابزار Coding Agentی که خودتون استفاده میکنین
- Architecture Decision Records یا ADR
- Context Engineering
- Spec-Driven Development
یه نکته مهم هم اینه که همه ساختارهایی که توی این مقاله دیدیم، استاندارد رسمی و اجباری نیستن.
چیزهایی مثل ADR از قبل در مهندسی نرمافزار وجود داشتن، بعضی فایلها مثل AGENTS.md توسط Coding Agentها پشتیبانی میشن و ساختارهایی مثل .ai/tasks.md بیشتر یه Convention پیشنهادی برای مدیریت بهتر کار Agent هستن.
پس بهتره بهجای کپی کردن یه ساختار ثابت برای همه پروژهها، ایده پشت این ابزارها رو بفهمیم و متناسب با پروژه خودمون ازشون استفاده کنیم.
