Skip to content

Commit 6b7fb0d

Browse files
committed
fix(eval_optimize_loop): address AI review round 9 — 2 critical + 6 warning
Critical: - optimizer: cumulative multi-iteration (each iteration now uses previous prompt_after as prompt_before, not the original BASE_PROMPTS every time) - baseline real mode image_id hash: ACK, docstring already marks PLACEHOLDER Warnings: - run_pipeline: remove unused import time and redundant sys import - auditor: add None guard in save() baseline dict comprehension - gate/attribution: extract PASS_THRESHOLD constant (0.6) from fake_judge, share across gate._check_no_new_hard_fail and attribution judge checks - _pid_alive ctypes: already fixed in round 6, no change needed - candidate_train_scores simulated: already documented Suggestion: - validator: warn on unknown failure_category fallback in CANDIDATE_PREDICTIONS
1 parent 7781aac commit 6b7fb0d

7 files changed

Lines changed: 23 additions & 11 deletions

File tree

examples/optimization/eval_optimize_loop/fake/fake_judge.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ class JudgeResult:
3737
failure_reason: str = ""
3838

3939

40+
# Shared threshold: gate _check_no_new_hard_fail and attribution judge checks
41+
# use the same value as FakeJudge.passed threshold.
42+
PASS_THRESHOLD = 0.6
43+
4044
class FakeJudge:
4145
"""基于规则的假 Judge。
4246

examples/optimization/eval_optimize_loop/run_pipeline.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
python run_pipeline.py --quiet # minimal output
88
"""
99

10-
import argparse, asyncio, json, os as _os, sys, time
10+
import argparse, asyncio, json, os as _os, sys
1111
from pathlib import Path
1212
from datetime import datetime, timezone
1313

@@ -35,7 +35,6 @@ def _read_critical_case_ids(val_path: Path) -> list[str]:
3535
data = json.load(f)
3636
return [c["case_id"] for c in data.get("cases", []) if c.get("critical", False)]
3737
except Exception as e:
38-
import sys as _sys
3938
print(f"Warning: cannot read critical case ids from {val_path}: {e}", file=_sys.stderr)
4039
return [] # empty: skip critical-case gate rather than guess wrong id
4140

examples/optimization/eval_optimize_loop/src/attribution.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from typing import Optional
1313

1414
from src.baseline import BaselineResult, BaselineCaseResult
15+
from fake.fake_judge import PASS_THRESHOLD
1516

1617

1718
@dataclass
@@ -189,13 +190,13 @@ def _attribute_case(
189190
evidence.append(f"human_review with low conf={conf_val}")
190191

191192
# Rule 3: Judge scores
192-
if case.judge_recognition >= 0 and case.judge_recognition < 0.6:
193+
if case.judge_recognition >= 0 and case.judge_recognition < PASS_THRESHOLD:
193194
candidates.append(("llm_rubric_fail", 0.80))
194195
evidence.append(f"judge_recognition={case.judge_recognition:.2f} < 0.6")
195-
if case.judge_blacklist >= 0 and case.judge_blacklist < 0.6:
196+
if case.judge_blacklist >= 0 and case.judge_blacklist < PASS_THRESHOLD:
196197
candidates.append(("knowledge_recall_insufficient", 0.75))
197198
evidence.append(f"judge_blacklist={case.judge_blacklist:.2f} < 0.6")
198-
if case.judge_response >= 0 and case.judge_response < 0.6:
199+
if case.judge_response >= 0 and case.judge_response < PASS_THRESHOLD:
199200
candidates.append(("llm_rubric_fail", 0.65))
200201
evidence.append(f"judge_response={case.judge_response:.2f} < 0.6")
201202

examples/optimization/eval_optimize_loop/src/auditor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def save(self, audit_trail, baseline, attribution, optimization, validation=None
3939
ts_dir = audit_trail.run_id
4040
audit_path = self.output_dir / "audit" / ts_dir
4141
audit_path.mkdir(parents=True, exist_ok=True)
42-
full = {"audit_trail":audit_trail.to_dict(),"baseline":{k:v.to_dict() for k,v in baseline.items()},"attribution":attribution.to_dict(),"optimization":optimization.to_dict()}
42+
full = {"audit_trail":audit_trail.to_dict(),"baseline":{k:v.to_dict() if v else {} for k,v in baseline.items()}},"attribution":attribution.to_dict(),"optimization":optimization.to_dict()}
4343
if validation: full["validation"] = validation.to_dict()
4444
if gate_decision: full["gate_decision"] = gate_decision
4545
with open(audit_path/"optimization_report.json","w",encoding="utf-8") as f:

examples/optimization/eval_optimize_loop/src/gate.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from dataclasses import dataclass, field
99
from pathlib import Path
1010
from typing import Optional
11+
from fake.fake_judge import PASS_THRESHOLD
12+
1113

1214

1315
@dataclass
@@ -149,8 +151,8 @@ def _check_no_new_hard_fail(
149151
candidate: dict[str, float],
150152
) -> GateCheck:
151153
max_new = self.rules["no_new_hard_fail"].get("max_new_fails", 0)
152-
base_fails = sum(1 for s in baseline.values() if s < 0.6)
153-
cand_fails = sum(1 for s in candidate.values() if s < 0.6)
154+
base_fails = sum(1 for s in baseline.values() if s < PASS_THRESHOLD)
155+
cand_fails = sum(1 for s in candidate.values() if s < PASS_THRESHOLD)
154156
new_fails = max(0, cand_fails - base_fails)
155157
passed = new_fails <= max_new
156158
return GateCheck(

examples/optimization/eval_optimize_loop/src/optimizer.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,13 @@ def optimize(
224224
prompt_type = target["prompt_target"]
225225
confidence = target["confidence"]
226226

227-
# ???????
228-
prompt_before = self._get_base_prompt(prompt_type)
227+
# prompt_before: use previous iteration's result for cumulative optimization
228+
if candidates:
229+
prompt_before = candidates[-1].prompt_after
230+
else:
231+
prompt_before = self._get_base_prompt(prompt_type)
229232

230-
# ???????
233+
# generate optimization append
231234
prompt_after, change_log = self._generate_optimization(
232235
prompt_type, category, prompt_before, confidence
233236
)

examples/optimization/eval_optimize_loop/src/validator.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ def run(self, val_baseline, optimization_result, simulate_regression=False):
6868
return self._run_real(val_baseline, candidate)
6969

7070
def _run_fake(self, val_baseline, candidate, simulate_regression=False):
71+
if candidate.failure_category not in CANDIDATE_PREDICTIONS:
72+
import warnings
73+
warnings.warn(f"Unknown failure_category '{candidate.failure_category}', falling back to final_answer_mismatch")
7174
pred_map = REGRESSION_PREDICTIONS if simulate_regression else CANDIDATE_PREDICTIONS.get(
7275
candidate.failure_category, CANDIDATE_PREDICTIONS["final_answer_mismatch"])
7376
deltas = []

0 commit comments

Comments
 (0)