مفاهیم
معیارها و امتیازدهندهها
تابع امتیازی را بنویسید که به موتور میگوید «بهتر» یعنی چه.
معیار به Skynet میگوید یک خروجی چقدر خوب است. معیار یک تابع Python در metric.py است. همهٔ موتورها همین تابع را فراخوانی میکنند. این صفحه قرارداد، مقدار بازگشتی و چند مثال را ارائه میدهد.
قرارداد
def score(input, output, expected=None):
...
return score_value, {"feedback": "..."}| آرگومان | محتوای آن |
|---|---|
input | یک dict با فیلدهای ورودی نمونه |
output | آنچه run(artifact, input) شما برای این نمونه برگرداند |
expected | مقدار مورد انتظار نمونه، یا None وقتی نمونه مقدار مورد انتظار ندارد |
اگر تابع شما فقط دو آرگومان بگیرد، Skynet آن را به شکل score(input, output) فراخوانی میکند.
برای یک برنامهٔ DSPy، Skynet فراخوانی معیار DSPy را با همین تابع تطبیق میدهد. شما برای هر نوع آرتیفکت فقط یک معیار مینویسید. صفحهٔ بهینهسازی چگونه کار میکند را بخوانید.
مقدار بازگشتی
score باید یک جفت برگرداند (یک tuple یا یک list با دو عضو):
- امتیاز. یک عدد. بهینهساز تلاش میکند آن را بالاتر ببرد.
- اطلاعات جانبی. یک dict. باید کلید
"feedback"با مقدار رشتهای داشته باشد.
اطلاعات جانبی میتواند کلید "scores" هم داشته باشد. این کلید نامها را به عددها نگاشت میکند، برای مثال {"format": 1.0, "accuracy": 0.5}.
اگر مقدار بازگشتی شکل دیگری داشته باشد، بررسی قرارداد در مقدار بازگشتی معیار ناموفق میشود.
| مقدار بازگشتی | معتبر |
|---|---|
(0.8, {"feedback": "Close. Missing the date."}) | بله |
[1.0, {"feedback": "OK", "scores": {"format": 1.0}}] | بله |
0.8 | خیر. اطلاعات جانبی وجود ندارد. |
(0.8, "Close.") | خیر. اطلاعات جانبی dict نیست. |
(0.8, {}) | خیر. رشتهٔ feedback وجود ندارد. |
("0.8", {"feedback": "OK"}) | خیر. امتیاز یک رشته است. |
(0.8, {"feedback": "OK", "scores": {"a": "high"}}) | خیر. یک امتیاز نامدار عدد نیست. |
نوشتن بازخورد مفید
GEPA، DSPy GEPA و Auto متن بازخورد را میخوانند تا نسخهٔ بعدی را بنویسند. بگویید چه چیزی اشتباه است و خروجی درست چه شکلی دارد.
| بازخورد ضعیف | بازخورد مفید |
|---|---|
| «اشتباه است.» | «انتظار 'billing' بود، 'other' دریافت شد. پیام به یک برداشت از حساب اشاره میکند.» |
| «قالب بد است.» | «خروجی JSON معتبر نیست. بعد از آخرین فیلد یک ویرگول اضافه دارد.» |
مثالها
تطابق دقیق
def score(input, output, expected=None):
want = expected["label"]
if output == want:
return 1.0, {"feedback": "Correct."}
return 0.0, {"feedback": f"Expected {want!r}, got {output!r}."}expected یک dict است که کلید آن نام ستون خروجی شما است. صفحهٔ مجموعهدادهها و تقسیم را بخوانید.
چند بررسی
import json
def score(input, output, expected=None):
try:
data = json.loads(output)
except ValueError as exc:
return 0.0, {"feedback": f"Output is not valid JSON: {exc}", "scores": {"format": 0.0, "fields": 0.0}}
want = expected["fields"]
found = [key for key in want if key in data]
fields = len(found) / len(want) if want else 1.0
missing = [key for key in want if key not in data]
feedback = "All fields present." if not missing else f"Missing fields: {', '.join(missing)}."
return 0.5 + 0.5 * fields, {"feedback": feedback, "scores": {"format": 1.0, "fields": fields}}مدل در نقش داور
معیار میتواند یک مدل را فراخوانی کند. llm را از ماژول کمکی skynet وارد کنید. فراخوانیای که از معیار انجام میشود به مدل معیار میرود.
from skynet import llm
def score(input, output, expected=None):
verdict = llm(
"Answer PASS or FAIL, then give one sentence of reasons.",
input=f"Question: {input['question']}\nAnswer: {output}",
)
passed = str(verdict).strip().upper().startswith("PASS")
return (1.0 if passed else 0.0), {"feedback": str(verdict)}اگر مدل معیار را انتخاب نکنید، معیار از همان مدلی استفاده میکند که مدل بازاندیشی است.
دقت، سرعت و هزینه
یک معیار میتواند دقت را با زمان اجرای اندازهگیریشده و هزینهٔ مدل ترکیب کند. REWARD_SPEC را در سطح ماژول تعریف کنید و مقدار reward را برگردانید.
from skynet import reward
REWARD_SPEC = {
"weights": {"accuracy": 0.7, "speed": 0.2, "cost": 0.1},
"accuracy": {},
"speed": {"reference": 2000},
"cost": {"reference": 0.01},
}
def score(input, output, expected=None):
ok = output == expected["label"]
return reward(REWARD_SPEC, 1.0 if ok else 0.0, "Correct." if ok else "Wrong label.")weightsبایدaccuracy،speedوcostرا داشته باشد. هر وزن 0 یا بیشتر است و همهٔ وزنها نمیتوانند 0 باشند. Skynet آنها را طوری مقیاس میدهد که مجموعشان 1 شود.- واحد
speed.referenceمیلیثانیه است. واحدcost.referenceدلار آمریکا است. هر دو باید مثبت باشند. - بدون
accuracy.reference، دقت امتیازی از 0 تا 1 است. با آن، دقت یک خطا است و مقدار کمتر بهتر است.
Skynet زمان و هزینه را خودش اندازه میگیرد. کد اجرا نمیتواند آنها را تغییر دهد. اگر Skynet نتواند زمان یا هزینه را اندازه بگیرد، آن بخش امتیاز 0 میگیرد و بازخورد این را اعلام میکند.
معیار همچنین میتواند اندازهگیریها را مستقیماً با observation() و service_cost() از skynet بخواند.
محدودیتها
| مورد | مقدار |
|---|---|
| مهلت زمانی معیار | بهطور پیشفرض 60 ثانیه، حداکثر 600 ثانیه |
| نمونههای بررسی قرارداد | 3 نمونه |