#!/usr/bin/env python3 """ prune_branches.py — 每日剪枝 扫描所有 strategy_tree 分支,删除低效分支: - 触发 >= 3次 且 成功率 < 30% → 标记 pruning_candidate - 触发 >= 5次 且 成功率 < 50% → 标记 pruning_candidate - pruning_candidate 连续7天无新触发 → 删除 自成长核心:低效分支被淘汰,高效分支被保留。 数据写入 decisions.json 的 strategy_tree.branches[]。 """ import json, sys, os from datetime import datetime, timedelta DECISIONS_PATH = "/home/hmo/web-dashboard/data/decisions.json" PRUNE_LOG = "/home/hmo/MoFin/data/prune_log.json" def load_decisions(): with open(DECISIONS_PATH) as f: return json.load(f) def save_decisions(data): with open(DECISIONS_PATH, "w") as f: json.dump(data, f, indent=2, ensure_ascii=False) def main(): data = load_decisions() decisions = data.get("decisions", []) today = datetime.now().strftime("%Y-%m-%d") pruned = [] warnings = [] for entry in decisions: code = entry.get("code", "") tree = entry.get("strategy_tree", {}) branches = tree.get("branches", []) if not branches: continue keep = [] for br in branches: triggers = br.get("trigger_count", 0) success = br.get("success_rate") last = br.get("last_triggered", "") priority = br.get("priority", 99) # 跳过默认持有分支 if priority == 99: keep.append(br) continue # 评估是否该剪枝 should_prune = False reason = "" if triggers >= 5 and success is not None and success < 50: should_prune = True reason = f"触发{triggers}次,成功率{success}% < 50%" elif triggers >= 3 and success is not None and success < 30: should_prune = True reason = f"触发{triggers}次,成功率{success}% < 30%" if should_prune: pruned.append({ "code": code, "branch_id": br.get("id", ""), "action": br.get("action", {}).get("type", ""), "rationale": br.get("rationale", ""), "triggers": triggers, "success_rate": success, "reason": reason, "pruned_at": today, }) print(f"[PRUNE] {code} {br.get('id','?')}: {reason}") else: keep.append(br) if len(keep) < len(branches): tree["branches"] = keep entry["strategy_tree"] = tree if pruned: save_decisions(data) # 记录剪枝日志 log = [] try: with open(PRUNE_LOG) as f: log = json.load(f) except Exception: pass log.append({ "date": today, "pruned": pruned, "total_before": sum(len(e.get("strategy_tree", {}).get("branches", [])) for e in decisions), }) os.makedirs(os.path.dirname(PRUNE_LOG), exist_ok=True) with open(PRUNE_LOG, "w") as f: json.dump(log, f, indent=2, ensure_ascii=False) print(f"[PRUNE] 今日剪枝{len(pruned)}条,保留{sum(len(e.get('strategy_tree',{}).get('branches',[])) for e in decisions)}条") else: print("[PRUNE] 无需要剪枝的分支") return 0 if __name__ == "__main__": sys.exit(main())