SSD Nodes Learn Hosting plans →
मार्गदर्शक Matt Connorद्वारे Matt Connor · अपडेटेड 2026-08-30

AI agents साठी self-hosted evals कसे तयार करावे

vendor शिवाय 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, त्यावर agent चालवणारी script, प्रत्येक उत्तराचे मूल्यमापन करणाऱ्या checks चा संच आणि तुम्ही query करू शकता अशी results table. या यादीतील कोणत्याही गोष्टीसाठी vendor आवश्यक नाही. संपूर्ण प्रक्रिया काहीशे lines च्या Python code आणि एका 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 मध्ये रूपांतर करणे, प्रत्येक बदलावर प्रत्येक case चे grading करणे आणि pass rate निर्माण करणाऱ्या commit च्या शेजारी तो साठवणे. तुम्ही agent कोणत्याही कामासाठी चालवत असलात तरी हीच loop कार्य करते. चालवण्यायोग्य self-hosted agent frameworks यांच्यात मुख्य फरक इतकाच असतो की ते trace मधील किती माहिती तुम्हाला आपोआप देतात.

एजंट दुसऱ्या आठवड्यात का बिघडतो

एजंट म्हणजे prompt, model, tool definitions आणि रनटाइमला मिळवला जाणारा context यांचे संयोजन. तुमच्या application code मध्ये बदल न करता या चारही गोष्टी बदलू शकतात. त्यामुळे नेहमीच्या code review मध्ये आक्षेप घेण्यासारखे काही दिसत नाही.

सर्वात सामान्य कारण म्हणजे prompt मध्ये केलेला बदल. उद्धट उत्तर थांबवण्यासाठी तुम्ही एक वाक्य जोडता. त्या वाक्यामुळे पुन्हा चाचणी न केलेल्या input वरचे वर्तन बदलते. Traces मध्ये हे स्पष्ट दिसते: मागील आठवड्यात त्याच प्रश्नासाठी असलेल्या trace मध्ये create_refund tool call आहे, तर या आठवड्यातील trace मध्ये तो नाही आणि त्याऐवजी उत्तरात नम्र माफी मागितली जाते. कोणतीही error निर्माण झाली नाही, त्यामुळे alert देखील सुरू झाला नाही.

दुसरे कारण म्हणजे model. प्रत्येक run सोबत पाठवलेला अचूक model string नोंदवा, claude-haiku-4-5-20251001; तुमच्या लक्षात असलेल्या shorthand वर अवलंबून राहू नका. कारण model बदललेल्या दिवशी pass rate कमी झाला, हे model प्रत्येक row मध्ये नोंदवलेले असेल तेव्हाच निदान करता येते.

तिसरे कारण म्हणजे tools. Tool description चे शब्द बदलल्याने model tool कधी call करायचे हे बदलते. तुमचे tools VPS वर चालणाऱ्या MCP servers मार्फत येत असतील, तर schema दुसऱ्या process मध्ये असते. त्यामुळे तुमच्या repository मध्ये कोणताही diff नसतानाही ते बदलू शकते. चौथे कारण म्हणजे retrieval: तोच प्रश्न रात्री पुन्हा तयार केलेल्या index वर जातो आणि उत्तर नवीन document नुसार बदलते.

तुम्ही आधीच संकलित करत असलेल्या traces मधून golden set तयार करा

eval cases स्वतः तयार करू नका. ती traffic मधून घ्या. तुम्ही तुमच्या agent साठी self-hosted Langfuse tracing आधीपासून चालवत असाल, तर प्रत्येक request त्याच्या input, tool calls आणि output सह साठवली जाते. केससाठी आवश्यक असलेला कच्चा data यामधूनच मिळतो.

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 चे instrumentation कसे करतो यावर अवलंबून असतात. त्यामुळे अपेक्षित field names ऐवजी प्रत्यक्ष दिसणाऱ्या field names चे mapping करा. त्यानंतर प्रत्येक ओळीला एक JSON object अशा स्वरूपात, evals/cases.jsonl मध्ये 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 चा बदल घडवतो आणि कारण नसताना बदलणाऱ्या या संख्येकडे दुर्लक्ष केले जाते.
  • तुम्ही दुरुस्त केलेला प्रत्येक production bug त्याच दिवशी एक case बनवा. या सवयीमुळे set योग्य दिशेने वाढतो.
  • प्रत्येक case मध्ये एकच behaviour तपासा. refund amount आणि tone एकत्र तपासणारा case fail झाल्यास नेमके काय चुकले हे समजत नाही.
  • id कधीही बदलू नका, कारण id मुळे आजच्या run ची तुलना मागील महिन्याच्या run शी करता येते.
  • Commit करण्यापूर्वी redact करा. ही file git मध्ये जाणार आहे, त्यामुळे customer names आणि तुमच्या मालकीचे नसलेले order numbers काढून टाका.

प्रथम deterministic checks वापरून grading करा, कारण त्यासाठी कोणताही खर्च येत नाही

ज्या गोष्टींचे उत्तर निश्चित असते, त्यांच्यासाठी साधे assertion वापरा. Model call लागत नाही, खर्च होत नाही आणि संदिग्धता राहत नाही. Deterministic checks मुळे structural regressions आढळतात. याच regressions मुळे तुमच्या agent भोवतालच्या system मध्ये समस्या निर्माण होतात: 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

त्या list मध्ये tool budget ठेवा. एखादा agent आज एखादे प्रकरण 3 calls मध्ये सोडवतो आणि उद्या 11 calls घेतो, तर अंतिम उत्तर योग्य असले तरी ही regression आहे, कारण तो केलेल्या प्रत्येक call साठी तुम्हाला खर्च करावा लागतो.

LLM as judge, आणि ते चुकण्याचे चार मार्ग

Assertions मधून जे उत्तर टिकते, त्यासाठी वाचून तपासणारा grader आवश्यक असतो. LLM judge म्हणजे दुसऱ्या मॉडेलला केलेला call असतो. त्याला प्रश्न, agent चे उत्तर आणि एक criterion दिले जाते. त्यानंतर तो verdict परत करतो. “उत्तराने वापरकर्त्याने विचारलेल्या प्रश्नाचे उत्तर दिले आहे का” हे तपासण्याचा हा एकमेव व्यावहारिक मार्ग आहे.

Judge वापरण्यायोग्य बनवण्यासाठी चार नियम पाळा:

  • Binary verdict द्या; 1 ते 10 score कधीही देऊ नका. अशा scale वर जवळजवळ प्रत्येक गोष्टीसाठी 7 किंवा 8 मिळते. त्यामुळे संख्या बदलत नाही आणि त्यातून काहीही शिकता येत नाही.
  • प्रत्येक call मध्ये एकच criterion ठेवा. Refund amount बद्दल किंवा tone बद्दल विचारा; दोन्ही एकाच वेळी विचारू नका.
  • एखाद्या case साठी expected answer उपलब्ध असल्यास ते judge ला द्या. Reference शी तुलना करून grading करणे, कोणत्याही संदर्भाशिवाय grading करण्यापेक्षा खूप सोपे असते.
  • Output shape निश्चित करा आणि त्याचे strict parsing करा.
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 चालवणे महत्त्वाचे आहे, कारण तपासणी न केलेला judge अचूक दिसणारे पण अर्थहीन numbers तयार करतो.

Length bias. मोठी उत्तरे अधिक वेळा pass होतात. याची test करा: judge ने fail केलेली दहा उत्तरे घ्या. प्रत्येक उत्तरात नवीन तथ्य न जोडणारे, आत्मविश्वासपूर्ण filler असलेले दोन परिच्छेद जोडा. त्यानंतर त्यांचे पुन्हा grading करा. यापैकी कोणत्याही verdict चे रूपांतर pass मध्ये झाले, तर तो length bias आहे आणि दुरुस्त करण्याची गरज rubric मध्ये आहे.

Self-preference. Judge अनेकदा स्वतःच्या model family मधील output ला इतर model family मधील output पेक्षा अधिक अनुकूलपणे grade करतो. याची test करा: त्याच 30 उत्तरांचे grading दोन वेगवेगळ्या family मधील judges कडून करा आणि प्रत्येक case साठी verdicts ची तुलना करा. जिथे त्यांचे verdicts वेगळे असतील, तिथे case स्वतः वाचा.

Position bias. दोन उत्तरांची, A आणि B ची, तुलना करण्यासाठी judge वापरत असल्यास त्यांचा क्रम बदला आणि पुन्हा run करा. क्रम बदलल्यावर verdict बदलला, तर त्या rubric साठी pairwise comparison अजून सुरक्षित नाही.

Rubric drift. अस्पष्ट criteria मुळे judges सर्व गोष्टींना मान्यता देतात. “उत्तर helpful आहे का” हे जवळजवळ कोणतेही उत्तर pass करते. “उत्तराने refund amount dollars मध्ये सांगितला आहे का” हे तुम्हाला अपेक्षित असलेले उत्तरच pass करते. तपासला जाणारा fact स्पष्टपणे नमूद होईपर्यंत प्रत्येक criterion पुन्हा लिहा.

या चारही समस्यांसाठी एकच guard वापरा. स्वतः हाताने label केलेले 30 cases जतन करा. Judge model किंवा judge prompt बदलताना प्रत्येक वेळी judge च्या निकालांची तुमच्या labels शी तुलना करा. दहा पैकी एकापेक्षा अधिक case मध्ये तो तुमच्याशी असहमत असेल, तर त्याने तयार केलेल्या कोणत्याही pass rate वर विश्वास ठेवण्यापूर्वी rubric दुरुस्त करा. Judge हा code आहे. त्यामुळे code प्रमाणे त्याचे versioning आणि review करा.

स्वस्त मॉडेल वापरा आणि गरज पडल्यास frontier मॉडेलकडे जा

प्रत्येक commit वेळी प्रत्येक प्रकरणाचे परीक्षण सर्वात महागड्या मॉडेलने करणे म्हणजे ज्या agent ची चाचणी घेत आहात त्याच्या खर्चापेक्षा eval चा खर्च वाढणे. Grader ची किंमत लक्षात घेऊन त्यांचा क्रम लावा आणि उत्तर स्पष्ट होताच प्रक्रिया थांबवा.

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 US dollars आणि Claude Opus 5 वर 9.00 खर्च येतो. सुरुवातीला हा फरक किरकोळ वाटतो. परंतु मोठ्या प्रमाणावर तो लक्षणीय होतो. 60 प्रकरणांच्या संचाचे प्रत्येक commit वेळी परीक्षण केले आणि आठवड्यात 40 commits केले, तर nightly job चालवण्यापूर्वीच आठवड्याला 2,400 judge calls होतात.

Eval कामासाठी दोन सवलती थेट लागू करता येतात आणि त्या एकत्र वापरता येतात. Eval runs परस्परसंवादी नसल्यामुळे Batch API asynchronous delivery च्या बदल्यात input आणि output या दोन्हींच्या किमती निम्म्या करते. ही chart मधील पहिली row आहे. प्रत्येक call मध्ये rubric आणि instructions byte-for-byte समान असल्यामुळे prompt caching योग्य ठरते. Cache read साठी मूळ input price च्या एक-दशांश खर्च येतो. पाच मिनिटांच्या cache write साठी मूळ input price च्या 1.25 पट खर्च येतो. त्यामुळे एकदा cache hit झाल्यानंतर cache चा खर्च भरून निघतो. या Anthropic list prices August 2026 मधील आहेत. Sonnet 5 साठी introductory pricing 31 August 2026 पर्यंत आहे. त्यामुळे त्या तारखेनंतर तिसरा bar वाढतो.

क्रमानुसार ladder:

  • प्रत्येक प्रकरणावर deterministic checks. API चा कोणताही खर्च नाही.
  • वरील checks पार केलेल्या प्रकरणांवर small model judge.
  • Small judge ने fail सांगितलेल्या किंवा कमी confidence सह pass सांगितलेल्या प्रकरणांवरच frontier judge.
  • आठवड्यातून एकदा, लहान 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 गृहीत न धरता त्याचे मोजमाप करा. महिन्यातून एकदा संपूर्ण संचाचे strict judge नेही परीक्षण करा आणि दोन्ही columns ची तुलना करा. काही मोजक्या प्रकरणांपेक्षा जास्त प्रकरणांमध्ये फरक आढळल्यास small model साठी तुमचे rubric पुरेसे स्पष्ट नाही. अशा वेळी rubric मध्ये सुधारणा करा. Agent स्वतः किती खर्च करतो हे नियंत्रित करणे वेगळे काम आहे. त्यासाठी VPS वरील AI agent साठी खर्च नियंत्रण पहा.

तुमच्या मालकीच्या प्रणालीतील pass rate कालांतराने नोंदवा

एखाद्या commit शी जोडता न येणारा pass rate हा केवळ अंदाज असतो. प्रत्येक 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 लोड करा. त्यानंतर sqlite3 -box evals/results.db < evals/passrate.sql ने trend वाचा. 60 cases वर दररोज एक वर्ष run केल्यास सुमारे 22,000 rows तयार होतील. त्यामुळे store स्वतःच एक स्वतंत्र project बनत नाही. फाइल वेगवेगळ्या machines मध्ये share केली जाऊ लागल्यास महत्त्वाच्या ठरणाऱ्या settings साठी VPS वर SQLite production मध्ये चालवणे पहा.

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

एखाद्या agent मध्ये बिघाड घडवू शकणाऱ्या बदलांवर suite चालवा. यामध्ये prompt edits, model changes आणि tool changes येतात; repository मधील प्रत्येक commit वर suite चालवण्याची गरज नाही. जलद subset साठी pre-push hook पुरेसा आहे:

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

पूर्ण runs अधिक धीमे असतात. ते schedule वर चालवणे योग्य आहे. रात्री चालणारी VPS वरील systemd service आणि timer deployed prompt विरुद्ध संपूर्ण set चालवते. त्यामुळे repository च्या बाहेरून येणारे बदलही आढळतात, उदाहरणार्थ hosted tool चे behaviour बदलणे.

मानवी पुनरावलोकन, संपूर्ण तपासणीऐवजी नमुना-आधारित

Judge चे calibration मानवी labels विरुद्ध केले जाते, त्यामुळे हे labels तयार करणारी व्यक्ती आवश्यक आहे. दर आठवड्याला एक sample वाचा: Judge ज्या प्रत्येक case मध्ये अयशस्वी ठरला तो, तसेच random पद्धतीने निवडलेले दहा pass cases. Random pass cases हा महत्त्वाचा अर्धा भाग आहे. कारण Judge ने शांतपणे चुकीची उत्तरे pass करायला सुरुवात केली असेल, तर स्वतःच्या verdicts वर आधारित कोणत्याही dashboard मध्ये तो उत्तम दिसेल.

प्रत्येकी तीन मिनिटे अशा पंधरा cases साठी आठवड्याला 45 मिनिटे लागतात. त्यातून तुम्ही आणि Judge यांच्यात मतभेद असलेल्या rubric मधील दुरुस्त्या मिळतात. तसेच, ज्यांचा कोणी विचार केला नव्हता अशा failure types साठी नवीन cases मिळतात. मानवी verdict त्याच table मध्ये लिहा आणि graded_by ला human असे set करा. त्यामुळे Judge आणि मानव यांच्यातील agreement हा स्मरणशक्तीवर अवलंबून न राहता query द्वारे तपासता येतो.

eval harness मध्ये काय बिघडते

anthropic.RateLimitError पहिल्या पूर्ण run मध्ये. एकाच वेळी 60 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 म्हणून करा. Parse failure ला कधीही pass म्हणून मोजू नका. Errors चे passes मध्ये रूपांतर करणारा suite agent खराब होत असतानाही 100% कडे जातो.

Flaky cases. Agent त्याचे output sample करत असल्यामुळे एकाच input ला एका run मध्ये pass मिळतो आणि पुढच्या run मध्ये fail होतो. Flaky case तीन वेळा run करा आणि case delete करण्याऐवजी त्याचे fraction नोंदवा. तीनपैकी दोन runs मध्ये pass होणारा case ही वास्तविक robustness bug आहे आणि ग्राहक ती शोधेल.

Golden set rot. Suite green करण्यासाठी कोणी expected answer संपादित करतो. evals/cases.jsonl मधील diffs चे agent मधील diffs इतक्याच काळजीपूर्वक review करा, कारण ती file म्हणजे correct ची तुमची लिखित व्याख्या आहे.

कधीही fail न होणारा suite. एका महिन्यासाठी 100% वर स्थिर असलेला pass rate म्हणजे set ने product चा मागोवा घेणे थांबवले आहे. अलीकडील दहा traces घ्या, agent ने चुकीच्या पद्धतीने हाताळलेले traces शोधा आणि ते add करा. त्यानंतर जाणीवपूर्वक काहीतरी मोडा आणि run red होत असल्याची खात्री करा. यालाच test suite ला mutation testing लागू होते याची तपासणी म्हणतात आणि तुमच्या set मध्ये अजूनही दोष उघड करण्याची क्षमता आहे हे जाणून घेण्याचा हा एकमेव मार्ग आहे.

FAQ

AI agent eval set मध्ये किती cases आवश्यक असतात?

40 ते 80 cases पासून सुरुवात करा आणि प्रत्यक्ष failures मधून set वाढवत जा. सुमारे 20 पेक्षा कमी cases असतील, तर एका flaky result मुळे pass rate मध्ये 5 points चा फरक पडतो आणि ही संख्या उपयुक्त माहिती देत नाही. काहीशे cases पेक्षा जास्त झाल्यावर प्रत्येक run साठी खरा खर्च आणि वेळ लागतो, पण प्रत्येक नवीन case मुळे मिळणारे coverage फारच कमी असते. महत्त्वाची मोजणी cases ची संख्या नाही. तुमच्या माहितीत असलेल्या production failure types पैकी किमान एकदा set मध्ये दिसणाऱ्या types चे प्रमाण महत्त्वाचे आहे.

माझ्या agent चे grading करण्यासाठी LLM judge वर विश्वास ठेवता येईल का?

तुमच्या स्वतःच्या labels विरुद्ध त्याचे मोजमाप केल्यानंतरच. तुम्ही स्वतः तपासलेले 30 cases जतन करा. judge model किंवा judge prompt बदलल्यावर प्रत्येक वेळी judge ची या cases विरुद्ध score करा. Judges मध्ये length bias दिसतो. म्हणजे अनावश्यकपणे लांब केलेली उत्तरे अधिक वेळा pass होतात. self-preference देखील दिसते. म्हणजे त्यांच्या स्वतःच्या model family मधील output ला अधिक अनुकूल grading मिळते. दोन्ही बाबी तपासता येतात: failed answer मध्ये अनावश्यक मजकूर वाढवून पुन्हा त्याचे grading करा, किंवा त्याच answers चे grading दुसऱ्या family मधील judge कडून करून घ्या. दहा cases पैकी एकापेक्षा जास्त cases वर judge तुमच्या labels शी असहमत असेल, तर rubric वापरण्यासाठी खूप अस्पष्ट आहे.

Evals चे grading कोणत्या model ने करावे?

स्वस्त model वापरा आणि आवश्यकतेनुसार पुढील model कडे पाठवा. Deterministic assertions साठी खर्च नसतो, त्यामुळे त्या प्रत्येक case वर प्रथम चालवा. स्पष्ट pass निकालांसाठी small model पुरेसे असते. फक्त 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 वापरल्यास दोन्हीपैकी कोणताही खर्च निम्मा होतो.

Evals मुळे production monitoring ची गरज संपते का?

नाही, कारण ते वेगवेगळ्या प्रश्नांची उत्तरे देतात. Eval suite मुळे तुम्ही deploy करणार असलेला बदल निश्चित cases च्या set वर परिणाम सुधारतो की खराब करतो, हे समजते. Tracing आणि monitoring मुळे सध्या प्रत्यक्ष users कोणत्या समस्यांना सामोरे जात आहेत, हे समजते. यात कोणत्याही case मध्ये समाविष्ट नसलेले inputs देखील येतात. हे दोन्ही एकमेकांना पूरक असतात: traces मधून नवीन cases मिळतात आणि eval suite तुमचा fix प्रत्यक्षात काम झाला का, हे ठरवते.