Prompt Engineering چیست؟
مدلهای زبانی بزرگ یا LLMها میتوانند کد بنویسند، خطاها را تحلیل کنند، تست تولید کنند و درباره معماری نرمافزار پیشنهاد بدهند.
اما کیفیت پاسخ آنها تا حد زیادی به کیفیت ورودی ما بستگی دارد.
فرض کنید فقط این درخواست را به یک مدل بدهیم:
این کد رو بهتر کن.
مدل تقریباً هیچ اطلاعاتی درباره پروژه ندارد.
نمیداند:
- هدف کد چیست
- از چه زبان و Frameworkی استفاده میکنیم
- محدودیت Performance داریم یا نه
- امنیت چقدر مهم است
- قرار است چه چیزی تغییر کند
- چه چیزی نباید تغییر کند
در مقابل میتوانیم درخواست دقیقتری بنویسیم:
این کد مربوط به یک REST API در Django است.
وظیفه:
کد را از نظر خوانایی، Performance و امنیت بررسی کن.
محدودیتها:
- رفتار فعلی API نباید تغییر کند
- کتابخانه جدید اضافه نکن
- ابتدا مشکلات را توضیح بده
- سپس نسخه Refactor شده را ارائه کن
- در پایان Test Caseهای مهم را پیشنهاد بده
هر دو Prompt درباره بهبود کد هستند، اما مدل در نمونه دوم اطلاعات بسیار بیشتری برای تصمیمگیری دارد.
به فرآیند طراحی و بهینهسازی این ورودیها Prompt Engineering گفته میشود.
چرا Prompt Engineering برای برنامهنویسان مهم است؟
یک توسعهدهنده معمولاً از هوش مصنوعی برای کارهایی مثل موارد زیر استفاده میکند:
- تولید کد
- Debugging
- Refactoring
- Code Review
- تولید Unit Test
- مستندسازی
- طراحی API
- طراحی دیتابیس
- نوشتن SQL
- تحلیل Error و Stack Trace
- یادگیری Framework جدید
در تمام این کاربردها یک Prompt ضعیف میتواند پاسخی ایجاد کند که ظاهراً درست ولی در عمل بیاستفاده باشد.
مدل قرار نیست معماری پروژه را از طریق تلهپاتی کشف کند. فعلاً این قابلیت خوشبختانه به Backlog تمدن بشری منتقل شده است.
یک Prompt خوب از چه بخشهایی تشکیل میشود؟
برای Prompt Engineering فرمول مطلقی وجود ندارد، اما در بسیاری از مسائل فنی میتوان از ساختار زیر استفاده کرد:
- Context
- +
- Task
- +
- Constraints
- +
- Input
- +
- Expected Output
بیایید هر بخش را بررسی کنیم.
1. Context یا زمینه مسئله
Context به مدل توضیح میدهد در چه محیطی کار میکنیم.
مثلاً:
من روی یک Backend با Django و PostgreSQL کار میکنم.
این سرویس یک API برای دریافت سفارشهای کاربران است و روزانه تعداد زیادی درخواست دریافت میکند.
همین اطلاعات باعث میشود پاسخ مدل متناسبتر با شرایط پروژه باشد.
بدون Context ممکن است مدل راهحلی پیشنهاد دهد که از نظر تئوری درست ولی برای پروژه شما نامناسب باشد.
2. Task یا وظیفه
دقیقاً مشخص کنید از مدل چه میخواهید.
Prompt مبهم:
این تابع رو بررسی کن.
Prompt بهتر:
این تابع را از نظر موارد زیر بررسی کن:
1. پیچیدگی زمانی
2. خوانایی
3. مدیریت خطا
4. مشکلات امنیتی احتمالی
وظیفه هرچه مشخصتر باشد، احتمال دریافت پاسخ پراکنده کمتر میشود.
3. Constraints یا محدودیتها
محدودیتها یکی از مهمترین بخشهای Prompt فنی هستند.
برای مثال:
محدودیتها:
- Python 3.12
- بدون Library خارجی
- Interface فعلی تابع تغییر نکند
- کد باید Thread-safe باشد
- Query اضافه به دیتابیس ایجاد نشود
اگر محدودیتها را مشخص نکنید، مدل ممکن است راهحلی ارائه کند که از اساس با پروژه شما سازگار نیست.
4. Input یا داده ورودی
اطلاعات لازم برای حل مسئله را در اختیار مدل قرار دهید.
برای Debugging معمولاً این موارد مفید هستند:
Environment:
Python 3.12
Django 5.x
PostgreSQL
Expected behavior:
کاربر باید بتواند سفارش خودش را دریافت کند.
Actual behavior:
API با Status Code 500 پاسخ میدهد.
Error:
...
Relevant code:
...
این ساختار بسیار بهتر از فرستادن یک Stack Trace چندصدخطی همراه با جمله جاودانهی:
چرا کار نمیکنه؟
است.
5. Expected Output یا شکل خروجی
میتوانید مشخص کنید پاسخ مدل چگونه ساختاربندی شود.
مثلاً:
پاسخ را در این ساختار بده:
1. مشکل اصلی
2. دلیل ایجاد مشکل
3. راهحل پیشنهادی
4. کد اصلاحشده
5. Test Caseهای ضروری
این کار مخصوصاً زمانی مفید است که خروجی AI قرار است وارد Workflow دیگری شود.
تفاوت Prompt ضعیف و Prompt خوب
فرض کنید کد زیر را داریم:
def get_user(users, id):
for user in users:
if user["id"] == id:
return user
Prompt ضعیف:
بهترش کن
مشکل این Prompt این است که «بهتر» تعریف نشده است.
آیا هدف سرعت است؟
خوانایی؟
Type Safety؟
مدیریت خطا؟
Prompt بهتر:
کد Python زیر را Review کن.
هدف:
افزایش خوانایی و Type Safety.
شرایط:
- پیچیدگی غیرضروری اضافه نکن
- رفتار تابع حفظ شود
- اگر کاربر پیدا نشد مقدار None برگردد
- از Python 3.12 استفاده میکنیم
ابتدا مشکلات را توضیح بده و سپس نسخه Refactor شده را بنویس.
حالا مدل مسئله مشخصتری برای حل کردن دارد.
از AI بخواهید قبل از کدنویسی مسئله را تحلیل کند
یکی از اشتباهات رایج این است که بلافاصله از مدل درخواست تولید کد کنیم.
مثلاً:
یک سیستم Rate Limiting بساز.
پاسخ مدل ممکن است از نظر Syntax کاملاً معتبر باشد، اما هنوز نمیدانیم:
- سیستم Distributed است یا نه
- Redis داریم یا نه
- محدودیت بر اساس User است یا IP
- چند Request مجاز است
- Fail-open میخواهیم یا Fail-closed
- نیاز به Atomic Operation داریم یا خیر
Prompt بهتر میتواند این باشد:
برای یک REST API نیاز به Rate Limiting دارم.
قبل از نوشتن کد:
1. اطلاعاتی که برای انتخاب معماری لازم داری مشخص کن.
2. گزینههای مناسب را مقایسه کن.
3. Edge Caseهای مهم را توضیح بده.
4. سپس یک راهحل پیشنهاد کن.
فعلاً کد ننویس.
این روش جلوی مقدار قابل توجهی از «کد حرفهای برای مسئلهای که اصلاً مسئله ما نبود» را میگیرد.
استفاده از Prompt Engineering برای Debugging
هوش مصنوعی برای Debugging میتواند بسیار مفید باشد، به شرطی که اطلاعات کافی دریافت کند.
به جای:
این ارور رو درست کن
از ساختاری شبیه زیر استفاده کنید:
من یک API با FastAPI دارم.
Expected behavior:
API باید اطلاعات کاربر را برگرداند.
Actual behavior:
در بعضی درخواستها با خطای 500 مواجه میشوم.
Environment:
Python 3.12
FastAPI
PostgreSQL
SQLAlchemy
Error:
[Stack Trace]
Relevant code:
[Code]
ابتدا علتهای احتمالی را به ترتیب بررسی کن.
برای هر علت توضیح بده چگونه میتوان آن را تأیید یا رد کرد.
بعد از تحلیل، راهحل پیشنهادی را ارائه بده.
قسمت مهم این Prompt جمله زیر است:
توضیح بده چگونه میتوان آن را تأیید یا رد کرد.
این باعث میشود مدل فقط حدس نزند، بلکه روش بررسی پیشنهاد کند.
Prompt Engineering برای Code Review
میتوان AI را به عنوان مرحله اولیه Code Review استفاده کرد.
نمونه:
این Pull Request را مثل یک Senior Backend Developer بررسی کن.
تمرکز Review:
- Bugهای احتمالی
- Security
- Performance
- Race Condition
- Error Handling
- Readability
- Test Coverage
برای هر مشکل این موارد را مشخص کن:
Severity:
Reason:
Suggested fix:
روی Styleهای سلیقهای تمرکز نکن.
فقط مشکلاتی را گزارش کن که ارزش اصلاح دارند.
این Prompt مدل را از تولید لیست بیپایانی از پیشنهادهای کماهمیت دور میکند.
Prompt Engineering برای Refactoring
برای Refactoring باید مشخص کنیم چه چیزی اجازه تغییر دارد.
مثلاً:
کد زیر را Refactor کن.
اهداف:
- کاهش تکرار
- افزایش خوانایی
- سادهتر شدن تست
محدودیتها:
- Public API تغییر نکند
- رفتار فعلی حفظ شود
- Dependency جدید اضافه نشود
- Optimization زودهنگام انجام نده
قبل از کد جدید، دقیقاً توضیح بده چه بخشهایی را تغییر میدهی و چرا.
عبارت «رفتار فعلی حفظ شود» اهمیت زیادی دارد.
مدلها گاهی هنگام Refactor کردن تصمیم میگیرند همزمان Business Logic را هم «بهبود» دهند. اتفاقی که در محیط Production معمولاً با شکلهای خلاقانهای از فاجعه همراه است.
تولید Unit Test با AI
به جای درخواست:
برای این تابع تست بنویس
اطلاعات بیشتری بدهید:
برای تابع زیر Unit Test بنویس.
Framework:
pytest
مواردی که باید پوشش داده شوند:
- Happy path
- Empty input
- Invalid input
- Boundary values
- Duplicate data
برای هر Test توضیح کوتاهی درباره دلیل وجود آن بده.
از Mock فقط زمانی استفاده کن که واقعاً لازم باشد.
در این حالت مدل فقط چند Test تصادفی تولید نمیکند و مجبور است Coverage را منطقیتر بررسی کند.
استفاده از AI برای طراحی API
Prompt Engineering فقط برای تولید کد نیست.
میتوان برای طراحی سیستم هم از آن استفاده کرد.
مثلاً:
میخواهم API مدیریت Task طراحی کنم.
نیازمندیها:
- ساخت Task
- ویرایش Task
- حذف Task
- تغییر وضعیت
- فیلتر براساس وضعیت
- Pagination
قبل از نوشتن کد:
1. Endpointها را پیشنهاد کن.
2. HTTP Method مناسب هرکدام را مشخص کن.
3. Request و Response نمونه بده.
4. Status Codeهای مناسب را پیشنهاد کن.
5. Edge Caseهای مهم را مشخص کن.
فعلاً هیچ کدی تولید نکن.
با این کار AI نقش یک ابزار طراحی را پیدا میکند، نه فقط دستگاه تولید Syntax.
Few-shot Prompting چیست؟
گاهی میتوان با ارائه چند مثال به مدل نشان داد چه نوع خروجیای انتظار داریم.
به این روش Few-shot Prompting گفته میشود.
مثلاً:
Input:
get_user_by_id
Output:
تابعی برای دریافت کاربر بر اساس شناسه.
Input:
create_order
Output:
تابعی برای ایجاد سفارش جدید.
Input:
cancel_subscription
Output:
مدل با مشاهده نمونهها الگوی موردنظر را تشخیص میدهد.
این روش برای خروجیهایی که Format مشخص دارند بسیار کاربردی است.
Zero-shot Prompting چیست؟
وقتی بدون ارائه مثال از مدل میخواهیم کاری انجام دهد، معمولاً با Zero-shot Prompting سروکار داریم.
مثلاً:
کد زیر را از نظر SQL Injection بررسی کن.
در بسیاری از وظایف ساده همین روش کافی است.
لازم نیست هر Prompt را تبدیل به پایاننامه دکترا کنیم.
Structured Output چیست؟
در پروژههای نرمافزاری معمولاً بهتر است خروجی مدل ساختار مشخصی داشته باشد.
مثلاً به جای:
اطلاعات این متن را استخراج کن.
میتوان گفت:
اطلاعات را فقط با ساختار زیر برگردان:
{
"name": string,
"email": string | null,
"company": string | null
}
این نوع Prompt برای زمانی مفید است که خروجی مدل مستقیماً توسط Backend پردازش میشود.
البته حتی در این حالت خروجی باید Validate شود.
AI دیتابیس با Constraint نیست و اعتماد کامل به خروجی آن روش جالبی برای آشنایی با Incident Response است.
نقش Context در کیفیت پاسخ
یکی از مهمترین اصول Prompt Engineering این است:
مدل فقط اطلاعاتی را میبیند که در Context آن قرار گرفته است.
اگر مدل نداند پروژه از Django استفاده میکند، ممکن است راهحلی برای Flask پیشنهاد دهد.
اگر نداند دیتابیس PostgreSQL است، ممکن است قابلیت مخصوص MySQL پیشنهاد کند.
اگر نداند API عمومی است، ممکن است Security را نادیده بگیرد.
بنابراین اطلاعات مرتبط را به Prompt اضافه کنید.
اما این به معنی ارسال کل Repository نیست.
چه Contextی را نباید ارسال کنیم؟
نباید اطلاعات حساس پروژه را بیدلیل وارد Prompt کنیم.
برای مثال:
- SECRET_KEY
- DATABASE_PASSWORD
- ACCESS_TOKEN
- PRIVATE_KEY
- API_KEY
همچنین:
- اطلاعات شخصی کاربران
- دادههای محرمانه سازمان
- Credentialها
- Production secrets
- فایل کامل
.env
نباید بدون بررسی سیاست امنیتی سرویس AI ارسال شوند.
قبل از ارسال Log نیز اطلاعات حساس را حذف یا Mask کنید.
Prompt طولانی همیشه Prompt بهتر نیست
یکی از برداشتهای اشتباه این است که هرچه Prompt طولانیتر باشد، نتیجه بهتر میشود.
این موضوع همیشه درست نیست.
Prompt باید اطلاعات مرتبط داشته باشد، نه صرفاً حجم زیاد.
Prompt خوب:
هدف + Context لازم + محدودیت + خروجی مورد انتظار
Prompt بد:
پنج صفحه توضیح نامرتبط + مسئله اصلی مخفیشده در خط آخر
مدل هم مثل توسعهدهندهای که Ticket بد نوشتهشده دریافت کرده، از اطلاعات اضافه معجزه استخراج نمیکند.
Prompt را مرحلهای کنید
برای مسائل پیچیده، لازم نیست همهچیز را در یک درخواست انجام دهید.
میتوان Workflow را به چند مرحله تقسیم کرد.
برای مثال:
مرحله اول: تحلیل
- کد را بررسی کن و مشکلات را پیدا کن.
- فعلاً هیچ تغییری ایجاد نکن.
مرحله دوم: طراحی راهحل
برای سه مشکل اصلی، راهحلهای ممکن را مقایسه کن.
مرحله سوم: پیادهسازی
راهحل دوم را پیادهسازی کن.
مرحله چهارم: تست
برای نسخه جدید Test Caseهای لازم را بنویس.
این روش معمولاً کنترل بیشتری نسبت به یک Prompt بزرگ دارد.
از مدل بخواهید فرضیاتش را مشخص کند
یک تکنیک بسیار کاربردی این است:
قبل از پاسخ، فرضیاتی که درباره مسئله در نظر گرفتهای مشخص کن.
مثلاً ممکن است مدل فرض کرده باشد:
- سیستم Single Server است
- دیتابیس PostgreSQL است
- User Authentication وجود دارد
- حجم داده کم است
اگر این فرضیات اشتباه باشند، میتوان قبل از پیادهسازی آنها را اصلاح کرد.
از مدل بخواهید Trade-offها را توضیح دهد
در مهندسی نرمافزار معمولاً یک جواب مطلق وجود ندارد.
به جای:
بهترین معماری برای این پروژه چیست؟
Prompt بهتری بنویسید:
برای این مسئله سه معماری مناسب پیشنهاد کن.
برای هرکدام موارد زیر را توضیح بده:
- مزایا
- معایب
- پیچیدگی پیادهسازی
- هزینه نگهداری
- شرایطی که این گزینه مناسب نیست
این نوع سؤال کمک میکند AI نقش ابزار تحلیل را داشته باشد، نه Oracle مقدس معماری نرمافزار.
Prompt Template کاربردی برای برنامهنویسان
میتوانید Template زیر را برای بسیاری از درخواستهای فنی استفاده کنید:
Context:
[پروژه، تکنولوژی، محیط و اطلاعات ضروری]
Task:
[کاری که باید انجام شود]
Requirements:
[نیازمندیها]
Constraints:
[محدودیتها]
Input:
[کد، Error، داده یا مسئله]
Please:
1. ابتدا مسئله را تحلیل کن.
2. فرضیاتت را مشخص کن.
3. مشکلات احتمالی را توضیح بده.
4. راهحل پیشنهادی را ارائه کن.
5. Edge Caseها را بررسی کن.
6. در صورت نیاز کد تولید کن.
Output format:
[ساختار مورد انتظار پاسخ]
لازم نیست برای هر سؤال همه بخشها را استفاده کنید.
Template باید متناسب با پیچیدگی مسئله کوتاه یا کامل شود.
نمونه Prompt برای Debugging
Context:
یک REST API با Django REST Framework دارم.
Environment:
Python 3.12
Django
PostgreSQL
Problem:
Endpoint دریافت سفارش در بعضی درخواستها بسیار کند میشود.
Expected:
زمان پاسخ کمتر از 300ms.
Actual:
برخی Requestها بیشتر از 2 ثانیه طول میکشند.
Task:
مشکل را تحلیل کن.
قبل از پیشنهاد تغییر:
1. دلایل احتمالی را اولویتبندی کن.
2. برای هر مورد روش اندازهگیری یا تأیید پیشنهاد بده.
3. از حدس بدون شواهد خودداری کن.
4. سپس Optimizationهای مناسب را پیشنهاد بده.
نمونه Prompt برای Code Review
این کد Python را برای Production Review کن.
تمرکز:
- correctness
- security
- performance
- maintainability
برای هر مشکل این ساختار را استفاده کن:
Problem:
Severity:
Why:
Suggested change:
موارد سلیقهای یا Formatting را گزارش نکن.
نمونه Prompt برای یادگیری یک مفهوم جدید
Prompt Engineering فقط برای پروژه نیست.
مثلاً:
Redis را برای یک Backend Developer توضیح بده.
فرض کن:
- PostgreSQL را میشناسم
- با Cache آشنایی ابتدایی دارم
توضیح بده:
1. Redis چیست
2. چه مسئلهای حل میکند
3. چه زمانی نباید از آن استفاده کنم
4. سه مثال واقعی Backend
5. یک نمونه ساده با Python
از توضیح بازاریابی و تعریفهای مبهم خودداری کن.
این Prompt سطح دانش مخاطب را مشخص میکند و جلوی توضیحات بیشازحد ابتدایی را میگیرد.
اشتباهات رایج در Prompt Engineering
درخواست مبهم
یه API خوب بساز.
«خوب» معیار فنی نیست.
ندادن Context
مدل بدون دانستن Stack پروژه ممکن است راهحل نامرتبط ارائه کند.
درخواست چند کار نامرتبط با هم
مثلاً در یک Prompt بخواهیم:
- معماری طراحی کند
- Backend بنویسد
- Frontend بسازد
- تست تولید کند
- Deployment انجام دهد
تقسیم مسئله معمولاً نتیجه بهتری ایجاد میکند.
اعتماد کامل به خروجی
Prompt خوب احتمال خطا را کاهش میدهد، اما آن را صفر نمیکند.
کد تولیدشده باید:
- Review شود
- اجرا شود
- تست شود
- از نظر امنیت بررسی شود
درخواست پاسخ بدون تعیین معیار
به جای:
کدوم بهتره؟
معیار بدهید:
این دو روش را از نظر Performance، پیچیدگی، قابلیت نگهداری و هزینه مقایسه کن.
آیا Prompt Engineering جای دانش برنامهنویسی را میگیرد؟
خیر.
هرچه دانش فنی توسعهدهنده بیشتر باشد، بهتر میتواند:
- سؤال درست مطرح کند
- پاسخ اشتباه را تشخیص دهد
- Trade-offها را بررسی کند
- کد تولیدشده را Review کند
- محدودیتهای سیستم را توضیح دهد
اگر توسعهدهنده نداند SQL Injection چیست، احتمالاً نمیتواند تشخیص دهد AI یک Query ناامن تولید کرده است.
Prompt Engineering بیش از آنکه جایگزین دانش فنی باشد، توانایی استفاده مؤثر از دانش فنی در تعامل با مدلهای زبانی است.
یک Workflow مناسب برای کار با AI
برای مسائل فنی میتوان از این فرآیند استفاده کرد:
نکته مهم این است که تولید کد فقط یکی از مراحل است.
گاهی ارزش واقعی AI در مرحله تحلیل و بررسی گزینهها بیشتر از نوشتن خود کد است.
جمعبندی
Prompt Engineering یعنی طراحی ورودیهایی که به مدل زبانی کمک میکنند مسئله، محدودیتها و نتیجه مورد انتظار را بهتر درک کند.
برای یک توسعهدهنده، Prompt خوب معمولاً چند ویژگی دارد:
- Context کافی ارائه میدهد
- وظیفه را دقیق مشخص میکند
- محدودیتها را تعریف میکند
- خروجی مورد انتظار را مشخص میکند
- مسئله پیچیده را به مراحل کوچکتر تقسیم میکند
- فرضیات مدل را قابل مشاهده میکند
- از مدل میخواهد Trade-offها را توضیح دهد
در نهایت هدف Prompt Engineering پیدا کردن چند «کلمه جادویی» برای صحبت با هوش مصنوعی نیست.
هدف این است که مسئله را آنقدر دقیق تعریف کنیم که مدل بتواند پاسخ قابل ارزیابی و قابل استفادهای تولید کند.
و این مهارت چندان هم با مهندسی نرمافزار غریبه نیست. بخش بزرگی از برنامهنویسی از ابتدا همین بوده است: توضیح دقیق مسئله به موجودی که کوچکترین ابهام شما را با روشی کاملاً غیرمنتظره تفسیر میکند. قبلاً آن موجود کامپیوتر بود، حالا یک مدل زبانی هم به جمع اضافه شده است.
