SSD Nodes Learn Hosting plans →
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-29

AI agents کے لیے self-hosted evals کیسے بنائیں

اپنی repository میں حقیقی traces سے golden cases بنائیں، پہلے سستے deterministic checks چلائیں، پھر LLM judge سے grading کریں اور ہر commit کا pass rate محفوظ کریں۔

AI agents کے لیے self-hosted evals کیا ہیں

AI agents کے لیے self-hosted evals چار چیزوں پر مشتمل ہوتے ہیں جو آپ اپنی repository میں رکھتے ہیں: محفوظ شدہ cases کی ایک file، agent کو ان cases پر چلانے والا script، ہر جواب کی grading کرنے والے checks کا ایک set، اور نتائج کی ایک table جسے آپ query کر سکیں۔ اس فہرست میں کسی بھی چیز کے لیے vendor ضروری نہیں۔ پورا loop چند سو lines کی Python اور ایک SQLite file سے چل سکتا ہے۔

Demo میں agent اس لیے کامیاب رہا کیونکہ پانچ inputs آپ نے خود منتخب کیے تھے۔ دوسرے ہفتے یہ اس لیے ناکام ہونے لگا کہ prompt کی ایک line تبدیل ہو گئی، یا model بدل گیا، یا tool کی description تبدیل ہو گئی، اور ان میں سے کسی چیز کی measurement موجود نہیں تھی۔ Eval loop، "اب یہ زیادہ خراب محسوس ہوتا ہے" کو "commit 4f1c9ab پر pass rate 60 میں سے 58 سے کم ہو کر 60 میں سے 51 ہو گیا" میں تبدیل کر دیتا ہے۔

اس loop کے چار steps ہیں، اور یہ guide ہر step کے لیے ایک section پر مشتمل ہے: حقیقی traces جمع کرنا، دلچسپ traces کو cases میں شامل کرنا، ہر change پر ہر case کی grading کرنا، اور pass rate کو اسے پیدا کرنے والے commit کے ساتھ store کرنا۔ یہی loop اس بات سے قطع نظر کام کرتا ہے کہ آپ agent کو کس چیز پر چلاتے ہیں، اور چلانے کے قابل self-hosted agent frameworks میں بنیادی فرق زیادہ تر اس بات کا ہوتا ہے کہ وہ trace کا کتنا حصہ آپ کو خود فراہم کرتے ہیں۔

ایجنٹ دوسرے ہفتے میں کیوں خراب ہو جاتا ہے

ایجنٹ prompt، model، tools کی definitions اور runtime پر حاصل کیے جانے والے context پر مشتمل ہوتا ہے۔ ان چاروں میں سے کوئی بھی آپ کی application code تبدیل کیے بغیر بدل سکتا ہے، اس لیے معمول کے code review میں قابل اعتراض تبدیلی نظر نہیں آتی۔

سب سے عام وجہ prompt میں ترمیم ہے۔ آپ غیر شائستہ جواب روکنے کے لیے ایک جملہ شامل کرتے ہیں۔ یہ جملہ ایسے inputs پر behaviour بدل دیتا ہے جنہیں دوبارہ test نہیں کیا گیا۔ Traces میں یہ بات واضح دکھائی دیتی ہے: پچھلے ہفتے اسی سوال کی trace میں create_refund tool call موجود تھا، جبکہ اس ہفتے کی trace میں یہ موجود نہیں ہے اور جواب اس کے بجائے شائستہ معذرت ہے۔ کوئی error پیدا نہیں ہوا، اس لیے کوئی alert بھی trigger نہیں ہوا۔

دوسری وجہ model ہے۔ ہر run کے ساتھ بھیجے گئے exact model string کو record کریں، claude-haiku-4-5-20251001 نہ کہ وہ مختصر نام جو آپ ذہن میں رکھتے ہیں۔ اس کی وجہ یہ ہے کہ models تبدیل کرنے والے دن pass rate میں کمی کی تشخیص اسی وقت ممکن ہوتی ہے جب model اس row میں درج ہو۔

تیسری وجہ tools ہیں۔ tool description کی wording تبدیل کرنے سے وہ وقت بدل جاتا ہے جب model اسے call کرنے کا فیصلہ کرتا ہے۔ اگر آپ کے tools VPS پر چلنے والے MCP servers کے ذریعے آتے ہیں تو schema ایک دوسرے process میں موجود ہوتا ہے۔ اس لیے یہ آپ کے repository میں کسی diff کے بغیر بھی تبدیل ہو سکتا ہے۔ چوتھی وجہ retrieval ہے: وہی سوال ایسے index تک پہنچتا ہے جسے رات کے دوران دوبارہ build کیا گیا ہو، اور جواب نئی document کے مطابق آتا ہے۔

پہلے سے جمع کیے جانے والے traces سے golden set تیار کریں

Eval cases خود سے نہ بنائیں۔ انہیں traffic سے حاصل کریں۔ اگر آپ پہلے ہی اپنے agent کے لیے self-hosted Langfuse tracing چلا رہے ہیں تو ہر request اس کے input، tool calls اور output کے ساتھ محفوظ ہوتی ہے۔ یہی وہ خام مواد ہے جس کی ایک case کو ضرورت ہوتی ہے۔

Public API سے root observations کی ایک مدت export کریں۔ اس میں basic authentication استعمال ہوتی ہے، جہاں public key username اور secret key password ہوتا ہے۔

export LF_HOST="https://langfuse.example.com"
curl -sS -u "$LF_PUBLIC_KEY:$LF_SECRET_KEY" \
  "$LF_HOST/api/public/v2/observations?limit=50&isRootObservation=true&fromStartTime=2026-07-01T00:00:00Z" \
  | jq '.data[0]'

Parsing لکھنے سے پہلے ایک record پڑھیں۔ Rows data کے اندر واپس آتی ہیں، لیکن question اور reply رکھنے والے field names اس بات پر منحصر ہوتے ہیں کہ آپ کا agent اپنے spans کو کیسے instrument کرتا ہے۔ اس لیے اپنی توقع کے بجائے اصل میں نظر آنے والی values کو map کریں۔ پھر evals/cases.jsonl میں ہر سطر پر ایک JSON object لکھ کر cases دستی طور پر تیار کریں:

{"id": "refund-double-charge", "tags": ["smoke"], "input": "I was charged twice for order 41822.", "must_call": ["lookup_order", "create_refund"], "must_not_include": ["I cannot help"], "rubric": "The reply confirms exactly one refund for order 41822 and states the amount."}

یہ پانچ اصول set کو قابلِ استعمال رکھتے ہیں:

  • آغاز کے لیے 40 سے 80 cases کافی ہیں۔ 20 سے کم cases میں ایک flaky case pass rate کو 5 points تک بدل دیتی ہے، اور بلاوجہ بدلنے والی number کو نظرانداز کر دیا جاتا ہے۔
  • Production کا ہر bug درست کرنے والے دن ہی ایک case بنائیں۔ یہی عادت set کو درست سمت میں بڑھاتی ہے۔
  • ہر case میں صرف ایک behaviour ہو۔ ایسی case جو refund amount اور tone دونوں کو جانچے، fail ہونے پر کوئی واضح معلومات نہیں دیتی۔
  • id کبھی تبدیل نہ کریں، کیونکہ id ہی آج کے run کا گزشتہ ماہ کے run سے موازنہ ممکن بناتی ہے۔
  • Commit کرنے سے پہلے redact کریں۔ یہ file git میں شامل ہوگی، اس لیے customer names اور وہ order numbers ہٹا دیں جو آپ کی ملکیت میں نہیں ہیں۔

پہلے deterministic checks کے ذریعے grading کریں، کیونکہ یہ مفت ہوتے ہیں

جس چیز کا درست جواب موجود ہو، اس پر سادہ assertion کافی ہے۔ model call کی ضرورت نہیں، کوئی لاگت نہیں، اور کوئی ابہام نہیں۔ deterministic checks ان structural regressions کو پکڑتے ہیں جو آپ کے agent کے گرد موجود systems کو ناکام بناتے ہیں: JSON parse نہیں ہوتا، tool کو کبھی call نہیں کیا گیا، ممنوعہ phrase دوبارہ آ گیا، یا جواب میں کسی source کا حوالہ نہیں دیا گیا۔

صرف ایک function آپ کے agent کے بارے میں جانتا ہے۔ harness کی باقی تمام چیزیں generic ہیں۔

import json, os, urllib.request

def run_agent(case):
    req = urllib.request.Request(
        os.environ["AGENT_URL"],
        data=json.dumps({"input": case["input"]}).encode(),
        headers={"content-type": "application/json"},
    )
    with urllib.request.urlopen(req, timeout=120) as resp:
        return json.load(resp)


def deterministic(case, result):
    text = result.get("output", "")
    called = [c["name"] for c in result.get("tool_calls", [])]
    failures = []
    for tool in case.get("must_call", []):
        if tool not in called:
            failures.append(f"tool not called: {tool}")
    for phrase in case.get("must_not_include", []):
        if phrase.lower() in text.lower():
            failures.append(f"forbidden phrase: {phrase}")
    if len(called) > case.get("max_tool_calls", 12):
        failures.append(f"too many tool calls: {len(called)}")
    return failures

اس فہرست میں tool budget بھی شامل رکھیں۔ اگر کوئی agent آج ایک case 3 calls میں حل کرتا ہے اور کل 11 calls لیتا ہے، تو final answer درست ہونے کے باوجود یہ regression ہے، کیونکہ ہر call کی ادائیگی آپ کو کرنا پڑتی ہے۔

LLM بطور judge، اور وہ چار طریقے جن سے یہ غلط نتیجہ دیتا ہے

Assertions سے گزرنے والے ہر جواب کے لیے ایسا grader درکار ہوتا ہے جو جواب کو پڑھ سکے۔ LLM judge دوسری model call ہوتی ہے: اسے سوال، agent کا جواب، اور ایک criterion دیا جاتا ہے، پھر یہ verdict واپس دیتی ہے۔ یہ جانچنے کا واحد عملی طریقہ ہے کہ "کیا جواب صارف کے پوچھے گئے سوال کا جواب دیتا ہے"۔

چار اصول judge کو قابلِ استعمال بناتے ہیں:

  • Binary verdict استعمال کریں، 1 سے 10 تک score کبھی نہیں۔ Scale تقریباً ہر جواب کے لیے 7 یا 8 واپس کرتا ہے، اس لیے number کبھی تبدیل نہیں ہوتا اور آپ کو اس سے کچھ معلوم نہیں ہوتا۔
  • ہر call میں ایک criterion رکھیں۔ Refund amount کے بارے میں پوچھیں یا tone کے بارے میں، دونوں کے بارے میں ایک ساتھ نہیں۔
  • جہاں expected answer موجود ہو، judge کو وہ ضرور دیں۔ Reference کے مقابلے میں grading کرنا abstract grading کے مقابلے میں کہیں آسان ہے۔
  • Output shape مقرر کریں اور اسے سختی سے parse کریں۔
from anthropic import Anthropic

client = Anthropic()  # reads ANTHROPIC_API_KEY from the environment


def judge_prompt(case, output):
    return (
        "You grade one answer against one criterion.\n"
        "Reply with JSON only, in this exact shape:\n"
        '{"verdict": "pass", "confidence": "high", "reason": "one short sentence"}\n'
        f"Criterion: {case['rubric']}\n"
        f"Question: {case['input']}\n"
        f"Answer: {output}\n"
        "Length is not a criterion. Judge only the criterion above."
    )


def judge(case, output, model):
    msg = client.messages.create(
        model=model,
        max_tokens=200,
        messages=[{"role": "user", "content": judge_prompt(case, output)}],
    )
    return json.loads(msg.content[0].text)

اب failure modes دیکھیں۔ ہر failure mode کے لیے ایک test ہے جو آپ آج ہی چلا سکتے ہیں۔ یہ tests چلانا اہم ہے، کیونکہ unchecked judge ایسے numbers پیدا کرتا ہے جو precise دکھائی دیتے ہیں مگر بے معنی ہوتے ہیں۔

Length bias۔ طویل جوابات زیادہ مرتبہ pass ہوتے ہیں۔ Test کریں: judge کے fail کیے ہوئے 10 جوابات لیں، ہر جواب میں پراعتماد مگر غیر ضروری filler کے 2 paragraphs شامل کریں جن میں کوئی نئی fact نہ ہو، پھر انہیں دوبارہ judge کریں۔ اگر کوئی verdict pass میں تبدیل ہو جائے تو یہ length bias ہے، اور rubric ہی وہ چیز ہے جسے درست کرنا چاہیے۔

Self-preference۔ Judge اکثر اپنے model family کے output کو کسی دوسرے model family کے output کے مقابلے میں زیادہ نرمی سے grade کرتا ہے۔ Test کریں: وہی 30 جوابات 2 مختلف model families کے judges سے grade کرائیں اور verdicts کا case by case موازنہ کریں۔ جہاں اختلاف ہو، case خود پڑھیں۔

Position bias۔ اگر آپ judge کو 2 جوابات، A اور B، کا موازنہ کرنے کے لیے استعمال کرتے ہیں تو order تبدیل کر کے دوبارہ چلائیں۔ اگر swap کے بعد verdict تبدیل ہو جائے تو اس کا مطلب ہے کہ اس rubric کے لیے pairwise comparison ابھی محفوظ نہیں۔

Rubric drift۔ مبہم criteria ایسے judges پیدا کرتے ہیں جو تقریباً ہر چیز سے متفق ہو جاتے ہیں۔ "کیا جواب مددگار ہے" تقریباً ہر چیز کو pass کر دیتا ہے۔ "کیا جواب dollars میں refund amount بیان کرتا ہے" صرف وہی جواب pass کرتا ہے جو آپ کا مطلوبہ تھا۔ ہر criterion کو اس وقت تک rewrite کریں جب تک اس میں جانچی جانے والی fact واضح طور پر بیان نہ ہو۔

ایک guardrail ان چاروں مسائل کا احاطہ کرتا ہے۔ 30 ایسے cases محفوظ رکھیں جنہیں آپ نے دستی طور پر label کیا ہو، اور جب بھی judge model یا judge prompt تبدیل کریں، judge کو اپنے labels کے مقابلے میں score کریں۔ اگر یہ 10 میں سے 1 سے زیادہ case پر آپ سے اختلاف کرے تو اس کے پیدا کردہ کسی بھی pass rate پر اعتماد کرنے سے پہلے rubric درست کریں۔ Judge بھی code ہے، اس لیے اسے code کی طرح version اور review کیا جاتا ہے۔

سستے ماڈل سے جانچیں، پھر frontier model تک جائیں

ہر commit پر ہر کیس کو سب سے مہنگے model سے جانچنے کی وجہ سے eval کا بل اس agent سے بھی زیادہ ہو جاتا ہے جس کی جانچ کی جا رہی ہوتی ہے۔ graders کو قیمت کے لحاظ سے ترتیب دیں، اور جواب واضح ہوتے ہی جانچ روک دیں۔

ChartCost to judge 1,000 eval cases, list prices, August 2026
The data behind this chart
[
  {
    "label": "Haiku 4.5, Batch API",
    "usd_per_1000_judge_calls": "0.90"
  },
  {
    "label": "Haiku 4.5",
    "usd_per_1000_judge_calls": "1.80"
  },
  {
    "label": "Sonnet 5",
    "usd_per_1000_judge_calls": "3.60"
  },
  {
    "label": "Opus 5",
    "usd_per_1000_judge_calls": "9.00"
  }
]

یہ اعداد و شمار فی judge call تقریباً 1,200 input tokens اور 120 output tokens فرض کرتے ہیں۔ ایک سوال، ایک جواب اور ایک criterion کے لیے یہ حقیقت پسندانہ حجم ہے۔ 1,000 cases کی جانچ پر Claude Haiku 4.5 میں 1.80 امریکی ڈالر اور Claude Opus 5 میں 9.00 امریکی ڈالر خرچ ہوتے ہیں۔ فی call فرق معمولی دکھائی دیتا ہے، لیکن تعداد بڑھنے پر یہ فرق نمایاں ہو جاتا ہے۔ 60 cases کے set کو ہر commit پر، ہفتے میں 40 commits کے حساب سے جانچنے پر، nightly job چلنے سے پہلے ہی ہفتے میں 2,400 judge calls ہو جاتے ہیں۔

Eval کام پر 2 discounts براہِ راست لاگو ہوتے ہیں، اور دونوں ایک ساتھ استعمال کیے جا سکتے ہیں۔ Eval runs interactive نہیں ہوتے، اس لیے Batch API asynchronous delivery کے بدلے input اور output دونوں کی قیمت آدھی کر دیتا ہے۔ یہی chart کی پہلی row ہے۔ Rubric اور instructions ہر call میں byte for byte یکساں ہوتے ہیں، اس لیے prompt caching موزوں ہے: cache read کی قیمت base input price کا دسواں حصہ ہے، جبکہ 5 minute cache write کی قیمت base input price سے 1.25 گنا ہے۔ اس لیے cache ایک ہی hit کے بعد اپنی لاگت پوری کر لیتا ہے۔ یہ Anthropic کی August 2026 کی list prices ہیں، اور Sonnet 5 کی introductory pricing 31 August 2026 تک ہے۔ اس تاریخ کے بعد تیسرا bar بلند ہو جائے گا۔

Ladder کی ترتیب یہ ہے:

  • ہر case پر deterministic checks۔ API کی کوئی لاگت نہیں۔
  • ان cases پر small model judge جو ان checks سے گزر جائیں۔
  • صرف وہاں frontier judge جہاں small judge fail کہے، یا کم confidence کے ساتھ pass کہے۔
  • ہفتے میں ایک بار چھوٹے sample پر human review۔
CHEAP = "claude-haiku-4-5-20251001"
STRICT = "claude-opus-5"


def grade(case, result):
    hard = deterministic(case, result)
    if hard:
        return False, "deterministic", "; ".join(hard)
    first = judge(case, result["output"], CHEAP)
    if first["verdict"] == "pass" and first["confidence"] == "high":
        return True, CHEAP, first["reason"]
    second = judge(case, result["output"], STRICT)
    return second["verdict"] == "pass", STRICT, second["reason"]

اس طریقے میں grading accuracy کے بدلے کچھ لاگت کم ہوتی ہے۔ اس trade کو فرض کرنے کے بجائے اسے measure کریں۔ مہینے میں ایک بار پورے set کو strict judge سے بھی grade کریں، پھر دونوں columns کا موازنہ کریں۔ اگر چند cases سے زیادہ پر نتائج مختلف ہوں تو small model کے لیے rubric بہت ڈھیلا ہے، اور درست کرنے والی چیز rubric ہی ہے۔ Agent خود کتنا خرچ کرتا ہے، اسے کنٹرول کرنا الگ کام ہے، جس کی وضاحت VPS پر AI agent کے لیے لاگت کا کنٹرول میں ہے۔

وقت کے ساتھ اپنے نظام میں پاس ریٹ کا جائزہ لیں

جس پاس ریٹ کو کسی commit کے ساتھ منسلک نہ کیا جا سکے، وہ محض ایک تاثر ہے۔ ہر run میں ہر case کے لیے ایک row محفوظ کریں، اور اسی row میں commit اور model درج کریں۔

CREATE TABLE IF NOT EXISTS results (
  run_id      TEXT NOT NULL,
  ran_at      TEXT NOT NULL,
  git_sha     TEXT NOT NULL,
  agent_model TEXT NOT NULL,
  case_id     TEXT NOT NULL,
  passed      INTEGER NOT NULL,
  graded_by   TEXT NOT NULL,
  reason      TEXT
);
SELECT run_id, git_sha, agent_model,
       count(*) AS cases,
       round(100.0 * sum(passed) / count(*), 1) AS pass_pct
FROM results
GROUP BY run_id
ORDER BY ran_at DESC
LIMIT 10;

sqlite3 evals/results.db < evals/schema.sql سے schema load کریں، پھر sqlite3 -box evals/results.db < evals/passrate.sql سے trend پڑھیں۔ 60 cases پر روزانہ runs کا ایک سال تقریباً 22,000 rows بنتا ہے، اس لیے store خود ایک الگ project نہیں بنتا۔ VPS پر SQLite کو production میں چلانا ان settings کا احاطہ کرتا ہے جو اس وقت اہم ہو جاتی ہیں جب یہ file متعدد machines کے درمیان share کی جائے۔

runner کسی شخص کے لیے بھی یہی معلومات print کرتا ہے:

run 2026-08-05T09:14:22Z  sha 4f1c9ab  model claude-sonnet-5  58/60 pass (96.7%)
FAIL refund-double-charge  deterministic: tool not called: create_refund
FAIL pto-policy-question   judge(opus): reply gives no dollar amount

Suite کو ان changes پر run کریں جو agent کو متاثر کر سکتے ہیں۔ اس میں ہر repository commit کے بجائے prompt edits، model changes اور tool changes شامل ہیں۔ pre-push hook تیز subset کو cover کرتا ہے:

cat > .git/hooks/pre-push <<'EOF'
#!/bin/sh
python3 evals/run.py --set smoke || exit 1
EOF
chmod +x .git/hooks/pre-push

Full runs سست ہوتے ہیں، اس لیے انہیں schedule پر چلائیں۔ VPS پر ایک nightly systemd service اور timer deployed prompt کے خلاف پورا set چلاتا ہے۔ یہی وہ changes پکڑتا ہے جو repository کے باہر سے آتی ہیں، مثلاً کسی hosted tool کا بدل جانے والا behaviour۔

انسانی جائزہ، مکمل کے بجائے نمونہ جاتی

جج کی calibration انسانی labels کے ساتھ کی جاتی ہے، اس لیے کسی کو یہ labels تیار کرنا ہوں گے۔ ہر ہفتے ایک sample پڑھیں: ہر وہ case جس میں جج ناکام رہا ہو، اور اس کے علاوہ randomly منتخب کیے گئے دس passes۔ random passes زیادہ اہم ہیں، کیونکہ جو جج خاموشی سے خراب جوابات کو pass کرنا شروع کر دے، وہ اپنے ہی verdicts سے بنائے گئے کسی بھی dashboard پر درست دکھائی دے گا۔

پندرہ cases، ہر ایک کے لیے تین منٹ، ہفتے میں 45 منٹ بنتے ہیں۔ اس کے بدلے rubric میں ان مقامات کی corrections ملتی ہیں جہاں آپ اور جج کے فیصلے مختلف ہوں، اور ان failure types کے لیے نئے cases بھی ملتے ہیں جن کا کسی نے پہلے تصور نہیں کیا تھا۔ انسانی verdict کو اسی table میں لکھیں، اور graded_by کو human پر set کریں، تاکہ جج اور انسان کے درمیان agreement یادداشت کے بجائے query بن جائے۔

خود eval harness میں کیا خرابی پیدا ہوتی ہے

anthropic.RateLimitError پہلے مکمل run پر۔ ایک ساتھ ساٹھ cases چلانے سے آپ کے tier کی request یا token limit تجاوز کر جاتی ہے۔ concurrency کو چار workers تک محدود کریں، اور nightly run کو Batch API پر منتقل کریں۔

json.JSONDecodeError: Expecting value: line 1 column 1 (char 0) judge کی طرف سے۔ model نے prose میں جواب دیا، یا اپنے JSON کو code fence میں لپیٹ دیا۔ ایک بار retry کریں، پھر case کو error کے طور پر record کریں۔ parse failure کو کبھی pass شمار نہ ہونے دیں، کیونکہ جو suite errors کو passes میں تبدیل کرتا ہے، وہ agent کی کارکردگی خراب ہونے کے باوجود 100% کی طرف بڑھتا رہتا ہے۔

Flaky cases۔ ایک ہی input ایک run میں pass اور اگلے run میں fail ہوتا ہے، کیونکہ agent اپنے output کی sampling کرتا ہے۔ flaky case کو تین بار run کریں اور case حذف کرنے کے بجائے اس کا fraction record کریں۔ جو case تین میں سے دو runs میں pass ہو، وہ حقیقی robustness bug ہے، اور customer اسے تلاش کر لے گا۔

Golden set کا زوال۔ کوئی شخص suite کو green کرنے کے لیے expected answer میں ترمیم کر دیتا ہے۔ evals/cases.jsonl کے diffs کا review agent کے diffs کی طرح احتیاط سے کریں، کیونکہ یہ file درست نتیجے کی آپ کی تحریری تعریف ہے۔

ایسا suite جو کبھی fail نہ ہو۔ ایک ماہ تک 100% پر قائم pass rate کا مطلب ہے کہ set نے product کی نگرانی کرنا چھوڑ دی ہے۔ حالیہ دس traces نکالیں، ان میں وہ traces تلاش کریں جنہیں agent نے خراب طریقے سے handle کیا، اور انہیں شامل کریں۔ پھر جان بوجھ کر کوئی چیز خراب کریں اور تصدیق کریں کہ run red ہو جاتا ہے۔ یہی وہ check ہے جس پر mutation testing test suite پر لاگو ہوتی ہے منحصر ہے، اور یہی جاننے کا واحد طریقہ ہے کہ آپ کے set میں اب بھی مؤثر جانچ کی صلاحیت موجود ہے۔

FAQ

ایک AI agent eval set میں کتنے cases ہونے چاہییں؟

40 سے 80 cases سے شروع کریں اور حقیقی failures کی بنیاد پر set کو بڑھائیں۔ تقریباً 20 cases سے کم ہونے پر ایک غیر مستحکم نتیجہ pass rate کو 5 points تک بدل دیتا ہے، اس لیے یہ تعداد قابلِ اعتماد معلومات فراہم نہیں کرتی۔ چند سو cases سے زیادہ ہونے پر ہر run میں حقیقی لاگت اور وقت صرف ہوتا ہے، جبکہ ہر نیا case coverage میں معمولی اضافہ کرتا ہے۔ اہم پیمانہ cases کی تعداد نہیں، بلکہ یہ ہے کہ production میں معلوم failure types میں سے کتنے set میں کم از کم 1 بار شامل ہیں۔

کیا میں اپنے agent کی grading کے لیے LLM judge پر اعتماد کر سکتا ہوں؟

صرف اس وقت جب آپ اسے اپنے labels کے مقابلے میں ناپ چکے ہوں۔ 30 cases کو خود ہاتھ سے grade کریں، اور جب بھی judge model یا judge prompt تبدیل کریں، judge کو انہی cases کے مقابلے میں score کریں۔ Judges میں length bias ہوتا ہے، جس میں غیر ضروری طور پر طویل answers زیادہ مرتبہ pass ہو جاتے ہیں، اور self-preference بھی ہوتا ہے، جس میں اپنے model family کے output کو زیادہ نرمی سے grade کیا جاتا ہے۔ دونوں کی جانچ ممکن ہے: failed answer کو غیر ضروری طور پر طویل کر کے دوبارہ judge کریں، یا انہی answers کو کسی دوسری model family کے judge سے grade کریں۔ اگر judge 10 میں سے 1 سے زیادہ cases پر آپ کے labels سے اختلاف کرے تو rubric اتنا مبہم ہے کہ اسے استعمال نہیں کیا جا سکتا۔

Evals کی grading کے لیے کون سا model استعمال کرنا چاہیے؟

سستا model پہلے استعمال کریں اور ضرورت پڑنے پر مہنگے model کی طرف جائیں۔ Deterministic assertions کی کوئی لاگت نہیں ہوتی، اس لیے وہ ہر case پر سب سے پہلے چلتی ہیں۔ ایک small model واضح passes کو handle کر سکتا ہے۔ صرف fails اور low-confidence verdicts کو frontier model کے پاس بھیجیں۔ August 2026 کی list prices کے مطابق، 1,000 cases کی grading پر Claude Haiku 4.5 کے ساتھ تقریباً 1.80 US dollars اور Claude Opus 5 کے ساتھ تقریباً 9.00 لاگت آتی ہے، اور چونکہ eval runs asynchronous ہوتے ہیں، اس لیے Batch API دونوں figures کو نصف کر دیتی ہے۔

کیا evals production monitoring کی جگہ لے سکتی ہیں؟

نہیں، کیونکہ دونوں مختلف سوالات کا جواب دیتی ہیں۔ Eval suite آپ کو بتاتی ہے کہ جو تبدیلی آپ deploy کرنے والے ہیں، وہ cases کے ایک مقررہ set کے نتائج کو بہتر بناتی ہے یا خراب۔ Tracing اور monitoring آپ کو بتاتی ہیں کہ حقیقی users اس وقت کن چیزوں کا سامنا کر رہے ہیں، جن میں وہ inputs بھی شامل ہیں جن کا کوئی case موجود نہیں۔ دونوں ایک دوسرے کو data فراہم کرتے ہیں: traces نئے cases فراہم کرتی ہیں، اور eval suite یہ طے کرتی ہے کہ آپ کا fix واقعی مؤثر تھا یا نہیں۔