SSD Nodes Learn Hosting plans →
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-23

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 में रखते हैं: saved cases की एक file, एक script जो उन पर agent को run करती है, checks का एक set जो प्रत्येक उत्तर को grade करता है, और results की एक table जिसे आप query कर सकते हैं। उस सूची में किसी भी चीज़ के लिए vendor की आवश्यकता नहीं है। पूरा loop कुछ सौ lines का Python code और एक SQLite file है।

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

इस loop में चार चरण होते हैं, और यह guide प्रत्येक चरण के लिए एक section है: वास्तविक traces collect करना, दिलचस्प traces को cases में बदलना, हर बदलाव पर हर case को grade करना, और pass rate को उसे उत्पन्न करने वाले commit के साथ store करना। यही loop तब भी काम करता है जब आप agent को किसी भी चीज़ पर run करें, और चलाने योग्य 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 तैयार करें

मूल्यांकन के मामलों (eval cases) को खुद न बनाएँ। उन्हें सीधे traffic से लें। यदि आप पहले से ही अपने agent के लिए self-hosted Langfuse tracing का उपयोग कर रहे हैं, तो प्रत्येक request अपने input, tool calls और output के साथ संग्रहीत होती है। यही वह कच्चा माल है जिसकी एक 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 में प्रति पंक्ति एक 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."}

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

  • शुरुआत करने के लिए 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 के साथ ग्रेडिंग करें, क्योंकि ये मुफ्त हैं

जिसका भी सही उत्तर निश्चित है, उसके लिए एक साधारण assertion का उपयोग करें। इसमें किसी model call, लागत या अस्पष्टता की आवश्यकता नहीं होती। Deterministic checks संरचनात्मक regressions को पकड़ लेते हैं, और यही वे त्रुटियाँ हैं जो आपके agent के आसपास की प्रणालियों को बाधित करती हैं: जैसे JSON का पार्स न होना, tool का कभी कॉल न किया जाना, वर्जित वाक्यांश का वापस आना, या उत्तर में किसी स्रोत का उल्लेख न होना।

केवल एक 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 में समस्या हल करता है और कल 11 calls लेता है, वह regression का शिकार है, भले ही अंतिम उत्तर सही हो, क्योंकि आप उसके द्वारा की गई प्रत्येक call के लिए भुगतान करते हैं।

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

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

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

  • Binary verdict दें, कभी भी 1 से 10 का score न दें। एक scale लगभग हर चीज़ के लिए 7 और 8 ही देती है, इसलिए संख्या कभी बदलती नहीं है और आप उससे कुछ नहीं सीख पाते।
  • प्रति call एक ही criterion रखें। refund की राशि के बारे में पूछें, या tone के बारे में, दोनों एक साथ नहीं।
  • जब भी case का कोई अपेक्षित उत्तर हो, तो 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 है जिसे आप आज दोपहर चला सकते हैं, और उन्हें चलाना महत्वपूर्ण है, क्योंकि एक unchecked judge ऐसी संख्याएँ देता है जो सटीक दिखती हैं लेकिन उनका कोई अर्थ नहीं होता।

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

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

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

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

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

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

हर commit पर सबसे महंगे मॉडल से हर केस को जज करना, eval के खर्च को उस एजेंट से भी बड़ा बना देता है जिसे वह टेस्ट कर रहा है। ग्रेडर्स को उनकी कीमत के अनुसार क्रमबद्ध करें और जैसे ही उत्तर स्पष्ट हो जाए, प्रक्रिया रोक दें।

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"
  }
]

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

eval कार्य पर दो छूट स्पष्ट रूप से लागू होती हैं, और वे एक साथ जुड़ती हैं। Eval रन इंटरैक्टिव नहीं होते हैं, इसलिए Batch API एसिंक्रोनस डिलीवरी के बदले इनपुट और आउटपुट दोनों कीमतों को आधा कर देता है, जो चार्ट की पहली पंक्ति है। रूब्रिक और निर्देश हर कॉल में बाइट-दर-बाइट समान होते हैं, इसलिए prompt caching काम आता है: एक कैश रीड की लागत बेस इनपुट कीमत का दसवां हिस्सा होती है, और पांच मिनट का कैश राइट बेस इनपुट का 1.25 गुना होता है, इसलिए एक ही हिट के बाद कैश अपनी लागत वसूल कर लेता है। ये अगस्त 2026 तक Anthropic की लिस्ट कीमतें हैं, और Sonnet 5 पर 31 अगस्त 2026 तक शुरुआती कीमतें लागू हैं, इसलिए उस तारीख के बाद तीसरा बार (bar) ऊपर चढ़ जाएगा।

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

  • हर केस पर Deterministic चेक। इसमें कोई API लागत नहीं आती।
  • उन केस पर एक छोटा मॉडल जज, जो उन चेक से पास हो गए हैं।
  • एक frontier जज केवल वहां, जहाँ छोटा जज 'fail' कहे, या कम आत्मविश्वास के साथ 'pass' कहे।
  • सप्ताह में एक बार, एक छोटे सैंपल पर मानवीय समीक्षा।
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"]

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

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

यदि आप पास रेट को किसी commit के साथ नहीं जोड़ सकते, तो वह केवल एक अनुमान है। प्रत्येक रन के लिए हर केस की एक पंक्ति स्टोर करें, जिसमें 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 लोड करें, फिर 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 को उन बदलावों पर चलाएं जो किसी agent को तोड़ सकते हैं, जिसका अर्थ है prompt में बदलाव, model में बदलाव और tool में बदलाव, न कि रिपॉजिटरी के हर commit पर। एक pre-push हुक इस तेज़ सबसेट को कवर करता है:

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

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

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

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) जज की ओर से। मॉडल ने गद्य में उत्तर दिया, या अपने JSON को code fence में लपेट दिया। एक बार पुनः प्रयास करें, फिर मामले को error के रूप में दर्ज करें। parse failure को कभी भी pass न मानें, क्योंकि जो suite त्रुटियों को pass में बदल देता है, वह 100% की ओर बढ़ता है जबकि agent का प्रदर्शन खराब होता जाता है।

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

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

एक suite जो कभी fail नहीं होता। एक महीने तक 100% पर स्थिर pass rate का मतलब है कि set ने product को ट्रैक करना बंद कर दिया है। हाल के दस traces निकालें, उन मामलों को खोजें जिन्हें agent ने खराब तरीके से संभाला, और उन्हें जोड़ें। फिर जानबूझकर कुछ खराब करें और पुष्टि करें कि रन red हो जाता है, जो कि वह जांच है जिसे mutation testing test suite पर लागू होती है और यही एकमात्र तरीका है यह जानने का कि आपके set में अभी भी दम है।

FAQ

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

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

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

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

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

सस्ते से शुरुआत करें और आवश्यकतानुसार upgrade करें। Deterministic assertions की कोई लागत नहीं होती, इसलिए उन्हें हर case पर सबसे पहले चलाएं। एक छोटा model स्पष्ट रूप से pass होने वाले cases को संभाल लेता है। केवल विफल (fails) और कम-विश्वास (low-confidence) वाले verdicts को ही frontier model के पास भेजें। अगस्त 2026 की सूची कीमतों के अनुसार, 1,000 cases को judge करने की लागत 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 यह तय करता है कि आपका fix वास्तव में काम कर रहा है या नहीं।