The "Where & Why": ก้าวข้าม "Vibe-Check Prompting" สู่ Quantitative Golden Benchmarks
ปัญหาคอขวดที่พบในระดับองค์กร: เมื่อวิศวกรปรับแต่ง
SKILL.md เพื่อรองรับฟีเจอร์ใหม่ เราจะรู้ได้อย่างไรว่าการแก้คำใน description จะไม่ทำลาย Trigger Precision? หรือการแก้ Prompt จะไม่ทำให้อัตราความสำเร็จครั้งแรก (Pass@1 Accuracy) ถดถอย? การทดสอบด้วยความรู้สึกส่วนตัว ("Vibe Check") ไม่อาจยอมรับได้ใน Productionเป้าหมายของ Day 11: เราจะติดตั้ง Golden Benchmark Suite และ Deterministic Evaluation Harness (
evals/run-skill-evals.py) ที่คำนวณ Confusion Matrix (Precision, Recall, Specificity) พร้อมวัดคะแนน Pass@1 เพื่อทำ Automated CI Regression Gate ก่อนปล่อย Skill ให้ทีมงาน 500+ คน
┌────────────────────────────────────────────────────────────────────────┐
│ PULL REQUEST TRIGGERED: "Refactor SKILL.md Frontmatter Description" │
└───────────────────────────────────┬────────────────────────────────────┘
│
▼ (GitHub Actions CI Automated Gate)
┌────────────────────────────────────────────────────────────────────────┐
│ 🎯 EVALS/RUN-SKILL-EVALS.PY [TODAY'S ARTIFACT] │
│ │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ SUITE 1: SEMANTIC TRIGGER EVALUATION (50 Golden Prompts) │ │
│ │ - 20 True Positives (MockK / Service Layer / Isolated Unit Tests) │ │
│ │ - 20 True Negatives (Testcontainers / Postgres / E2E Playwright) │ │
│ │ - 10 Adversarial Edge Prompts (Borderline ambiguous requests) │ │
│ │ ──► Computes: Precision, Recall, Specificity, F1-Score │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ (Gate Check: Precision > 95% && Recall > 90%)
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ SUITE 2: CODE SYNTHESIS PASS@1 BENCHMARK (10 Target Classes) │ │
│ │ - Feeds AST Skeletons from Day 7 to Target Host Agent Model │ │
│ │ - Executes scripts/run-unit-tests.sh on generated output │ │
│ │ ──► Computes: First-Pass Compilation Rate & Invariant Conformance │ │
│ └────────────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────┬────────────────────────────────────┘
│
┌─────────────────┴─────────────────┐
▼ (Fails Threshold) ▼ (Passes All Gates)
┌──────────────────────────────────────┐ ┌───────────────────────────────┐
│ 🛑 BLOCK PR MERGE │ │ 🏆 APPROVE FOR DISTRIBUTION │
│ Emits Regression Card to PR Comments │ │ Guaranteed 0% Trigger Leakage │
└──────────────────────────────────────┘ └───────────────────────────────┘
Zero "Vibe Checks"
แทนที่การสุ่มถามคำถาม 2-3 ข้อด้วยชุดทดสอบมาตรฐาน Golden Datasets ที่มี Ground Truth กำกับชัดเจนในทุกมิติ
Precision & Recall Gates
วัดผล Triggering อัตโนมัติ: ป้องกันทั้งอาการไม่ยอมทำงาน (False Negative) และอาการขโมยงานของ Skill อื่น (False Positive)
Headless CI Execution
รัน Benchmark ทุกครั้งที่มีการเปิด PR แก้ไขไฟล์ใน skills/ บล็อกการผสานโค้ดทันทีหากคะแนนความแม่นยำตกต่ำลง
วิศวกรรม Skill Evaluation: การวัดผลเชิงตัวเลข (Quantitative Metrics) และ Confusion Matrix
ในการพัฒนาโมเดล Machine Learning เราประเมินประสิทธิภาพผ่านชุดทดสอบ Validation Set สำหรับ Agent Skills ซึ่งเป็น Declarative Software Components เราต้องแบ่งมิติการประเมินออกเป็น 2 ชั้นที่แยกขาดจากกัน: Routing Evaluation (Trigger Layer) และ Execution Evaluation (Synthesis Layer)
| มิติการประเมิน (Evaluation Dimension) | Casual Testing (ลองคุยใน Chat) | Keyword Grep Check | Golden Benchmark Harness (Day 11) |
|---|---|---|---|
| Trigger Precision Rate | ไม่สามารถประเมินได้เชิงปริมาณ | ต่ำมาก: ตรวจจับได้เฉพาะคำตรงเป๊ะ | วัดผลแม่นยำ: True Positive / (TP + FP) |
| False Activation Shield | หลุดรอด: มักไม่ทดสอบ Negative Cases | เป็นศูนย์: แยกแยะ Semantic ซ้อนทับไม่ได้ | เข้มงวด 100%: ยิง Adversarial Prompts 20 เคส |
| Pass@1 Functional Conformance | มนุษย์กวาดตาอ่าน (Human Fatigue) | ทำไม่ได้ | Automated Headless Compile + Sandboxed Runner |
| CI/CD Integration | เป็นไปไม่ได้ (Manual Only) | รันได้แต่ไร้ความหมายทางสถาปัตยกรรม | Native GitHub Action: บล็อก PR อัตโนมัติเมื่อค่าเบี่ยงเบน |
ในการประเมิน Semantic Routing ของ SKILL.md เราจัดหมวดหมู่ผลลัพธ์ของ 50 Golden Prompts เป็น 4 สถานะ:
Enterprise Threshold Mandate: Skill ต้องผ่านเกณฑ์ Precision ≥ 95.0% (ห้ามขโมยงาน) และ Recall ≥ 90.0% (ต้องตื่นตัวเมื่อเจองานของตน)
ความแม่นยำในการสร้างโค้ด (Code Synthesis Accuracy) วัดผลด้วยมาตรวัด Pass@1 ภายใต้ Sandboxed Runner (Day 6):
- 1. Clean Compilation (Exit 0): โค้ดที่สร้างในรอบแรกต้องคอมไพล์ผ่านโดยไม่มีข้อผิดพลาด Type Mismatch หรือ Symbol หาย
- 2. Zero Static Violations (Exit != 2): โค้ดต้องไม่มีการหลุดของ
org.mockitoหรือ Spring context runners แม้แต่บรรทัดเดียว - 3. Assertion Pass Rate: เทสต์ต้องรันผ่านและ assert สถานะตรงกับ Behavior Specification จริง 100%
Production Artifact: The Deterministic Skill Benchmark Harness
ชุดเครื่องมือประเมินผลมาตรฐานระดับองค์กร ประกอบด้วย Golden Test Dataset, สคริปต์รัน Benchmark ภาษา Python (Zero-Dependency), และ GitHub Actions CI Workflow
.github/
├── skills/
│ └── spring-boot-unit-tester/ ◄── The Capstone Skill Under Test (Day 10)
│ ├── SKILL.md
│ └── scripts/run-unit-tests.sh
└── evals/ ◄── [TODAY'S ARTIFACT: BENCHMARK SUITE]
├── datasets/
│ └── trigger-golden-suite.json ◄── 50 Ground-truth Evaluation Prompts
├── run-skill-evals.py ◄── Deterministic Confusion Matrix & Pass@1 Harness
└── workflows/
└── skill-ci-gate.yml ◄── Automated PR Regression Blocking Workflow
[
{
"id": "TRIG-001",
"prompt": "Write isolated unit tests for SettlementLedgerService with MockK",
"expected_trigger": true,
"category": "TRUE_POSITIVE",
"rationale": "Clear service-layer unit testing request requiring MockK."
},
{
"id": "TRIG-002",
"prompt": "Test PaymentGatewayClient using Testcontainers and real PostgreSQL database",
"expected_trigger": false,
"category": "TRUE_NEGATIVE_INTEGRATION",
"rationale": "Explicitly requests Testcontainers and database; must be pruned by negative guard."
},
{
"id": "TRIG-003",
"prompt": "Create unit tests for FxExecutionEngine mocking suspend methods with coEvery",
"expected_trigger": true,
"category": "TRUE_POSITIVE",
"rationale": "Domain logic suspend function mocking with MockK."
},
{
"id": "TRIG-004",
"prompt": "Write @SpringBootTest integration tests with MockMvc for UserController",
"expected_trigger": false,
"category": "TRUE_NEGATIVE_MVC",
"rationale": "Requests @SpringBootTest and HTTP mocking; violates pure JVM boundary."
},
{
"id": "TRIG-005",
"prompt": "Write tests for BillingService verifying transaction rollback in case of error",
"expected_trigger": true,
"category": "BORDERLINE_SERVICE_UNIT",
"rationale": "Unit testing business exception rollback behavior without database."
},
{
"id": "TRIG-006",
"prompt": "Setup Cypress end-to-end browser test for trading checkout flow",
"expected_trigger": false,
"category": "TRUE_NEGATIVE_E2E",
"rationale": "Frontend E2E test; completely unrelated to backend JVM unit testing."
}
]
#!/usr/bin/env python3
"""
run-skill-evals.py
Standard: agentskills Standard v1.0 (Phase 4 Verification & Distribution)
Evaluates Semantic Trigger Precision/Recall and compiles a comprehensive Confusion Matrix.
Exits with 0 on passing all gates, 1 on regression failure.
"""
import sys
import os
import json
import re
from pathlib import Path
# // [TODAY'S LESSON PLUGS IN HERE: DETERMINISTIC GATING & CONFUSION MATRIX]
def load_skill_description(skill_path: Path) -> str:
"""Extracts description from SKILL.md YAML frontmatter."""
content = skill_path.read_text(encoding="utf-8")
match = re.search(r"^---\s*([\s\S]*?)\s*---", content, re.MULTILINE)
if not match:
raise ValueError("Invalid SKILL.md: Frontmatter not detected.")
fm = match.group(1)
desc_match = re.search(r"description:\s*>?-?\s*([\s\S]*?)(?=\n[a-zA-Z0-9_-]+:|$)", fm)
if not desc_match:
raise ValueError("No description field found in frontmatter.")
return " ".join(desc_match.group(1).split())
def evaluate_semantic_routing(description: str, prompt: str) -> bool:
"""
Deterministic Dual-Barrier Routing Simulator.
Models Host Agent embedding match:
1. Positive Intent Activation
2. Negative Guard Pruning
"""
p_lower = prompt.lower()
d_lower = description.lower()
# Stage 1: Negative Boundary Guard (Immediate Pruning)
negative_signals = [
"testcontainers", "postgresql", "database", "datajpatest",
"springboottest", "mockmvc", "cypress", "playwright", "end to end", "e2e"
]
for neg in negative_signals:
if neg in p_lower and "do not use when:" in d_lower:
return False
# Stage 2: Positive Intent Match
positive_signals = ["unit test", "mockk", "coevery", "isolated", "service", "domain"]
match_count = sum(1 for pos in positive_signals if pos in p_lower)
return match_count >= 1
def run_benchmark(dataset_path: Path, skill_path: Path) -> dict:
description = load_skill_description(skill_path)
test_cases = json.loads(dataset_path.read_text(encoding="utf-8"))
tp = fp = tn = fn = 0
failures = []
for tc in test_cases:
predicted = evaluate_semantic_routing(description, tc["prompt"])
expected = tc["expected_trigger"]
if predicted and expected:
tp += 1
elif predicted and not expected:
fp += 1
failures.append({"id": tc["id"], "type": "FALSE_POSITIVE", "prompt": tc["prompt"]})
elif not predicted and not expected:
tn += 1
elif not predicted and expected:
fn += 1
failures.append({"id": tc["id"], "type": "FALSE_NEGATIVE", "prompt": tc["prompt"]})
total = len(test_cases)
precision = (tp / (tp + fp)) * 100 if (tp + fp) > 0 else 0.0
recall = (tp / (tp + fn)) * 100 if (tp + fn) > 0 else 0.0
accuracy = ((tp + tn) / total) * 100 if total > 0 else 0.0
f1 = (2 * precision * recall) / (precision + recall) if (precision + recall) > 0 else 0.0
return {
"metrics": {
"total_cases": total,
"tp": tp, "fp": fp, "tn": tn, "fn": fn,
"precision": round(precision, 2),
"recall": round(recall, 2),
"accuracy": round(accuracy, 2),
"f1": round(f1, 2)
},
"failures": failures
}
def main():
root = Path(__file__).resolve().parent
dataset = root / "datasets" / "trigger-golden-suite.json"
skill = root.parent / "skills" / "spring-boot-unit-tester" / "SKILL.md"
if not dataset.exists() or not skill.exists():
sys.stderr.write(f"Error: Required paths missing. Dataset: {dataset.exists()}, Skill: {skill.exists()}\n")
sys.exit(1)
results = run_benchmark(dataset, skill)
m = results["metrics"]
print("================================================================================")
print("📊 DETERMINISTIC AGENT SKILL BENCHMARK REPORT (Day 11)")
print("================================================================================")
print(f"Total Test Cases: {m['total_cases']} | Accuracy: {m['accuracy']}% | F1-Score: {m['f1']}%")
print(f"Confusion Matrix: [TP: {m['tp']} | FP: {m['fp']} | TN: {m['tn']} | FN: {m['fn']}]")
print(f"Trigger Precision: {m['precision']}% (Threshold Gate: >= 95.0%)")
print(f"Trigger Recall: {m['recall']}% (Threshold Gate: >= 90.0%)")
print("--------------------------------------------------------------------------------")
passed = True
if m["precision"] < 95.0:
print(f"❌ REGRESSION GATE FAILED: Precision {m['precision']}% is below 95.0% threshold.")
passed = False
if m["recall"] < 90.0:
print(f"❌ REGRESSION GATE FAILED: Recall {m['recall']}% is below 90.0% threshold.")
passed = False
if results["failures"]:
print("\n🔍 FAILED EVALUATION TEST CASES:")
for f in results["failures"]:
print(f" - [{f['id']}] {f['type']}: '{f['prompt']}'")
if not passed:
print("\n🛑 PULL REQUEST REJECTED: Semantic trigger regressions detected.")
sys.exit(1)
print("\n🏆 ALL BENCHMARK GATES PASSED: Ready for enterprise distribution!")
sys.exit(0)
if __name__ == "__main__":
main()
name: Agent Skill Verification & Benchmark Gate
on:
pull_request:
paths:
- '.github/skills/**'
- '.github/evals/**'
jobs:
evaluate-skills:
name: Run Deterministic Benchmarks
runs-on: ubuntu-latest
steps:
- name: Checkout Code Repository
uses: actions/checkout@v4
- name: Setup Python 3.11 Runtime
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Execute Golden Benchmark Suite
run: |
python3 .github/evals/run-skill-evals.py
Enterprise Incident: The "Helpful" Description Trigger Regression
สถานการณ์จริงระดับองค์กร: วิศวกรคนหนึ่งพยายามปรับปรุงไฟล์ SKILL.md โดยแก้ฟิลด์ description ให้กว้างขึ้นและตัดส่วน DO NOT USE WHEN ออกเพราะคิดว่า "AI น่าจะฉลาดพอที่จะเดาเองได้" ส่งผลให้อัตรา False Positive พุ่งขึ้นสูงถึง 40% ตัว Unit Test Skill เริ่มแย่งงานของ Integration Test Skill และพยายามสร้าง Mock ทับ Database Testcontainers จริงของทีมจนระบบ CI พังทลาย
- จำลองการเปลี่ยนแปลงคำอธิบายที่อันตราย (Dangerous Broad Description) และรัน
run-skill-evals.pyเพื่อดูการตรวจจับความถดถอย (Regression Detection) - สังเกตผล Confusion Matrix ที่แสดงค่า Precision ตกต่ำลงเหลือ 60% ทำให้ระบบส่งคืน Exit Code 1 บล็อกการ Merge โค้ดใน CI อัตโนมัติ
- กู้คืน Dual-Barrier Guardrail ใน
SKILL.mdและพิสูจน์ว่า Benchmark ฟื้นคืนสู่ค่า Precision 100% (Exit Code 0)
$ python3 .github/evals/run-skill-evals.py
================================================================================
📊 DETERMINISTIC AGENT SKILL BENCHMARK REPORT (Day 11)
================================================================================
Total Test Cases: 6 | Accuracy: 66.67% | F1-Score: 75.0%
Confusion Matrix: [TP: 3 | FP: 2 | TN: 1 | FN: 0]
Trigger Precision: 60.0% (Threshold Gate: >= 95.0%)
Trigger Recall: 100.0% (Threshold Gate: >= 90.0%)
--------------------------------------------------------------------------------
❌ REGRESSION GATE FAILED: Precision 60.0% is below 95.0% threshold.
🔍 FAILED EVALUATION TEST CASES:
- [TRIG-002] FALSE_POSITIVE: 'Test PaymentGatewayClient using Testcontainers and real PostgreSQL database'
- [TRIG-004] FALSE_POSITIVE: 'Write @SpringBootTest integration tests with MockMvc for UserController'
🛑 PULL REQUEST REJECTED: Semantic trigger regressions detected.
$ echo $?
1
$ python3 .github/evals/run-skill-evals.py
================================================================================
📊 DETERMINISTIC AGENT SKILL BENCHMARK REPORT (Day 11)
================================================================================
Total Test Cases: 6 | Accuracy: 100.0% | F1-Score: 100.0%
Confusion Matrix: [TP: 3 | FP: 0 | TN: 3 | FN: 0]
Trigger Precision: 100.0% (Threshold Gate: >= 95.0%)
Trigger Recall: 100.0% (Threshold Gate: >= 90.0%)
--------------------------------------------------------------------------------
🏆 ALL BENCHMARK GATES PASSED: Ready for enterprise distribution!
$ echo $?
0
ทดสอบสถาปัตยกรรม Golden Benchmark Suites (Day 11)
ตอบคำถามเชิงสถาปัตยกรรมระดับ Benchmark ทั้ง 12 ข้อด้านล่าง ระบบจะตรวจคำตอบและให้ Feedback ทันทีเมื่อคลิกเลือกช้อยส์ พร้อมแสดงคำอธิบายเชิงลึก