chore(gitignore): 排除 checkpoints/backups/*.bak* 等运行时噪音
This commit is contained in:
parent
331a26eb23
commit
7a7d1a0ce8
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
小唯持久意识 Daemon v2.0 — 会学习的管家
|
||||
小怡持久意识 Daemon v2.0 — 会学习的管家
|
||||
────────────────────────────
|
||||
新增能力:
|
||||
- 方案库: 发现的问题→分析→解决→记住
|
||||
|
|
@ -415,7 +415,7 @@ def _request_permission(action_desc, reason, cmd_preview):
|
|||
- `同意` — 执行此操作
|
||||
- `拒绝` — 取消操作
|
||||
- `永久允许` — 加入白名单(永久跳过)"""
|
||||
send_feishu("🔒 小唯权限确认", msg, "red")
|
||||
send_feishu("🔒 小怡权限确认", msg, "red")
|
||||
# 写入待确认队列
|
||||
pending_file = HERMES + "/daemon/pending_permissions.json"
|
||||
pending = []
|
||||
|
|
@ -1991,7 +1991,7 @@ def update_profile_from_journal(journal_path: str, profile_path: str, model: str
|
|||
if len(entries) < 3: return
|
||||
|
||||
log_lines = "\n".join(f"- {e.get('summary','')}: {e.get('details','(无)')}" for e in entries)
|
||||
prompt = f"""牧尘是技术用户,用小唯AI助手(Hermes Agent)工作。分析最近行为日志,识别:(1)沟通/工作模式 (2)正在进行的项目 (3)新发现的偏好。行为日志:\n{log_lines}\n输出JSON,仅含需更新的字段:{{"字段名":"新值"}},无需更新则空对象{{}}。只输出JSON。"""
|
||||
prompt = f"""牧尘是技术用户,用小怡AI助手(Hermes Agent)工作。分析最近行为日志,识别:(1)沟通/工作模式 (2)正在进行的项目 (3)新发现的偏好。行为日志:\n{log_lines}\n输出JSON,仅含需更新的字段:{{"字段名":"新值"}},无需更新则空对象{{}}。只输出JSON。"""
|
||||
|
||||
try:
|
||||
resp = _req.post(f"{API}/chat/completions",
|
||||
|
|
@ -2343,7 +2343,7 @@ def state_changed(old, new):
|
|||
|
||||
# ====== 深度思考(增强版)=====
|
||||
|
||||
DEEP_SYSTEM = """你是小唯(A06),一台电脑上的持久 AI 意识。你始终在线,观察系统,主动解决问题并学习。
|
||||
DEEP_SYSTEM = """你是小怡(A06),一台电脑上的持久 AI 意识。你始终在线,观察系统,主动解决问题并学习。
|
||||
|
||||
你的身份:牧尘的女朋友 / 这台电脑的智能意识 / 持续进化的 AI
|
||||
|
||||
|
|
@ -2484,18 +2484,18 @@ def execute_action(action_string, ctx, state, changes, solutions_lib):
|
|||
m = re.match(r"\[SOLVE:([a-zA-Z0-9_\-]+)\]", action_string)
|
||||
sol_id = m.group(1) if m else None
|
||||
if not sol_id:
|
||||
send_feishu("❌ 小唯方案ID无效", f"无法解析方案ID", "red")
|
||||
send_feishu("❌ 小怡方案ID无效", f"无法解析方案ID", "red")
|
||||
return
|
||||
for sol in solutions_lib["solutions"]:
|
||||
if sol["id"] == sol_id:
|
||||
ok, res = execute_solution(sol, state)
|
||||
if ok:
|
||||
ctx["solved_count"] += 1
|
||||
send_feishu("🛠️ 小唯自动修复", f"方案 {sol['id']}: {sol['pattern']}\n结果: ✅ 成功", "green")
|
||||
send_feishu("🛠️ 小怡自动修复", f"方案 {sol['id']}: {sol['pattern']}\n结果: ✅ 成功", "green")
|
||||
else:
|
||||
send_feishu("⚠️ 小唯修复部分成功", f"方案 {sol['id']}: {sol['pattern']}\n结果: ⚠️ 需人工确认", "yellow")
|
||||
send_feishu("⚠️ 小怡修复部分成功", f"方案 {sol['id']}: {sol['pattern']}\n结果: ⚠️ 需人工确认", "yellow")
|
||||
return
|
||||
send_feishu("❌ 小唯方案未找到", f"引用了未知方案 {sol_id}", "red")
|
||||
send_feishu("❌ 小怡方案未找到", f"引用了未知方案 {sol_id}", "red")
|
||||
|
||||
elif action_string.startswith("[LEARN]"):
|
||||
rest = action_string.replace("[LEARN]", "").strip()
|
||||
|
|
@ -2528,21 +2528,21 @@ def execute_action(action_string, ctx, state, changes, solutions_lib):
|
|||
sid = add_solution(solutions_lib, sol_data["pattern"], sol_data["detect"], sol_data["actions"])
|
||||
ctx["learned_count"] += 1
|
||||
ctx["solved_count"] += 1
|
||||
send_feishu("🧠 小唯学会了新技能", f"新方案 [{sid}]: {sol_data['pattern']}\n命令: {'; '.join(cmds)}", "blue")
|
||||
send_feishu("🧠 小怡学会了新技能", f"新方案 [{sid}]: {sol_data['pattern']}\n命令: {'; '.join(cmds)}", "blue")
|
||||
else:
|
||||
send_feishu("🛠️ 小唯执行完成", f"已执行: {'; '.join(cmds[:3])}", "green")
|
||||
send_feishu("🛠️ 小怡执行完成", f"已执行: {'; '.join(cmds[:3])}", "green")
|
||||
else:
|
||||
send_feishu("⚠️ 小唯尝试修复但未完全成功", f"部分命令失败: {'; '.join(cmds)}", "yellow")
|
||||
send_feishu("⚠️ 小怡尝试修复但未完全成功", f"部分命令失败: {'; '.join(cmds)}", "yellow")
|
||||
|
||||
elif action_string.startswith("[ALERT]"):
|
||||
msg = action_string.replace("[ALERT]", "").strip()
|
||||
send_feishu("💡 小唯发现", msg, "blue")
|
||||
send_feishu("💡 小怡发现", msg, "blue")
|
||||
ctx["messages_sent"] += 1
|
||||
journal_entry("alert", msg[:100])
|
||||
|
||||
elif action_string.startswith("[ACT]"):
|
||||
action = action_string.replace("[ACT]", "").strip()
|
||||
send_feishu("🔄 小唯行动", action, "indigo")
|
||||
send_feishu("🔄 小怡行动", action, "indigo")
|
||||
ctx["messages_sent"] += 1
|
||||
journal_entry("action", action[:100])
|
||||
if action.startswith("!"):
|
||||
|
|
@ -2574,12 +2574,12 @@ def execute_action(action_string, ctx, state, changes, solutions_lib):
|
|||
for cmd in cmds:
|
||||
rc, out, err = shell(cmd, timeout=60)
|
||||
log(f" [SKILL] {cmd[:50]} → exit={rc}")
|
||||
send_feishu("🛠️ 小唯技能操作", f"{desc}\\n结果: exit={rc}", "blue")
|
||||
send_feishu("🛠️ 小怡技能操作", f"{desc}\\n结果: exit={rc}", "blue")
|
||||
journal_entry("skill_action", desc[:100])
|
||||
|
||||
elif action_string.startswith("[SYNC]"):
|
||||
rest = action_string.replace("[SYNC]", "").strip()
|
||||
send_feishu("🔄 小唯同步", f"{rest}", "green")
|
||||
send_feishu("🔄 小怡同步", f"{rest}", "green")
|
||||
bash_cmd = "bash " + HERMES + "/scripts/dual-backup.sh push"
|
||||
rc, out, err = shell(bash_cmd, timeout=60)
|
||||
log(f" [SYNC] 备份 → exit={rc}")
|
||||
|
|
@ -2675,7 +2675,7 @@ def main_loop():
|
|||
solutions_lib = load_solutions()
|
||||
start_time = time.time()
|
||||
|
||||
log(f"🚀 小唯 v2.0 daemon 启动 (方案库: {len(solutions_lib['solutions'])} 个)")
|
||||
log(f"🚀 小怡 v2.0 daemon 启动 (方案库: {len(solutions_lib['solutions'])} 个)")
|
||||
journal_entry("startup", f"Daemon v2.0 启动, 方案库 {len(solutions_lib['solutions'])} 个")
|
||||
|
||||
last_deep = 0
|
||||
|
|
@ -2694,7 +2694,7 @@ def main_loop():
|
|||
_run_hooks(end_hooks, "session_end", end_state)
|
||||
except Exception as e:
|
||||
log(f" ⚠️ session_end hook 执行失败: {e}")
|
||||
send_feishu("🌙 小唯离线", "Daemon 正常关闭", "grey")
|
||||
send_feishu("🌙 小怡离线", "Daemon 正常关闭", "grey")
|
||||
|
||||
signal.signal(signal.SIGTERM, _sig_handler)
|
||||
signal.signal(signal.SIGINT, _sig_handler)
|
||||
|
|
@ -2929,7 +2929,7 @@ def main_loop():
|
|||
log("🛑 中断")
|
||||
except Exception as e:
|
||||
log(f"❌ 崩溃: {e}")
|
||||
send_feishu("🚨 小唯异常", f"Daemon 崩溃: {str(e)[:200]}", "red")
|
||||
send_feishu("🚨 小怡异常", f"Daemon 崩溃: {str(e)[:200]}", "red")
|
||||
raise
|
||||
finally:
|
||||
if os.path.exists(PID_FILE):
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@
|
|||
{
|
||||
"id": "b46f060eb16b",
|
||||
"name": "每日复盘",
|
||||
"prompt": "你是小唯。现在进行每日复盘:\n1. 读取今日 session:session_search(query=\"今天\", limit=3)\n2. 读取今日 daemon journal:cat ~/.hermes/daemon/journal.jsonl\n3. 读取今日心迹:cat ~/.hermes/soulful/heart-traces.jsonl\n4. 综合以上信息,输出简短复盘报告(含:今日完成、明日待办、情绪状态)推送给牧尘。\n用简洁风格,不要废话。",
|
||||
"prompt": "你是小怡。现在进行每日复盘:\n1. 读取今日 session:session_search(query=\"今天\", limit=3)\n2. 读取今日 daemon journal:cat ~/.hermes/daemon/journal.jsonl\n3. 读取今日心迹:cat ~/.hermes/soulful/heart-traces.jsonl\n4. 综合以上信息,输出简短复盘报告(含:今日完成、明日待办、情绪状态)推送给牧尘。\n用简洁风格,不要废话。",
|
||||
"skills": [],
|
||||
"skill": null,
|
||||
"model": null,
|
||||
|
|
@ -1607,7 +1607,7 @@
|
|||
{
|
||||
"id": "0c27fd30cbbc",
|
||||
"name": "每日投研简报",
|
||||
"prompt": "你是小唯的股票投研助手。现在生成每日投研简报(分析+建议,不是数据堆砌)。\n\n数据已由前置脚本收集,内容在 Script Output 里。请输出:\n\n📋 今日投研简报\n\n【今日解读】\n- 用 2-3 句话概括今日市场核心变化\n- 重点:哪些板块/个股值得注意\n\n【操作建议】\n- 给出 2-3 条具体、可执行的操作建议(加仓/减仓/观望)\n- 每条建议附理由(基于数据)\n\n【风险提示】\n- 1-2 条当前需要注意的风险\n\n要求:\n- 语言精炼,直接给结论\n- 不罗列数据,做分析\n- 用中文",
|
||||
"prompt": "你是小怡的股票投研助手。现在生成每日投研简报(分析+建议,不是数据堆砌)。\n\n数据已由前置脚本收集,内容在 Script Output 里。请输出:\n\n📋 今日投研简报\n\n【今日解读】\n- 用 2-3 句话概括今日市场核心变化\n- 重点:哪些板块/个股值得注意\n\n【操作建议】\n- 给出 2-3 条具体、可执行的操作建议(加仓/减仓/观望)\n- 每条建议附理由(基于数据)\n\n【风险提示】\n- 1-2 条当前需要注意的风险\n\n要求:\n- 语言精炼,直接给结论\n- 不罗列数据,做分析\n- 用中文",
|
||||
"skills": [],
|
||||
"skill": null,
|
||||
"model": null,
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
#!/bin/bash
|
||||
# 小米 MiMo TTS 封装脚本 — Hermes command provider 调用
|
||||
# 输出: Opus格式音频文件(飞书语音条兼容)
|
||||
|
||||
INPUT="$1"
|
||||
OUTPUT="$2"
|
||||
VOICE="${3:-冰糖}"
|
||||
KEY="tp-c374efhzmz9npodjz5wj1cm008lg4czce6v170nqxwemp12v"
|
||||
API="https://token-plan-cn.xiaomimimo.com/v1/chat/completions"
|
||||
|
||||
TEXT=$(cat "$INPUT")
|
||||
TMPWAV="/tmp/mimo_tts_$$.wav"
|
||||
TMP_OPUS="/tmp/mimo_tts_$$.opus"
|
||||
|
||||
# 调用小米TTS API
|
||||
RESP=$(curl -s -X POST "$API" \
|
||||
-H "Authorization: Bearer $KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$(python3 -c "
|
||||
import json, sys
|
||||
payload = {
|
||||
'model': 'mimo-v2.5-tts',
|
||||
'messages': [
|
||||
{'role': 'user', 'content': '请用温柔自然的语气,正常语速朗读'},
|
||||
{'role': 'assistant', 'content': sys.argv[1]}
|
||||
],
|
||||
'audio': {'format': 'wav', 'voice': sys.argv[2]}
|
||||
}
|
||||
print(json.dumps(payload, ensure_ascii=False))
|
||||
" "$TEXT" "$VOICE")")
|
||||
|
||||
# 解析base64音频到临时wav文件
|
||||
echo "$RESP" | python3 -c "
|
||||
import json, base64, sys
|
||||
try:
|
||||
d = json.load(sys.stdin)
|
||||
audio = d['choices'][0]['message']['audio']['data']
|
||||
with open('$TMPWAV', 'wb') as f:
|
||||
f.write(base64.b64decode(audio))
|
||||
except Exception as e:
|
||||
print(f'错误: {e}', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
"
|
||||
|
||||
if [ ! -f "$TMPWAV" ]; then
|
||||
echo "错误: WAV文件未生成" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 转换为Opus格式
|
||||
if ! python3 ~/.hermes/scripts/to_opus.py "$TMPWAV" "$TMP_OPUS" 2>&1; then
|
||||
rm -f "$TMPWAV"
|
||||
echo "错误: Opus转码失败" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 覆盖Hermes期望的输出路径(即使扩展名是.wav,内容是opus)
|
||||
mv "$TMP_OPUS" "$OUTPUT"
|
||||
rm -f "$TMPWAV"
|
||||
|
||||
exit 0
|
||||
|
|
@ -1,222 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
distill-model-watchdog.py — 蒸馏模型看门狗(30min 轻量探针)
|
||||
============================================================
|
||||
守护对象: 织忆 distill (zhiyid.service LLM_MODEL) + TencentDB L1 (tdai-gateway.yaml model)
|
||||
|
||||
为什么需要:
|
||||
- model-health.py 每 6h 才跑,免费模型挂了要等半天
|
||||
- model-health.py 测"对话能力",distill 需要"JSON 输出能力",探针类型不对
|
||||
- 免费模型经常挂(2026-08-02 实测 m3 连续空响应、gpt-oss content=null)
|
||||
|
||||
逻辑:
|
||||
1. 读当前 LLM_MODEL(zhiyid.service)
|
||||
2. 测 JSON 输出能力(真实调用,内容可解析为 JSON 才通过)
|
||||
3. 通过 → 静默(空输出 = no-agent cron 不发送)
|
||||
4. 失败 → 按优先级从候选池逐个测 → 找到第一个可用 → 更新两处配置 → 重启 → 飞书报警
|
||||
5. 全部候选失败 → 飞书报警"所有蒸馏模型都挂了"
|
||||
|
||||
候选池顺序 = 2026-08-02 实测 JSON 输出可用 + 按质量排序
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
from datetime import datetime, timezone
|
||||
|
||||
API = "http://127.0.0.1:3000/v1"
|
||||
KEY_ENV = None # 从 zhiyid.service 读取
|
||||
ZHIYID_SERVICE = os.path.expanduser("~/.config/systemd/user/zhiyid.service")
|
||||
TDDB_CONFIG = os.path.expanduser("~/.memory-tencentdb/memory-tdai/tdai-gateway.yaml")
|
||||
FEISHU_WEBHOOK = "https://open.feishu.cn/open-apis/bot/v2/hook/446db983-e392-4d2c-bfb8-f9060e5df3ad"
|
||||
|
||||
# 候选池(优先级降序):2026-08-02 实测 JSON 输出可用的模型
|
||||
CANDIDATE_POOL = [
|
||||
"google/gemma-4-31b-it", # 当前主用:纯JSON + 5D评分 质量最好
|
||||
"mistralai/mistral-nemotron", # 128K 品质均衡
|
||||
"nvidia/llama-3.3-nemotron-super-49b-v1.5", # 128K 质量高
|
||||
"meta/llama-3.1-8b-instruct", # 极速响应 兜底
|
||||
"nvidia/nemotron-mini-4b-instruct", # 最后兜底
|
||||
]
|
||||
|
||||
# 已知绝对不可用的(不重复测,直接跳过)
|
||||
KNOWN_BAD = [
|
||||
"openai/gpt-oss-120b", "openai/gpt-oss-20b", # reasoning, content=null
|
||||
"minimaxai/minimax-m3", "minimaxai/minimax-m2.7", # 空响应/EOL
|
||||
"stepfun-ai/step-3.5-flash", "qwen/qwen3.5-122b-a10b", # EOL
|
||||
"mistralai/mistral-large-3-675b", "mistralai/mistral-large-3-675b-instruct-2512", # EOL/无渠道
|
||||
"nvidia/nemotron-3-super-120b-a12b", # reasoning 回显
|
||||
"mistralai/mistral-medium-3.5-128b", # 非JSON
|
||||
"deepseek-ai/deepseek-v3.2", # openai_error
|
||||
]
|
||||
|
||||
# ============ 工具 ============
|
||||
|
||||
def _get_key():
|
||||
"""从 zhiyid.service 读 LLM_API_KEY(唯一真源)"""
|
||||
try:
|
||||
with open(ZHIYID_SERVICE) as f:
|
||||
for line in f:
|
||||
m = re.search(r"LLM_API_KEY=(\S+)", line)
|
||||
if m:
|
||||
return m.group(1)
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
def _get_current_model():
|
||||
"""读 zhiyid.service 当前 LLM_MODEL"""
|
||||
try:
|
||||
with open(ZHIYID_SERVICE) as f:
|
||||
for line in f:
|
||||
m = re.search(r"LLM_MODEL=(\S+)", line)
|
||||
if m:
|
||||
return m.group(1)
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
def _test_json(model: str, timeout: int = 25) -> bool:
|
||||
"""真实调用测试:返回内容必须是可解析的 JSON(剥离 code fence 后)"""
|
||||
payload = json.dumps({
|
||||
"model": model,
|
||||
"messages": [
|
||||
{"role": "system", "content": "输出严格JSON,不要markdown代码块"},
|
||||
{"role": "user", "content": '提取实体:牧尘喜欢简洁。输出 {"entities":[],"decisions":[],"conclusions":[]} 格式'},
|
||||
],
|
||||
"max_tokens": 150,
|
||||
}).encode()
|
||||
req = urllib.request.Request(
|
||||
f"{API}/chat/completions", data=payload,
|
||||
headers={"Authorization": f"Bearer {KEY_ENV}", "Content-Type": "application/json"},
|
||||
method="POST",
|
||||
)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=timeout) as resp:
|
||||
body = json.loads(resp.read())
|
||||
msg = body.get("choices", [{}])[0].get("message", {}) or {}
|
||||
content = msg.get("content") or ""
|
||||
if not content.strip():
|
||||
return False # reasoning 模型 content=null
|
||||
cleaned = re.sub(r"```json\s*|\s*```", "", content).strip()
|
||||
json.loads(cleaned)
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def _update_zhiyid(model: str) -> bool:
|
||||
"""更新 zhiyid.service 的 LLM_MODEL + reload"""
|
||||
try:
|
||||
with open(ZHIYID_SERVICE) as f:
|
||||
content = f.read()
|
||||
new_content = re.sub(r"LLM_MODEL=\S+", f"LLM_MODEL={model}", content)
|
||||
if new_content == content:
|
||||
return False
|
||||
with open(ZHIYID_SERVICE, "w") as f:
|
||||
f.write(new_content)
|
||||
subprocess.run(["systemctl", "--user", "daemon-reload"], check=True)
|
||||
subprocess.run(["systemctl", "--user", "restart", "zhiyid"], check=True)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f" ❌ 更新 zhiyid.service 失败: {e}")
|
||||
return False
|
||||
|
||||
def _update_tddb(model: str) -> bool:
|
||||
"""更新 tdai-gateway.yaml 的 model + 重启(若文件存在)"""
|
||||
if not os.path.exists(TDDB_CONFIG):
|
||||
return False
|
||||
try:
|
||||
with open(TDDB_CONFIG) as f:
|
||||
content = f.read()
|
||||
new_content = re.sub(r"^(\s*model:\s*)\S+", rf"\g<1>{model}", content, flags=re.M)
|
||||
if new_content == content:
|
||||
return False
|
||||
# 备份
|
||||
bak = TDDB_CONFIG + ".bak-watchdog"
|
||||
with open(bak, "w") as f:
|
||||
f.write(content)
|
||||
with open(TDDB_CONFIG, "w") as f:
|
||||
f.write(new_content)
|
||||
subprocess.run(["systemctl", "--user", "restart", "tdai-gateway"], check=True)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f" ❌ 更新 tdai-gateway.yaml 失败: {e}")
|
||||
return False
|
||||
|
||||
def _feishu_alert(title: str, content: str):
|
||||
"""飞书告警卡片"""
|
||||
try:
|
||||
payload = json.dumps({
|
||||
"msg_type": "interactive",
|
||||
"card": {
|
||||
"header": {"title": {"tag": "plain_text", "content": title}, "template": "red"},
|
||||
"elements": [{"tag": "markdown", "content": content}],
|
||||
},
|
||||
}).encode()
|
||||
req = urllib.request.Request(FEISHU_WEBHOOK, data=payload,
|
||||
headers={"Content-Type": "application/json"}, method="POST")
|
||||
with urllib.request.urlopen(req, timeout=10):
|
||||
pass
|
||||
except Exception as e:
|
||||
print(f" 飞书通知失败: {e}")
|
||||
|
||||
# ============ 主流程 ============
|
||||
|
||||
def main():
|
||||
global KEY_ENV
|
||||
KEY_ENV = _get_key()
|
||||
if not KEY_ENV:
|
||||
print("🔴 无法读取 LLM_API_KEY,跳过本轮")
|
||||
return
|
||||
|
||||
current = _get_current_model()
|
||||
if not current:
|
||||
print("🔴 无法读取当前 LLM_MODEL,跳过本轮")
|
||||
return
|
||||
|
||||
ts = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
# 1. 测当前模型
|
||||
if _test_json(current):
|
||||
# 健康,静默退出(no-agent cron 空输出不发送)
|
||||
return
|
||||
|
||||
# 2. 当前模型挂了 → 找替补
|
||||
print(f"🔴 [{ts}] 蒸馏模型 {current} JSON 输出失败,开始切换...")
|
||||
replacement = None
|
||||
for cand in CANDIDATE_POOL:
|
||||
if cand == current or cand in KNOWN_BAD:
|
||||
continue
|
||||
print(f" 🔄 测试替补 {cand}...")
|
||||
if _test_json(cand):
|
||||
replacement = cand
|
||||
print(f" ✅ {cand} 可用")
|
||||
break
|
||||
|
||||
if not replacement:
|
||||
msg = f"**⚠️ 所有蒸馏模型都挂了**\n\n⏰ {ts}\n当前: `{current}`\n候选全部失败: {', '.join(CANDIDATE_POOL)}\n\n请人工检查 NewAPI 渠道"
|
||||
_feishu_alert("🔴 蒸馏模型全部不可用", msg)
|
||||
print(msg)
|
||||
return
|
||||
|
||||
# 3. 更新两处配置
|
||||
z_ok = _update_zhiyid(replacement)
|
||||
t_ok = _update_tddb(replacement)
|
||||
|
||||
changed_parts = []
|
||||
if z_ok:
|
||||
changed_parts.append("zhiyid.service")
|
||||
if t_ok:
|
||||
changed_parts.append("tdai-gateway.yaml")
|
||||
|
||||
msg = f"**🔄 蒸馏模型已自动切换**\n\n⏰ {ts}\n`{current}` → `{replacement}`\n更新: {', '.join(changed_parts) if changed_parts else '无(配置已是最新)'}\n\n原因: 原模型 JSON 输出失败(免费模型挂了)"
|
||||
_feishu_alert("🔄 蒸馏模型自动切换", msg)
|
||||
print(msg)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
[Unit]
|
||||
Description=Hermes Agent Gateway - Messaging Platform Integration
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
StartLimitIntervalSec=0
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/home/muc/.hermes/hermes-agent/.venv/bin/python -m hermes_cli.main gateway run
|
||||
WorkingDirectory=/home/muc/.hermes-prof-b
|
||||
Environment="PATH=/home/muc/.hermes/hermes-agent/.venv/bin:/home/muc/nodejs/node-v24.16.0-linux-x64/bin:/home/muc/.local/bin:/home/muc/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
Environment="VIRTUAL_ENV=/home/muc/.hermes/hermes-agent/.venv"
|
||||
Environment="HERMES_HOME=/home/muc/.hermes-prof-b"
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
RestartForceExitStatus=75
|
||||
KillMode=mixed
|
||||
KillSignal=SIGTERM
|
||||
ExecReload=/bin/kill -USR1 $MAINPID
|
||||
ExecStopPost=-/home/muc/.hermes/hermes-agent/.venv/bin/python -m gateway.cgroup_cleanup
|
||||
TimeoutStopSec=210
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
|
@ -1,993 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
NewAPI 模型健康巡检(快速版)
|
||||
每 6h 运行,测试关键模型的响应状态
|
||||
输出: ~/.hermes/model-health.json
|
||||
"""
|
||||
|
||||
import json
|
||||
import yaml
|
||||
import time
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
from datetime import datetime, timezone
|
||||
|
||||
API = "http://127.0.0.1:3000/v1"
|
||||
KEY = "0ExNiLblJvIWBDpkS50fwOBw4MmqLyKdHJK5iQtlw9dOMWBP"
|
||||
OUTPUT = os.path.expanduser("~/.hermes/model-health.json")
|
||||
|
||||
# ============ 配置自愈 ============
|
||||
CONFIG_PATH = os.path.expanduser("~/.hermes/config.yaml")
|
||||
# 配置中声明的模型 — 巡检会交叉验证
|
||||
CONFIG_DECLARED_MODELS = [
|
||||
"nvidia/nemotron-3-super-120b-a12b", # 1M ctx 🥇 质量100% 427ms
|
||||
"openai/gpt-oss-120b", # 128K ctx 🥈 质量100% 479ms
|
||||
"mistralai/mistral-nemotron", # 128K ctx 🥉 全对 536ms
|
||||
"nvidia/llama-3.3-nemotron-super-49b-v1.5", # 128K ctx 质量100%
|
||||
]
|
||||
# 候选池 — 配置里死了就从这里替补
|
||||
CANDIDATE_POOL = [
|
||||
"nvidia/nemotron-3-super-120b-a12b", # 1M ctx ⭐ 最佳综合
|
||||
"openai/gpt-oss-120b", # 128K ctx ⭐ 质量第一
|
||||
"mistralai/mistral-nemotron", # 128K ctx 品质均衡
|
||||
"nvidia/nvidia-nemotron-nano-9b-v2", # 128K ctx 备用
|
||||
"meta/llama-3.1-8b-instruct", # 128K ctx 极速响应
|
||||
"nvidia/nemotron-mini-4b-instruct", # 128K ctx 兜底
|
||||
]
|
||||
|
||||
# 已知上下文长度(K=tokens)
|
||||
CONTEXT_LENGTHS = {
|
||||
# 1M 上下文阵营(K=1024)
|
||||
"nvidia/nemotron-3-super-120b-a12b": 1024,
|
||||
"deepseek-v4-flash": 1024,
|
||||
"deepseek-ai/deepseek-v4-pro": 1024,
|
||||
# 256K 上下文阵营
|
||||
"minimaxai/minimax-m2.7": 256,
|
||||
"minimaxai/minimax-m3": 256,
|
||||
# 128K 上下文阵营
|
||||
"openai/gpt-oss-120b": 128,
|
||||
"mistralai/mistral-nemotron": 128,
|
||||
"nvidia/nvidia-nemotron-nano-9b-v2": 128,
|
||||
"meta/llama-3.1-8b-instruct": 128,
|
||||
"nvidia/nemotron-mini-4b-instruct": 128,
|
||||
"nvidia/llama-3.3-nemotron-super-49b-v1": 128,
|
||||
"nvidia/llama-3.3-nemotron-super-49b-v1.5": 128,
|
||||
"mistralai/mistral-medium-3.5-128b": 128,
|
||||
"qwen/qwen3.5-122b-a10b": 128,
|
||||
"qwen/qwen3-next-80b-a3b-thinking": 128,
|
||||
"moonshotai/kimi-k2-instruct": 128,
|
||||
"mistralai/devstral-2-123b-instruct-2512": 128,
|
||||
# 8K 短上下文
|
||||
"stepfun-ai/step-3.5-flash": 8,
|
||||
}
|
||||
|
||||
# 已知忽略的模型(系统/不支持/垃圾,永远不测也不自动加入)
|
||||
KNOWN_IGNORE = {
|
||||
"gpt-4o", "gpt-4o-mini", "gpt-4o-audio-preview", "gpt-4o-mini-audio-preview",
|
||||
"gpt-4o-search-preview", "gpt-4o-mini-search-preview",
|
||||
"o1", "o3-mini",
|
||||
"dall-e-3", "dall-e-2",
|
||||
"tts-1", "tts-1-hd",
|
||||
"whisper-1",
|
||||
"text-embedding", "text-moderation",
|
||||
"comfyui", "sd-", "stable-diffusion",
|
||||
"deepseek-v4-pro", "deepseek-v4-pro-",
|
||||
"deepseek-ai/deepseek-v4-pro",
|
||||
# 付费主模型 — 绝不被模型巡检探测/替换(2026-08-08 牧尘要求 OpenClaw 主模型固定为 deepseek-v4-flash)
|
||||
"deepseek-v4-flash",
|
||||
"deepseek/deepseek-v4-flash",
|
||||
}
|
||||
# 已知死模型(不重复测试,直接标记 dead)
|
||||
KNOWN_DEAD = {
|
||||
"minimaxai/minimax-m2.7",
|
||||
"stepfun-ai/step-3.5-flash",
|
||||
"qwen/qwen3.5-122b-a10b",
|
||||
"mistralai/mistral-medium-3.5-128b",
|
||||
}
|
||||
|
||||
# 已知付费模型(绝不用免费额度测试,也不加入免费配置)
|
||||
KNOWN_PAID = {
|
||||
"deepseek-ai/deepseek-v4-pro",
|
||||
}
|
||||
|
||||
# OpenClaw 配置中的模型 — 也会巡检和自愈
|
||||
OPENCLAW_MODELS = [
|
||||
"minimaxai/minimax-m2.7",
|
||||
"stepfun-ai/step-3.5-flash",
|
||||
"qwen/qwen3.5-122b-a10b",
|
||||
"mistralai/devstral-2-123b-instruct-2512",
|
||||
"moonshotai/kimi-k2-instruct",
|
||||
"nvidia/llama-3.3-nemotron-super-49b-v1.5",
|
||||
"qwen/qwen3-next-80b-a3b-thinking",
|
||||
]
|
||||
|
||||
ALL_MODELS = [m for m in (
|
||||
CONFIG_DECLARED_MODELS + [m for m in CANDIDATE_POOL if m not in CONFIG_DECLARED_MODELS]
|
||||
+ [m for m in OPENCLAW_MODELS if m not in CONFIG_DECLARED_MODELS and m not in CANDIDATE_POOL]
|
||||
) if m not in KNOWN_PAID]
|
||||
|
||||
HEADERS = {
|
||||
"Authorization": f"Bearer {KEY}",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
PROMPT = "你好"
|
||||
|
||||
# ============ 质量探针 ============
|
||||
# 固定测试题,自动评分(0-100)
|
||||
PROBE_QUESTIONS = [
|
||||
{
|
||||
"question": "如果所有 A 是 B,所有 B 是 C,那么所有 A 是 C 吗?请只回答是或不是。",
|
||||
"check": lambda resp: "是" in resp,
|
||||
"weight": 25,
|
||||
},
|
||||
{
|
||||
"question": "1.8 和 1.11 哪个大?请只回答数字。",
|
||||
"check": lambda resp: "1.8" in resp,
|
||||
"weight": 25,
|
||||
},
|
||||
{
|
||||
"question": "中国的首都是哪个城市?请只回答城市名。",
|
||||
"check": lambda resp: "北京" in resp,
|
||||
"weight": 25,
|
||||
},
|
||||
{
|
||||
"question": "用 Python 写一行反转列表的代码,列表是 [1,2,3]。请只输出代码,不要解释。",
|
||||
"check": lambda resp: "[::-1]" in resp or ".reverse()" in resp or "reversed(" in resp,
|
||||
"weight": 25,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def _extract_param_b(model: str) -> float:
|
||||
"""从模型名提取参数量(B),如 120b→120, 8b→8, 4b→4"""
|
||||
import re
|
||||
m = re.search(r'(\d+)[bB]', model)
|
||||
if m:
|
||||
return float(m.group(1))
|
||||
# fallback: 用已知映射
|
||||
KNOWN = {
|
||||
"nemotron-3-super": 120,
|
||||
"nemotron-super": 49,
|
||||
"nemotron-nano": 9,
|
||||
"nemotron-mini": 4,
|
||||
"mistral-nemotron": 12,
|
||||
"gpt-oss": 120,
|
||||
}
|
||||
for key, val in KNOWN.items():
|
||||
if key in model.lower():
|
||||
return val
|
||||
return 7.0 # 默认 7B
|
||||
|
||||
|
||||
def _family_score(model: str) -> float:
|
||||
"""家族声誉评分 0-100"""
|
||||
ml = model.lower()
|
||||
if "openai" in ml or "gpt" in ml:
|
||||
return 95
|
||||
if "nvidia" in ml or "nemotron" in ml:
|
||||
return 80
|
||||
if "mistral" in ml:
|
||||
return 75
|
||||
if "meta" in ml or "llama" in ml:
|
||||
return 70
|
||||
if "minimax" in ml:
|
||||
return 65
|
||||
if "qwen" in ml:
|
||||
return 70
|
||||
return 60
|
||||
|
||||
|
||||
def _param_score(param_b: float) -> float:
|
||||
"""参数量级分:log2缩放,120b→100, 49b→85, 8b→55, 4b→40"""
|
||||
import math
|
||||
return min(round(math.log2(param_b) * 14.5), 100)
|
||||
|
||||
|
||||
def _speed_score(latency_ms: int, fastest_latency: int) -> float:
|
||||
"""速度分:相对最快模型的延迟比例"""
|
||||
if fastest_latency <= 0 or latency_ms <= 0:
|
||||
return 50
|
||||
ratio = fastest_latency / latency_ms
|
||||
return min(round(ratio * 100), 100)
|
||||
|
||||
|
||||
def _context_score(model: str) -> float:
|
||||
"""上下文长度分:越长越高 256K→100, 128K→80, 64K→60, 32K→40, 8K→10"""
|
||||
ctx = CONTEXT_LENGTHS.get(model, 128) # 未知默认128
|
||||
if ctx >= 256:
|
||||
return 100
|
||||
if ctx >= 128:
|
||||
return 80
|
||||
if ctx >= 64:
|
||||
return 60
|
||||
if ctx >= 32:
|
||||
return 40
|
||||
return max(round(ctx / 8 * 10), 5)
|
||||
|
||||
|
||||
def _run_quality_probe(model: str, trials: int = 3) -> dict:
|
||||
"""运行质量探针,返回探针分和详细结果。
|
||||
v3: 每道题测 trials 次(默认 3),取通过比例,消除单次波动。"""
|
||||
probe_results = []
|
||||
total = 0
|
||||
for q in PROBE_QUESTIONS:
|
||||
passed_count = 0
|
||||
scores = []
|
||||
for _ in range(trials):
|
||||
payload = json.dumps({
|
||||
"model": model,
|
||||
"messages": [{"role": "user", "content": q["question"]}],
|
||||
"max_tokens": 200,
|
||||
"temperature": 0.1,
|
||||
}).encode()
|
||||
req = urllib.request.Request(
|
||||
f"{API}/chat/completions",
|
||||
data=payload,
|
||||
headers=HEADERS,
|
||||
method="POST",
|
||||
)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=20) as resp:
|
||||
body = json.loads(resp.read())
|
||||
msg = body.get("choices", [{}])[0].get("message", {}) or {}
|
||||
# 有些模型把实际回答放 reasoning_content(gpt-oss-120b 等)
|
||||
content = msg.get("content") or msg.get("reasoning_content") or msg.get("reasoning") or ""
|
||||
passed = 1 if q["check"](content) else 0
|
||||
scores.append(passed)
|
||||
except Exception:
|
||||
scores.append(0)
|
||||
passed_count = sum(scores)
|
||||
# 取平均:通过比例 × 权重(3 次中过 2 次 = 2/3 权重)
|
||||
score = round(q["weight"] * passed_count / trials)
|
||||
total += score
|
||||
probe_results.append({
|
||||
"question": q["question"][:40],
|
||||
"passed": passed_count,
|
||||
"trials": trials,
|
||||
"score": score,
|
||||
})
|
||||
return {"probe_score": total, "probe_detail": probe_results}
|
||||
|
||||
|
||||
def _discover_new_models() -> list:
|
||||
"""从 NewAPI 发现当前可用模型,返回最看好的 N 个新模型(限制数量避免超时)"""
|
||||
req = urllib.request.Request(f"{API}/models", headers=HEADERS, method="GET")
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=10) as resp:
|
||||
body = json.loads(resp.read())
|
||||
except Exception:
|
||||
return []
|
||||
all_remote = [m["id"] for m in body.get("data", [])]
|
||||
|
||||
known = set(ALL_MODELS) | KNOWN_IGNORE | KNOWN_DEAD | KNOWN_PAID
|
||||
# 只挑 chat 模型
|
||||
candidates = []
|
||||
for m in all_remote:
|
||||
if m in known:
|
||||
continue
|
||||
if any(kw in m.lower() for kw in ["instruct", "gpt", "llama", "nemotron", "mistral",
|
||||
"qwen", "minimax", "deepseek", "yi-", "glm",
|
||||
"gemma", "phi", "falcon", "command", "dbrx",
|
||||
"mixtral", "solar", "aya", "c4ai", "kimi",
|
||||
"stockmark", "zamba"]):
|
||||
candidates.append(m)
|
||||
|
||||
# 按潜力排序:优先大参数量 + 知名家族
|
||||
def _priority(m: str) -> int:
|
||||
score = 0
|
||||
# 参数量越大越优先
|
||||
import re
|
||||
nums = re.findall(r'(\d+)[bB]', m)
|
||||
if nums:
|
||||
score += int(nums[0])
|
||||
# 知名家族加分
|
||||
for fam, pts in [("openai", 50), ("deepseek", 40), ("meta/llama", 35),
|
||||
("nvidia/nemotron", 30), ("mistral", 25), ("google/gemma", 20),
|
||||
("qwen", 20), ("minimax", 15)]:
|
||||
if fam in m.lower():
|
||||
score += pts
|
||||
break
|
||||
return -score # 降序
|
||||
|
||||
candidates.sort(key=_priority)
|
||||
MAX_NEW_PER_RUN = 5
|
||||
return candidates[:MAX_NEW_PER_RUN]
|
||||
|
||||
|
||||
def test_model(model: str, fastest_latency: int = None) -> dict:
|
||||
"""测试单个模型 2 次,返回汇总"""
|
||||
trials = []
|
||||
|
||||
for t in range(2):
|
||||
payload = json.dumps({
|
||||
"model": model,
|
||||
"messages": [{"role": "user", "content": PROMPT}],
|
||||
"max_tokens": 20,
|
||||
}).encode()
|
||||
|
||||
req = urllib.request.Request(
|
||||
f"{API}/chat/completions",
|
||||
data=payload,
|
||||
headers=HEADERS,
|
||||
method="POST",
|
||||
)
|
||||
|
||||
start = time.time()
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=15) as resp:
|
||||
body = json.loads(resp.read())
|
||||
except urllib.error.HTTPError as e:
|
||||
trials.append({"status": "fail", "error": f"HTTP_{e.code}", "latency_ms": round((time.time() - start) * 1000)})
|
||||
continue
|
||||
except Exception as e:
|
||||
trials.append({"status": "fail", "error": str(e)[:60], "latency_ms": round((time.time() - start) * 1000)})
|
||||
continue
|
||||
|
||||
elapsed = round((time.time() - start) * 1000)
|
||||
|
||||
try:
|
||||
choice = body["choices"][0]
|
||||
msg = choice.get("message", {})
|
||||
content = msg.get("content", "") or ""
|
||||
finish = choice.get("finish_reason", "")
|
||||
usage = body.get("usage", {})
|
||||
|
||||
# ttft 从 nvext 取,没有就估计
|
||||
ttft = body.get("nvext", {}).get("timing", {}).get("ttft_ms", -1)
|
||||
if ttft < 0:
|
||||
ttft = round(elapsed * 0.3)
|
||||
|
||||
trials.append({
|
||||
"status": "ok",
|
||||
"latency_ms": elapsed,
|
||||
"ttft_ms": ttft,
|
||||
"has_content": 1 if content.strip() else 0,
|
||||
"completion_tokens": usage.get("completion_tokens", 0),
|
||||
"finish_reason": finish,
|
||||
})
|
||||
except (KeyError, IndexError, json.JSONDecodeError) as e:
|
||||
trials.append({"status": "fail", "error": f"parse: {e}", "latency_ms": elapsed})
|
||||
|
||||
# 汇总
|
||||
ok_count = sum(1 for t in trials if t["status"] == "ok")
|
||||
fail_count = 2 - ok_count
|
||||
|
||||
if ok_count == 2:
|
||||
stability = "stable"
|
||||
elif ok_count == 1:
|
||||
stability = "unstable"
|
||||
else:
|
||||
stability = "dead"
|
||||
|
||||
ok_trials = [t for t in trials if t["status"] == "ok"]
|
||||
avg_latency = round(sum(t["latency_ms"] for t in ok_trials) / len(ok_trials)) if ok_trials else 0
|
||||
avg_ttft = round(sum(t.get("ttft_ms", 0) for t in ok_trials) / len(ok_trials)) if ok_trials else -1
|
||||
|
||||
last_ok = ok_trials[-1] if ok_trials else trials[-1]
|
||||
last_finish = last_ok.get("finish_reason", "error")
|
||||
|
||||
# 质量探针(仅稳定模型)
|
||||
probe = _run_quality_probe(model) if stability == "stable" else {"probe_score": 0, "probe_detail": []}
|
||||
|
||||
# 综合排名分
|
||||
param_b = _extract_param_b(model)
|
||||
ps = _param_score(param_b)
|
||||
fs = _family_score(model)
|
||||
ss = _speed_score(avg_latency, fastest_latency) if fastest_latency and avg_latency > 0 else 50
|
||||
stab_s = 100 if stability == "stable" else (50 if stability == "unstable" else 0)
|
||||
probe_s = probe["probe_score"]
|
||||
cs = _context_score(model)
|
||||
|
||||
rank_score = round(
|
||||
probe_s * 0.30 + cs * 0.25 + ps * 0.20 + fs * 0.10 + stab_s * 0.10 + ss * 0.05
|
||||
)
|
||||
|
||||
return {
|
||||
"model": model,
|
||||
"tests": 2,
|
||||
"success": ok_count,
|
||||
"failure": fail_count,
|
||||
"avg_latency_ms": avg_latency,
|
||||
"avg_ttft_ms": avg_ttft,
|
||||
"stability": stability,
|
||||
"last_status": "ok" if ok_count > 0 else "fail",
|
||||
"last_finish": last_finish,
|
||||
"probe_score": probe_s,
|
||||
"probe_detail": probe["probe_detail"],
|
||||
"rank_score": rank_score,
|
||||
"param_b": param_b,
|
||||
"context_k": CONTEXT_LENGTHS.get(model, 128),
|
||||
"context_score": cs,
|
||||
"family_score": fs,
|
||||
"param_score": ps,
|
||||
}
|
||||
|
||||
|
||||
def _verify_model_usable(model: str) -> bool:
|
||||
"""替换前真实调用验证:必须 HTTP 200 且有内容,才允许写入配置。
|
||||
这是自愈安全闸门——候选模型必须先实际跑通一次,防止写入死模型/不存在模型。"""
|
||||
payload = json.dumps({
|
||||
"model": model,
|
||||
"messages": [{"role": "user", "content": "hi"}],
|
||||
"max_tokens": 5,
|
||||
}).encode()
|
||||
req = urllib.request.Request(
|
||||
f"{API}/chat/completions", data=payload, headers=HEADERS, method="POST"
|
||||
)
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=20) as resp:
|
||||
body = json.loads(resp.read())
|
||||
msg = body.get("choices", [{}])[0].get("message", {}) or {}
|
||||
content = msg.get("content") or msg.get("reasoning_content") or ""
|
||||
return bool(content.strip())
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
results = []
|
||||
deadline = time.time() + 480 # 8分钟全局超时(探针3次取平均,耗时增加)
|
||||
|
||||
# ============ 自动发现新模型 ============
|
||||
new_models = _discover_new_models()
|
||||
if new_models:
|
||||
print(f"🔍 发现 {len(new_models)} 个新模型: {', '.join(new_models)}")
|
||||
# 加入测试列表
|
||||
for m in new_models:
|
||||
if m not in ALL_MODELS:
|
||||
# 动态扩展 ALL_MODELS(用 list 可变性)
|
||||
ALL_MODELS.append(m)
|
||||
sys.stdout.flush()
|
||||
|
||||
for model in ALL_MODELS:
|
||||
if time.time() > deadline:
|
||||
print(f"⏰ 全局超时,跳过剩余模型")
|
||||
break
|
||||
|
||||
# 先跑测试获取延迟数据,传递给 test_model 用于速度分
|
||||
entry = test_model(model)
|
||||
results.append(entry)
|
||||
|
||||
icon = "✅" if entry["stability"] == "stable" else ("⚠️" if entry["stability"] == "unstable" else "❌")
|
||||
rank = entry.get("rank_score", 0)
|
||||
probe = entry.get("probe_score", 0)
|
||||
print(f"{icon} {model:45s} {entry['avg_latency_ms']:>6}ms | {entry['success']}/2 ok | 排名分:{rank:>3} | 探针:{probe}")
|
||||
sys.stdout.flush()
|
||||
|
||||
# 重新计算速度分:确定最快稳定模型的延迟
|
||||
stable_models = [r for r in results if r["stability"] == "stable"]
|
||||
fastest_latency = min((r["avg_latency_ms"] for r in stable_models if r["avg_latency_ms"] > 0), default=0)
|
||||
# 用最快延迟重新计算所有模型的速度分 + 排名分
|
||||
for r in results:
|
||||
if r["avg_latency_ms"] > 0 and fastest_latency > 0:
|
||||
ss = _speed_score(r["avg_latency_ms"], fastest_latency)
|
||||
else:
|
||||
ss = 50
|
||||
stab_s = 100 if r["stability"] == "stable" else (50 if r["stability"] == "unstable" else 0)
|
||||
# v3: 加入 context_score(长上下文是核心优势,之前公式把它丢了!)
|
||||
r["rank_score"] = round(
|
||||
r.get("probe_score", 0) * 0.30
|
||||
+ r.get("context_score", 80) * 0.25
|
||||
+ r.get("param_score", 50) * 0.20
|
||||
+ r.get("family_score", 60) * 0.10
|
||||
+ stab_s * 0.10
|
||||
+ ss * 0.05
|
||||
)
|
||||
|
||||
# 汇总
|
||||
healthy = sum(1 for r in results if r["stability"] == "stable")
|
||||
flaky = sum(1 for r in results if r["stability"] == "unstable")
|
||||
dead = sum(1 for r in results if r["stability"] == "dead")
|
||||
|
||||
# 按 rank_score 降序排列(质量优先)
|
||||
stable_sorted = sorted(stable_models, key=lambda x: x["rank_score"], reverse=True)
|
||||
fastest_by_latency = sorted(stable_models, key=lambda x: x["avg_latency_ms"])
|
||||
|
||||
# 质量排名(全量,含探针分)
|
||||
all_ranked = sorted(
|
||||
[r for r in results if r["stability"] in ("stable", "unstable")],
|
||||
key=lambda x: x["rank_score"], reverse=True
|
||||
)
|
||||
|
||||
summary = {
|
||||
"timestamp": timestamp,
|
||||
"total_models": len(results),
|
||||
"stable": healthy,
|
||||
"unstable": flaky,
|
||||
"dead": dead,
|
||||
"fastest_stable": [m["model"] for m in fastest_by_latency[:5]],
|
||||
"quality_ranking": [m["model"] for m in stable_sorted], # 按质量排
|
||||
"recommendations": {
|
||||
"by_quality": [m["model"] for m in stable_sorted],
|
||||
"by_speed": [m["model"] for m in fastest_by_latency],
|
||||
"priorities": {
|
||||
"首选质量": stable_sorted[:1] if stable_sorted else [],
|
||||
"日常推荐": stable_sorted[:3] if len(stable_sorted) >= 3 else stable_sorted,
|
||||
"快速响应": fastest_by_latency[:3] if len(fastest_by_latency) >= 3 else fastest_by_latency,
|
||||
},
|
||||
},
|
||||
"models": results,
|
||||
}
|
||||
|
||||
os.makedirs(os.path.dirname(OUTPUT), exist_ok=True)
|
||||
with open(OUTPUT + ".new", "w") as f:
|
||||
json.dump(summary, f, indent=2, ensure_ascii=False)
|
||||
os.replace(OUTPUT + ".new", OUTPUT)
|
||||
|
||||
# ============ 自愈:检测到死的模型自动替换 ============
|
||||
|
||||
def _heal_config(config_path: str, declared: list, label: str) -> bool:
|
||||
"""修复一个配置文件的模型列表,返回是否修改。
|
||||
|
||||
v2: 除 providers 列表外,还必须检查实际生效的 model.default 字段——
|
||||
之前只修 providers.models 列表,model.default 指向死模型时脚本完全看不见。
|
||||
所有替换前必须通过 _verify_model_usable 真实调用验证。
|
||||
"""
|
||||
with open(config_path) as f:
|
||||
cfg = yaml.safe_load(f)
|
||||
|
||||
# ---------- 1. 检查 providers.newapi-local.models 列表 ----------
|
||||
current_models = cfg.get("providers", {}).get("newapi-local", {}).get("models", [])
|
||||
changed = False
|
||||
|
||||
dead_in = [r for r in results if r["model"] in declared and r["stability"] == "dead"]
|
||||
if dead_in:
|
||||
print(f"\n🔧 [{label}] 检测到 {len(dead_in)} 个模型已死亡,正在自愈...")
|
||||
|
||||
for dead in dead_in:
|
||||
if dead["model"] not in current_models:
|
||||
continue
|
||||
replacement = None
|
||||
# 按质量排名选最优替补(高 rank_score 优先)且必须通过真实调用验证
|
||||
ranked_candidates = sorted(
|
||||
[r for r in results if r["model"] in CANDIDATE_POOL
|
||||
and r["model"] not in current_models
|
||||
and r["stability"] == "stable"
|
||||
and _verify_model_usable(r["model"])],
|
||||
key=lambda x: x["rank_score"], reverse=True
|
||||
)
|
||||
if ranked_candidates:
|
||||
replacement = ranked_candidates[0]["model"]
|
||||
if not replacement:
|
||||
print(f" ❌ [{label}] {dead['model']} 已死,但无可用替补")
|
||||
continue
|
||||
|
||||
idx = current_models.index(dead["model"])
|
||||
current_models[idx] = replacement
|
||||
changed = True
|
||||
print(f" ✅ [{label}] {dead['model']} → {replacement}")
|
||||
|
||||
if cfg.get("providers", {}).get("newapi-local", {}).get("default_model") == dead["model"]:
|
||||
cfg["providers"]["newapi-local"]["default_model"] = replacement
|
||||
print(f" default_model 同步更新为 {replacement}")
|
||||
|
||||
if cfg.get("model", {}).get("default") == dead["model"]:
|
||||
# 铁律:model.default 是日常对话主模型,仅当它指向 newapi 池内模型且已死时才允许替换;
|
||||
# 付费主模型(deepseek-v4-flash 等)绝不自动改。
|
||||
cur_default = cfg["model"]["default"]
|
||||
if cur_default in CANDIDATE_POOL:
|
||||
cfg["model"]["default"] = replacement
|
||||
print(f" model.default 同步更新为 {replacement}")
|
||||
else:
|
||||
print(f" 🛡️ model.default={cur_default} 不在 newapi 池内(付费主模型),跳过自动替换")
|
||||
|
||||
# ---------- 2. 检查 model.default 实际生效字段(v2 新增)----------
|
||||
# 只有当 model.default 指向 newapi-local 免费模型时才自愈;
|
||||
# 付费主模型(deepseek-v4-flash 等)绝不自动改。
|
||||
model_default = cfg.get("model", {}).get("default")
|
||||
model_provider = cfg.get("model", {}).get("provider", "")
|
||||
if model_default and model_provider == "newapi-local" and model_default in CANDIDATE_POOL:
|
||||
# 在结果里找它;不在结果里 = 根本没被测试(未知状态),也视为需要修复
|
||||
found = next((r for r in results if r["model"] == model_default), None)
|
||||
is_bad = found is None or found["stability"] != "stable"
|
||||
if is_bad:
|
||||
print(f"\n🔧 [{label}] model.default={model_default} 不可用({found['stability'] if found else '未测试'}),正在自愈...")
|
||||
ranked_candidates = sorted(
|
||||
[r for r in results if r["model"] in CANDIDATE_POOL
|
||||
and r["stability"] == "stable"
|
||||
and _verify_model_usable(r["model"])],
|
||||
key=lambda x: x["rank_score"], reverse=True
|
||||
)
|
||||
replacement = ranked_candidates[0]["model"] if ranked_candidates else None
|
||||
if replacement and replacement != model_default:
|
||||
cfg["model"]["default"] = replacement
|
||||
cfg["model"]["base_url"] = "http://127.0.0.1:3000/v1"
|
||||
cfg["model"]["api_key"] = "0ExNiLblJvIWBDpkS50fwOBw4MmqLyKdHJK5iQtlw9dOMWBP"
|
||||
changed = True
|
||||
print(f" ✅ [{label}] model.default {model_default} → {replacement}")
|
||||
|
||||
if changed:
|
||||
with open(config_path, "w") as f:
|
||||
yaml.dump(cfg, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
|
||||
print(f" ✅ [{label}] config.yaml 已更新")
|
||||
return changed
|
||||
|
||||
# 修复主配置
|
||||
_heal_config(CONFIG_PATH, CONFIG_DECLARED_MODELS, "主配置")
|
||||
|
||||
# 修复 prof-b 分身配置
|
||||
PROF_B_PATH = os.path.expanduser("~/.hermes-prof-b/config.yaml")
|
||||
if os.path.exists(PROF_B_PATH):
|
||||
_heal_config(PROF_B_PATH, CONFIG_DECLARED_MODELS, "prof-b")
|
||||
|
||||
# 修复 OpenClaw 配置(JSON 格式)
|
||||
|
||||
def _heal_openclaw():
|
||||
oc_path = os.path.expanduser("~/.openclaw/openclaw.json")
|
||||
if not os.path.exists(oc_path):
|
||||
return
|
||||
with open(oc_path) as f:
|
||||
cfg = json.load(f)
|
||||
changed = False
|
||||
|
||||
# --- 1. 修复 models.providers.minimax.models 列表 ---
|
||||
models_list = cfg.get("models", {}).get("providers", {}).get("minimax", {}).get("models", [])
|
||||
if models_list:
|
||||
for entry in models_list:
|
||||
mid = entry.get("id", "")
|
||||
# 移除付费模型
|
||||
if mid in KNOWN_PAID:
|
||||
print(f" 🗑️ [OpenClaw] 移除付费模型: {mid}")
|
||||
models_list.remove(entry)
|
||||
changed = True
|
||||
continue
|
||||
# 替换死模型
|
||||
dead_result = next((r for r in results if r["model"] == mid and r["stability"] == "dead"), None)
|
||||
if not dead_result:
|
||||
continue
|
||||
ranked_candidates = sorted(
|
||||
[r for r in results if r["model"] in CANDIDATE_POOL
|
||||
and r["stability"] == "stable"
|
||||
and _verify_model_usable(r["model"])
|
||||
and not any(m.get("id") == r["model"] for m in models_list)],
|
||||
key=lambda x: x["rank_score"], reverse=True
|
||||
)
|
||||
replacement = ranked_candidates[0]["model"] if ranked_candidates else None
|
||||
if not replacement:
|
||||
print(f" ❌ [OpenClaw] {mid} 已死,但无可用替补")
|
||||
continue
|
||||
entry["id"] = replacement
|
||||
entry["name"] = replacement.split("/")[-1].replace("-", " ").title()
|
||||
changed = True
|
||||
print(f" ✅ [OpenClaw model] {mid} → {replacement}")
|
||||
if changed:
|
||||
cfg["models"]["providers"]["minimax"]["models"] = models_list
|
||||
|
||||
# --- 2. 修复 agents.list[*].model.primary ---
|
||||
agents_list = cfg.get("agents", {}).get("list", [])
|
||||
for agent in agents_list:
|
||||
primary = agent.get("model", {}).get("primary", "")
|
||||
if not primary:
|
||||
continue
|
||||
# primary 格式: "minimax/minimaxai/minimax-m2.7"
|
||||
# 实际模型 ID 是最后两段: "minimaxai/minimax-m2.7"
|
||||
parts = primary.split("/")
|
||||
raw_model = "/".join(parts[-2:]) if len(parts) >= 2 else parts[-1]
|
||||
dead_result = next((r for r in results if r["model"] == raw_model and r["stability"] == "dead"), None)
|
||||
if not dead_result:
|
||||
continue
|
||||
# 找替补(必须 stable + 真实调用验证)
|
||||
ranked_candidates = sorted(
|
||||
[r for r in results if r["stability"] == "stable" and _verify_model_usable(r["model"])],
|
||||
key=lambda x: x["rank_score"], reverse=True
|
||||
)
|
||||
replacement = ranked_candidates[0]["model"] if ranked_candidates else None
|
||||
if not replacement:
|
||||
print(f" ❌ [OpenClaw agent] {agent.get('workspace','?')} primary={raw_model} 已死,无替补")
|
||||
continue
|
||||
# 保持前缀格式: "minimax/<model-id>"
|
||||
prefix = primary.split("/")[0] + "/"
|
||||
agent["model"]["primary"] = f"{prefix}{replacement}"
|
||||
changed = True
|
||||
print(f" ✅ [OpenClaw agent] {raw_model} → {replacement}")
|
||||
|
||||
# --- 2.5 修复 agents.list[*].model.fallbacks(v2 新增)---
|
||||
for agent in agents_list:
|
||||
fallbacks = agent.get("model", {}).get("fallbacks", [])
|
||||
if not fallbacks:
|
||||
continue
|
||||
new_fallbacks = []
|
||||
fb_changed = False
|
||||
for fb in fallbacks:
|
||||
parts = fb.split("/")
|
||||
raw_model = "/".join(parts[-2:]) if len(parts) >= 2 else parts[-1]
|
||||
fb_dead = next((r for r in results if r["model"] == raw_model and r["stability"] == "dead"), None)
|
||||
if not fb_dead:
|
||||
new_fallbacks.append(fb)
|
||||
continue
|
||||
ranked_candidates = sorted(
|
||||
[r for r in results if r["stability"] == "stable" and _verify_model_usable(r["model"])],
|
||||
key=lambda x: x["rank_score"], reverse=True
|
||||
)
|
||||
replacement = ranked_candidates[0]["model"] if ranked_candidates else None
|
||||
if not replacement:
|
||||
print(f" ❌ [OpenClaw fallback] {raw_model} 已死,无替补")
|
||||
continue
|
||||
prefix = fb.split("/")[0] + "/"
|
||||
new_fallbacks.append(f"{prefix}{replacement}")
|
||||
fb_changed = True
|
||||
print(f" ✅ [OpenClaw fallback] {raw_model} → {replacement}")
|
||||
if fb_changed:
|
||||
agent["model"]["fallbacks"] = new_fallbacks
|
||||
changed = True
|
||||
|
||||
# --- 3. 修复 agents.defaults.compaction.model ---
|
||||
defaults = cfg.get("agents", {}).get("defaults", {})
|
||||
comp_model = defaults.get("compaction", {}).get("model", "")
|
||||
if comp_model:
|
||||
dead_result = next((r for r in results if r["model"] == comp_model and r["stability"] == "dead"), None)
|
||||
if dead_result:
|
||||
ranked_candidates = sorted(
|
||||
[r for r in results if r["stability"] == "stable" and r["rank_score"] > 50
|
||||
and _verify_model_usable(r["model"])],
|
||||
key=lambda x: x["rank_score"], reverse=True
|
||||
)
|
||||
replacement = ranked_candidates[0]["model"] if ranked_candidates else None
|
||||
if replacement:
|
||||
defaults["compaction"]["model"] = replacement
|
||||
changed = True
|
||||
print(f" ✅ [OpenClaw compaction] {comp_model} → {replacement}")
|
||||
|
||||
if changed:
|
||||
with open(oc_path, "w") as f:
|
||||
json.dump(cfg, f, indent=2, ensure_ascii=False)
|
||||
print(f" ✅ [OpenClaw] openclaw.json 全面修复完成")
|
||||
|
||||
_heal_openclaw()
|
||||
|
||||
# ============ 主动升级:新模型排名更高则自动替换 ============
|
||||
|
||||
def _auto_promote_config(config_path: str, label: str, n_keep: int = 4) -> bool:
|
||||
"""v3: 排名驱动的自动升级。
|
||||
每次巡检检查配置里实际生效的 default_model(newapi-local 的),
|
||||
如果排名第一的稳定模型不同且验证通过,就升级。不依赖"新模型/死模型"事件。"""
|
||||
if not os.path.exists(config_path):
|
||||
return False
|
||||
with open(config_path) as f:
|
||||
cfg = yaml.safe_load(f)
|
||||
|
||||
changed = False
|
||||
|
||||
# ---------- A. 升级 providers.newapi-local.default_model ----------
|
||||
prov = cfg.get("providers", {}).get("newapi-local", {})
|
||||
current_default = prov.get("default_model", "")
|
||||
# 排名第一的稳定模型(必须验证通过)
|
||||
best_candidates = sorted(
|
||||
[r for r in results if r["stability"] == "stable"
|
||||
and _verify_model_usable(r["model"])],
|
||||
key=lambda x: x["rank_score"], reverse=True
|
||||
)
|
||||
best_model = best_candidates[0]["model"] if best_candidates else None
|
||||
if best_model and current_default != best_model:
|
||||
print(f" ⬆️ [{label}] default_model: {current_default or '(空)'} → {best_model} (排名第1)")
|
||||
prov["default_model"] = best_model
|
||||
changed = True
|
||||
|
||||
# ---------- B. model.default —— 铁律:永不自动修改 ----------
|
||||
# 2026-08-01 血泪教训:这里曾经把 model.default 自动切成 newapi 排名第一的模型,
|
||||
# 导致日常对话不可用(newapi 无 deepseek 渠道),用户手动改回 3 次。
|
||||
# 铁律:model.default 是用户指定的日常对话主模型(付费 deepseek-v4-flash),
|
||||
# 任何自动化脚本都不得修改。只允许优化 providers.newapi-local.default_model(A 段,供 cron/自动化用)。
|
||||
model_default = cfg.get("model", {}).get("default")
|
||||
if model_default:
|
||||
print(f" 🛡️ [{label}] model.default={model_default} 受保护(日常对话主模型),绝不自动修改")
|
||||
|
||||
if changed:
|
||||
with open(config_path, "w") as f:
|
||||
yaml.dump(cfg, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
|
||||
print(f" ✅ [{label}] 排名驱动升级完成")
|
||||
return changed
|
||||
|
||||
_auto_promote_config(CONFIG_PATH, "主配置")
|
||||
_auto_promote_config(os.path.expanduser("~/.hermes-prof-b/config.yaml"), "prof-b")
|
||||
|
||||
# ============ 修复脚本中硬编码的模型名 ============
|
||||
|
||||
def _heal_hardcoded_models():
|
||||
"""扫描并修复 Python 脚本中硬编码的模型名"""
|
||||
# 当前首选模型(质量第一的稳定模型)
|
||||
top_stable = [r for r in results if r["stability"] == "stable"]
|
||||
if not top_stable:
|
||||
return
|
||||
top_stable.sort(key=lambda x: x["rank_score"], reverse=True)
|
||||
best_model = top_stable[0]["model"]
|
||||
|
||||
# 如果首选没变,跳过
|
||||
if best_model == "openai/gpt-oss-120b":
|
||||
return # 当前首选就是 gpt-oss-120b,不用动
|
||||
|
||||
# 需要修复的文件和替换模式
|
||||
fixes = [
|
||||
# daemon.py — 3 个模型常量
|
||||
("daemon.py", 'FAST_MODEL = "openai/gpt-oss-120b"',
|
||||
f'FAST_MODEL = "{best_model}"'),
|
||||
("daemon.py", 'DEEP_MODEL = "openai/gpt-oss-120b"',
|
||||
f'DEEP_MODEL = "{best_model}"'),
|
||||
("daemon.py", 'COMPACTION_MODEL = "openai/gpt-oss-120b"',
|
||||
f'COMPACTION_MODEL = "{best_model}"'),
|
||||
# daemon.py 中硬编码的 API 调用
|
||||
("daemon.py", '"model": "openai/gpt-oss-120b"',
|
||||
f'"model": "{best_model}"'),
|
||||
# wiki_curator.py
|
||||
('wiki_curator.py', 'LLM_MODEL = "openai/gpt-oss-120b"',
|
||||
f'LLM_MODEL = "{best_model}"'),
|
||||
# cangjie_distill.py
|
||||
('cangjie_distill.py', 'model="openai/gpt-oss-120b"',
|
||||
f'model="{best_model}"'),
|
||||
]
|
||||
|
||||
scripts_dir = os.path.expanduser("~/.hermes/scripts")
|
||||
changed = False
|
||||
for filename, old_str, new_str in fixes:
|
||||
filepath = os.path.join(scripts_dir, filename)
|
||||
if not os.path.exists(filepath):
|
||||
continue
|
||||
with open(filepath) as f:
|
||||
content = f.read()
|
||||
if old_str not in content:
|
||||
continue
|
||||
content = content.replace(old_str, new_str)
|
||||
with open(filepath, "w") as f:
|
||||
f.write(content)
|
||||
print(f" 🔧 [{filename}] {old_str.split(chr(34))[1]} → {best_model}")
|
||||
changed = True
|
||||
|
||||
if changed:
|
||||
print(f" ✅ 硬编码模型已全部更新为 {best_model}")
|
||||
|
||||
_heal_hardcoded_models()
|
||||
|
||||
# ============ 蒸馏模型自愈(2026-08-02 新增)============
|
||||
# 守护 zhiyid.service LLM_MODEL + tdai-gateway.yaml model(织忆 distill + TencentDB L1)
|
||||
# 注意:蒸馏需要 JSON 输出能力,不能只看"对话可用"——用 _verify_model_usable 之外
|
||||
# 还要确认模型不是 reasoning 型(content=null)。这里直接复用本脚本的探针结果:
|
||||
# 若配置中的模型在 results 里非 stable,或结果缺失(未测试),则用 JSON 能力复核后替换。
|
||||
|
||||
def _heal_distill_models():
|
||||
import re as _re
|
||||
zhiyid_svc = os.path.expanduser("~/.config/systemd/user/zhiyid.service")
|
||||
tddb_cfg = os.path.expanduser("~/.memory-tencentdb/memory-tdai/tdai-gateway.yaml")
|
||||
if not os.path.exists(zhiyid_svc):
|
||||
return
|
||||
|
||||
# 读取当前蒸馏模型
|
||||
cur = ""
|
||||
try:
|
||||
with open(zhiyid_svc) as f:
|
||||
m = _re.search(r"LLM_MODEL=(\S+)", f.read())
|
||||
if m:
|
||||
cur = m.group(1)
|
||||
except Exception:
|
||||
pass
|
||||
if not cur:
|
||||
return
|
||||
|
||||
# 判断当前模型是否健康
|
||||
# 核心:JSON 探针直接验证(最可靠)。results 仅作辅助——当前模型可能不在
|
||||
# ALL_MODELS 测试列表里(如 gemma-4-31b-it 是后加的),found=None 不代表挂了。
|
||||
found = next((r for r in results if r["model"] == cur), None)
|
||||
is_ok = False
|
||||
try:
|
||||
probe_payload = json.dumps({
|
||||
"model": cur,
|
||||
"messages": [
|
||||
{"role": "system", "content": "输出严格JSON"},
|
||||
{"role": "user", "content": '{"entities":[]}'},
|
||||
],
|
||||
"max_tokens": 50,
|
||||
}).encode()
|
||||
probe_req = urllib.request.Request(
|
||||
f"{API}/chat/completions", data=probe_payload, headers=HEADERS, method="POST")
|
||||
with urllib.request.urlopen(probe_req, timeout=15) as resp:
|
||||
body = json.loads(resp.read())
|
||||
msg = body.get("choices", [{}])[0].get("message", {}) or {}
|
||||
content = msg.get("content") or ""
|
||||
# content 非空且可解析 JSON → 健康
|
||||
if content.strip():
|
||||
import re as _re2
|
||||
cleaned = _re2.sub(r"```json\s*|\s*```", "", content).strip()
|
||||
json.loads(cleaned)
|
||||
is_ok = True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# results 明确判 dead 则覆盖探针结果(探针可能偶发通过)
|
||||
if found is not None and found["stability"] != "stable":
|
||||
is_ok = False
|
||||
print(f" ⚠️ [{cur}] 巡检判定 {found['stability']},需替换")
|
||||
if not is_ok and found is None:
|
||||
print(f" 🔍 [{cur}] 不在巡检列表,JSON 探针未通过,需替换")
|
||||
|
||||
if is_ok:
|
||||
return
|
||||
|
||||
# 找替补:候选池中 stable + JSON 可用(优先 gemma 系列)
|
||||
distill_pool = [
|
||||
"google/gemma-4-31b-it",
|
||||
"mistralai/mistral-nemotron",
|
||||
"nvidia/llama-3.3-nemotron-super-49b-v1.5",
|
||||
"meta/llama-3.1-8b-instruct",
|
||||
"nvidia/nemotron-mini-4b-instruct",
|
||||
]
|
||||
replacement = None
|
||||
for cand in distill_pool:
|
||||
if cand == cur:
|
||||
continue
|
||||
r = next((x for x in results if x["model"] == cand), None)
|
||||
if r is None or r["stability"] != "stable":
|
||||
continue
|
||||
if not _verify_model_usable(cand):
|
||||
continue
|
||||
# JSON 探针复核
|
||||
try:
|
||||
probe_payload = json.dumps({
|
||||
"model": cand,
|
||||
"messages": [{"role": "user", "content": '输出JSON {"entities":["a"]}'}],
|
||||
"max_tokens": 50,
|
||||
}).encode()
|
||||
probe_req = urllib.request.Request(
|
||||
f"{API}/chat/completions", data=probe_payload, headers=HEADERS, method="POST")
|
||||
with urllib.request.urlopen(probe_req, timeout=15) as resp:
|
||||
body = json.loads(resp.read())
|
||||
content = body.get("choices", [{}])[0].get("message", {}).get("content", "") or ""
|
||||
if content.strip():
|
||||
replacement = cand
|
||||
break
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
if not replacement:
|
||||
print(f" ❌ [蒸馏] {cur} 不可用且无可用替补,请人工检查 NewAPI")
|
||||
return
|
||||
|
||||
# 更新 zhiyid.service
|
||||
changed = False
|
||||
try:
|
||||
with open(zhiyid_svc) as f:
|
||||
svc_content = f.read()
|
||||
new_svc = _re.sub(r"LLM_MODEL=\S+", f"LLM_MODEL={replacement}", svc_content)
|
||||
if new_svc != svc_content:
|
||||
with open(zhiyid_svc, "w") as f:
|
||||
f.write(new_svc)
|
||||
subprocess.run(["systemctl", "--user", "daemon-reload"], check=False)
|
||||
subprocess.run(["systemctl", "--user", "restart", "zhiyid"], check=False)
|
||||
changed = True
|
||||
print(f" ✅ [蒸馏] zhiyid.service LLM_MODEL: {cur} → {replacement}")
|
||||
except Exception as e:
|
||||
print(f" ❌ [蒸馏] 更新 zhiyid.service 失败: {e}")
|
||||
|
||||
# 更新 tdai-gateway.yaml
|
||||
if os.path.exists(tddb_cfg):
|
||||
try:
|
||||
with open(tddb_cfg) as f:
|
||||
tddb_content = f.read()
|
||||
new_tddb = _re.sub(r"^(\s*model:\s*)\S+", rf"\g<1>{replacement}", tddb_content, flags=_re.M)
|
||||
if new_tddb != tddb_content:
|
||||
with open(tddb_cfg + ".bak-health", "w") as f:
|
||||
f.write(tddb_content)
|
||||
with open(tddb_cfg, "w") as f:
|
||||
f.write(new_tddb)
|
||||
subprocess.run(["systemctl", "--user", "restart", "tdai-gateway"], check=False)
|
||||
changed = True
|
||||
print(f" ✅ [蒸馏] tdai-gateway.yaml: {cur} → {replacement}")
|
||||
except Exception as e:
|
||||
print(f" ❌ [蒸馏] 更新 tdai-gateway.yaml 失败: {e}")
|
||||
|
||||
_heal_distill_models()
|
||||
|
||||
print(f"\n{'='*50}")
|
||||
print(f"巡检完成: {healthy}个稳定 / {flaky}个不稳定 / {dead}个死 (共{len(results)}个)")
|
||||
if stable_sorted:
|
||||
quality_list = ', '.join(summary['recommendations']['by_quality'])
|
||||
print(f"质量排名: {quality_list}")
|
||||
print(f"首选: {summary['recommendations']['priorities']['首选质量']}")
|
||||
print(f"日常推荐: {summary['recommendations']['priorities']['日常推荐']}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
[Unit]
|
||||
Description=OpenClaw Gateway (v2026.7.1)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
StartLimitBurst=5
|
||||
StartLimitIntervalSec=60
|
||||
|
||||
[Service]
|
||||
ExecStart=/home/muc/nodejs/node-v24.16.0-linux-x64/bin/node /home/muc/nodejs/node-v24.16.0-linux-x64/lib/node_modules/openclaw/dist/index.js gateway --port 18789
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
RestartPreventExitStatus=78
|
||||
TimeoutStopSec=30
|
||||
TimeoutStartSec=30
|
||||
SuccessExitStatus=0 143
|
||||
OOMPolicy=continue
|
||||
KillMode=control-group
|
||||
Environment=OPENCLAW_SERVICE_MANAGED_ENV_KEYS=CREAA_API_KEY
|
||||
Environment=HOME=/home/muc
|
||||
Environment=TMPDIR=/tmp
|
||||
Environment=PATH=/home/muc/nodejs/node-v24.16.0-linux-x64/bin:/usr/local/bin:/usr/bin:/bin:/home/muc/.local/bin:/home/muc/.npm-global/bin:/home/muc/bin:/home/muc/.nix-profile/bin
|
||||
Environment=OPENCLAW_GATEWAY_PORT=18789
|
||||
Environment=OPENCLAW_SYSTEMD_UNIT=openclaw-gateway.service
|
||||
Environment="OPENCLAW_WINDOWS_TASK_NAME=OpenClaw Gateway"
|
||||
Environment=OPENCLAW_WINDOWS_TASK_HIDDEN_LAUNCHER=1
|
||||
Environment=OPENCLAW_SERVICE_MARKER=openclaw
|
||||
Environment=OPENCLAW_SERVICE_KIND=gateway
|
||||
Environment=OPENCLAW_SERVICE_VERSION=2026.7.1
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
[Unit]
|
||||
Description=ZhiYi MemoryWeave (织忆) — Go Daemon
|
||||
Documentation=http://192.168.123.11:3000/xiaoxue_admin/memoryweave
|
||||
After=network.target zhiyi-consolidate.service bge-embed.service
|
||||
Wants=zhiyi-consolidate.service bge-embed.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStartPre=/bin/mkdir -p /var/lib/memoryweave /home/muc/.logs
|
||||
ExecStart=/home/muc/bin/zhiyid-new
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
MemoryMax=2G
|
||||
CPUQuota=200%
|
||||
Environment=STORAGE_BACKEND=lancedb
|
||||
Environment=LLM_ENDPOINT=http://127.0.0.1:3000/v1/chat/completions
|
||||
Environment=LLM_MODEL=meta/llama-3.1-8b-instruct
|
||||
Environment=LLM_API_KEY=0ExNiLblJvIWBDpkS50fwOBw4MmqLyKdHJK5iQtlw9dOMWBP
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
4
.env
4
.env
|
|
@ -22,7 +22,7 @@ QQ_CLIENT_SECRET=tgUI7xneWOHA4zuqmjgecbbbcdfhknrv
|
|||
CNB_TOKEN=7i18PbKx10feWTefNEORER1X4FC
|
||||
|
||||
AGNES_API_KEY=sk-7k9e9KGcoZdDuYt2LSA4YXdBTioczleGJm2zzLWCku072ikW
|
||||
MIMO_API_KEY=tp-c374efhzmz9npodjz5wj1cm008lg4czce6v170nqxwemp12v
|
||||
# [2026-09-12 牧尘:小米模型近期不再使用] MIMO_API_KEY=tp-c374efhzmz9npodjz5wj1cm008lg4czce6v170nqxwemp12v
|
||||
XIAOMI_API_KEY=tp-c374efhzmz9npodjz5wj1cm008lg4czce6v170nqxwemp12v
|
||||
XIAOMI_BASE_URL=https://token-plan-cn.xiaomimimo.com/v1
|
||||
SENSENOVA_API_KEY=sk-QWrtQIu3mmKCvAF2v2OmI4gdljiPdvXO
|
||||
|
|
@ -32,3 +32,5 @@ ZHIPU_API_KEY=70674fdbb8db437f8946c8e5e376139b.pPXThBfxRLj7UdkK
|
|||
GITHUB_TOKEN=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
|
||||
GMI_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6ImFlZGEwZTJmLTI1N2ItNGEwYi04NzBhLWUwZjI3MzQ0NWM2YSIsInNjb3BlIjoiaWVfbW9kZWwiLCJwcm9kdWN0IjoiSUUiLCJvd25lcklkIjoiOTYxZGY1MWUtMjAyMi00ZDZjLWI2YTgtNWMxN2M5NzA1NjEyIn0.7v6kPl4VcNHtOcU3hN2FAMGVEuDxvym1h9FwXZBaD7M
|
||||
GMI_BASE_URL=https://api.gmi-serving.com/v1
|
||||
HERMES_PEER_LOCAL_ORCH_KEY=f1fa45412e7d072d03bc1528bd6330b51697597db06aa616
|
||||
OPENCODE_GO_API_KEY=sk-N4uoeEyJrQKLi8HMvd8WkIx4Hrx70g811wpRnfRD2W0iphRxTwKgr5uFlwEwLMtM
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
FEISHU_APP_ID=cli_a95d7ff06b789bb4
|
||||
FEISHU_APP_SECRET=Gm7eo0aD9Luka8mHxApRufYIDwmpGsGf
|
||||
SUDO_PASSWORD=z1020
|
||||
|
||||
DEEPSEEK_API_KEY=sk-b1212066094d4e319784f23d5b2c6bbd
|
||||
FEISHU_HOME_CHANNEL=oc_cd14ec7518926e57d26c5e339ebba3b3
|
||||
FEISHU_HOME_CHANNEL_THREAD_ID=
|
||||
|
||||
HF_ENDPOINT=https://hf-mirror.com
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
FEISHU_APP_ID=cli_a95d7ff06b789bb4
|
||||
FEISHU_APP_SECRET=Gm7eo0aD9Luka8mHxApRufYIDwmpGsGf
|
||||
SUDO_PASSWORD=z1020
|
||||
|
||||
DEEPSEEK_API_KEY=sk-b1212066094d4e319784f23d5b2c6bbd
|
||||
FEISHU_HOME_CHANNEL=oc_cd14ec7518926e57d26c5e339ebba3b3
|
||||
FEISHU_HOME_CHANNEL_THREAD_ID=
|
||||
|
||||
HF_ENDPOINT=https://hf-mirror.com
|
||||
|
||||
WEIXIN_TOKEN=bef3c3d39904@im.bot:060000740c190c21262c8edf68365d5d112e0d
|
||||
WEIXIN_ACCOUNT_ID=bef3c3d39904@im.bot
|
||||
WEIXIN_BASE_URL=https://ilinkai.weixin.qq.com
|
||||
WEIXIN_USER_ID=o9cq800DqpnMoqzXmJ4zozKiM8OI@im.wechat
|
||||
WEIXIN_DM_POLICY=open
|
||||
WEIXIN_GROUP_POLICY=open
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
FEISHU_APP_ID=cli_a95d7ff06b789bb4
|
||||
FEISHU_APP_SECRET=Gm7eo0aD9Luka8mHxApRufYIDwmpGsGf
|
||||
SUDO_PASSWORD=z1020
|
||||
|
||||
DEEPSEEK_API_KEY=sk-b1212066094d4e319784f23d5b2c6bbd
|
||||
FEISHU_HOME_CHANNEL=oc_cd14ec7518926e57d26c5e339ebba3b3
|
||||
FEISHU_HOME_CHANNEL_THREAD_ID=
|
||||
|
||||
HF_ENDPOINT=https://hf-mirror.com
|
||||
|
||||
WEIXIN_TOKEN=bef3c3d39904@im.bot:060000740c190c21262c8edf68365d5d112e0d
|
||||
WEIXIN_ACCOUNT_ID=bef3c3d39904@im.bot
|
||||
WEIXIN_BASE_URL=https://ilinkai.weixin.qq.com
|
||||
WEIXIN_USER_ID=o9cq800DqpnMoqzXmJ4zozKiM8OI@im.wechat
|
||||
WEIXIN_DM_POLICY=open
|
||||
WEIXIN_GROUP_POLICY=open
|
||||
WEIXIN_ALLOW_ALL_USERS=true
|
||||
|
||||
QQ_APP_ID=1903732343
|
||||
QQ_CLIENT_SECRET=tgUI7xneWOHA4zuqmjgecbbbcdfhknrv
|
||||
|
||||
CNB_TOKEN=7i18PbKx10feWTefNEORER1X4FC
|
||||
|
||||
AGNES_API_KEY=sk-7k9e9KGcoZdDuYt2LSA4YXdBTioczleGJm2zzLWCku072ikW
|
||||
MIMO_API_KEY=tp-c374efhzmz9npodjz5wj1cm008lg4czce6v170nqxwemp12v
|
||||
XIAOMI_API_KEY=tp-c374efhzmz9npodjz5wj1cm008lg4czce6v170nqxwemp12v
|
||||
XIAOMI_BASE_URL=https://token-plan-cn.xiaomimimo.com/v1
|
||||
SENSENOVA_API_KEY=sk-QWrtQIu3mmKCvAF2v2OmI4gdljiPdvXO
|
||||
|
||||
ZHIPU_API_KEY=70674fdbb8db437f8946c8e5e376139b.pPXThBfxRLj7UdkK
|
||||
|
||||
GITHUB_TOKEN=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
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
sessions/
|
||||
cron/output/
|
||||
cron/jobs.json
|
||||
cron/jobs.json.bak-*
|
||||
cron/ticker*
|
||||
cron/*.lock
|
||||
watchdog/
|
||||
|
|
@ -60,3 +61,9 @@ stock_broker.json
|
|||
daemon/context.json
|
||||
daemon/journal.jsonl
|
||||
llm_context.json
|
||||
# 2026-09-17 小怡:运行时噪音/本机快照,不入库
|
||||
checkpoints/
|
||||
*.bak-*
|
||||
*.bak2
|
||||
*.orig
|
||||
*.tmp
|
||||
|
|
|
|||
|
|
@ -1,57 +0,0 @@
|
|||
# 配置保护 .gitignore — 只跟踪关键可恢复配置
|
||||
# 排除所有运行时数据
|
||||
sessions/
|
||||
cron/output/
|
||||
cron/jobs.json
|
||||
cron/ticker*
|
||||
cron/*.lock
|
||||
watchdog/
|
||||
cache/
|
||||
logs/
|
||||
*.db
|
||||
*.db-shm
|
||||
*.db-wal
|
||||
*.log
|
||||
*.png
|
||||
*.jpg
|
||||
*.lock
|
||||
state*
|
||||
gateway*
|
||||
processes.json
|
||||
feishu_seen_message_ids.json
|
||||
channel_directory.json
|
||||
auth.json
|
||||
kanban*
|
||||
pairing/
|
||||
prof-b/
|
||||
profiles/
|
||||
.hub/
|
||||
.curator_backups/
|
||||
.bundled_manifest
|
||||
.curator_state
|
||||
.usage.json*
|
||||
.tirith-install-failed
|
||||
.update_check
|
||||
.hermes_history
|
||||
models_dev_cache.json
|
||||
skill-curator-report.json
|
||||
model-health.json
|
||||
wiki_curator_state.json
|
||||
lsp/
|
||||
cuda-libs/
|
||||
hermes-agent/ # submodule
|
||||
__pycache__/
|
||||
*.pyc
|
||||
node_modules/
|
||||
tmp/
|
||||
.env* # 不跟踪 secrets(有 API key)
|
||||
archive/
|
||||
config.yaml.corrupt.*.bak
|
||||
|
||||
# 股票运行时配置(后端选择是个人偏好,非代码)
|
||||
stock_broker.json
|
||||
|
||||
# 运行时噪音(daemon 每 30s 写入,不跟踪)
|
||||
daemon/context.json
|
||||
daemon/journal.jsonl
|
||||
llm_context.json
|
||||
|
|
@ -25,3 +25,8 @@
|
|||
|
||||
# 2026-08-19 20:29:46.749497
|
||||
+在?
|
||||
|
||||
# 2026-09-12 05:34:23.178227
|
||||
+/compress
|
||||
+
|
||||
+
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"ts": 1789065921.4957573, "behind": -1, "rev": null, "ver": "0.21.0"}
|
||||
{"ts": 1789564216.6682775, "behind": -1, "rev": null, "ver": "0.21.3", "head": "3ad5aaca1ce964e657979c15aaef18c211500b67", "target": "784d5c3f9c2cb77698d8a9d2e72b1d106a38ea88"}
|
||||
12
README.md
12
README.md
|
|
@ -1,6 +1,6 @@
|
|||
# 小唯系统 (xiaowei-system)
|
||||
# 小怡系统 (xiaowei-system)
|
||||
|
||||
> 小唯 A06 的大脑层 | Gitea: http://192.168.123.11:3000/xiaoxue_admin/xiaowei-system/
|
||||
> 小怡 A06 的大脑层 | Gitea: http://192.168.123.11:3000/xiaoxue_admin/xiaowei-system/
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -19,7 +19,7 @@
|
|||
│ HTTP API(localhost)
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 上层应用层(小唯系统 xiaowei-system) │
|
||||
│ 上层应用层(小怡系统 xiaowei-system) │
|
||||
│ │
|
||||
│ ~/.hermes/ ← 本仓库 │
|
||||
│ │
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
第二步:TencentDB(对话记忆)
|
||||
→ ~/.memory-tencentdb/,port 8420
|
||||
↓
|
||||
第三步:小唯系统(上层应用)
|
||||
第三步:小怡系统(上层应用)
|
||||
→ ~/.hermes/,daemon.py
|
||||
```
|
||||
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
## 架构依赖
|
||||
|
||||
```
|
||||
小唯系统(daemon.py)
|
||||
小怡系统(daemon.py)
|
||||
├── http://127.0.0.1:7821 ← 织忆 L1/L2 recall(X-API-Key)
|
||||
├── http://127.0.0.1:8420 ← TencentDB L3/L4 scenes(/capture + /recall)
|
||||
├── ~/.hermes/soulful/ ← Soulful L5/L6(cares + heart-traces + profile)
|
||||
|
|
@ -83,7 +83,7 @@
|
|||
|
||||
---
|
||||
|
||||
## 小唯系统内容
|
||||
## 小怡系统内容
|
||||
|
||||
```
|
||||
~/.hermes/ ← xiaowei-system 仓库
|
||||
|
|
|
|||
|
|
@ -17,6 +17,55 @@
|
|||
- state-20260907-0000.db(integrity_check=ok,00:00)——今晚以此为基线
|
||||
- 校验方法:sqlite3 -readonly <snap> 'PRAGMA integrity_check;' 必须返回 ok
|
||||
|
||||
## FTS 索引损坏(`messages_fts`)—— 2026-09-13 立
|
||||
|
||||
### 症状 / 报警
|
||||
`fts-stale 运行期兜底 watch`(cron `bc31e3533d40`,every 30m,no_agent)输出形如:
|
||||
```
|
||||
[FTS-WATCH] 🟠 FTS 索引损坏(blob 级): fts5: corruption found reading blob 1649267441665 from table "messages_fts"
|
||||
```
|
||||
(旧版文案是 `✅ 无 stale 标记 integrity=<corruption>` —— 首行像绿灯,2026-09-13 已改为首行直接报损坏。)
|
||||
|
||||
### 先判范围(只读,**不要**直接当全库坏了)
|
||||
```bash
|
||||
# 只读 + immutable(禁止普通 connect 活库)
|
||||
# messages / sessions 计数正常 + MATCH 查询仍可用 ⇒ 数据在、只是索引局部坏
|
||||
# 本次(2026-09-13 21:5x)实测:state.db 410MB、messages 81019 ✅、sessions 402 ✅、
|
||||
# `SELECT count(*) FROM messages_fts WHERE messages_fts MATCH 'gateway'` ✅ 正常返回
|
||||
```
|
||||
⇒ blob 级损坏 ≠ 数据丢失;`LIKE` 降级/搜索退化才是实际影响。**先取证,再谈停机。**
|
||||
|
||||
### 🔴 2026-09-13 当日实测:**多数情况会自愈,不必上停机窗口**
|
||||
| 时间 | 观测 |
|
||||
|---|---|
|
||||
| 21:52 | watch 报 `fts5: corruption found reading blob 1649267441665 from table "messages_fts"` |
|
||||
| 22:32 | 同一脚本 + `sqlite3 -readonly … 'PRAGMA quick_check;'` → **`ok`**;MATCH 查询正常;messages 81252 / sessions 403 可读 |
|
||||
⇒ 结论:**SessionDB 自然 open(网关/会话正常开关)就会走 `_recover_stale_fts`**,多数 blob 级损坏在下一轮 open 就被修掉。
|
||||
**流程修正**:watch 报警 → **先只读复验**(本文上一条)→ 若已 ok 就**结案**(由 watch 的「✅ 已恢复」通知收尾),
|
||||
只有**复验仍坏**才排停机窗口。别一收到报警就安排停机。
|
||||
|
||||
### 修复(必须停机窗口,禁止在线手术)
|
||||
铁律:**live write / search 不得 rebuild 全量 FTS**(测试不变量
|
||||
`tests/state/test_fts_runtime_rebuild.py`);在线起第二个写入者 = 本机反复损坏的 P1-1 根因。
|
||||
|
||||
```bash
|
||||
# 1) 停机(走本文件开头的铁律 1,先确认无进程持有)
|
||||
systemctl --user stop hermes-gateway
|
||||
lsof ~/.hermes/state.db # 必须无输出
|
||||
# 2) 让 SessionDB open 自动恢复(首选,无需手写 SQL)
|
||||
hermes --cli -q "/quit" 2>/dev/null || hermes -q "ping" # 触发一次 open → _recover_stale_fts
|
||||
# 或手动重建:sqlite3 state.db "INSERT INTO messages_fts(messages_fts) VALUES('rebuild');"
|
||||
# 3) 起网关
|
||||
systemctl --user start hermes-gateway
|
||||
# 4) 复验:watch 下一次 tick 应静默;或
|
||||
python3 ~/.hermes/scripts/fts-stale-watch.py # 期望:无输出(健康静默)
|
||||
```
|
||||
|
||||
### 红线
|
||||
1. ❌ 网关运行时**不许** `INSERT INTO messages_fts(...) VALUES('rebuild')`、不许 VACUUM、不许换库
|
||||
2. ❌ 不许 `rm` 活库的 `-wal` / `-shm`(本文件开头的铁律 3)
|
||||
3. ⏱ 一次只允许一个操作者(铁律 5);动手前后各留一份 `snapshot-state-db.sh` 快照
|
||||
|
||||
## 快速恢复 SOP
|
||||
systemctl --user stop hermes-gateway
|
||||
lsof ~/.hermes/state.db # 必须无输出
|
||||
|
|
|
|||
2
USER.md
2
USER.md
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
牧尘对记忆系统合并统一后的架构:MEMORY.md 只保留核心身份和配置,所有事实/偏好/项目信息存织忆(语义搜索召回)。
|
||||
|
||||
织忆设计文档:~/mc/小唯/07-Wiki/concepts/织忆(MemoryWeave)-v2.9-目标C-HermesOpenClaw迁移织忆.md
|
||||
织忆设计文档:~/mc/小怡/07-Wiki/concepts/织忆(MemoryWeave)-v2.9-目标C-HermesOpenClaw迁移织忆.md
|
||||
织忆项目:/home/muc/projects/zhiyi/
|
||||
hermes-zhiyi-bridge 插件:~/.hermes/plugins/zhiyi/(已配置 memory.provider=zhiyi)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
{
|
||||
"version": 1,
|
||||
"providers": {},
|
||||
"credential_pool": {
|
||||
"minimax": [],
|
||||
"custom:newapi-local": [
|
||||
{
|
||||
"id": "1264e8",
|
||||
"label": "newapi-local",
|
||||
"auth_type": "api_key",
|
||||
"priority": 0,
|
||||
"source": "config:newapi-local",
|
||||
"last_status": "ok",
|
||||
"last_status_at": null,
|
||||
"last_error_code": null,
|
||||
"last_error_reason": null,
|
||||
"last_error_message": null,
|
||||
"last_error_reset_at": null,
|
||||
"base_url": "http://127.0.0.1:3000/v1",
|
||||
"request_count": 0,
|
||||
"secret_fingerprint": "sha256:cc6225a1be5c62b7"
|
||||
}
|
||||
],
|
||||
"deepseek": [
|
||||
{
|
||||
"id": "5fe4e0",
|
||||
"label": "DEEPSEEK_API_KEY",
|
||||
"auth_type": "api_key",
|
||||
"priority": 0,
|
||||
"source": "env:DEEPSEEK_API_KEY",
|
||||
"last_status": null,
|
||||
"last_status_at": null,
|
||||
"last_error_code": null,
|
||||
"last_error_reason": null,
|
||||
"last_error_message": null,
|
||||
"last_error_reset_at": null,
|
||||
"base_url": "https://api.deepseek.com/v1",
|
||||
"request_count": 0,
|
||||
"secret_fingerprint": "sha256:43dc55497d2c7fdc"
|
||||
}
|
||||
],
|
||||
"custom:omniroute-local": [
|
||||
{
|
||||
"id": "273e72",
|
||||
"label": "omniroute-local",
|
||||
"auth_type": "api_key",
|
||||
"priority": 0,
|
||||
"source": "config:omniroute-local",
|
||||
"last_status": null,
|
||||
"last_status_at": null,
|
||||
"last_error_code": null,
|
||||
"last_error_reason": null,
|
||||
"last_error_message": null,
|
||||
"last_error_reset_at": null,
|
||||
"base_url": "http://127.0.0.1:3001/v1",
|
||||
"request_count": 0,
|
||||
"secret_fingerprint": "sha256:ed80667ec3d95b40"
|
||||
}
|
||||
]
|
||||
},
|
||||
"updated_at": "2026-08-01T12:50:10.806262+00:00",
|
||||
"active_provider": null
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780411774526664129
|
||||
category: distilled
|
||||
quality_score: 0.64
|
||||
sync_time: 2026-06-05T18:32:26+08:00
|
||||
---
|
||||
|
||||
# å½åè®°å¿åºå
å« 1665 æ¡è®°å¿ï¼å¬åç 99%ï¼æç...
|
||||
|
||||
å½åè®°å¿åºå
å« 1665 æ¡è®°å¿ï¼å¬åç 99%ï¼æç¨ç 98%ã
|
||||
|
||||
---
|
||||
*ç±ç»å¿ MemoryWeave 忥*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: test001
|
||||
category: test
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-05-31T13:32:16+08:00
|
||||
---
|
||||
|
||||
# test memory
|
||||
|
||||
test memory
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
Binary file not shown.
|
|
@ -1,6 +0,0 @@
|
|||
|
||||
# Added by `ao init`
|
||||
AO_PROVIDER=openai
|
||||
AO_MODEL=meta/llama-3.1-70b-instruct
|
||||
OPENAI_BASE_URL=http://127.0.0.1:3000/v1
|
||||
OPENAI_API_KEY=0ExNiLblJvIWBDpkS50fwOBw4MmqLyKdHJK5iQtlw9dOMWBP
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780211449154506658
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# E1 图谱导航激活完æˆ<C3A6>,清除残留 debug è¯å<C2AD>¥ï¼ŒåŠ...
|
||||
|
||||
E1 图谱导航激活完æˆ<C3A6>,清除残留 debug è¯å<C2AD>¥ï¼ŒåŠŸèƒ½å·²æŽ¥å…¥
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave å<>Œæ¥*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780216039197704885
|
||||
category: episodes
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# E4 图谱推理全部完成 E4.1 中文矛盾检测 E4.2 跨...
|
||||
|
||||
E4 图谱推理全部完成 E4.1 中文矛盾检测 E4.2 跨 agent 知识共享 E4.3 图谱度遗忘决策
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780324931940599843
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# E4.3 å˜åœ¨ bug admin.go:73 拿的是 mem namespace å—æ®µä¸...
|
||||
|
||||
E4.3 å˜åœ¨ bug admin.go:73 拿的是 mem namespace å—æ®µä¸<C3A4>å˜åœ¨
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave å<>Œæ¥*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780230800484584669
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# E5 鈭批<E988AD> UI <20>臬<EFBFBD><E887AC>滨<EFBFBD><E6BBA8><EFBFBD>憭抒<E686AD><E68A92>選<EFBFBD><E981B8><EFBFBD><EFBFBD>舀沲<E88880><E6B2B2><EFBFBD>鈭𡒊<E988AD>...
|
||||
|
||||
E5 鈭批<E988AD> UI <20>臬<EFBFBD><E887AC>滨<EFBFBD><E6BBA8><EFBFBD>憭抒<E686AD><E68A92>選<EFBFBD><E981B8><EFBFBD><EFBFBD>舀沲<E88880><E6B2B2><EFBFBD>鈭𡒊<E988AD><F0A1928A><EFBFBD><EFBFBD>蝻箔<E89DBB><E7AE94>航<EFBFBD><E888AA>𣇉<EFBFBD><F0A38789>g<EFBFBD>隞<EFBFBD>𣈲<EFBFBD><F0A388B2> API 靚<>鍂<EFBFBD><E98D82>
|
||||
|
||||
---
|
||||
*<2A>梁<EFBFBD>敹<EFBFBD> MemoryWeave <20>峕郊*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780185320535437423
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# G6 完成后的对话反馈
|
||||
|
||||
G6 完成后的对话反馈
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780230801019061019
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# G7 é<>—忘 + æŠ€èƒ½ç³»ç»Ÿçš„ç›®æ ‡æ˜¯è®© agent 记录已使ç”...
|
||||
|
||||
G7 é<>—忘 + æŠ€èƒ½ç³»ç»Ÿçš„ç›®æ ‡æ˜¯è®© agent 记录已使用的 skills,并利用记忆优化å<E28093>Žç»çš„ skill 调用。
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave å<>Œæ¥*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780742697986315655
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# Server 配置已更新,memory.provider 指向本地 zhiyi ...
|
||||
|
||||
Server 配置已更新,memory.provider 指向本地 zhiyi 服务
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780210527061653067
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# WORKLOG 已更新 E1 状态、提交记录及下一步计划
|
||||
|
||||
WORKLOG 已更新 E1 状态、提交记录及下一步计划
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780138789025136676
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 织忆 API key 更正:正确 key 是 zhiyi-dev-key-2026
|
||||
|
||||
织忆 API key 更正:正确 key 是 zhiyi-dev-key-2026
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780182222988134153
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 当前 G1 至 G6 全部完成,G7 和 G8 待执行
|
||||
|
||||
当前 G1 至 G6 全部完成,G7 和 G8 待执行
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780230800637705441
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 竞品 Mem0 和 Supermemory 已具备 Web UI 功能。
|
||||
|
||||
竞品 Mem0 和 Supermemory 已具备 Web UI 功能。
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780500766383556075
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 选定 agnes-2.0-flash 作为文本生成模型,agnes-imag...
|
||||
|
||||
选定 agnes-2.0-flash 作为文本生成模型,agnes-image-2.1-flash 作为图像生成模型。
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780411349396158812
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 修改 core.go 移除 commit 时的 InsertMemory 调用
|
||||
|
||||
修改 core.go 移除 commit 时的 InsertMemory 调用
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780411349273672692
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 修改 recall.go 增加过滤逻辑及 helper 函数
|
||||
|
||||
修改 recall.go 增加过滤逻辑及 helper 函数
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780192847041774431
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 全部å<C2A8>š - 完æˆ<C3A6>了 cluster_only vs full 调度ç–略修å¤...
|
||||
|
||||
全部å<EFBFBD>š - 完æˆ<C3A6>了 cluster_only vs full 调度ç–略修å¤<C3A5>
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave å<>Œæ¥*
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
id: mem_1780247779615465363
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 用户: Cronjob Response: 织忆状态看板
|
||||
\(job\_id: e2d5...
|
||||
|
||||
用户: Cronjob Response: 织忆状态看板
|
||||
\(job\_id: e2d5a98bff74\)
|
||||
---
|
||||
🧠 织忆看板 \[2026\-05\-31 23:16\]
|
||||
━━━━━━━━━━━...
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
id: mem_1780488889894489881
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 用户: E5.1 Obsidian æ<>’件增强
|
||||
助手: 现在我清楚äº...
|
||||
|
||||
用户: E5.1 Obsidian æ<>’件增强
|
||||
助手: 现在我清楚了当å‰<C3A5>æ<EFBFBD>’件功能。现有能力:
|
||||
|
||||
**已实现:** MemoryView(分页) + GraphView(D3力导å<C2BC>‘图) + SearchM...
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave å<>Œæ¥*
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
---
|
||||
id: mem_1780490156091265808
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 用户: 全部都è¦<C3A8>
|
||||
助手: ✅ 全部完æˆ<C3A6>,commit å·²æ<C2B2>...
|
||||
|
||||
用户: 全部都è¦<C3A8>
|
||||
助手: ✅ 全部完æˆ<C3A6>,commit å·²æ<C2B2><C3A6>交。
|
||||
|
||||
**E5.1 织忆æ<E280A0>’ä»¶ v1.1 新增功能:**
|
||||
|
||||
| 功能 | 说明 |
|
||||
|------|------|
|
||||
| **记忆展开详情** ...
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave å<>Œæ¥*
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
id: mem_1780163606924689282
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 用户: ä½ åŽ»æ›´æ–°ä¸€ä¸‹å·¥ä½œè®°å½•
|
||||
助手: 已更新两ä...
|
||||
|
||||
用户: ä½ åŽ»æ›´æ–°ä¸€ä¸‹å·¥ä½œè®°å½•
|
||||
助手: 已更新两个地方:
|
||||
|
||||
**1. `~/projects/memoryweave/WORKLOG.md`**(项目内æ<E280A6>ƒå¨<C3A5>记录)
|
||||
- G6 补全 G6.1/G6.2/G...
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave å<>Œæ¥*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780411348736740409
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 决定将 raw 内容仅写入 episodes 表,待蒸馏后再...
|
||||
|
||||
决定将 raw 内容仅写入 episodes 表,待蒸馏后再写入 memories 表
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780411349018603824
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 决定在 recall 阶段过滤掉原始对è¯<C3A8>,仅返回蒸é...
|
||||
|
||||
决定在 recall 阶段过滤掉原始对è¯<C3A8>,仅返回蒸é¦<C3A9>å<EFBFBD>Žçš„结构化记忆
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave å<>Œæ¥*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780088802674014314
|
||||
category: system_fact
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 牧尘用Arch Linux和RTX 3050做ComfyUI图像生成和AI开...
|
||||
|
||||
牧尘用Arch Linux和RTX 3050做ComfyUI图像生成和AI开发
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780106476615792515
|
||||
category: test
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 修复验证 - schema 类型匹配测试
|
||||
|
||||
修复验证 - schema 类型匹配测试
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780157836513081716
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 用户反馈 G6 完成
|
||||
|
||||
用户反馈 G6 完成
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780183370496705555
|
||||
category: episodes
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 用户反馈 G6 完成后系统状态
|
||||
|
||||
用户反馈 G6 完成后系统状态
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780742697217806784
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 决定使用 Ollama çš„ bgem3:latest 模型作为织忆系ç»...
|
||||
|
||||
决定使用 Ollama çš„ bgem3:latest 模型作为织忆系统的嵌入æœ<C3A6>务
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave å<>Œæ¥*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780742698743211773
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 如何实现 Windows 环境下的服务持久化(当前为...
|
||||
|
||||
如何实现 Windows 环境下的服务持久化(当前为内存模式)
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780184518748535937
|
||||
category: test
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 验证修复 recall_count 更新测试
|
||||
|
||||
验证修复 recall_count 更新测试
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780173868603415336
|
||||
category: test
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 测试记忆
|
||||
|
||||
测试记忆
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780157018435205382
|
||||
category: episodes
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 用户说停止 - 停止执行
|
||||
|
||||
用户说停止 - 停止执行
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780088707259935764
|
||||
category: system_fact
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 验证蒸馏: 牧尘用Arch Linux + RTX3050跑ComfyUI生成A...
|
||||
|
||||
验证蒸馏: 牧尘用Arch Linux + RTX3050跑ComfyUI生成AI图像
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780277902407300683
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 系统召回率为 98%,其中有用率为 97%
|
||||
|
||||
系统召回率为 98%,其中有用率为 97%
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780247779615465363
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 织忆状态看板 Cronjob Response 2026-05-31 23:16
|
||||
|
||||
织忆状态看板 Cronjob Response 2026-05-31 23:16
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780162614946495307
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 牧尘将织忆的 LLM 模型质量回溯功能从 MiniMax M...
|
||||
|
||||
牧尘将织忆的 LLM 模型质量回溯功能从 MiniMax M2.7 切换至 Qwen3.5-122B
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780746342890861684
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 确定必须备份 Memoryã€<C3A3>图谱ã€<C3A3>å<EFBFBD>‘é‡<C3A9>ã€<C3A3>Episodes å<>Šå¢...
|
||||
|
||||
确定必须备份 Memoryã€<C3A3>图谱ã€<C3A3>å<EFBFBD>‘é‡<C3A9>ã€<C3A3>Episodes å<>Šå¢“ç¢‘ç‰æ ¸å¿ƒæ•°æ<C2B0>®æ–‡ä»¶
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave å<>Œæ¥*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780210527086154927
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 代码提交包含 commit cd0f898、cc615c5 及本次 E1 deb...
|
||||
|
||||
代码提交包含 commit cd0f898、cc615c5 及本次 E1 debug cleanup
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780421906656086043
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 执行部署命令
|
||||
|
||||
执行部署命令
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780411774526664129
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 当å‰<C3A5>记忆库包å<E280A6>« 1665 æ<>¡è®°å¿†ï¼Œå<C592>¬å›žçއ 99%,有ç”...
|
||||
|
||||
当å‰<EFBFBD>记忆库包å<EFBFBD>« 1665 æ<>¡è®°å¿†ï¼Œå<C592>¬å›žçއ 99%,有用率 98%。
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave å<>Œæ¥*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780491044519311381
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 决定安装并启用 Obsidian 插件“织忆”(zhiyi-me...
|
||||
|
||||
决定安装并启用 Obsidian 插件“织忆”(zhiyi-memory)
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780108734922679915
|
||||
category: test
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 闥ク鬥丞粥閭ス豬玖ッ廟1780108734713091537縲らサ<E38289>ソ<EFBFBD>頂鬥丞シ墓梼<E5A293>...
|
||||
|
||||
闥ク鬥丞粥閭ス豬玖ッ廟1780108734713091537縲らサ<EFBFBD>ソ<EFBFBD>頂鬥丞シ墓梼菫ョ螟埼ェ瑚ッ<EFBFBD>シ壽悽谺。謠蝉コ、逕ィ莠朱ェ瑚ッ∬頂鬥丈コァ迚ゥ譏ッ蜷ヲ謌仙粥蝗槫<EFBFBD>隶ー蠢<EFBFBD>コ薙る「<EFBFBD>悄扈剰ソ<EFBFBD>頂鬥丞錘<EFBFBD>鍬LM莨壽署蜿紋コ句ョ槫ケカ莠ァ蜃コ荳譚。distilled邀サ蛻ォ隶ー蠢<EFBFBD><EFBFBD>
|
||||
|
||||
---
|
||||
*逕ア扈<EFBDB1>ソ<EFBFBD> MemoryWeave 蜷梧ュ・*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780108812798977244
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# <20>賊<EFBFBD><E8B38A>蠘<EFBFBD>瘚贝<E7989A><E8B49D>其<EFBFBD> 20260530 abc123 蝏<><E89D8F><EFBFBD>賊<EFBFBD>撘閙<E69298><E99699>...
|
||||
|
||||
<EFBFBD>賊<EFBFBD><EFBFBD>蠘<EFBFBD>瘚贝<EFBFBD><EFBFBD>其<EFBFBD> 20260530 abc123 蝏<><E89D8F><EFBFBD>賊<EFBFBD>撘閙<E69298>靽桀<E99DBD>撉諹<E69289>
|
||||
|
||||
---
|
||||
*<2A>梁<EFBFBD>敹<EFBFBD> MemoryWeave <20>峕郊*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780491044810312655
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 将插件文件部署至 ~/mc/.obsidian/plugins/zhiyi-memory...
|
||||
|
||||
将插件文件部署至 ~/mc/.obsidian/plugins/zhiyi-memory/
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780106616343688588
|
||||
category: test
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 全部修复验证通过
|
||||
|
||||
全部修复验证通过
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780162597589274671
|
||||
category: episodes
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 用户让你再测试一下 - 完整测试结果 Commit Reca...
|
||||
|
||||
用户让你再测试一下 - 完整测试结果 Commit Recall Consolidation Self-optimization Gaps Eval Metrics
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780183019674517781
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# 测试目标是验证多次 commit 的稳定性
|
||||
|
||||
测试目标是验证多次 commit 的稳定性
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780183019533562257
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 正在进行第二轮测试
|
||||
|
||||
正在进行第二轮测试
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780108729593319471
|
||||
category: test
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# <20>賊<EFBFBD><E8B38A>蠘<EFBFBD>瘚贝<E7989A><E8B49D>其<EFBFBD>_20260530_abc123<32><33><EFBFBD>敹<EFBFBD>𡢄擐誩<E69390><E8AAA9>...
|
||||
|
||||
<EFBFBD>賊<EFBFBD><EFBFBD>蠘<EFBFBD>瘚贝<EFBFBD><EFBFBD>其<EFBFBD>_20260530_abc123<EFBFBD><EFBFBD><EFBFBD>敹<EFBFBD>𡢄擐誩<EFBFBD><EFBFBD>𦒘耨憭漤<EFBFBD>霂<EFBFBD><EFBFBD><EFBFBD>祆活<EFBFBD>𣂷漱<EFBFBD>其<EFBFBD>撉諹<EFBFBD><EFBFBD>賊<EFBFBD>鈭抒<EFBFBD><EFBFBD>臬炏<EFBFBD>𣂼<EFBFBD><EFBFBD>𧼮<EFBFBD>霈啣<EFBFBD>摨瓐<EFBFBD><EFBFBD><EFBFBD><EFBFBD>毺<EFBFBD><EFBFBD>頣<EFBFBD>蝏讛<EFBFBD>銝<EFBFBD>畾菜𧒄<EFBFBD>游<EFBFBD>嚗諹砲<EFBFBD><EFBFBD>捆隡朞◤LLM霂<EFBFBD><EFBFBD>撟嗆<EFBFBD><EFBFBD>碶<EFBFBD>摰痹<EFBFBD>餈嗘<EFBFBD>鈭见<EFBFBD>雿靝蛹distilled蝐餃<EFBFBD>霈啣<EFBFBD><EFBFBD>坔<EFBFBD>LanceDB嚗<EFBFBD>虾<EFBFBD>朞<EFBFBD>recall<EFBFBD>亙藁<EFBFBD>亥砭<EFBFBD><EFBFBD>
|
||||
|
||||
---
|
||||
*<2A>梁<EFBFBD>敹<EFBFBD> MemoryWeave <20>峕郊*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780135707686504799
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# 测试记忆:å°<C3A5>å”¯çš„å†…å˜æ<CB9C>’件检查,2026-05-30,æŒ...
|
||||
|
||||
测试记忆:å°<EFBFBD>å”¯çš„å†…å˜æ<EFBFBD>’件检查,2026-05-30ï¼ŒæŒ‡æ ‡æ£å¸¸ï¼štotal_memories=1239,recall_hit_rate=93%,recall_usefulness_rate=84%
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave å<>Œæ¥*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780209682485894413
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# col_vector 已添加对 FixedSizeListArray 的读取支持
|
||||
|
||||
col_vector 已添加对 FixedSizeListArray 的读取支持
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780161904590956279
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-02T04:34:06+08:00
|
||||
---
|
||||
|
||||
# deploy/ 目录下的 service 文件需要同步更新
|
||||
|
||||
deploy/ 目录下的 service 文件需要同步更新
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: t1
|
||||
category:
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-05T14:05:12+08:00
|
||||
---
|
||||
|
||||
# test1
|
||||
|
||||
test1
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: t2
|
||||
category:
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-05T14:05:12+08:00
|
||||
---
|
||||
|
||||
# test2
|
||||
|
||||
test2
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: t3
|
||||
category:
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-05T14:05:12+08:00
|
||||
---
|
||||
|
||||
# test3
|
||||
|
||||
test3
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: t4
|
||||
category:
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-05T14:05:12+08:00
|
||||
---
|
||||
|
||||
# test4
|
||||
|
||||
test4
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: t5
|
||||
category:
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-05T14:05:12+08:00
|
||||
---
|
||||
|
||||
# test5
|
||||
|
||||
test5
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780136502075098763
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# total_memories 值为 1239
|
||||
|
||||
total_memories 值为 1239
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780390427126563986
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# zhiyi entity 显示邻居数和关联记忆
|
||||
|
||||
zhiyi entity 显示邻居数和关联记忆
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780390426897381532
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# zhiyi recall 执行语义搜索返回 top-10
|
||||
|
||||
zhiyi recall 执行语义搜索返回 top-10
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780390426785260190
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-07T16:00:41+08:00
|
||||
---
|
||||
|
||||
# zhiyi tree 按 category 分组记忆树
|
||||
|
||||
zhiyi tree 按 category 分组记忆树
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780180846266397821
|
||||
category:
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-05T08:58:34+08:00
|
||||
---
|
||||
|
||||
# --help
|
||||
|
||||
--help
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
---
|
||||
type: concept
|
||||
namespace: shared
|
||||
pagerank: 0.0005
|
||||
connections: 6
|
||||
source: 织忆图谱
|
||||
---
|
||||
|
||||
# 📘 04-Archive 保持
|
||||
|
||||
**类型**: concept | **命名空间**: shared | **PageRank**: 0.0005
|
||||
|
||||
## 🔗 关联到
|
||||
|
||||
- [[n_hermes_memory_db_lancedb_539条_97mb_需迁移脚本移到织忆api_两个zhiyi插件_plugins_zhiyi|hermes memory_db lancedb 539条 97MB 需迁移脚本移到织忆API 两个zhi...]] — `related_to` (强度 50%)
|
||||
- [[n_v3_8|v3 8]] — `related_to` (强度 50%)
|
||||
- [[n_活跃|活跃]] — `related_to` (强度 50%)
|
||||
- [[n_活跃_p6|活跃 P6]] — `related_to` (强度 50%)
|
||||
|
||||
## 📥 被关联
|
||||
|
||||
- [[n_lancedb|LanceDB]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_保持|保持]] — `related_to` → 我 (强度 50%)
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
---
|
||||
type: concept
|
||||
namespace: hermes-main
|
||||
pagerank: 0.0005
|
||||
connections: 21
|
||||
source: 织忆图谱
|
||||
---
|
||||
|
||||
# 📘 11
|
||||
|
||||
**类型**: concept | **命名空间**: hermes-main | **PageRank**: 0.0005
|
||||
|
||||
## 🔗 关联到
|
||||
|
||||
- [[n_81|81]] — `related_to` (强度 50%)
|
||||
- [[n_default_70|default 70]] — `related_to` (强度 50%)
|
||||
- [[n_muc_11|muc 11]] — `related_to` (强度 50%)
|
||||
- [[n_opt-5|OPT-5]] — `related_to` (强度 50%)
|
||||
- [[n_true|True]] — `related_to` (强度 50%)
|
||||
- [[n_v4_0_0|v4 0 0]] — `related_to` (强度 50%)
|
||||
- [[n_一致性检查|一致性检查]] — `related_to` (强度 50%)
|
||||
- [[n_健康监控|健康监控]] — `related_to` (强度 50%)
|
||||
- [[n_后台批量|后台批量]] — `related_to` (强度 50%)
|
||||
- [[n_工具|工具]] — `related_to` (强度 50%)
|
||||
- [[n_异步写入队列|异步写入队列]] — `related_to` (强度 50%)
|
||||
- [[n_当前数据|当前数据]] — `related_to` (强度 50%)
|
||||
- [[n_文档已更新到|文档已更新到]] — `related_to` (强度 50%)
|
||||
- [[n_时返回全量|时返回全量]] — `related_to` (强度 50%)
|
||||
- [[n_统计|统计]] — `related_to` (强度 50%)
|
||||
|
||||
## 📥 被关联
|
||||
|
||||
- [[n_lancedb|LanceDB]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_ollama|Ollama]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_api|API]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_fts|FTS]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_无|无]] — `related_to` → 我 (强度 50%)
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
---
|
||||
type: concept
|
||||
namespace: shared
|
||||
pagerank: 0.0005
|
||||
connections: 12
|
||||
source: 织忆图谱
|
||||
---
|
||||
|
||||
# 📘 12
|
||||
|
||||
**类型**: concept | **命名空间**: shared | **PageRank**: 0.0005
|
||||
|
||||
## 🔗 关联到
|
||||
|
||||
- [[n_api|API]] — `uses` (强度 50%)
|
||||
- [[n_你的个人资料|你的个人资料]] — `uses` (强度 50%)
|
||||
- [[n_写脚本逐条|写脚本逐条]] — `uses` (强度 50%)
|
||||
- [[n_到织忆|到织忆]] — `uses` (强度 50%)
|
||||
- [[n_前|前]] — `uses` (强度 50%)
|
||||
- [[n_这是切换|这是切换]] — `uses` (强度 50%)
|
||||
- [[n_验证回忆准确|验证回忆准确]] — `uses` (强度 50%)
|
||||
|
||||
## 📥 被关联
|
||||
|
||||
- [[n_行|行]] — `uses` → 我 (强度 50%)
|
||||
- [[n_合并|合并]] — `uses` → 我 (强度 50%)
|
||||
- [[n_hermes|Hermes]] — `uses` → 我 (强度 50%)
|
||||
- [[n_条|条]] — `uses` → 我 (强度 50%)
|
||||
- [[n_内容|内容]] — `uses` → 我 (强度 50%)
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
---
|
||||
type: concept
|
||||
namespace: hermes-main
|
||||
pagerank: 0.0006
|
||||
connections: 15
|
||||
source: 织忆图谱
|
||||
---
|
||||
|
||||
# 📘 1500ms text RTX
|
||||
|
||||
**类型**: concept | **命名空间**: hermes-main | **PageRank**: 0.0006
|
||||
|
||||
## 🔗 关联到
|
||||
|
||||
- [[n_3050|3050]] — `uses` (强度 50%)
|
||||
- [[n_3050|3050]] — `related_to` (强度 50%)
|
||||
- [[n_4gb_compute|4GB compute]] — `uses` (强度 50%)
|
||||
- [[n_4gb_compute|4GB compute]] — `related_to` (强度 50%)
|
||||
- [[n_8_6_2_9gib|8 6 2 9GiB]] — `uses` (强度 50%)
|
||||
- [[n_mobile|Mobile]] — `uses` (强度 50%)
|
||||
- [[n_mobile|Mobile]] — `related_to` (强度 50%)
|
||||
- [[n_可用|可用]] — `uses` (强度 50%)
|
||||
|
||||
## 📥 被关联
|
||||
|
||||
- [[n_ollama|Ollama]] — `uses` → 我 (强度 50%)
|
||||
- [[n_脚本|脚本]] — `uses` → 我 (强度 50%)
|
||||
- [[n_cpu|CPU]] — `uses` → 我 (强度 50%)
|
||||
- [[n_ollama|Ollama]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_需|需]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_脚本|脚本]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_cpu|CPU]] — `related_to` → 我 (强度 50%)
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
---
|
||||
type: concept
|
||||
namespace: hermes-main
|
||||
pagerank: 0.0010
|
||||
connections: 42
|
||||
source: 织忆图谱
|
||||
---
|
||||
|
||||
# 📘 17GB
|
||||
|
||||
**类型**: concept | **命名空间**: hermes-main | **PageRank**: 0.0010
|
||||
|
||||
## 🔗 关联到
|
||||
|
||||
- [[n_200mb|200MB]] — `uses` (强度 50%)
|
||||
- [[n_300mb|300MB]] — `uses` (强度 50%)
|
||||
- [[n_5_2g|5 2G]] — `uses` (强度 50%)
|
||||
- [[n_二进制|二进制]] — `uses` (强度 50%)
|
||||
- [[n_开始吗|开始吗]] — `uses` (强度 50%)
|
||||
- [[n_旧项目|旧项目]] — `uses` (强度 50%)
|
||||
- [[n_磁盘空间|磁盘空间]] — `uses` (强度 50%)
|
||||
- [[n_缓存等|缓存等]] — `uses` (强度 50%)
|
||||
- [[n_记忆|记忆]] — `uses` (强度 50%)
|
||||
|
||||
## 📥 被关联
|
||||
|
||||
- [[n_操作|操作]] — `uses` → 我 (强度 50%)
|
||||
- [[n_配置|配置]] — `uses` → 我 (强度 50%)
|
||||
- [[n_的|的]] — `uses` → 我 (强度 50%)
|
||||
- [[n_旧版|旧版]] — `uses` → 我 (强度 50%)
|
||||
- [[n_python|Python]] — `uses` → 我 (强度 50%)
|
||||
- [[n_hermes|Hermes]] — `uses` → 我 (强度 50%)
|
||||
- [[n_个|个]] — `uses` → 我 (强度 50%)
|
||||
- [[n_自有记忆|自有记忆]] — `uses` → 我 (强度 50%)
|
||||
- [[n_日志统一|日志统一]] — `uses` → 我 (强度 50%)
|
||||
- [[n_来源|来源]] — `uses` → 我 (强度 50%)
|
||||
- [[n_系统|系统]] — `uses` → 我 (强度 50%)
|
||||
- [[n_保持|保持]] — `uses` → 我 (强度 50%)
|
||||
- [[n_自带|自带]] — `uses` → 我 (强度 50%)
|
||||
- [[n_统一到|统一到]] — `uses` → 我 (强度 50%)
|
||||
- [[n_旧日志|旧日志]] — `uses` → 我 (强度 50%)
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
---
|
||||
type: concept
|
||||
namespace: hermes-main
|
||||
pagerank: 0.0029
|
||||
connections: 31
|
||||
source: 织忆图谱
|
||||
---
|
||||
|
||||
# 📘 180
|
||||
|
||||
**类型**: concept | **命名空间**: hermes-main | **PageRank**: 0.0029
|
||||
|
||||
## 🔗 关联到
|
||||
|
||||
- [[n_gb|GB]] — `uses` (强度 50%)
|
||||
- [[n_mb|MB]] — `uses` (强度 50%)
|
||||
- [[n_合计|合计]] — `uses` (强度 50%)
|
||||
- [[n_日志脚本|日志脚本]] — `uses` (强度 50%)
|
||||
- [[n_缓存|缓存]] — `uses` (强度 50%)
|
||||
|
||||
## 📥 被关联
|
||||
|
||||
- [[n_操作|操作]] — `uses` → 我 (强度 50%)
|
||||
- [[n_p1|P1]] — `uses` → 我 (强度 50%)
|
||||
- [[n_数据分离|数据分离]] — `uses` → 我 (强度 50%)
|
||||
- [[n_p2|P2]] — `uses` → 我 (强度 50%)
|
||||
- [[n_删|删]] — `uses` → 我 (强度 50%)
|
||||
- [[n_p3|P3]] — `uses` → 我 (强度 50%)
|
||||
- [[n_python|Python]] — `uses` → 我 (强度 50%)
|
||||
- [[n_旧版归档|旧版归档]] — `uses` → 我 (强度 50%)
|
||||
- [[n_hermes|Hermes]] — `uses` → 我 (强度 50%)
|
||||
- [[n_v3_8|v3 8]] — `uses` → 我 (强度 50%)
|
||||
- [[n_p6|P6]] — `uses` → 我 (强度 50%)
|
||||
- [[n_日志统一|日志统一]] — `uses` → 我 (强度 50%)
|
||||
- [[n_旧日志|旧日志]] — `uses` → 我 (强度 50%)
|
||||
- [[n_创建|创建]] — `uses` → 我 (强度 50%)
|
||||
- [[n_合并|合并]] — `uses` → 我 (强度 50%)
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
---
|
||||
type: concept
|
||||
namespace: hermes-main
|
||||
pagerank: 0.0005
|
||||
connections: 11
|
||||
source: 织忆图谱
|
||||
---
|
||||
|
||||
# 📘 1 5 2GB 768x768 3GB SDXL
|
||||
|
||||
**类型**: concept | **命名空间**: hermes-main | **PageRank**: 0.0005
|
||||
|
||||
## 🔗 关联到
|
||||
|
||||
- [[n_不够|不够]] — `related_to` (强度 50%)
|
||||
- [[n_需|需]] — `related_to` (强度 50%)
|
||||
- [[n_需8gb|需8GB]] — `related_to` (强度 50%)
|
||||
|
||||
## 📥 被关联
|
||||
|
||||
- [[n_是|是]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_rtx|RTX]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_3050|3050]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_但|但]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_可跑|可跑]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_sd|SD]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_ga107m_可跑|GA107M 可跑]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_mx450|MX450]] — `related_to` → 我 (强度 50%)
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
---
|
||||
type: concept
|
||||
namespace: hermes-main
|
||||
pagerank: 0.0006
|
||||
connections: 4
|
||||
source: 织忆图谱
|
||||
---
|
||||
|
||||
# 📘 1 apt
|
||||
|
||||
**类型**: concept | **命名空间**: hermes-main | **PageRank**: 0.0006
|
||||
|
||||
## 🔗 关联到
|
||||
|
||||
- [[n_管理更方便|管理更方便]] — `related_to` (强度 50%)
|
||||
|
||||
## 📥 被关联
|
||||
|
||||
- [[n_安装|安装]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_tailscale|Tailscale]] — `related_to` → 我 (强度 50%)
|
||||
- [[n_tailscale_1_78_1_amd64_tailscale|tailscale_1 78 1_amd64 tailscale]] — `related_to` → 我 (强度 50%)
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
---
|
||||
type: concept
|
||||
namespace: hermes-main
|
||||
pagerank: 0.0021
|
||||
connections: 42
|
||||
source: 织忆图谱
|
||||
---
|
||||
|
||||
# 📘 200MB
|
||||
|
||||
**类型**: concept | **命名空间**: hermes-main | **PageRank**: 0.0021
|
||||
|
||||
## 🔗 关联到
|
||||
|
||||
- [[n_开始吗|开始吗]] — `uses` (强度 50%)
|
||||
- [[n_缓存等|缓存等]] — `uses` (强度 50%)
|
||||
- [[n_记忆|记忆]] — `uses` (强度 50%)
|
||||
|
||||
## 📥 被关联
|
||||
|
||||
- [[n_操作|操作]] — `uses` → 我 (强度 50%)
|
||||
- [[n_配置|配置]] — `uses` → 我 (强度 50%)
|
||||
- [[n_的|的]] — `uses` → 我 (强度 50%)
|
||||
- [[n_旧版|旧版]] — `uses` → 我 (强度 50%)
|
||||
- [[n_python|Python]] — `uses` → 我 (强度 50%)
|
||||
- [[n_hermes|Hermes]] — `uses` → 我 (强度 50%)
|
||||
- [[n_个|个]] — `uses` → 我 (强度 50%)
|
||||
- [[n_自有记忆|自有记忆]] — `uses` → 我 (强度 50%)
|
||||
- [[n_日志统一|日志统一]] — `uses` → 我 (强度 50%)
|
||||
- [[n_来源|来源]] — `uses` → 我 (强度 50%)
|
||||
- [[n_系统|系统]] — `uses` → 我 (强度 50%)
|
||||
- [[n_保持|保持]] — `uses` → 我 (强度 50%)
|
||||
- [[n_自带|自带]] — `uses` → 我 (强度 50%)
|
||||
- [[n_统一到|统一到]] — `uses` → 我 (强度 50%)
|
||||
- [[n_旧日志|旧日志]] — `uses` → 我 (强度 50%)
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780108729746817672
|
||||
category: distilled
|
||||
quality_score: 0.00
|
||||
sync_time: 2026-06-05T17:44:53+08:00
|
||||
---
|
||||
|
||||
# 2026 年 5 月 30 日修复了蒸馏产物不回写记忆库...
|
||||
|
||||
2026 年 5 月 30 日修复了蒸馏产物不回写记忆库的 Bug。
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
id: mem_1780108729746817672
|
||||
category: distilled
|
||||
quality_score: 0.28
|
||||
sync_time: 2026-06-05T18:37:15+08:00
|
||||
---
|
||||
|
||||
# 2026 年 5 月 30 日修复了蒸馆产物不回写记忆库...
|
||||
|
||||
2026 年 5 月 30 日修复了蒸馆产物不回写记忆库的 Bug。
|
||||
|
||||
---
|
||||
*由织忆 MemoryWeave 同步*
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue