Lompat ke konten
dokumentasi.id
Commit 51864a8
v1
Star1,9 rb

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

12

Pengujian dan Evaluasi

Halaman ini menjelaskan harness evals/ yang mengukur apakah Guardian membaik antar rilis, perubahan prompt agen, pembaruan knowledge base, dan penambahan wrapper tool. Harness itu dibagi menjadi tiga tier independen: fixture parser, integrasi workflow, dan grounding analyst. Semua skor dihasilkan oleh primitif di evals/scoring.py yang mengembalikan dataclass, bukan mencetak keluaran, sehingga hasilnya bisa diagregasi atau diserialisasi ke JSON oleh lapisan test. evals/scoring.py:1-11

graph TD
  IN["fixtures/<tool>/<case>.input.txt"] --> DF["discover_fixtures()"]
  EXP["fixtures/<tool>/<case>.expected.json"] --> DF
  DF --> FX["Fixture: id = tool::case"]
  FX --> TP["test_parser_fixture"]
  TP --> PT["BaseTool.parse_output"]
  PT --> AS["assert_subset()"]
  AS --> OK["lulus atau AssertionError berisi path"]
  CASE["EVAL_CASES (WorkflowEvalCase)"] --> TW["test_workflow_finds_expected"]
  TW --> SB["score_binary()"]
  SB --> BS["BinaryClassificationScore"]
  BS --> M1["precision / recall / f1"]
  J1["datasets/*.jsonl"] --> AG["test_analyst_grounding"]
  AG --> HS["score_hallucinations()"]
  HS --> M2["HallucinationScore: hallucination_rate"]
  AG --> CS["score_cost()"]
  CS --> M3["CostEfficiencyScore: cost_per_finding"]
  style OK fill:#2d7d46,color:#fff
  style M1 fill:#8b5cf6,color:#fff
  style M2 fill:#8b5cf6,color:#fff
  style M3 fill:#8b5cf6,color:#fff
  style CASE fill:#f59e0b,color:#000
  style J1 fill:#f59e0b,color:#000
  style TW fill:#dc2626,color:#fff
  style AG fill:#dc2626,color:#fff
%% fig: Alur fixture dan dataset sampai skor
%% desc: Fixture parser mengalir ke parse_output dan assert_subset, sedangkan tier workflow serta tier agent memakai scorer di evals/scoring.py untuk menghasilkan presisi, recall, F1, dan laju halusinasi.
Fig. 1: Alur fixture dan dataset sampai skorFixture parser mengalir ke parse_output dan assert_subset, sedangkan tier workflow serta tier agent memakai scorer di evals/scoring.py untuk menghasilkan presisi, recall, F1, dan laju halusinasi.

Tiga tingkat eval

TierYang diukurBiayaMarkerBerkas
Unit (Tier 1)kebenaran parse_output pada golden fixturegratisdefaultevals/test_parser_fixtures.py
Workflow (Tier 2)finding end-to-end terhadap aplikasi rentan ber-dockerdockerintegrationevals/test_workflow_integration.py
Agent (Tier 3)laju halusinasi, presisi/recall finding, validitas CVSS, biayatoken APIagent_evalevals/test_analyst_grounding.py

docs/EVAL_GUIDE.md:9-13

Tier 1: fixture parser

Satu fixture adalah pasangan berkas di subdirektori bersaudara: evals/fixtures/<tool_name>/<case_name>.input.txt berisi stdout mentah tool, dan evals/fixtures/<tool_name>/<case_name>.expected.json berisi dict hasil parse yang diharapkan. Menambah fixture untuk tool baru adalah jalur termurah untuk memperluas cakupan eval, karena tidak ada kode yang perlu diubah. evals/fixtures_loader.py:1-16

discover_fixtures menelusuri evals/fixtures/ dan mengembalikan setiap pasangan; pasangan yang kehilangan berkas expected.json dilewati. Setiap Fixture mengekspos id berbentuk f"{self.tool}::{self.case}" yang dipakai sebagai id parametrize. evals/fixtures_loader.py:28-61

Contohnya, evals/fixtures/nuclei/two_findings.expected.json hanya menuliskan kunci yang wajib cocok: vulnerabilities, count, dan by_severity. evals/fixtures/nuclei/two_findings.expected.json:1-8

Perbandingan dilakukan oleh assert_subset: setiap kunci di expected harus muncul di actual, list dibandingkan secara posisional, dict secara rekursif, dan nilai lain harus sama persis. Ketidakcocokan melempar AssertionError yang menyertakan path, misalnya f"{path}: actual list shorter ({len(actual)}) than expected ({len(expected)})". evals/fixtures_loader.py:64-91

test_parser_fixtures.py memanggil discover_fixtures() sekali saat import, lalu memparametrisasi test_parser_fixture atas seluruh fixture dengan ids=[f.id for f in _FIXTURES]. evals/test_parser_fixtures.py:23-42

Kelas tool diresolusi lewat TOOL_REGISTRY di core.tool_agent, dipisah pada : menjadi module dan class. Tool yang tidak terdaftar membuat test di-skip dengan pesan f"tool {tool_name} not in registry". Instans dibuat dengan tool_cls.__new__(tool_cls) dan tool.config = {}, karena parser tidak boleh bergantung pada config untuk membaca stdout-nya sendiri. evals/test_parser_fixtures.py:26-52

Tier 2: integrasi workflow

Setiap WorkflowEvalCase mendeklarasikan compose_file (fragmen docker-compose.yml), workflow (nama workflow Guardian), expected_findings (identifier yang wajib muncul), min_findings (batas bawah jumlah mentah), dan timeout_seconds dengan nilai default 600. evals/test_workflow_integration.py:30-38

EVAL_CASES saat ini memuat tiga seed case: dvwa_web_pentest dengan min_findings=3, juiceshop_web_full dengan min_findings=5, dan dvga_graphql dengan min_findings=2. evals/test_workflow_integration.py:44-66

Test ini memakai marker integration, memanggil pytest.importorskip("docker"), lalu pytest.skip dengan pesan bahwa scaffolding siap tetapi orkestrasi compose_file belum disambungkan. evals/test_workflow_integration.py:69-83

⚠️ Tier 2 dan Tier 3 tidak berjalan pada pemanggilan pytest biasa. Keduanya melewati diri sendiri lewat pytest.skip dan baru ikut berjalan ketika marker yang sesuai dipilih, misalnya pytest evals/ -m integration. evals/test_workflow_integration.py:69-83 evals/test_analyst_grounding.py:78-92

Tier 3: grounding analyst

test_analyst_grounding.py mengukur kualitas pertimbangan LLM, bukan kebenaran parsing tool. Setiap case memuat baris JSONL (tool_output, expected_findings) dari evals/datasets/ dan meminta analyst menafsirkannya. evals/test_analyst_grounding.py:1-24

_load_jsonl membaca berkas baris per baris, melewati baris kosong dan baris yang dimulai dengan //, serta melempar AssertionError(f"{path}:{line_no} bad JSON: {e}") ketika JSON tidak valid. _all_cases menggabungkan seluruh berkas *.jsonl di DATASETS_DIR secara terurut. evals/test_analyst_grounding.py:47-75

Dataset seed berisi empat record: tiga dari nuclei termasuk CVE-2021-44228 dan CVE-2017-5638, serta satu dari trivy dengan CVE-2022-3517. evals/datasets/analyst_grounding_seed.jsonl:1-4

test_analyst_grounding memakai marker agent_eval dan saat ini langsung pytest.skip("Agent-level eval pending OllamaProvider (item A4) for free CI runs."), sehingga belum ada panggilan API yang dibelanjakan. evals/test_analyst_grounding.py:78-92

Presisi, recall, dan F1

BinaryClassificationScore menyimpan true_positives, false_positives, dan false_negatives. Properti precision membagi true_positives dengan true_positives + false_positives, recall membagi dengan true_positives + false_negatives, dan f1 menghitung 2 * p * r / (p + r). Ketiga properti mengembalikan 0.0 ketika penyebutnya nol. evals/scoring.py:19-40

score_binary mengubah kedua sisi menjadi set lebih dahulu, sehingga duplikat tidak menggelembungkan skor; irisan menjadi true positive, selisih prediksi menjadi false positive, dan selisih ground truth menjadi false negative. evals/scoring.py:93-109

ScorerDataclassMetrikPerilaku sisi kosong
score_binaryBinaryClassificationScoreprecision, recall, f10.0
score_hallucinationsHallucinationScorehallucination_rate, grounding_rate0.0
score_costCostEfficiencyScorecost_per_findingfloat("inf")
—RankingScoretop1_accuracy, top3_accuracy0.0

evals/scoring.py:19-87

HallucinationScore melacak referensi CVE/CWE yang dikarang: grounded_refs adalah referensi yang ditemukan di KB atau keluaran tool, hallucinated_refs adalah sisanya, dan hallucination_rate membagi hallucinated_refs dengan total_refs. score_hallucinations menghitung jumlah referensi yang ada di grounded_set. evals/scoring.py:43-57 evals/scoring.py:112-123

CostEfficiencyScore menyimpan total_cost_usd dan valid_findings; cost_per_finding menjadi metrik utama untuk routing judge A7 dan mengembalikan float("inf") ketika tidak ada finding valid. evals/scoring.py:60-69 evals/scoring.py:126-133

RankingScore dipakai eval tool ranker A5 dengan membandingkan top-k ranker terhadap tool terbaik sebenarnya, melalui top1_accuracy dan top3_accuracy. evals/scoring.py:72-87

Scorer ini sederhana dengan sengaja; tujuannya adalah konsistensi antar eval, bukan implementasi metrik mutakhir. evals/scoring.py:8-11

Menjalankan pytest dan job CI

PerintahCakupan
pytest evals/tier unit saja
pytest evals/ -m integrationmenambah tier workflow
pytest evals/ -m agent_evalmenambah tier agent
pytest evals/ -m "integration or agent_eval"keduanya
pytest tests/ evals/semua yang gratis

docs/EVAL_GUIDE.md:17-23

Test unit di tests/ memakai fixture base_config dari tests/conftest.py, yaitu dict config minimal berisi scope, pentest, logging, dan output yang diterima validator maupun tool. evals/scoring.py:93-109 tests/conftest.py:10-22

Target make lint menjalankan ruff check . lalu black --check ., sedangkan make test menjalankan pytest. Makefile:67-79

Job CI lint-and-test berjalan pada matriks ubuntu-latest dan windows-latest dengan Python 3.11 dan 3.12, memasang pip install -e ".[dev]", lalu menjalankan ruff check ., black --check ., dan pytest -q. Karena tidak ada marker yang dipilih, CI hanya mencakup tier yang tidak di-skip. .github/workflows/ci.yml:12-42

Job kedua, secret-scan, menjalankan gitleaks/gitleaks-action@v2 dengan fetch-depth: 0 agar seluruh riwayat dapat diperiksa. .github/workflows/ci.yml:44-54

Acceptance gate per item

ItemGate
A1 (RAG)CVE-match rate ≥85% pada evals/datasets/kb_grounding.jsonl
A2 (Debate)F1 ≥ baseline single-agent + 5pp
A3 (Vision)≥75% deskripsi visual benar pada 20 case
A4 (Ollama)workflow recon selesai dan structured output valid
A5 (Ranker)Top-1 accuracy > baseline LLM
A7 (Judge)biaya ≤30% putaran ke-N pada kualitas setara
B-tierintegration test menghasilkan finding tidak kosong dan session JSON valid

docs/EVAL_GUIDE.md:69-79

Untuk menambah fixture cukup menaruh dua berkas di evals/fixtures/<tool>/<case>.{input.txt,expected.json}; untuk menambah case workflow, ubah EVAL_CASES; untuk menambah case agent, tambahkan baris ke evals/datasets/<name>.jsonl dan pastikan record tidak memuat IP, hostname, atau kredensial internal. docs/EVAL_GUIDE.md:25-61

Detail penggunaan workflow yang dijalankan oleh tier integrasi ada di Engine Workflow DSL v2, dan kontrak parser yang diuji tier unit dijelaskan di Integrasi Tool dan Pemilihan Tool.