#!/usr/bin/env python3 """ memory-governance.py — 记忆治理脚本(2026-08-12) 触发:每周日 03:00 cron(memory-governance cron) 功能: 1. 织忆低价值记忆标记(7天未recall + 重要性<0.3 → tombstone 候选) 2. 织忆去重(复用 /api/v1/consolidate/memory P2) 3. 生成治理报告(清理了什么,透明可审计) 4. 推送飞书报告 设计原则:只标记/报告,不硬删(防止误删重要记忆);MEMORY.md 压缩由会话内批量操作完成。 """ import json import urllib.request import subprocess import datetime import os import sys ZHIYI_URL = "http://localhost:7821" ZHIYI_KEY = "zhiyi-dev-key-2026" FEISHU_HOME = "oc_81f6df701c872a1122f32080e366543f" # AI创业核心群 def api_get(path): req = urllib.request.Request( f"{ZHIYI_URL}{path}", headers={"X-API-Key": ZHIYI_KEY}, ) try: with urllib.request.urlopen(req, timeout=15) as resp: return json.loads(resp.read()) except Exception as e: return {"error": str(e)} def api_post(path, body): data = json.dumps(body).encode() req = urllib.request.Request( f"{ZHIYI_URL}{path}", data=data, headers={"X-API-Key": ZHIYI_KEY, "Content-Type": "application/json"}, ) try: with urllib.request.urlopen(req, timeout=30) as resp: return json.loads(resp.read()) except Exception as e: return {"error": str(e)} def main(): report = [] now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M") # 1. 织忆健康画像 stats = api_get("/api/v1/stats") if not isinstance(stats, dict) or "error" in stats: report.append(f"❌ 织忆 stats 拉取失败: {stats if isinstance(stats, str) else stats.get('error')}") else: total = stats.get("total_memories", "?") report.append(f"📊 织忆现状: {total} 条记忆") # 2. 离线整合(去重 + 更新),limit 控制成本 cons = api_post("/api/v1/consolidate/memory", {"namespace": "hermes-main", "limit": 10}) if not isinstance(cons, dict) or "error" in cons: report.append(f"⚠️ consolidate 异常: {cons if isinstance(cons, str) else cons.get('error')}") else: report.append(f"🧹 去重整合: processed={cons.get('processed', 0)} updated={cons.get('updated', 0)} deleted={cons.get('deleted', 0)}") # 3. 淘汰候选(7天未recall + 低重要性)— 通过 recall 抽样判断 # 简化策略:拉最近记忆,标记低价值候选(数据层支持时启用) try: # 尝试拉记忆列表(如果 API 支持) mems = api_get("/api/v1/memories?limit=100") if isinstance(mems, dict) and "items" in mems: candidates = [] for m in mems.get("items", []): imp = m.get("computed_importance", 1.0) recall = m.get("recall_count", 0) if imp < 0.3 and recall == 0: candidates.append(m.get("id", "")[:12]) if candidates: report.append(f"🗑️ 淘汰候选(低价值未recall): {len(candidates)} 条 -> {candidates[:5]}") else: report.append("🗑️ 淘汰候选: 0 条(暂无低价值记忆)") else: report.append("🗑️ 淘汰候选: API 不支持列表查询,跳过(织忆自动管理)") except Exception as e: report.append(f"🗑️ 淘汰候选跳过: {e}") # 4. 输出报告 body = "\n".join(report) print(f"🧠 记忆治理报告 {now}\n" + body) # 5. 推送飞书(通过 hermes send_message 或直接脚本) # 用 feishu webhook 简单推送(如果配置了)或由 cron 自动投递 # cron no_agent 模式下 stdout 即投递内容 if __name__ == "__main__": main()