SSD Nodes Learn 🎉 VPS $5.50/ماہ سے
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-13

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

اپنی repository میں golden cases، deterministic checks اور LLM judge رکھ کر eval loop بنائیں، پھر ہر commit کے ساتھ pass rate محفوظ کریں تاکہ regressions فوراً نظر آئیں۔

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

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

Demo میں agent اس لیے کامیاب رہا کیونکہ پانچ inputs آپ نے خود منتخب کیے تھے۔ دوسرے ہفتے میں یہ اس لیے ناکام ہوا کہ prompt کی ایک line، model، یا tool description تبدیل ہو گئی، اور ان تبدیلیوں میں سے کسی کو بھی کوئی measurement cover نہیں کر رہا تھا۔ 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 کا کتنا حصہ آپ کو خود فراہم کرتے ہیں۔

دوسرے ہفتے agent کیوں ناکام ہونے لگتا ہے

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

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

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

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

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

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

Public API سے root observations کا ایک window 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 کرتا ہے۔ اس لیے اپنی توقع کے بجائے اصل data میں موجود fields map کریں۔ پھر cases خود لکھیں، ہر سطر میں ایک JSON object، evals/cases.jsonl میں:

{"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 کا حوالہ موجود نہیں۔

Harness میں صرف ایک function آپ کے agent کے بارے میں جانتا ہے۔ باقی تمام اجزا 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 ہوتی ہے: اسے question، agent کا answer اور ایک criterion دیا جاتا ہے، پھر یہ verdict واپس دیتا ہے۔ یہ جانچنے کا واحد عملی طریقہ ہے کہ "کیا reply نے صارف کے سوال کا جواب دیا؟"

درج ذیل چار اصول 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۔ لمبے answers زیادہ مرتبہ pass ہوتے ہیں۔ Test کریں: judge کے fail کیے ہوئے 10 answers لیں، ہر answer میں اعتماد سے لکھے گئے ایسے 2 paragraphs شامل کریں جن میں کوئی نیا fact نہ ہو، پھر انہیں دوبارہ judge کریں۔ اگر کوئی verdict pass میں تبدیل ہو جائے تو یہ length bias ہے، اور rubric کو درست کرنے کی ضرورت ہے۔

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

Position bias۔ اگر آپ judge کو دو answers، A اور B، کا تقابل کرنے کے لیے استعمال کرتے ہیں تو ترتیب بدل کر دوبارہ چلائیں۔ اگر swap کے بعد verdict تبدیل ہو جائے تو pairwise comparison اس rubric کے لیے ابھی قابلِ اعتماد نہیں ہے۔

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

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

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

ہر commit پر ہر case کو سب سے مہنگے model سے جانچنا اس طرح eval bill کو اس agent سے بھی بڑا کر دیتا ہے جسے جانچا جا رہا ہو۔ Grader models کو قیمت کے لحاظ سے ترتیب دیں، اور جواب واضح ہوتے ہی عمل روک دیں۔

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 US dollars اور Claude Opus 5 میں 9.00 لاگت آتی ہے۔ یہ فرق بظاہر معمولی لگتا ہے، لیکن تعداد بڑھنے پر نمایاں ہو جاتا ہے۔ 60 cases کے set کو ہر commit پر، ہفتے میں 40 commits کے حساب سے جانچنے پر، nightly job چلانے سے پہلے ہی ہفتے میں 2,400 judge calls ہو جاتے ہیں۔

Eval کام پر دو 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 کا دسواں حصہ ہوتی ہے، جبکہ پانچ منٹ کی cache write کی قیمت base input کا 1.25 گنا ہوتی ہے۔ اس لیے ایک ہی hit کے بعد cache کی لاگت پوری ہو جاتی ہے۔ یہ Anthropic کی August 2026 تک کی list prices ہیں، اور Sonnet 5 کی introductory pricing 31 August 2026 تک ہے۔ اس تاریخ کے بعد تیسرا bar بلند ہو جائے گا۔

یہ ladder ترتیب کے ساتھ ہے:

  • ہر case پر deterministic checks چلائیں۔ API cost بالکل نہیں۔
  • ان 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 خود کتنی لاگت خرچ کرتا ہے، اسے control کرنا الگ کام ہے۔ اس کی وضاحت VPS پر AI agent کے لیے cost control میں ہے۔

اپنے زیرِ انتظام نظام میں وقت کے ساتھ pass rate کو track کریں

جس pass rate کو کسی 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 کو ان تبدیلیوں پر چلائیں جو agent کو متاثر کر سکتی ہیں، یعنی prompt edits، model changes اور tool changes؛ repository میں ہونے والے ہر commit پر نہیں۔ pre-push hook فوری subset کا احاطہ کرتا ہے:

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 چلاتا ہے۔ اس سے وہ تبدیلیاں بھی پکڑی جاتی ہیں جو آپ کی repository کے باہر سے آتی ہیں، مثلاً کسی hosted tool کا بدل جانے والا behaviour۔

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

Judge کو انسانی لیبلز کے مطابق calibrated کیا جاتا ہے، اس لیے کسی شخص کو یہ لیبلز تیار کرنے ہوتے ہیں۔ ہر ہفتے ایک sample پڑھیں: ہر وہ case جس میں Judge ناکام رہا ہو، اور اس کے علاوہ random طور پر منتخب کیے گئے 10 passes۔ Random passes زیادہ اہم ہیں، کیونکہ اگر Judge خاموشی سے خراب answers کو pass کرنا شروع کر دے تو اپنے ہی verdicts سے بنائے گئے کسی بھی dashboard پر وہ بظاہر درست دکھائی دے گا۔

ہر ہفتے 15 cases، ہر case کے لیے 3 منٹ، یعنی کل 45 منٹ، کافی ہیں۔ اس عمل سے rubric میں ان مقامات کی corrections ملتی ہیں جہاں آپ اور Judge متفق نہیں ہوتے، اور ان failure types کے لیے نئے cases بھی ملتے ہیں جن کا کسی نے پہلے تصور نہیں کیا تھا۔ انسانی verdict کو اسی table میں graded_by کو human پر set کر کے لکھیں، تاکہ Judge اور انسان کے درمیان 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 نے نثری جواب دیا، یا اپنے JSON کو code fence میں لپیٹ دیا۔ ایک بار retry کریں، پھر case کو error کے طور پر record کریں۔ parse failure کو کبھی pass نہ شمار کریں، کیونکہ errors کو passes میں تبدیل کرنے والی suite، agent کے خراب ہونے کے باوجود، 100% کی طرف بڑھتی رہتی ہے۔

Flaky cases۔ ایک ہی input ایک run میں pass اور اگلے run میں fail ہوتا ہے، کیونکہ agent اپنے output کو sample کرتا ہے۔ flaky case کو تین بار چلائیں اور case حذف کرنے کے بجائے اس کا تناسب 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 کی tracking روک دی ہے۔ حالیہ دس traces نکالیں، ان میں وہ traces تلاش کریں جنہیں agent نے خراب طریقے سے handle کیا، اور انہیں شامل کریں۔

FAQ

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

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

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

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

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

سستے model سے grade کریں اور ضرورت پڑنے پر زیادہ طاقتور model کو کام دیں۔ Deterministic assertions کی کوئی لاگت نہیں ہوتی، اس لیے وہ ہر case پر پہلے چلیں۔ چھوٹا 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 آپ کو بتاتا ہے کہ جس change کو آپ ship کرنے والے ہیں، وہ fixed cases کے set کو بہتر کرتا ہے یا خراب۔ Tracing اور monitoring آپ کو بتاتے ہیں کہ حقیقی users اس وقت کیا استعمال کر رہے ہیں، جن میں وہ inputs بھی شامل ہیں جن کا کوئی case موجود نہیں۔ دونوں ایک دوسرے کو feed کرتے ہیں: traces نئے cases فراہم کرتے ہیں، اور eval suite طے کرتا ہے کہ آپ کا fix حقیقتاً کام کر گیا یا نہیں۔