offer-catcher-agent-v2 / scripts /debug_stress_v3.py
hungryb's picture
v2: agent report + filtered corpus + evidence contract
54b5b64 verified
Raw
History Blame Contribute Delete
4.52 kB
#!/usr/bin/env python3
"""debug_stress_v3.py - 详细打印每个 stress case 的中间状态"""
import json
import sys
from pathlib import Path
# 把项目根目录加入 sys.path,使 import src.xxx 能工作
ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(ROOT))
from src.resume_parser import parse_resume
from src.matcher import rank_jobs
from src.conversion import attach_conversion_scores
from src.strategy_planner import gen_strategy_package, _infer_action
EVAL_PATH = ROOT / "eval" / "golden_cases.json"
def main():
cases = json.loads(EVAL_PATH.read_text(encoding="utf-8"))
stress_cases = [c for c in cases if c.get("eval_split") == "stress"]
print(f"Total cases: {len(cases)}")
print(f"Stress cases: {len(stress_cases)}\n")
for case in stress_cases:
cid = case["case_id"]
print(f"{'='*60}")
print(f"CASE: {cid}")
print(f"{'='*60}")
resume_text = case["resume_text"]
target_role = case.get("target_role", "")
target_city = case.get("target_city", "")
stage = case.get("stage", "")
# 1. 解析简历
profile = parse_resume(resume_text)
profile["_city"] = target_city
profile["_stage"] = stage
profile["_target_role"] = target_role
print(f"\n[PROFILE]")
print(f" _target_role: {profile.get('_target_role')}")
print(f" _city: {profile.get('_city')}")
print(f" _stage: {profile.get('_stage')}")
print(f" has_llm_project: {profile.get('has_llm_project')}")
print(f" has_metrics: {profile.get('has_metrics')}")
print(f" has_rec_project: {profile.get('has_rec_project')}")
print(f" skills count: {len(profile.get('skills', []))}")
print(f" skills (first 10): {profile.get('skills', [])[:10]}")
# 2. 计算 match + conversion 分数
scored = rank_jobs(
resume_text=resume_text,
profile=profile,
target_role=target_role,
target_city=target_city,
stage=stage,
top_k=8,
jobs_path=ROOT / "data" / "jobs.json",
)
# 3. 打印 top3 的详细分数
pkg = gen_strategy_package(scored, profile)
top3 = pkg.get("priority_top3", [])
print(f"\n[TOP3 JOBS]")
for i, t in enumerate(top3):
print(f" Top{i+1}: {t['title']}")
print(f" direction: {t.get('direction')}")
print(f" pass_score: {t.get('pass_score')}")
print(f" risk_score: {t.get('risk_score')}")
print(f" growth_score: {t.get('growth_score')}")
print(f" match_score: {t.get('match_score')}")
print(f" apply_priority: {t.get('apply_priority')}")
print(f" missing_skills: {t.get('missing_skills')}")
print(f" apply_action: {t.get('apply_action')}")
# 4. 对比 expected_action
if top3:
actual_action = top3[0]["apply_action"]
expected_action = case.get("expected_action", "")
match = "OK" if actual_action == expected_action else "MISMATCH"
print(f"\n[ACTION COMPARE]")
print(f" expected: {expected_action}")
print(f" actual: {actual_action}")
print(f" result: {match}")
# 5. 打印 _infer_action 的决策依据
print(f"\n[DECISION DETAIL] (top1 job)")
job = top3[0]
pass_s = job.get("pass_score", 50)
risk_s = job.get("risk_score", 50)
growth_s = job.get("growth_score", 50)
missing = job.get("missing_skills", [])
missing_count = len(missing) if isinstance(missing, list) else 0
has_llm = bool(profile.get("has_llm_project", False))
has_met = bool(profile.get("has_metrics", False))
has_rec = bool(profile.get("has_rec_project", False))
is_grad = "已毕业" in str(profile.get("_stage", "")) or "2025" in str(profile.get("_stage", ""))
print(f" pass={pass_s}, risk={risk_s}, growth={growth_s}")
print(f" missing_count={missing_count}")
print(f" has_llm={has_llm}, has_metrics={has_met}, has_rec={has_rec}")
print(f" is_graduated={is_grad}")
print(f" direction_match={profile.get('_target_role') in job.get('direction', '') or job.get('direction', '') in profile.get('_target_role', '')}")
print()
if __name__ == "__main__":
main()