fix: dedup three-bucket projection + honest C3 error-handling note

This commit is contained in:
2026-07-15 12:29:58 -04:00
parent aa10485b9f
commit 84b0b30213
2 changed files with 159 additions and 51 deletions
+91 -1
View File
@@ -1,8 +1,11 @@
"""离线诊断编排集成测试(LLM 类:MD 产出到 tests/outputs/)。
用 fake run_diagnosis + fake deps 覆盖编排契约,不实际调 LLM/VLM:
1. 续跑幂等 —— 已落盘题跳过第二次无剩余则 run_diagnosis 收到空列表。
1. 续跑幂等 —— 已落盘题跳过第二次 remaining 为空则直接早返回、不调用
run_diagnosis。
2. 投影正确 —— defect→T2、lapse→T1evolution_target 由 error_type 派生。
3. 三桶去重 —— 同题同时在 degraded 与 attributions 时按 degraded>infra>
attribution 优先级只落 1 行、tier=uncertain。
测试结束把编排过程(remaining、各 tier 计数、投影样例)写入
tests/outputs/test_baseline_diagnosis/<test>_<固定 ts>.mdCLAUDE.md §4.6)。
@@ -262,3 +265,90 @@ async def test_infra_and_degraded_projection(tmp_path, monkeypatch):
)
assert md_path.exists()
store.close()
@pytest.mark.asyncio
async def test_degraded_overrides_attribution(tmp_path, monkeypatch):
"""三桶去重:同题同时在 degraded 与 attributions 时只落 1 行且 tier=uncertain。
judge 解析失败会生成 degraded metrics,若仍是错题还会建 attribution
故同一 question_id 可同时出现在两桶。按 degraded>infra>attribution 优先级,
该题必须只落 1 行、tier=uncertaindegraded 置位),attribution 行被跳过。
"""
calls: list[tuple[str, ...]] = []
async def fake_run_diagnosis(
run_id,
questions,
tree_data,
llm,
run_log,
skill_store,
prompts,
*,
concurrency,
question_ids=None,
task_types=None,
only_incorrect=False,
):
calls.append(tuple(question_ids or []))
from core.evolution.types import DiagnosisResult, ErrorAttribution
# q5 同时出现在 attributionsjudge 解析失败仍建归因)与 degraded_question_ids。
return DiagnosisResult(
run_id=run_id,
error_attributions=[ErrorAttribution("q5", "reasoning_failure", None, "defect")],
infra_question_ids=[],
degraded_question_ids=["q5"],
)
monkeypatch.setattr("app.harness.baseline_diagnosis.run_diagnosis", fake_run_diagnosis)
deps = DiagnosisDeps(
run_log=_FakeRunLog(),
llm=_FakeLLM(),
skill_store=_FakeSkillStore(),
prompts=object(),
tree_data={},
concurrency=2,
)
store = SqliteDiagnosisSignalStore(str(tmp_path / "h.db"))
q_by_id = {"q5": _mk_q("q5")}
await run_baseline_diagnosis(
baseline_run_id="infer_adhoc",
diag_fingerprint="fp",
wrong_ids=["q5"],
questions=q_by_id,
store=store,
deps=deps,
)
all_rows = store.load("infer_adhoc", "fp")
assert len(all_rows) == 1 # 只落 1 行(无同 PK 双写)
row = all_rows[0]
assert row.question_id == "q5"
assert row.tier == "uncertain" # degraded 优先级最高
assert row.degraded is True
assert row.error_type is None # 走 degraded 投影而非 attribution
assert row.evolution_target is None
md_path = _write_md(
"test_degraded_overrides_attribution",
[
"# 离线诊断编排:三桶优先级去重",
"",
"## 任务描述",
"q5 同时出现在 error_attributionsdefect)与 degraded_question_ids"
"验证按 degraded>infra>attribution 优先级只落 1 行。",
"",
"## 落库结果",
"| question_id | 落库行数 | tier | degraded | error_type |",
"|---|---|---|---|---|",
f"| q5 | {len(all_rows)} | {row.tier} | {row.degraded} | {row.error_type} |",
"",
"## 结论",
"degraded 优先级最高,attribution 行被跳过 → 每题恰写一行、counts 恰计一次。",
],
)
assert md_path.exists()
store.close()