درس ۴ از ۱۱

Module 4

عنوان اصلی: Prompt Engineering Techniques هدف یادگیری ماژول: تسلط بر چهار تکنیک بنیادی که Anthropic در docs خود به‌عنوان «high-leverage» معرفی می‌کند: clear and direct بودن، specific بودن، استفاده از XML tags و multishot prompting (few-shot examples). این چهار تکنیک، با کنار هم گذاشتن، در اغلب وظایف classification و extraction، ۱۰ تا ۳۰ امتیاز دقت اضافه می‌کنند. مفاهیم کلیدی: clear and direct, specific, XML tags, multishot prompting, few-shot examples, system prompt, ablation, golden rule of prompting.

تا اینجا یاد گرفتیم چگونه prompt را measure کنیم. حالا یاد می‌گیریم چگونه آن را بهتر کنیم. توالی این چهار تکنیک عمدی است: clear و specific بودن، پیش‌نیاز XML tags است؛ XML tags پیش‌نیاز few-shot examples است. هر کدام را که اضافه کنید، باید روی eval module 3 باز نمره بگیرید تا lift را verify کنید.

۴.۱ Be clear and direct — قانون طلایی prompting

هدف: درونی‌کردن heuristic «با Claude مثل یک contractor تازه‌کار اما باهوش رفتار کنید» — context، goal و constraints را صریح بگویید.

قانون طلایی Anthropic. صفحه‌ی be clear and direct در docs، یک جمله‌ی محوری دارد: «هر چه مجبور باشید برای یک پیمانکار تازه‌وارد توضیح بدهید، باید برای Claude هم همان‌قدر توضیح بدهید.» عملاً یعنی مشخص کنید:

  • Claude کیست (نقش)
  • وظیفه چیست (task)
  • موفقیت چه شکلی است (success)
  • مخاطب کیست (audience)
  • چه format می‌خواهید (format)
  • چه چیزی ممنوع است (forbidden)

prompt های مبهم خروجی مبهم می‌گیرند. prompt مبهم: «یک ایمیل marketing بنویس». prompt شفاف: «یک ایمیل ۱۲۰ کلمه‌ای marketing به مشتریان فعلی ایرانی بنویس که ارسال رایگان بالای ۵٬۰۰۰٬۰۰۰ ریال را اعلام می‌کند؛ لحن دوستانه؛ یک CTA button با متن مشخص.»

چند قاعده‌ی نگارشی.

  • زبان imperative: «پنج ریسک را لیست کن.» بهتر از «اگر امکانش هست، شاید بتوانی چند ریسک ذکر کنی.»
  • بدون double negative: «هیچ‌گاه فراموش نکن X را شامل کنی» → «همیشه X را شامل کن».
  • اول task، بعد context: Claude به دستورات اول، وزن بیشتری می‌دهد. task اصلی را در ابتدا بگذارید، نه پس از یک بلوک متن طولانی.

وقتی خروجی مطلوب را نمی‌گیرید، قبل از بزرگ‌تر کردن مدل، specificity را بالا ببرید. ۹۰٪ مواقع، Haiku با prompt واضح بهتر از Opus با prompt مبهم کار می‌کند.

نمونه کد.

# Bad: vague
bad = "Write something about our return policy."

# Good: clear & direct
good = """\
Audience: existing customers writing in Persian.
Task: write a 100-word notice explaining our 7-day no-questions-asked return policy.
Tone: friendly, reassuring.
Format: plain text, no headings, ends with a single CTA: "بازگشت آسان".
Forbidden: legalese, English jargon."""

resp = client.messages.create(
    model="claude-opus-4-8", max_tokens=400,
    messages=[{"role": "user", "content": good}],
)

اشتباهات رایج.

  • دفن کردن task اصلی در انتهای یک context طولانی — Claude به دستورات اول وزن بیشتری می‌دهد.
  • استفاده‌ی مکرر از hedging («اگر ممکن است، شاید…») — مدل علامت می‌گیرد که شما هم مطمئن نیستید چه می‌خواهید.
  • فرض اینکه Claude business context را می‌داند — درباره‌ی محصول، مشتری و قوانین داخلی شما، هیچ نمی‌داند مگر بگویید.

۴.۲ Be specific — اعداد، فرمت، حذفیات

هدف: جایگزین کردن صفت‌های انتزاعی با عدد، format و example مشخص.

Specific = عملیاتی‌سازی Clear. «clear» می‌گوید چه می‌خواهی؛ «specific» می‌گوید چقدر، در چه قالبی، با چه استثناهایی. به‌جای صفت، عدد بدهید:

  • «مختصر» → «حداکثر ۵۰ کلمه»
  • «حرفه‌ای» → «سوم‌شخص، active voice، بدون contraction»
  • «informative» → «دقیقاً سه bullet: علت، اثر، راهکار»
  • «در پول» → «به IRR، بدون اعشار»

اصل ضدشهودی: آنچه نباید انجام دهد را هم بگویید. «شماره SKU جعل نکن» یک کلاس کامل از hallucination را می‌بندد که هیچ instruction مثبتی نمی‌بست. forbidden list به اندازه‌ی required list مهم است.

نمونه کد.

prompt = """\
You are a product copywriter for an Iranian e-commerce store.
Write a description for SKU PIP-0142 (a Vazirmatn-fonted Persian RTL t-shirt).

Format requirements (all required):
- Exactly 4 lines.
- Line 1: 5-word headline ending with an em-dash.
- Line 2: a 20-30 word benefit statement.
- Line 3: bullet list of 3 features, each ≤ 8 words, prefixed with "•".
- Line 4: a single sentence call-to-action containing the word "همین حالا".

Forbidden: pricing, shipping claims, emoji, English words other than the SKU."""

این prompt، عملاً یک contract است: هر دستور قابل‌سنجش است، forbidden list سه class hallucination رایج (قیمت اشتباه، shipping claim بی‌اساس، emoji غیرحرفه‌ای) را از پیش می‌بندد.

اشتباهات رایج.

  • Over-constraining در وظایف خلاقانه — اگر می‌خواهید آگهی شعرگونه بنویسد و ۲۰ قید می‌گذارید، خروجی ربات‌گونه می‌شود.
  • قیدهای متناقض («در ۱۰ کلمه detailed باش») — مدل یکی را می‌شکند و شما نمی‌دانید کدام را.
  • فراموش کردن واحد و زبان — اگر نگویید «به فارسی» و «به IRR»، احتمال دارد به انگلیسی یا با $ پاسخ بدهد.

۴.۳ XML tags — ساختاردهی به prompt

هدف: استفاده از XML tag ها برای تفکیک شفاف بخش‌های prompt (instructions، data، examples).

چرا XML؟ Claude به‌شدت روی شناسایی و احترام به XML tag ها به‌عنوان جداکننده‌ی section ها train شده. چهار مزیت کلیدی:

  1. Disambiguation: Claude می‌فهمد سوال کاربر (<question>) بخشی از document (<document>) نیست. این جلوی یک کلاس کامل از خطاها را می‌گیرد که در آنها مدل سوال را با document قاطی می‌کند.
  2. Referencability: می‌توانید بعداً بگویید «بر اساس policy داخل <document>، به <question> پاسخ بده». این ارجاع صریح، رفتار مدل را قابل‌پیش‌بینی می‌کند.
  3. Nesting: ساختار <example><input>…</input><output>…</output></example> کاملاً بدون ابهام است.
  4. Parsing راحت‌تر: post-processing شما می‌تواند با regex ساده، <answer> را تمیز استخراج کند.

نام‌گذاری. Schema ثابتی وجود ندارد. نام‌های semantic انتخاب کنید: <contract>, <rules>, <faqs>, <thinking>, <final_answer>. مهم این است که در یک پروژه consistent باشید.

نمونه کد.

prompt = """\
<instructions>
You are a contract-review assistant. Read the contract below, then answer the user's question.
Cite section numbers for each claim. If unsure, say so.
</instructions>

<contract>
{contract_text}
</contract>

<question>
What is the indemnification cap for vendor breach?
</question>

Reply inside <answer>…</answer> tags."""

post-processing:

import re
match = re.search(r"<answer>(.*?)</answer>", resp.content[0].text, re.DOTALL)
answer = match.group(1).strip() if match else None

اشتباهات رایج.

  • ساختن tag بسته‌ای که Claude در training ندیده — typo در closing tag باعث می‌شود parsing شکست بخورد.
  • ترکیب markdown heading با XML tag در یک prompt — مدل با هر دو ناسازگار رفتار می‌کند. یک style انتخاب کنید.
  • گذاشتن instruction واقعی بیرون tag ها («هر چه داخل tag هست را نادیده بگیر») — مدل را گیج می‌کند.

۴.۴ Examples (multishot prompting) — نمونه‌های few-shot

هدف: بالا بردن قابلیت اعتماد با ۳ تا ۵ few-shot examples متنوع که edge case ها را پوشش می‌دهند.

چرا multishot prompting قوی‌ترین تکنیک است؟ Anthropic آن را «بزرگ‌ترین leverage بدون fine-tuning» می‌نامد. نقطه‌ی شروع توصیه‌شده ۳ تا ۵ نمونه است؛ برای وظایف پیچیده‌تر، بیشتر. سه قاعده‌ی طلایی:

  1. Diversity: نمونه‌ها باید فضای ورودی را پوشش بدهند. اگر همه‌ی few-shot ها positive و کوتاه باشند، مدل یاد می‌گیرد همیشه positive جواب بدهد.
  2. Edge cases: عمداً نمونه‌های سخت را بگذارید — sarcasm، احساس mixed، code-switched (فارسی + انگلیسی)، typo دار. اگر مدل را روی خط راه نبرید، در production جلوی آن نمی‌آید.
  3. Same format as desired output: اگر می‌خواهید JSON بدهد، همه‌ی خروجی‌های examples باید JSON باشند. اگر یکی plain text باشد، مدل تصمیم می‌گیرد که format اختیاری است.

جای few-shot ها در prompt. قبل از task واقعی بگذارید، نه بعد. در XML tag بپیچید (<example><input>…</input><output>…</output></example>) تا boundary شفاف باشد.

نمونه کد.

prompt = """\
Classify Persian product reviews.

<example>
<input>این گوشی فوق العاده‌ست!</input>
<output>positive</output>
</example>
<example>
<input>افتضاح بود، پولم رو هدر دادم.</input>
<output>negative</output>
</example>
<example>
<input>خوب نبود ولی بد هم نبود.</input>
<output>mixed</output>
</example>
<example>
<input>خریدم.</input>
<output>neutral</output>
</example>

<input>{review}</input>
<output>"""

این prompt برای classifier فارسی، ساختار است که: clear (یک جمله task)، specific (چهار کلاس مشخص)، XML (boundary های بدون ابهام)، multishot (چهار نمونه‌ی متنوع شامل edge case neutral). هر چهار تکنیک ماژول، در یک prompt جمع‌اند.

اشتباهات رایج.

  • few-shot های همگی از یک کلاس — مدل آن کلاس را over-predict می‌کند.
  • نمونه‌های انگلیسی برای task فارسی — کیفیت روی متن فارسی به‌شدت افت می‌کند. نمونه‌ها باید به همان زبان target باشند.
  • few-shot هایی که context window را می‌خورند — اگر هر example چندصد token است و ۲۰ تا گذاشته‌اید، شاید زمان آن رسیده که به سراغ fine-tuning یا RAG بروید.

۴.۵ Ablation study — همه را با هم اندازه بگیرید

هدف: ترکیب چهار تکنیک در یک prompt production-grade و سنجش lift آن روی eval ساخته‌شده در Module 3.

روش. تابعی بنویسید که بسته به set تکنیک‌های فعال، prompt متفاوتی بسازد. سپس روی دیتاست ثابت، چهار run بگیرید: همه خاموش، فقط clarity، clarity+specificity، clarity+specificity+xml، و در نهایت همه‌ی چهار تا. این ablation study به شما می‌گوید کدام تکنیک چقدر امتیاز اضافه می‌کند — و آیا ارزش token هایش را دارد یا نه.

def make_prompt(techniques: set[str], review: str) -> str:
    parts = []
    if "clarity" in techniques:
        parts.append("Your task: classify the Persian review into "
                     "exactly one of: positive, negative, neutral, mixed.")
    if "specificity" in techniques:
        parts.append("Output: a single lowercase word, no punctuation, no explanation.")
    if "xml" in techniques:
        parts.append(f"<input>{review}</input>\n<output>")
    else:
        parts.append(review)
    if "fewshot" in techniques:
        parts.insert(1, FEW_SHOT_BLOCK)
    return "\n\n".join(parts)

نتایج تیپیک Anthropic روی دیتاست‌های classification و extraction:

  • clarity تنها: + ۵ تا ۱۰ امتیاز نسبت به baseline.
    • specificity: + ۳ تا ۸ امتیاز اضافه.
    • XML: + ۲ تا ۵ امتیاز اضافه (روی task های با document طولانی، بیشتر).
    • few-shot: + ۵ تا ۱۵ امتیاز اضافه.

جمع: ۱۵ تا ۳۸ امتیاز lift روی classification — معادل اختلاف Haiku تا Opus، اما بدون تغییر مدل و بدون افزایش هزینه‌ی per-call.

اشتباهات رایج.

  • ترکیب lift چند تکنیک بدون ablation — نمی‌فهمید کدام واقعاً کار کرد.
  • فراموش کردن bump version prompt هنگام تغییر technique — eval های هفته‌ی پیش با این هفته قابل‌مقایسه نیستند.
  • طولانی‌تر شدن prompt تا حدی که هزینه‌ی per-call از lift دقت بیشتر می‌شود — همیشه trade-off دقت/هزینه را بسنجید.