fix: wrap diagnosis run_log with StepsJsonRunLog (restore algo #7 traces)
This commit is contained in:
@@ -2168,13 +2168,15 @@ class Runner:
|
|||||||
self, run_id: str, *, question_ids: list[str] | None = None
|
self, run_id: str, *, question_ids: list[str] | None = None
|
||||||
) -> DiagnosisResult:
|
) -> DiagnosisResult:
|
||||||
"""执行两阶段诊断。"""
|
"""执行两阶段诊断。"""
|
||||||
|
from app.harness.baseline_run_log import StepsJsonRunLog
|
||||||
from app.harness.log import RunLogImpl
|
from app.harness.log import RunLogImpl
|
||||||
from app.harness.workspace import VersionedSkillStore
|
from app.harness.workspace import VersionedSkillStore
|
||||||
from app.question_gen import load_benchmark
|
from app.question_gen import load_benchmark
|
||||||
from core.evolution.diagnose import run_diagnosis
|
from core.evolution.diagnose import run_diagnosis
|
||||||
|
|
||||||
questions = load_benchmark(self._paths.questions_dir)
|
questions = load_benchmark(self._paths.questions_dir)
|
||||||
run_log = RunLogImpl(str(self._paths.db_path))
|
# traces 表空时(如训练 rollout 只落 steps_json)从 steps_json 重建轨迹,恢复算法 #7
|
||||||
|
run_log = StepsJsonRunLog(RunLogImpl(str(self._paths.db_path)))
|
||||||
skill_store = VersionedSkillStore(self._paths.skills_dir)
|
skill_store = VersionedSkillStore(self._paths.skills_dir)
|
||||||
diagnose_prompts = self._load_diagnose_prompts()
|
diagnose_prompts = self._load_diagnose_prompts()
|
||||||
|
|
||||||
|
|||||||
@@ -147,6 +147,70 @@ def _fake_question(question_id: str, video_id: str) -> object:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_diagnosis_reads_traces_from_steps_json(
|
||||||
|
runner_with_real_store: Runner,
|
||||||
|
) -> None:
|
||||||
|
"""traces 表为空但 predictions.steps_json 有轨迹时,诊断仍拿到非空 traces。
|
||||||
|
|
||||||
|
构造一条只写 steps_json、不写 traces 表的 predictions 行;patch run_diagnosis
|
||||||
|
捕获传入的 run_log,直接 await 其 get_traces 断言经 StepsJsonRunLog 从
|
||||||
|
steps_json 重建出非空轨迹(算法 #7 恢复)。
|
||||||
|
"""
|
||||||
|
from app.harness.inference import PREDICTIONS_SCHEMA
|
||||||
|
from app.harness.log import HarnessLog
|
||||||
|
|
||||||
|
steps_json = json.dumps(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"thought": "先看整体",
|
||||||
|
"tool_call": {"tool": "search_tree", "args": {"query": "开场"}},
|
||||||
|
"tool_output": "命中 L2 节点 A",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
ensure_ascii=False,
|
||||||
|
)
|
||||||
|
with HarnessLog(str(runner_with_real_store._paths.db_path), "infer_adhoc") as log:
|
||||||
|
log.create_table("predictions", PREDICTIONS_SCHEMA)
|
||||||
|
log.create_table("traces", {"video_id": "TEXT", "question_id": "TEXT", "step": "INTEGER"})
|
||||||
|
log.insert(
|
||||||
|
"predictions",
|
||||||
|
{
|
||||||
|
"video_id": _REAL_VIDEO_ID,
|
||||||
|
"question_id": _REAL_QUESTION_ID,
|
||||||
|
"task_type": "Action Reasoning",
|
||||||
|
"prediction": "A",
|
||||||
|
"answer": "B",
|
||||||
|
"evidence": "",
|
||||||
|
"reasoning": "",
|
||||||
|
"steps_used": 1,
|
||||||
|
"prompt_tokens": 0,
|
||||||
|
"completion_tokens": 0,
|
||||||
|
"stop_reason": "finished",
|
||||||
|
"steps_json": steps_json,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
captured: dict[str, object] = {}
|
||||||
|
|
||||||
|
async def _fake_run_diagnosis(**kwargs: object) -> DiagnosisResult:
|
||||||
|
captured["run_log"] = kwargs["run_log"]
|
||||||
|
return _empty_diagnosis_result()
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"core.evolution.diagnose.run_diagnosis",
|
||||||
|
new=AsyncMock(side_effect=_fake_run_diagnosis),
|
||||||
|
):
|
||||||
|
await runner_with_real_store._run_diagnosis(
|
||||||
|
"infer_adhoc", question_ids=[_REAL_QUESTION_ID]
|
||||||
|
)
|
||||||
|
|
||||||
|
run_log = captured["run_log"]
|
||||||
|
traces = await run_log.get_traces("infer_adhoc", question_ids=[_REAL_QUESTION_ID])
|
||||||
|
assert traces, "traces 表空时应从 steps_json 重建出非空轨迹"
|
||||||
|
assert traces[0]["tool_name"] == "search_tree"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_run_diagnosis_full_scan_loads_all_video_trees(
|
async def test_run_diagnosis_full_scan_loads_all_video_trees(
|
||||||
runner_with_real_store: Runner,
|
runner_with_real_store: Runner,
|
||||||
|
|||||||
Reference in New Issue
Block a user