xiaowei-system/scripts/memory-governance.py

97 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
memory-governance.py — 记忆治理脚本2026-08-12
触发:每周日 03:00 cronmemory-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()