SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-26

AI agent-এর জন্য self-hosted eval কীভাবে তৈরি করবেন

নিজের repository-তে real trace থেকে golden case বানান, আগে deterministic checks চালান, পরে LLM judge ব্যবহার করুন, এবং প্রতি commit-এ pass rate track করুন।

AI agent-এর জন্য self-hosted eval কী

AI agent-এর জন্য self-hosted eval বলতে আপনার নিজের repository-তে রাখা চারটি জিনিস বোঝায়: সংরক্ষিত case-এর একটি file, সেগুলোর ওপর agent চালানোর একটি script, প্রতিটি উত্তরের মান যাচাই করার checks-এর একটি set, এবং query করা যায় এমন ফলাফলের একটি table। এই তালিকার কোনো কিছুর জন্য vendor দরকার হয় না। পুরো loop কয়েকশো line-এর Python code এবং একটি SQLite file দিয়েই তৈরি করা যায়।

Demo-তে agent কাজ করেছিল, কারণ পাঁচটি input আপনি নিজেই বেছে নিয়েছিলেন। দ্বিতীয় সপ্তাহে এটি ব্যর্থ হয়েছিল, কারণ prompt-এর একটি line, model অথবা tool description পরিবর্তিত হয়েছিল এবং এর কোনো কিছুই কোনো measurement-এ ধরা পড়েনি। Eval loop “এখন খারাপ মনে হচ্ছে” কথাটিকে “commit 4f1c9ab-এ 60টির মধ্যে pass rate 58 থেকে 51-এ নেমেছে” এই নির্দিষ্ট ফলাফলে রূপান্তর করে।

এই loop-এর চারটি ধাপ আছে, এবং এই guide-এ প্রতিটি ধাপের জন্য একটি করে section রয়েছে: বাস্তব trace সংগ্রহ করা, গুরুত্বপূর্ণ trace-গুলোকে case হিসেবে অন্তর্ভুক্ত করা, প্রতিটি পরিবর্তনে প্রতিটি case-এর grade নির্ধারণ করা, এবং যে commit ফলাফল তৈরি করেছে তার পাশে pass rate সংরক্ষণ করা। আপনি agent-কে যে কাজেই চালান না কেন, একই loop কাজ করে। চালানোর উপযোগী self-hosted agent framework-গুলোর মধ্যে মূল পার্থক্য হলো তারা trace-এর কতটা অংশ আপনাকে স্বয়ংক্রিয়ভাবে দেয়।

দ্বিতীয় সপ্তাহে agent কেন কাজ করা বন্ধ করে

একটি agent হলো একটি prompt, একটি model, কিছু tool definition এবং run time-এ retrieved হওয়া context। আপনার application code পরিবর্তন না করেও এই চারটি উপাদানই পরিবর্তিত হতে পারে। তাই সাধারণ code review-এ আপত্তির মতো কিছু দেখা যায় না।

সবচেয়ে সাধারণ কারণ হলো prompt edit। অভদ্র উত্তর বন্ধ করতে আপনি একটি বাক্য যোগ করেন। এই বাক্য এমন input-এর আচরণও পরিবর্তন করে, যেগুলো আপনি পুনরায় পরীক্ষা করেননি। trace-এ বিষয়টি স্পষ্ট দেখা যায়: একই প্রশ্নের জন্য গত সপ্তাহের trace-এ একটি create_refund tool call ছিল, কিন্তু এই সপ্তাহের trace-এ তা নেই এবং তার বদলে উত্তরটি ভদ্রভাবে ক্ষমা চায়। কোনো error তৈরি হয়নি, তাই কোনো alert-ও চালু হয়নি।

দ্বিতীয় কারণ হলো model। প্রতিটি run-এর সঙ্গে পাঠানো exact model string রেকর্ড করুন, claude-haiku-4-5-20251001 মাথায় রাখা shorthand নয়। কারণ model পরিবর্তনের দিন pass rate কমে গেলে, model-এর নাম row-তে থাকলেই কেবল সমস্যাটি নির্ণয় করা যায়।

তৃতীয় কারণ হলো tool। কোনো tool description-এর ভাষা পরিবর্তন করলে model কখন সেটি call করবে, তা বদলে যেতে পারে। আপনার tool যদি VPS-এ চলা MCP server থেকে আসে, তাহলে schema অন্য একটি process-এ থাকে। ফলে repository-তে কোনো diff না থাকলেও সেটি আপনার অজান্তে পরিবর্তিত হতে পারে। চতুর্থ কারণ হলো retrieval: একই প্রশ্ন এমন একটি index-এ যায়, যেটি রাতারাতি পুনর্নির্মাণ করা হয়েছে, এবং উত্তরটি নতুন document অনুসরণ করে।

আপনি যে trace ইতিমধ্যে সংগ্রহ করছেন, সেখান থেকে golden set তৈরি করুন

Eval case নিজে থেকে তৈরি করবেন না। এগুলো traffic থেকেই নিন। আপনি যদি ইতিমধ্যে আপনার agent-এর জন্য self-hosted Langfuse tracing চালান, তাহলে প্রতিটি request-এর input, tool call এবং output সংরক্ষিত থাকে। একটি case তৈরির জন্য এটিই প্রয়োজনীয় raw material।

Public API ব্যবহার করে root observation-এর একটি সময়সীমা export করুন। এতে basic authentication ব্যবহৃত হয়। Username হিসেবে public key এবং password হিসেবে secret key দিন।

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 পড়ুন। Row-গুলো data-এর অধীনে আসে। তবে question এবং reply ধারণকারী field-এর নাম agent কীভাবে তার span instrument করেছে তার ওপর নির্ভর করে। তাই প্রত্যাশিত নাম ব্যবহার না করে বাস্তবে যা দেখছেন, তা map করুন। এরপর প্রতিটি case হাতে লিখে evals/cases.jsonl-এ প্রতি লাইনে একটি করে 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."}

এই set-টি নিয়মিত চালানোর উপযোগী রাখতে পাঁচটি নিয়ম অনুসরণ করুন:

  • শুরু করার জন্য 40 থেকে 80টি case যথেষ্ট। 20টির কম হলে একটি flaky case pass rate 5 point পরিবর্তন করে, ফলে কারণ ছাড়াই ওঠানামা করা সংখ্যাকে কেউ গুরুত্ব দেয় না।
  • যে production bug ঠিক করবেন, সেটি ঠিক করার দিনই একটি case হিসেবে যোগ করুন। এই অভ্যাস set-টিকে সঠিক দিকে বাড়তে সাহায্য করে।
  • প্রতি case-এ একটি behavior যাচাই করুন। Refund amount এবং tone একসঙ্গে যাচাই করা case ব্যর্থ হলে কোন অংশে সমস্যা হয়েছে তা বোঝা যায় না।
  • id কখনো পরিবর্তন করবেন না। কারণ আজকের run-এর সঙ্গে গত মাসের run তুলনা করার জন্য id প্রয়োজন।
  • Commit করার আগে sensitive data redact করুন। এই file git-এ যাবে। তাই customer name এবং আপনার মালিকানাধীন নয় এমন order number মুছে ফেলুন।

প্রথমে deterministic check দিয়ে grade করুন, কারণ এগুলোর কোনো খরচ নেই

যে বিষয়ের সঠিক উত্তর নির্ধারণ করা যায়, সেখানে plain assertion ব্যবহার করুন। কোনো model call নয়, কোনো খরচ নয়, কোনো অস্পষ্টতা নয়। Deterministic check structural regression শনাক্ত করে। এই regression-গুলোই আপনার agent-এর চারপাশের system ভেঙে দেয়: 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 3টি call-এ একটি case সমাধান করে এবং আগামীকাল 11টি call ব্যবহার করে, তাহলে final answer সঠিক হলেও এটি regression। কারণ agent যতবার call করে, প্রতিবারের জন্য আপনাকে অর্থ দিতে হয়।

LLM judge এবং এটি ভুল হওয়ার চারটি উপায়

Assertions পার হওয়া প্রতিটি উত্তরের জন্য এমন একটি grader দরকার, যা উত্তরটি পড়তে পারে। LLM judge হলো দ্বিতীয় একটি model call। এটি question, agent-এর answer এবং একটি criterion পায়, তারপর একটি verdict ফেরত দেয়। “Reply কি user-এর প্রশ্নের উত্তর দিয়েছে”—এটি যাচাই করার একমাত্র ব্যবহারিক উপায় হলো LLM judge।

একটি judge ব্যবহারযোগ্য করতে চারটি নিয়ম মানুন:

  • Binary verdict দিন, কখনো 1 থেকে 10-এর score নয়। Scale ব্যবহার করলে প্রায় সবকিছুর জন্য 7 বা 8 ফেরত আসে। ফলে number বদলায় না এবং তা থেকে কিছু শেখা যায় না।
  • প্রতি call-এ একটি criterion রাখুন। Refund amount সম্পর্কে অথবা tone সম্পর্কে জিজ্ঞেস করুন, দুটো একসঙ্গে নয়।
  • Case-এ 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 mode-গুলো দেখা যাক। প্রতিটির জন্য আপনি আজই একটি test চালাতে পারেন। এগুলো চালানো গুরুত্বপূর্ণ, কারণ unchecked judge এমন number তৈরি করে, যা নির্ভুল বলে মনে হয় কিন্তু আসলে অর্থহীন।

Length bias। উত্তর যত দীর্ঘ হয়, pass হওয়ার সম্ভাবনা তত বাড়ে। Test করুন: judge যে দশটি answer-কে fail করেছে, সেগুলো নিন। প্রতিটিতে নতুন কোনো fact যোগ না করে আত্মবিশ্বাসী filler হিসেবে দুইটি paragraph যোগ করুন এবং আবার judge করুন। কোনো verdict যদি pass-এ বদলে যায়, সেটিই length bias। তখন rubric-টি সংশোধন করতে হবে।

Self-preference। একটি judge প্রায়ই নিজের model family-এর output অন্য model family-এর output-এর তুলনায় বেশি সদয়ভাবে grade করে। Test করুন: দুইটি ভিন্ন family-এর judge দিয়ে একই 30টি answer grade করুন এবং case অনুযায়ী verdict তুলনা করুন। যেখানে মতভেদ হবে, case-টি নিজে পড়ুন।

Position bias। দুটি answer, A এবং B, তুলনা করতে judge ব্যবহার করলে order বদলে আবার চালান। Order বদলানোর পর verdict বদলে গেলে বুঝবেন, ওই rubric-এর জন্য pairwise comparison এখনো নিরাপদ নয়।

Rubric drift। অস্পষ্ট criterion agreeable judge তৈরি করে। “Answer কি helpful” হলে প্রায় সবকিছু pass হবে। “Answer কি dollar-এ refund amount উল্লেখ করেছে” হলে শুধু আপনার উদ্দেশ্য অনুযায়ী উত্তর pass হবে। প্রতিটি criterion-এ কোন fact যাচাই করা হচ্ছে, তা স্পষ্ট না হওয়া পর্যন্ত criterion-টি পুনর্লিখুন।

একটি guard চারটি সমস্যাই সামলায়। হাতে label করা 30টি case সংরক্ষণ করুন এবং judge model বা judge prompt পরিবর্তন করলেই judge-এর ফল আপনার label-এর সঙ্গে মিলিয়ে score করুন। দশটির মধ্যে একটির বেশি case-এ আপনার সঙ্গে মতভেদ হলে, judge-এর pass rate বিশ্বাস করার আগে rubric সংশোধন করুন। Judge হলো code। তাই code-এর মতোই এটিকে version করুন এবং review করুন।

সস্তা মডেল দিয়ে প্রাথমিক মূল্যায়ন করুন, প্রয়োজনে frontier মডেলে পাঠান

প্রতিটি commit-এ প্রতিটি কেসের বিচার সবচেয়ে ব্যয়বহুল মডেল দিয়ে করলে eval-এর বিল যে agent-কে পরীক্ষা করছে, তার খরচকেও ছাড়িয়ে যাবে। 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 token এবং 120 output token ধরা হয়েছে। একটি প্রশ্ন, একটি উত্তর এবং একটি criterion-এর জন্য এটি বাস্তবসম্মত আকার। 1,000টি কেস বিচার করতে Claude Haiku 4.5-এ খরচ হয় 1.80 US dollar এবং Claude Opus 5-এ 9.00। পার্থক্যটি প্রথমে সামান্য মনে হয়, কিন্তু সংখ্যাটি গুণ করলে তা দ্রুত বড় হয়। প্রতি commit-এ 60টি কেস, সপ্তাহে 40টি commit এবং প্রতি commit-এ বিচার করলে nightly job চালানোর আগেই সপ্তাহে 2,400টি judge call হয়।

Eval-এর ক্ষেত্রে দুটি discount সরাসরি প্রয়োগ করা যায় এবং এগুলো একসঙ্গে ব্যবহার করা যায়। Eval run ইন্টার‌্যাক্টিভ নয়। তাই asynchronous delivery-এর বিনিময়ে Batch API input ও output—উভয় দামের অর্ধেক নেয়। চার্টের প্রথম bar-টি এই দামের। প্রতিটি call-এ rubric এবং instruction byte for byte একই থাকে। তাই prompt caching উপযোগী: cache read-এর খরচ base input price-এর এক-দশমাংশ, আর পাঁচ মিনিটের cache write-এর খরচ base input price-এর 1.25 গুণ। ফলে একটি cache hit-এর পরই cache নিজের খরচ পুষিয়ে দেয়। এগুলো August 2026 অনুযায়ী Anthropic-এর list price। Sonnet 5-এর introductory pricing 31 August 2026 পর্যন্ত কার্যকর, তাই ওই তারিখের পরে তৃতীয় bar-টি উঁচু হবে।

ক্রমটি হবে:

  • প্রতিটি কেসে deterministic check চালান। কোনো API cost নেই।
  • ওই check পেরোনো কেসগুলোতে একটি ছোট model judge ব্যবহার করুন।
  • ছোট 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 কিছুটা কমে এবং খরচ কমে। তাই অনুমান না করে এই পরিবর্তনের প্রভাব মাপুন। মাসে একবার strict judge দিয়ে পুরো set-টিও grade করুন এবং দুটি ফলাফলের column তুলনা করুন। কয়েকটির বেশি কেসে মতপার্থক্য হলে বুঝবেন, ছোট model-এর জন্য আপনার rubric যথেষ্ট নির্দিষ্ট নয়। তখন rubric-ই সংশোধন করতে হবে। Agent নিজে কত খরচ করবে তা নিয়ন্ত্রণ করা আলাদা কাজ। এটি VPS-এ একটি AI agent-এর খরচ নিয়ন্ত্রণ অংশে ব্যাখ্যা করা হয়েছে।

নিজের নিয়ন্ত্রণাধীন সিস্টেমে সময়ের সঙ্গে pass rate ট্র্যাক করুন

যে 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টি case-এর ওপর এক বছর প্রতিদিন run চালালে প্রায় 22,000টি row হয়। তাই store নিজেই আলাদা project হয়ে ওঠে না। এই file একাধিক machine-এর মধ্যে share করা হলে যে settings গুরুত্বপূর্ণ হয়ে ওঠে, তা VPS-এ production-এ SQLite চালানো-এ ব্যাখ্যা করা হয়েছে।

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 edit, model change এবং tool change আছে। Repository-এর যেকোনো commit-এ run চালানোর প্রয়োজন নেই। দ্রুত 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

সম্পূর্ণ run ধীর এবং এগুলো schedule অনুযায়ী চালানো উচিত। একটি nightly VPS-এ systemd service এবং timer deployed prompt-এর বিরুদ্ধে পুরো set চালায়। এর মাধ্যমে repository-এর বাইরের উৎস থেকে আসা পরিবর্তন ধরা পড়ে। উদাহরণ হিসেবে, hosted tool-এর behaviour পরিবর্তিত হতে পারে।

মানব পর্যালোচনা, সম্পূর্ণ নয়—নমুনাভিত্তিক

Judge-কে মানবের label-এর সঙ্গে calibrate করা হয়, তাই কাউকে সেই label তৈরি করতে হবে। প্রতি সপ্তাহে একটি নমুনা পড়ুন: Judge যে প্রতিটি case-এ ব্যর্থ হয়েছে, তার সঙ্গে এলোমেলোভাবে বাছাই করা আরও দশটি pass। এলোমেলো pass-গুলোই গুরুত্বপূর্ণ অংশ, কারণ Judge যদি নীরবে খারাপ উত্তর pass করা শুরু করে, তাহলে তার নিজের verdict দিয়ে তৈরি যেকোনো dashboard-এ সেটিকে নিখুঁত দেখাবে।

প্রতি সপ্তাহে 15টি case, প্রতিটি 3 মিনিট করে, মোট 45 মিনিট সময় নেয়। এর বিনিময়ে আপনি rubric-এ এমন সংশোধন পান যেখানে আপনার ও Judge-এর মতভেদ রয়েছে। পাশাপাশি এমন failure type-এর নতুন case-ও পাওয়া যায়, যা আগে কেউ ভাবেনি। একই table-এ মানবের verdict লিখুন এবং graded_by-এর মান human সেট করুন। এতে Judge ও মানুষের agreement স্মৃতির বিষয় না থেকে query-এর মাধ্যমে যাচাই করা যায়।

eval harness নিজেই কোথায় ব্যর্থ হয়

anthropic.RateLimitError প্রথম পূর্ণ run-এ। একসঙ্গে 60টি case চালালে আপনার tier-এর request বা token limit অতিক্রম করে। Concurrency সর্বোচ্চ 4টি worker-এ সীমাবদ্ধ করুন এবং 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 error-কে pass-এ রূপান্তর করে, agent খারাপ হলেও তার score 100%-এর দিকে বাড়তে থাকে।

Flaky case। Agent তার output sample করে বলে একই input এক run-এ pass এবং পরের run-এ fail করে। Flaky case তিনবার run করুন এবং case মুছে না ফেলে fraction record করুন। তিনটির মধ্যে দুই run-এ pass করা case বাস্তব robustness bug, এবং কোনো customer এটি খুঁজে পাবেন।

Golden set-এর অবক্ষয়। Suite-কে green দেখানোর জন্য কেউ expected answer সম্পাদনা করতে পারে। Agent-এর diff-এর মতোই evals/cases.jsonl-এর diff-ও সতর্কতার সঙ্গে review করুন, কারণ ওই file-এ correct ফলের লিখিত সংজ্ঞা রয়েছে।

যে suite কখনো fail করে না। এক মাস ধরে pass rate 100%-এ স্থির থাকলে বুঝবেন set আর product-এর পরিবর্তন অনুসরণ করছে না। সাম্প্রতিক 10টি trace নিন, agent যেগুলো খারাপভাবে handle করেছে সেগুলো খুঁজে বের করুন এবং যোগ করুন। এরপর ইচ্ছাকৃতভাবে একটি সমস্যা তৈরি করে নিশ্চিত করুন যে run red হয়। এটিই test suite-এ mutation testing প্রযোজ্য কি না যাচাই করার পদ্ধতি এবং আপনার set এখনও কার্যকর আছে কি না জানার একমাত্র উপায়।

FAQ

একটি AI agent eval set-এ কতগুলো case প্রয়োজন?

40 থেকে 80 দিয়ে শুরু করুন এবং বাস্তব failure থেকে set-টি বাড়ান। প্রায় 20টির কম case থাকলে একটি flaky ফলাফল pass rate-কে 5 point পর্যন্ত বদলে দিতে পারে, ফলে সংখ্যাটি আর নির্ভরযোগ্য তথ্য দেয় না। কয়েকশ case পেরিয়ে গেলে প্রতিটি run-এ বাস্তব অর্থ ও সময় খরচ হয়, কিন্তু অতিরিক্ত case সামান্যই coverage যোগ করে। গুরুত্বপূর্ণ মাপটি মোট সংখ্যা নয়; বরং আপনার জানা production failure type-গুলোর কত অংশ set-এ অন্তত একবার আছে, সেটিই গুরুত্বপূর্ণ।

আমার agent-এর grade দেওয়ার জন্য কি LLM judge-কে বিশ্বাস করা যায়?

নিজের label দিয়ে সেটিকে যাচাই করার পরেই কেবল বিশ্বাস করুন। হাতে grade করা 30টি case আলাদা রাখুন। Judge model বা judge prompt পরিবর্তন করলে প্রতিবার judge-এর ফলাফল ওই case-গুলোর সঙ্গে মিলিয়ে score করুন। Judge-দের length bias থাকে। অর্থাৎ, অপ্রয়োজনীয়ভাবে দীর্ঘ করা answer বেশি pass করতে পারে। তাদের self-preference-ও থাকে। অর্থাৎ, নিজেদের model family-এর output তারা তুলনামূলকভাবে বেশি নমনীয়ভাবে grade করতে পারে। উভয় bias পরীক্ষা করা যায়: একটি failed answer দীর্ঘ করে আবার judge করুন, অথবা অন্য model family-এর judge দিয়ে একই answer grade করুন। Judge যদি প্রতি 10টির মধ্যে 1টির বেশি case-এ আপনার label-এর সঙ্গে দ্বিমত করে, তাহলে rubric এতটাই অস্পষ্ট যে এটি ব্যবহার করা যাবে না।

Evals grade করার জন্য কোন model ব্যবহার করা উচিত?

সস্তা model দিয়ে grade করুন এবং প্রয়োজনে উন্নত model-এ পাঠান। Deterministic assertion-এর কোনো খরচ নেই, তাই প্রতিটি case-এ সেগুলো প্রথমে চালান। একটি ছোট model স্পষ্ট pass শনাক্ত করতে পারে। শুধু fail এবং low-confidence verdict-গুলো frontier model-এ পাঠান। August 2026-এর list price অনুযায়ী, 1,000টি case judge করতে Claude Haiku 4.5 দিয়ে প্রায় 1.80 US dollar এবং Claude Opus 5 দিয়ে প্রায় 9.00 খরচ হয়। Eval run asynchronous হওয়ায় Batch API ব্যবহার করলে উভয় খরচই অর্ধেক হয়।

Evals কি production monitoring-এর বিকল্প?

না, কারণ তারা ভিন্ন প্রশ্নের উত্তর দেয়। একটি eval suite আপনাকে জানায়, যে পরিবর্তনটি আপনি এখন release করতে যাচ্ছেন সেটি একটি নির্দিষ্ট case set-এ ফলাফল ভালো করছে নাকি খারাপ করছে। Tracing এবং monitoring জানায়, বাস্তব user-রা এই মুহূর্তে কী ব্যবহার করছে; এর মধ্যে এমন input-ও থাকে যা কোনো case-এ নেই। তারা একে অপরকে সহায়তা করে: trace থেকে নতুন case তৈরি হয়, আর eval suite নির্ধারণ করে আপনার fix সত্যিই কাজ করেছে কি না।