AI एजेंट का मूल्यांकन: evals कैसे बनाएँ और भरोसेमंदी मापें, वाइब नहीं
AI एजेंट का मूल्यांकन तय कार्यों के सेट को नियमित रूप से चलाने, परिणाम की स्वचालित जाँच करने और मेट्रिक्स गिनने का काम है, न कि कुछ सफल सत्रों का प्रभाव। मुख्य बात केवल pass@k (k में से कम से कम एक प्रयास सफल) नहीं, बल्कि pass^k (k के सभी प्रयास सफल) भी मापना है, क्योंकि स्थिरता ही तय करती है कि एजेंट को बिना निगरानी के काम सौंपा जा सकता है या नहीं।
AI एजेंट का मूल्यांकन क्यों, जब दिख ही रहा है कि वह काम कर रहा है
यही तो दिक्कत है: दिखता ठीक से नहीं। प्रॉम्प्ट बदलने के बाद एजेंट पूरे सप्ताह कहीं नहीं अटका: यह मरम्मत का नतीजा है या बस सरल कार्यों का सप्ताह था? एक इंजीनियर को यकीन है कि नए टेम्पलेट ने सब बदल दिया, दूसरे ने वही लॉग देखा और कोई फ़र्क नहीं पाया। दोनों तभी तक सही हैं, जब तक उन्होंने कुछ गिना नहीं।
AI एजेंट का मूल्यांकन (evals) एहसास की जगह संख्या रखता है। आप तय कार्यों का सेट लेते हैं, एजेंट को चलाते हैं, परिणाम अपने-आप जाँचते हैं और बदलाव से पहले और बाद के मेट्रिक्स की तुलना करते हैं। तब «सुधरा या नहीं» का विवाद अधिकार से नहीं, तालिका से सुलझता है।
बिना evals के हार्नेस का कोई भी बदलाव (प्रॉम्प्ट, AGENTS.md, टूल-सेट, मॉडल) अंधेरे में दाँव है। evals के साथ यह मापने योग्य परिणाम वाला प्रयोग बन जाता है।
«वाइब» क्यों धोखा देता है
एजेंट के काम के एहसास में तीन व्यवस्थित गलतियाँ होती हैं, और तीनों झूठे भरोसे की ओर धकेलती हैं।
- सर्वाइवर बायस। सफल दौड़ें याद रहती हैं और सहकर्मियों को दिखाई जाती हैं, असफल दौड़ें दोबारा चलाई जाती हैं और भुला दी जाती हैं। सिर्फ़ सफल दौड़ों से निकली विश्वसनीयता यह नहीं बताती कि एजेंट असल में कहाँ टूटता है।
- छोटा नमूना। लगातार तीन सफल कार्य सामान्य घटना है, भले ही एजेंट आधे मामलों में ही सफल हो। इसकी संभावना 0,5³ = 12,5% है, यानी लगभग हर आठवीं शृंखला में।
- आत्मविश्वासी लहजा। एजेंट «हो गया, सारे टेस्ट पास हैं» उतने ही आत्मविश्वास से कहता है, जितना सच होने पर, और उतना ही गलत होने पर। मॉडल का आत्मविश्वास कैलिब्रेटेड नहीं है: उत्तर का लहजा सही होने का संकेत नहीं है।
इसलिए नियम है: जो दर्ज और दोबारा गिना नहीं गया, उसे अनमापा माना जाए।
pass@k और pass^k: दो मेट्रिक्स जिन्हें लोग मिला देते हैं
एजेंट नियतात्मक नहीं है: वही कार्य दोबारा चलाने पर कभी पास हो सकता है, कभी फ़ेल। इसलिए एक कार्य को कई बार चलाया जाता है और दो में से कोई एक मेट्रिक गिना जाता है।
pass@k: k में से कम से कम एक प्रयास सफल
यह मेट्रिक कोड-जनरेशन के मूल्यांकन से आया है। यह सवाल पूछता है: «अगर कई प्रयास दिए जाएँ, तो क्या सिस्टम यह कार्य सिद्धांततः हल कर सकता है?» यह ईमानदार मेट्रिक तब है, जब इंसान कई विकल्पों में से सर्वश्रेष्ठ चुनता हो, या जब कोई भरोसेमंद स्वचालित जाँच विफल प्रयासों को छाँट देती हो।
pass^k: k के सभी प्रयास सफल
यह मेट्रिक दूसरा सवाल पूछता है: «एजेंट यह कार्य कितनी स्थिरता से हल करता है?» यह बिना निगरानी के काम का वर्णन करता है, जब एजेंट कई बार चलता है और हर विफलता पैसा या समय खर्च करती है।
दोनों में फ़र्क बहुत बड़ा है। मान लीजिए एजेंट एक प्रयास में कोई कार्य 70% संभावना से हल करता है और प्रयास स्वतंत्र हैं:
| k | pass@k = 1 − 0,3^k | pass^k = 0,7^k |
|---|---|---|
| 1 | 70% | 70% |
| 3 | 97,3% | 34,3% |
| 5 | 99,8% | 16,8% |
| 10 | ~100% | 2,8% |
pass@5 के हिसाब से एजेंट लगभग आदर्श दिखता है, pass^5 के हिसाब से अविश्वसनीय। दोनों संख्याएँ सही हैं, बस अलग चीज़ों का वर्णन करती हैं। अगर आप एजेंट को स्वायत्त रूप से काम पर छोड़ने वाले हैं, तो pass^k देखें: वह उस चीज़ के ज़्यादा करीब है, जो असल काम में दिखेगी।
व्यवहार में कैसे गिनें
हर कार्य को n बार (जैसे 5) चलाएँ और सफलताओं की संख्या c लिखें। pass^k के लिए अनुमान यह है कि जिन दौड़ों में k लगातार सभी सफल हों, उनका अनुपात निकालें, या सरल रूप में सफलता-संभावना p = c / n का अनुमान लगाकर उसे घात में उठाएँ। कार्यों के सेट के लिए कार्यों पर औसत लें।
import json
from statistics import mean
# results.jsonl: {"task": "add-pagination", "runs": [true, true, false, true, true]}
rows = [json.loads(line) for line in open("results.jsonl")]
def pass_at_k(runs, k):
p = sum(runs) / len(runs)
return 1 - (1 - p) ** k
def pass_pow_k(runs, k):
p = sum(runs) / len(runs)
return p ** k
for k in (1, 3, 5):
print(k,
round(mean(pass_at_k(r["runs"], k) for r in rows), 3),
round(mean(pass_pow_k(r["runs"], k) for r in rows), 3))
n छोटा हो तो p की घात वाला अनुमान मोटा है, पर हार्नेस के संस्करणों की आपस में तुलना के लिए यह आमतौर पर काफ़ी है। ज़्यादा ज़रूरी यह है कि तुलनाओं के बीच n और कार्यों का सेट न बदले।
evals के लिए कार्यों का सेट कैसे बनाएँ
कार्यों का सेट सबसे कीमती संपत्ति है। अच्छा मेट्रिक खराब कार्यों पर वही नहीं मापता जो मापना चाहिए।
अपनी वास्तविकता से कार्य लें
SWE-bench जैसे सार्वजनिक बेंचमार्क मॉडलों की तुलना के लिए उपयोगी हैं, पर उनके कार्य चुने हुए होते हैं: स्पष्ट विवरण, तैयार टेस्ट। आपकी रिपॉज़िटरी में आवश्यकताएँ धुंधली हैं और कहीं टेस्ट नहीं हैं, इसलिए बेंचमार्क की संख्या लगभग हमेशा उससे ऊँची होती है जो एजेंट आपके यहाँ दिखाएगा। कार्यों का सबसे अच्छा स्रोत बंद किए गए टिकट और लॉग से निकली एजेंट की असली विफलताएँ हैं।
सेट की बनावट
- शुरुआत के लिए 20–50 कार्य। कम हों तो शोर संस्करणों का अंतर निगल जाता है। ज़्यादा हों तो रन महँगा हो जाता है और लोग उसे चलाना बंद कर देते हैं।
- विविध प्रकार: नई फ़ीचर, बग-सुधार, रिफ़ैक्टरिंग, किसी दूसरे मॉड्यूल का कार्य, और जाल वाला कार्य (जहाँ सही उत्तर «ऐसा करना मना है» या «स्पष्टीकरण चाहिए» है)।
- काम में विफल हुआ हर कार्य एक टेस्ट बन जाता है। इस तरह सेट उसी समझ के साथ बढ़ता है कि एजेंट कहाँ कमज़ोर है, और रिग्रेशन बिना नोटिस के वापस नहीं आते।
- स्थिर प्रारंभिक अवस्था: एक तय कमिट, तय निर्भरताएँ, एक जैसा वातावरण। वरना आप एजेंट को नहीं, वातावरण के बहाव को माप रहे होंगे।
कार्य का प्रारूप
हर कार्य एक विवरण, एक प्रारंभिक अवस्था और एक सफलता-मानदंड है, जिसे इंसान के बिना जाँचा जा सके।
id: add-pagination
repo_ref: 3f2c1ab
prompt: |
GET /payments में पेजिनेशन जोड़ो: पैरामीटर limit (डिफ़ॉल्ट 20, अधिकतम 100)
और cursor। उत्तर में next_cursor हो।
check:
- pytest tests/test_payments_pagination.py
- mypy app/
limits:
max_changed_files: 6
ध्यान दें: सफलता-मानदंड वही Definition of Done है, जो कमांड से लिखा गया है। अगर किसी कार्य का मानदंड लिखा ही न जा सके, तो यह संकेत है कि एजेंट को भी वह कार्य अस्पष्ट रूप से सौंपा गया है।
स्वचालित जाँच या LLM-जज
परिणाम की जाँच कोड से भी हो सकती है और दूसरे मॉडल से भी। हर तरीके का अपना क्षेत्र है।
| स्वचालित जाँच (कोड) | LLM-जज | |
|---|---|---|
| क्या जाँचता है | टेस्ट, टाइप, लिंटर, E2E, diff का आकार, प्रतिबंधित फ़ाइलें | आवश्यकताओं से मेल, पठनीयता, शैली, स्पष्टीकरण की गुणवत्ता |
| नियतात्मकता | पूरी | नहीं: मूल्यांकन हर रन में बदलता है |
| लागत | लगभग मुफ़्त | हर कार्य पर मॉडल का एक और कॉल |
| मुख्य जोखिम | सब कुछ नहीं जाँचता: टेस्ट हरे, पर फ़ीचर गलत | आत्मविश्वासी पर गलत समाधान से सहमत हो जाता है |
नियम: पहले कोड, जज ऊपर से
जो नियतात्मक रूप से जाँचा जा सके, उसे नियतात्मक रूप से ही जाँचें। LLM-जज केवल उन गुणों के लिए जोड़ें, जिन्हें कोड से व्यक्त नहीं किया जा सकता, और कभी टेस्ट की जगह नहीं।
LLM-जज को उपयोगी कैसे बनाएँ
- जनरेटर से अलग संदर्भ। जज को एजेंट का तर्क नहीं देखना चाहिए, केवल कार्य, मानदंड और अंतिम diff। वरना वह वही गलतियाँ दोहराएगा: यही N-version है, एक नज़र की जगह दो स्वतंत्र नज़रें।
- रूब्रिक, «दस अंकों के पैमाने पर आँकें» नहीं। ठोस सवाल, जिनका उत्तर हाँ/नहीं हो: «क्या limit > 100 की जाँच है», «क्या app/payments के बाहर की फ़ाइलें बदली गईं»।
- मैनुअल लेबलिंग पर कैलिब्रेशन। 20–30 परिणाम हाथ से लेबल करें और जज के फ़ैसलों से तुलना करें। मेल कम हो तो जज पर ज़्यादा भरोसा करने के बजाय रूब्रिक बदलें।
- गलतियों की असमानता। झूठा «तैयार» झूठे «तैयार नहीं» से महँगा है: पहला प्रोडक्शन में चला जाता है, दूसरा बस एक दोबारा चलाने की कीमत है। जज को ऐसे सेट करें कि संदेह में वह अस्वीकार करे।
सफलता के अनुपात के अलावा कौन से मेट्रिक्स गिनें
हल हुए कार्यों का अनुपात केवल ऊपरी परत है। यह जानने के लिए कि सुधार कहाँ करना है, क्लासिक इंजीनियरिंग के भरोसेमंदी-मेट्रिक्स चाहिए।
- MTBF — एजेंट कितने चरण या कार्य अटकने से पहले पूरे करता है। दिखाता है कि वह कितनी कम बार टूटता है।
- MTTR — विफलता के बाद कार्यशील अवस्था में लौटने में कितना समय लगता है। इसे घटाना लगभग हमेशा MTBF बढ़ाने से सस्ता पड़ता है: अच्छी प्रगति-फ़ाइल और दोहराई जा सकने वाली वातावरण-व्यवस्था पुनर्प्राप्ति को कई गुना छोटा कर देती है।
- विस्फोट-त्रिज्या (blast radius) — एक असफल चरण कितना कोड बिगाड़ता है। यह diff की सीमा और कार्य-प्रति के अलगाव से नियंत्रित होता है।
- झूठे «तैयार» का अनुपात — वे कार्य, जहाँ एजेंट ने सफलता घोषित की, पर जाँच गिर गई। यह सबसे खतरनाक मेट्रिक है: यही बताता है कि एजेंट की रिपोर्ट पर भरोसा किया जा सकता है या नहीं।
- लागत और समय — प्रति कार्य टोकन और मिनट। जो हार्नेस सफलता 5% बढ़ाए, पर लागत दोगुनी कर दे, वह हमेशा नहीं जीतता।
विफलताओं का लॉग: रोज़मर्रा के काम से evals
हर टीम तुरंत मूल्यांकन-रनर बनाने के लिए तैयार नहीं होती। न्यूनतम रूप है तीन कॉलम वाला विफलता-लॉग।
| कार्य | परिणाम | परत |
|-------------------------|------------------------------------|---------------|
| /payments पेजिनेशन | «तैयार», 2 टेस्ट लाल | सत्यापन |
| webhook टाइमआउट सुधार | pip install में 30 मिनट | वातावरण |
| refunds रिफ़ैक्टरिंग | ORM का पुराना सिंटैक्स | संदर्भ |
परत वह है, जहाँ एजेंट टूटता है: पाँच स्थानों में से एक: कार्य की विशिष्टता, संदर्भ, निष्पादन-वातावरण, सत्यापन का फ़ीडबैक, या अवस्था का प्रबंधन। बीस प्रविष्टियों के बाद असली अड़चन दिखने लगती है, और लगभग कभी वह नहीं होती जहाँ आपने सोचा था। लॉग की हर पंक्ति evals के कार्यों के सेट का उम्मीदवार है।
शक्तिशाली मॉडल क्यों नहीं बचाता
एजेंट की विफलताओं पर पहली प्रतिक्रिया होती है महँगा मॉडल लेना। कभी यह मदद करता है, पर अक्सर बेंचमार्क और आपकी वास्तविकता के बीच का अंतर मॉडल नहीं, उसके आसपास का वातावरण भरता है।
अगर एजेंट आधा घंटा वातावरण खड़ा करने में लगाता है, तो यह वातावरण की परत है, और सबसे महँगा मॉडल भी उतने ही समय लेगा। अगर एजेंट लाल टेस्टों के बावजूद «तैयार» कहता है, तो यह सत्यापन की परत है: उसके पास कोई कमांड नहीं जो सच बताए। अगर वह प्रोजेक्ट की शैली से अलग शैली में लिखता है, तो उसे प्रोजेक्ट के नियम नहीं दिए गए। इनमें से कोई समस्या मॉडल की बुद्धि की नहीं है।
evals इसे ईमानदारी से जाँचने देते हैं। सेट को मौजूदा मॉडल से और महँगे मॉडल से चलाएँ, फिर मौजूदा मॉडल से और ऐसे AGENTS.md के साथ जिसमें जाँच-कमांड हों। अक्सर दूसरा बदलाव, बिना किसी लागत के, पहले से ज़्यादा लाभ देता है। पर इस पर शब्द के भरोसे न रहें: ऐसी तुलनाओं के लिए ही सेट चाहिए।
एक सप्ताह की योजना: AI एजेंट का मूल्यांकन
- दिन 1. विफलता-लॉग शुरू करें और एजेंट की हर विफलता परत के संकेत के साथ लिखें।
- दिन 2. बंद टिकटों और लॉग से 20 कार्य चुनें। हर एक के लिए कमिट तय करें और सफलता-मानदंड कमांड से लिखें।
- दिन 3. रनर लिखें: साफ़ कार्य-प्रति, एजेंट को कार्य के विवरण से चलाना, जाँच-कमांड चलाना, परिणाम JSONL में लिखना।
- दिन 4. हर कार्य को 3–5 बार चलाएँ। pass@1, pass^3, झूठे «तैयार» का अनुपात और औसत लागत निकालें।
- दिन 5. हार्नेस में एक चीज़ बदलें और फिर चलाएँ। तुलना तभी करें जब सेट और दोहराव की संख्या एक जैसी हो।
एक बार में एक चर बदलें। अगर एक ही प्रयोग में मॉडल, प्रॉम्प्ट और टूल तीनों बदल दिए, तो पता नहीं चलेगा कि काम किसने किया।
AI एजेंट के मूल्यांकन में आम गलतियाँ
- हर कार्य पर एक रन। एजेंट की गैर-नियतात्मकता इस परिणाम को लॉटरी बना देती है। कम से कम तीन दोहराव।
- तुलनाओं के बीच सेट बदलना। नए कार्य जोड़े और साथ में प्रॉम्प्ट भी बदला, तो संख्याएँ तुलनीय नहीं रहतीं।
- एजेंट को जाँच-टेस्ट दिखना। अगर टेस्ट रिपॉज़िटरी में हैं, तो एजेंट कोड को उनके अनुरूप ढाल सकता है या टेस्ट ही बदल सकता है। छिपी जाँचें कार्य-प्रति से बाहर रखें और जाँचें कि एजेंट ने टेस्ट-फ़ाइलों को छुआ तो नहीं।
- जाँच की जगह एजेंट की रिपोर्ट। मॉडल के उत्तर में «सारे टेस्ट पास» परिणाम नहीं है। परिणाम रनर द्वारा चलाई गई कमांड का रिटर्न कोड है।
- केवल pass@k। प्रस्तुति के लिए सुंदर संख्या, और स्वायत्त काम के लिए खराब पूर्वानुमान।
संक्षेप में
AI एजेंट का मूल्यांकन तय वास्तविक कार्यों का सेट, स्वचालित जाँचें और ऐसे मेट्रिक्स हैं जो हार्नेस के हर बदलाव के बाद दोबारा गिने जाते हैं। pass@k बताता है कि एजेंट क्या कर सकता है, pass^k बताता है कि उस पर बिना निगरानी भरोसा किया जा सकता है या नहीं। स्वचालित जाँचें सच बताती हैं, और रूब्रिक तथा अलग संदर्भ वाला LLM-जज वहाँ जोड़ा जाता है जहाँ कोड असमर्थ है। पाँच परतों वाला विफलता-लॉग दिखाता है कि पहले क्या ठीक करना है, और अक्सर वह मॉडल नहीं होता। भरोसेमंदी के मेट्रिक्स और निदान का लूप कोर्स में harness engineering पर व्यवहार में समझाए गए हैं।
अक्सर पूछे जाने वाले प्रश्न
एजेंट के evals के लिए कितने कार्य चाहिए?
शुरुआत के लिए स्वचालित सफलता-मानदंड वाले 20–50 वास्तविक कार्य और हर कार्य के 3–5 दोहराव काफ़ी हैं। इससे छोटा सेट सुधार को शोर से अलग नहीं कर पाएगा, और बड़ा सेट महँगा होकर चलाना बंद करा देगा।
क्या एजेंट का मूल्यांकन केवल सार्वजनिक बेंचमार्क से किया जा सकता है?
नहीं। सार्वजनिक बेंचमार्क चुने हुए कार्यों और तैयार टेस्टों पर मॉडलों की तुलना करते हैं, जबकि आपकी रिपॉज़िटरी में आवश्यकताएँ और टेस्ट अलग हैं। अपने हार्नेस के बारे में फ़ैसलों के लिए अपना कार्य-सेट चाहिए।
pass@1 और pass^1 में क्या फ़र्क है?
कोई फ़र्क नहीं: एक प्रयास पर दोनों मेट्रिक्स सफल रनों के अनुपात के बराबर होते हैं। ये k के एक से बड़े होने पर अलग होने लगते हैं।
क्या LLM-जज वही मॉडल हो सकता है, जो एजेंट है?
हो सकता है, अगर उसका संदर्भ अलग हो: वह केवल कार्य, रूब्रिक और अंतिम diff देखे, एजेंट का तर्क नहीं। पर उसके फ़ैसलों को फिर भी मैनुअल लेबलिंग से मिलाना होगा।
evals कितनी बार चलाने चाहिए?
हार्नेस में हर महत्वपूर्ण बदलाव के बाद: प्रॉम्प्ट, निर्देश-फ़ाइल, टूल-सेट या मॉडल। साथ ही सेट को शेड्यूल पर चलाना उपयोगी है, ताकि वातावरण और निर्भरताओं के बहाव पकड़ में आएँ।
यह विषय “Harness Engineering: инженерия надёжности AI-агентов” कोर्स में अभ्यास के साथ विस्तार से समझाया गया है।
- Метрики надёжности AI-агента: MTBF, MTTR, радиус поражения и закон Литтла
- Почему AI-агент ломается в проде: пять слоёв отказа и диагностическая петля