SSD Nodes Learn 🎉 VPS $4.99/माह से
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-07

AI agents के लिए self-hosted evals कैसे बनाएं

अपने AI agents के लिए खुद का eval loop तैयार करें। वास्तविक traces से golden cases चुनें, deterministic checks और LLM judge का उपयोग करें और हर commit पर pass rate ट्रैक करें।

AI agents के लिए self-hosted evals क्या हैं

AI agents के लिए self-hosted evals वे चार चीजें हैं जिन्हें आप अपने स्वयं के repository में रखते हैं: सहेजे गए cases की एक file, एक script जो उन पर agent को चलाती है, जाँचों (checks) का एक समूह जो प्रत्येक उत्तर को grade करता है, और परिणामों की एक table जिसे आप query कर सकते हैं। उस सूची में किसी भी चीज़ के लिए vendor की आवश्यकता नहीं है। पूरा loop कुछ सौ lines का Python code और एक SQLite file है।

Agent demo में इसलिए काम कर गया क्योंकि आपने पाँच inputs खुद चुने थे। यह दूसरे सप्ताह में इसलिए खराब हो गया क्योंकि एक prompt line बदल गई, या कोई model बदल गया, या tool का विवरण बदल गया, और किसी भी measurement ने इसे cover नहीं किया। एक eval loop "अब यह पहले से खराब लग रहा है" को "commit 4f1c9ab पर pass rate 60 में से 58 से घटकर 60 में से 51 हो गया" में बदल देता है।

इस loop में चार चरण होते हैं, और यह guide हर चरण के लिए एक section है: वास्तविक traces एकत्र करें, दिलचस्प traces को cases में बदलें, हर बदलाव पर हर case को grade करें, और pass rate को उसे उत्पन्न करने वाले commit के साथ store करें। यही loop तब भी काम करता है जब आप agent को किसी भी चीज़ पर चलाएं, और चलाने योग्य self-hosted agent frameworks मुख्य रूप से इस बात में भिन्न होते हैं कि वे आपको मुफ्त में कितना trace प्रदान करते हैं।

Why the agent breaks in week two

An agent is a prompt, a model, a set of tool definitions, and whatever context gets retrieved at run time. All four can move without your application code changing, so a normal code review sees nothing to object to.

The most common cause is a prompt edit. You add one sentence to stop a rude reply. That sentence changes behaviour on inputs nobody retested, and the traces show it plainly: last week's trace for the same question contains a create_refund tool call, this week's contains none, and the reply is a polite apology instead. Nothing raised an error, so no alert fired.

The second cause is the model. Record the exact model string you sent with every run, claude-haiku-4-5-20251001 rather than a shorthand you keep in your head, because a pass rate that drops on the day you switched models is only diagnosable when the model is in the row.

The third is tools. Rewording a tool description changes when the model decides to call it. If your tools arrive over MCP servers running on a VPS, the schema lives in another process, so it can change under you with no diff in your repository at all. The fourth is retrieval: the same question hits an index that was rebuilt overnight, and the answer follows the new document.

पहले से एकत्रित traces से golden set तैयार करें

मूल्यांकन के लिए नए cases न बनाएँ। उन्हें सीधे traffic से लें। यदि आप पहले से ही अपने agent के लिए self-hosted Langfuse tracing का उपयोग कर रहे हैं, तो प्रत्येक request उसके input, tool calls और output के साथ store होती है। यही वह कच्चा माल है जिसकी एक 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 को पढ़ें। पंक्तियाँ data के अंतर्गत वापस आती हैं, लेकिन प्रश्न और उत्तर रखने वाले field के नाम इस पर निर्भर करते हैं कि आपका agent अपने spans को कैसे instrument करता है। इसलिए, जो आप वास्तव में देखते हैं उसे map करें, न कि वह जो आपने उम्मीद की थी। इसके बाद, evals/cases.jsonl में cases को हाथ से लिखें, प्रति पंक्ति एक JSON object:

{"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."}

सेट को उपयोगी बनाए रखने के लिए पाँच नियम हैं:

  • शुरुआत करने के लिए 40 से 80 cases पर्याप्त हैं। 20 से कम होने पर, एक अस्थिर (flaky) case pass rate को 5 अंकों तक बदल देता है, और बिना किसी कारण के बदलने वाले आँकड़ों को नजरअंदाज कर दिया जाता है।
  • आपके द्वारा ठीक किया गया प्रत्येक production bug उसी दिन एक case बन जाना चाहिए। यही आदत सेट को सही दिशा में विकसित करती है।
  • प्रति case केवल एक व्यवहार (behaviour) रखें। यदि कोई case refund की राशि और tone दोनों की जाँच करता है, तो विफल होने पर आपको यह पता नहीं चलेगा कि समस्या कहाँ है।
  • id कभी नहीं बदलता है, क्योंकि इसी id के माध्यम से आज के run की तुलना पिछले महीने के run से की जाती है।
  • commit करने से पहले redact करें। यह file git में जाती है, इसलिए ग्राहकों के नाम और ऐसे किसी भी order number को हटा दें जो आपके नहीं हैं।

सबसे पहले deterministic checks के साथ ग्रेडिंग करें, क्योंकि ये मुफ्त हैं

जिसका भी सही उत्तर निश्चित है, उसके लिए एक plain assertion का उपयोग करें। इसमें किसी model call, लागत या अस्पष्टता की आवश्यकता नहीं होती। Deterministic checks संरचनात्मक regressions (structural regressions) को पकड़ लेते हैं, और यही वे त्रुटियाँ हैं जो आपके agent के आसपास के सिस्टम को खराब करती हैं: जैसे JSON का parse न होना, tool का कभी call न किया जाना, प्रतिबंधित वाक्यांश (forbidden 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 आज 3 calls में एक case हल करता है और कल 11 calls में, तो यह एक regression है, भले ही अंतिम उत्तर सही हो, क्योंकि आप उसके द्वारा की गई प्रत्येक call के लिए भुगतान करते हैं।

LLM as judge, और इसके गलत होने के चार तरीके

जो भी assertions से बच जाता है, उसे एक ऐसे grader की आवश्यकता होती है जो उसे पढ़ सके। LLM judge एक दूसरा model call है: यह प्रश्न, agent का उत्तर और एक मानदंड (criterion) प्राप्त करता है, और फिर अपना निर्णय देता है। यह जांचने का एकमात्र व्यावहारिक तरीका है कि "क्या उत्तर वही है जो user ने पूछा था"।

चार नियम एक judge को उपयोगी बनाते हैं:

  • बाइनरी (Binary) निर्णय लें, कभी भी 1 से 10 का स्कोर न दें। एक scale लगभग हर चीज़ के लिए 7 और 8 ही देती है, इसलिए संख्या कभी बदलती नहीं है और आप उससे कुछ नहीं सीख पाते।
  • प्रति call एक ही मानदंड रखें। refund की राशि के बारे में पूछें, या tone के बारे में, दोनों एक साथ नहीं।
  • जब भी किसी मामले का कोई अपेक्षित उत्तर हो, तो judge को वह उत्तर दें। किसी reference के आधार पर grading करना, abstract रूप में grading करने की तुलना में कहीं अधिक आसान कार्य है।
  • output के आकार को force करें और उसे सख्ती से 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) देखें। प्रत्येक का एक test है जिसे आप आज दोपहर चला सकते हैं, और उन्हें चलाना महत्वपूर्ण है, क्योंकि एक अनियंत्रित judge ऐसी संख्याएं देता है जो सटीक दिखती हैं लेकिन उनका कोई अर्थ नहीं होता।

Length bias. लंबे उत्तर अधिक बार पास होते हैं। इसका परीक्षण करें: judge द्वारा विफल किए गए दस उत्तर लें, प्रत्येक में दो पैराग्राफ का आत्मविश्वासपूर्ण filler जोड़ें जो कोई नया तथ्य नहीं जोड़ते, और उन्हें फिर से judge करें। यदि कोई निर्णय pass में बदल जाता है, तो यह length bias है, और rubric को ठीक करने की आवश्यकता है।

Self-preference. एक judge अक्सर अपने ही model family के output को दूसरे की तुलना में अधिक उदारता से grade करता है। इसका परीक्षण करें: दो अलग-अलग families के judges के साथ उन्हीं 30 उत्तरों को grade करें और case-by-case आधार पर निर्णयों की तुलना करें। जहाँ वे असहमत हों, वहां आप स्वयं case को पढ़ें।

Position bias. यदि आप दो उत्तरों, A और B, की तुलना करने के लिए judge का उपयोग करते हैं, तो उनका क्रम बदलें और इसे फिर से चलाएं। यदि क्रम बदलने पर निर्णय बदल जाता है, तो इसका मतलब है कि pairwise comparison उस rubric के लिए अभी सुरक्षित नहीं है।

Rubric drift. अस्पष्ट मानदंड सहमत होने वाले judges पैदा करते हैं। "क्या उत्तर सहायक है" लगभग किसी भी चीज़ को पास कर देता है। "क्या उत्तर refund की राशि को dollars में बताता है" केवल उसी को पास करता है जिसे आप चाहते थे। प्रत्येक मानदंड को तब तक फिर से लिखें जब तक कि वह उस तथ्य का नाम न ले ले जिसकी जांच की जा रही है।

एक सुरक्षा उपाय इन चारों को कवर करता है। हाथ से लेबल किए गए 30 cases रखें, और हर बार जब आप judge model या judge prompt बदलते हैं, तो अपने labels के मुकाबले judge को score करें। यदि यह दस में से एक से अधिक मामलों में आपसे असहमत है, तो किसी भी pass rate पर भरोसा करने से पहले rubric को ठीक करें। Judge एक code है, इसलिए इसे code की तरह ही versioned और review किया जाना चाहिए।

सस्ते मॉडल से ग्रेडिंग शुरू करें, फिर frontier मॉडल पर जाएँ

हर commit पर सबसे महंगे मॉडल से हर मामले की जांच करना ही वह कारण है जिससे 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 मानते हैं, जो एक प्रश्न, एक उत्तर और एक मानदंड के लिए यथार्थवादी आकार है। 1,000 मामलों की जांच करने की लागत Claude Haiku 4.5 पर 1.80 अमेरिकी डॉलर और Claude Opus 5 पर 9.00 है। यह अंतर तब तक मामूली लगता है जब तक आप इसका गुणा न करें। 60 मामलों का एक सेट, जिसे हर commit पर जांचा जाता है, और प्रति सप्ताह 40 commits होते हैं, तो nightly job चलने से पहले ही प्रति सप्ताह 2,400 judge calls हो जाते हैं।

Eval कार्य पर दो तरह की छूट आसानी से लागू होती हैं, और वे एक साथ जुड़ती हैं। Eval runs इंटरैक्टिव नहीं होते हैं, इसलिए Batch API asynchronous delivery के बदले input और output दोनों कीमतों को आधा कर देता है, जो चार्ट की पहली पंक्ति है। Rubric और निर्देश हर call में byte-दर-byte समान होते हैं, इसलिए prompt caching काम आता है: एक cache read की लागत base input कीमत का दसवां हिस्सा होती है, और पांच मिनट का cache write base input का 1.25 गुना होता है, इसलिए एक ही hit के बाद cache अपनी लागत वसूल कर लेता है। ये अगस्त 2026 तक Anthropic की सूची कीमतें हैं, और Sonnet 5 पर 31 अगस्त 2026 तक शुरुआती कीमतें लागू हैं, इसलिए उस तारीख के बाद तीसरी बार (bar) की कीमत बढ़ जाएगी।

क्रमबद्ध सीढ़ी इस प्रकार है:

  • हर मामले पर Deterministic checks। इसमें कोई API लागत नहीं आती।
  • उन मामलों पर एक छोटा मॉडल judge, जो उन checks से पास हो गए।
  • एक frontier judge केवल वहां, जहां छोटा 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"]

यह लागत के बदले ग्रेडिंग की सटीकता में कुछ समझौता करता है, इसलिए मान लेने के बजाय इस समझौते को मापें। महीने में एक बार, पूरे सेट को strict judge के साथ ग्रेड करें और दोनों columns की तुलना करें। यदि वे कुछ मामलों से अधिक पर असहमत हैं, तो आपका rubric छोटे मॉडल के लिए बहुत ढीला है, और आपको rubric को ही ठीक करना होगा। Agent स्वयं कितना खर्च करता है, इसे नियंत्रित करना एक अलग कार्य है, जिसे VPS पर AI agent के लिए लागत नियंत्रण में कवर किया गया है।

अपने सिस्टम में समय के साथ पास रेट (pass rate) को ट्रैक करें

यदि आप पास रेट को किसी कमिट (commit) से नहीं जोड़ सकते, तो वह केवल एक अनुमान है। प्रत्येक रन के लिए हर केस की एक पंक्ति स्टोर करें, जिसमें उस पंक्ति के भीतर कमिट और मॉडल की जानकारी हो।

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 के साथ स्कीमा लोड करें, फिर sqlite3 -box evals/results.db < evals/passrate.sql के साथ ट्रेंड पढ़ें। 60 केसों पर प्रतिदिन चलने वाले एक वर्ष के रन लगभग 22,000 पंक्तियों के बराबर होते हैं, इसलिए यह डेटा स्टोर कभी भी एक अलग प्रोजेक्ट नहीं बनता। VPS पर प्रोडक्शन में SQLite चलाना उन सेटिंग्स को कवर करता है जो तब महत्वपूर्ण हो जाती हैं जब यह फाइल कई मशीनों के बीच साझा की जाती है।

रनर एक व्यक्ति के लिए भी वही जानकारी प्रिंट करता है:

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) को उन बदलावों पर चलाएं जो एजेंट को तोड़ सकते हैं, जिसका अर्थ है प्रॉम्प्ट में बदलाव, मॉडल में बदलाव और टूल में बदलाव, न कि रिपॉजिटरी में हर कमिट पर। एक pre-push हुक इस तेज़ सबसेट (subset) को कवर करता है:

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

पूर्ण रन धीमे होते हैं और उन्हें शेड्यूल पर चलना चाहिए। एक रात्रिकालीन VPS पर systemd सर्विस और टाइमर तैनात प्रॉम्प्ट के विरुद्ध पूरा सेट चलाता है, जो उन बदलावों को पकड़ता है जो आपकी रिपॉजिटरी के बाहर से आते हैं, जैसे कि कोई होस्ट किया गया टूल जिसका व्यवहार बदल गया हो।

मानवीय समीक्षा, संपूर्ण के बजाय नमूना आधारित

Judge को मानवीय labels के आधार पर कैलिब्रेट किया जाता है, इसलिए किसी को उन्हें तैयार करना होगा। हर सप्ताह एक नमूने की समीक्षा करें: वे सभी मामले जिनमें Judge विफल रहा, और साथ ही यादृच्छिक (random) रूप से चुने गए दस सफल मामले। यादृच्छिक सफल मामले इसका महत्वपूर्ण हिस्सा हैं, क्योंकि यदि कोई Judge चुपचाप गलत उत्तरों को सही ठहराने लगे, तो उसके अपने निर्णयों से बने किसी भी डैशबोर्ड पर वह बिल्कुल सही दिखेगा।

तीन मिनट प्रति मामले के हिसाब से पंद्रह मामले देखने में प्रति सप्ताह 45 मिनट लगते हैं। इससे rubric में सुधार होता है जहाँ आप और Judge असहमत हैं, साथ ही उन विफलता प्रकारों के लिए नए मामले मिलते हैं जिनकी किसी ने कल्पना भी नहीं की थी। मानवीय निर्णय को उसी तालिका में लिखें जहाँ graded_by को human पर सेट किया गया हो, ताकि Judge और मानव के बीच सहमति एक याददाश्त के बजाय एक query बन जाए।

eval harness में क्या खराब होता है

anthropic.RateLimitError पहले पूर्ण रन पर। एक साथ साठ मामलों को चलाने से आपके टियर की रिक्वेस्ट या टोकन सीमा पार हो जाती है। concurrency को चार workers पर सीमित करें, और nightly run को Batch API पर ले जाएँ।

json.JSONDecodeError: Expecting value: line 1 column 1 (char 0) जज की तरफ से। मॉडल ने गद्य (prose) में उत्तर दिया, या अपने JSON को code fence में लपेट दिया। एक बार पुनः प्रयास करें, फिर मामले को error के रूप में रिकॉर्ड करें। parse failure को कभी भी pass न मानें, क्योंकि जो suite त्रुटियों को pass में बदल देता है, वह 100% की ओर बढ़ता है जबकि agent का प्रदर्शन खराब होता जाता है।

Flaky मामले। एक ही इनपुट एक रन पर पास होता है और अगले पर फेल, क्योंकि agent अपने आउटपुट को sample करता है। flaky मामले को तीन बार चलाएं और मामले को हटाने के बजाय fraction रिकॉर्ड करें। जो मामला तीन में से दो बार पास होता है, वह एक वास्तविक robustness bug है, और ग्राहक इसे ढूंढ ही लेगा।

Golden set का पुराना होना। कोई suite को green करने के लिए अपेक्षित उत्तर (expected answer) को संपादित करता है। evals/cases.jsonl के diffs की समीक्षा उतनी ही सावधानी से करें जितनी agent के diffs की, क्योंकि वह फ़ाइल ही आपकी सही उत्तर की लिखित परिभाषा है।

एक suite जो कभी फेल नहीं होता। एक महीने तक 100% पर स्थिर pass rate का मतलब है कि set ने product को ट्रैक करना बंद कर दिया है। हाल के दस traces निकालें, उन मामलों को खोजें जिन्हें agent ने खराब तरीके से संभाला, और उन्हें जोड़ें।

FAQ

AI agent eval set के लिए कितने cases की आवश्यकता होती है?

40 से 80 cases से शुरुआत करें और वास्तविक विफलताओं (real failures) के आधार पर इस सेट को बढ़ाएं। 20 से कम cases होने पर, एक भी अस्थिर (flaky) परिणाम pass rate को 5 अंक तक बदल सकता है, जिससे डेटा का महत्व खत्म हो जाता है। कुछ सौ cases के बाद, हर रन में वास्तविक समय और पैसा खर्च होता है, जबकि अतिरिक्त cases से कवरेज में बहुत कम सुधार होता है। मायने यह नहीं रखता कि संख्या कितनी है: मायने यह रखता है कि आपके ज्ञात production failure types में से कितने कम से कम एक बार इस सेट में शामिल हैं।

क्या मैं अपने agent को ग्रेड करने के लिए LLM judge पर भरोसा कर सकता हूँ?

केवल तब, जब आपने इसे अपने स्वयं के labels के आधार पर मापा हो। अपने द्वारा हाथ से ग्रेड किए गए 30 cases को सुरक्षित रखें, और जब भी आप judge model या judge prompt बदलें, तो उनके विरुद्ध judge को स्कोर करें। Judges में 'length bias' होता है, जहाँ लंबे उत्तरों को अक्सर पास कर दिया जाता है, और 'self-preference' भी होता है, जहाँ वे अपने ही model family के आउटपुट को बेहतर ग्रेड देते हैं। दोनों ही परीक्षण योग्य हैं: एक विफल उत्तर में अतिरिक्त शब्द जोड़कर उसे फिर से जज करें, या किसी अन्य family के judge से उन्हीं उत्तरों को ग्रेड करवाएं। यदि judge हर दस में से एक से अधिक cases पर आपके labels से असहमत है, तो rubric बहुत अस्पष्ट है।

Evals को ग्रेड करने के लिए किस model का उपयोग करना चाहिए?

सस्ते से शुरुआत करें और आवश्यकतानुसार आगे बढ़ें। Deterministic assertions की कोई लागत नहीं होती, इसलिए उन्हें हर case पर सबसे पहले चलाएं। एक छोटा model स्पष्ट रूप से पास होने वाले cases को संभाल लेता है। केवल विफल (fails) और कम-विश्वास (low-confidence) वाले verdicts को ही frontier model के पास भेजें। अगस्त 2026 की सूची कीमतों के अनुसार, 1,000 cases को जज करने की लागत Claude Haiku 4.5 के साथ लगभग 1.80 US dollars और Claude Opus 5 के साथ लगभग 9.00 होती है, और चूंकि eval runs asynchronous होते हैं, इसलिए Batch API इन दोनों लागतों को आधा कर देता है।

क्या evals production monitoring की जगह ले सकते हैं?

नहीं, क्योंकि वे अलग-अलग सवालों के जवाब देते हैं। एक eval suite आपको यह बताता है कि जो बदलाव आप ship करने वाले हैं, वह cases के एक निश्चित सेट को बेहतर बनाता है या बदतर। Tracing और monitoring आपको यह बताते हैं कि वास्तविक users अभी किन समस्याओं का सामना कर रहे हैं, जिसमें वे inputs भी शामिल हैं जो किसी case में कवर नहीं होते। वे एक-दूसरे के पूरक हैं: traces नए cases प्रदान करते हैं, और eval suite यह तय करता है कि आपका सुधार वास्तव में काम कर रहा है या नहीं।