auto-snapshot 2026-08-03 03:00:39

This commit is contained in:
小唯 A06 2026-08-03 03:00:39 +08:00
parent 7a1910566c
commit e2a14f871a
28 changed files with 1463 additions and 193 deletions

View File

@ -1,25 +0,0 @@
#!/bin/bash
# tdai-gateway 看门狗:检查 systemd 服务 active + 8420 端口监听
# 正常 → 静默(空输出);异常 → 输出报警no-agent cron 会发送)
# 创建2026-08-02修复 systemd 崩溃循环 2534 次后补的监控
ALERT=""
if ! systemctl --user is-active tdai-gateway >/dev/null 2>&1; then
STATE=$(systemctl --user is-active tdai-gateway 2>/dev/null || echo unknown)
ALERT="tdai-gateway systemd 服务状态异常: ${STATE}"
fi
if ! ss -tln 2>/dev/null | grep -q ':8420 '; then
ALERT="${ALERT}${ALERT:+ | }tdai-gateway 端口 8420 未监听"
fi
if [ -n "$ALERT" ]; then
echo "🔴 tdai-gateway 异常 $(date '+%F %T')"
echo "$ALERT"
systemctl --user status tdai-gateway --no-pager 2>&1 | head -12
exit 0
fi
# 正常:空输出 = 静默
exit 0

View File

@ -315,27 +315,27 @@
"archived_at": null,
"created_at": "2026-07-17T03:43:05.089451+00:00",
"created_by": null,
"last_patched_at": "2026-07-18T12:39:50.390388+00:00",
"last_used_at": "2026-07-30T01:50:00.175477+00:00",
"last_viewed_at": "2026-07-30T01:50:00.172165+00:00",
"patch_count": 22,
"last_patched_at": "2026-08-02T13:04:01.231703+00:00",
"last_used_at": "2026-08-02T14:39:17.213975+00:00",
"last_viewed_at": "2026-08-02T14:39:17.208148+00:00",
"patch_count": 26,
"pinned": false,
"state": "active",
"use_count": 20,
"view_count": 20
"use_count": 24,
"view_count": 24
},
"cbm-code-analysis": {
"archived_at": null,
"created_at": "2026-07-30T03:28:33.803582+00:00",
"created_by": null,
"last_patched_at": "2026-07-30T03:30:30.927634+00:00",
"last_used_at": "2026-07-30T03:30:47.215892+00:00",
"last_viewed_at": "2026-07-30T03:30:47.203869+00:00",
"patch_count": 3,
"last_patched_at": "2026-08-02T15:20:56.394720+00:00",
"last_used_at": "2026-08-02T15:20:48.942850+00:00",
"last_viewed_at": "2026-08-02T15:20:48.923159+00:00",
"patch_count": 4,
"pinned": false,
"state": "active",
"use_count": 3,
"view_count": 3
"use_count": 4,
"view_count": 4
},
"claude-code": {
"archived_at": null,
@ -510,14 +510,14 @@
"archived_at": null,
"created_at": "2026-07-28T14:02:19.195060+00:00",
"created_by": "agent",
"last_patched_at": "2026-08-01T16:57:06.438287+00:00",
"last_used_at": "2026-08-01T16:56:55.948370+00:00",
"last_viewed_at": "2026-08-01T16:56:55.945187+00:00",
"patch_count": 2,
"last_patched_at": "2026-08-02T14:02:20.150209+00:00",
"last_used_at": "2026-08-02T14:02:11.814838+00:00",
"last_viewed_at": "2026-08-02T14:02:11.811551+00:00",
"patch_count": 3,
"pinned": false,
"state": "active",
"use_count": 2,
"view_count": 2
"use_count": 3,
"view_count": 3
},
"design-feasibility-review": {
"archived_at": null,
@ -549,14 +549,14 @@
"archived_at": null,
"created_at": "2026-05-05T15:53:48.597780+00:00",
"created_by": "agent",
"last_patched_at": "2026-08-01T12:42:25.333652+00:00",
"last_used_at": "2026-08-01T12:41:48.920445+00:00",
"last_viewed_at": "2026-08-01T12:41:48.909106+00:00",
"patch_count": 94,
"last_patched_at": "2026-08-02T17:46:05.621521+00:00",
"last_used_at": "2026-08-02T17:45:20.632761+00:00",
"last_viewed_at": "2026-08-02T17:45:20.628433+00:00",
"patch_count": 96,
"pinned": false,
"state": "active",
"use_count": 79,
"view_count": 79
"use_count": 81,
"view_count": 81
},
"devops/devops-umbrella": {
"archived_at": null,
@ -779,6 +779,19 @@
"use_count": 0,
"view_count": 0
},
"gitea-repo-mirroring": {
"archived_at": null,
"created_at": "2026-08-02T18:24:34.438054+00:00",
"created_by": "agent",
"last_patched_at": "2026-08-02T18:29:21.655125+00:00",
"last_used_at": "2026-08-02T18:47:12.319098+00:00",
"last_viewed_at": "2026-08-02T18:47:12.312935+00:00",
"patch_count": 3,
"pinned": false,
"state": "active",
"use_count": 4,
"view_count": 4
},
"github-auth": {
"archived_at": null,
"created_at": "2026-06-30T11:24:39.499832+00:00",
@ -835,27 +848,27 @@
"archived_at": null,
"created_at": "2026-08-01T11:50:01.274771+00:00",
"created_by": "agent",
"last_patched_at": "2026-08-01T14:21:36.844037+00:00",
"last_used_at": "2026-08-01T14:21:17.657665+00:00",
"last_viewed_at": "2026-08-01T14:21:17.646368+00:00",
"patch_count": 7,
"last_patched_at": "2026-08-02T16:21:17.978109+00:00",
"last_used_at": "2026-08-02T16:46:57.365738+00:00",
"last_viewed_at": "2026-08-02T16:46:57.362260+00:00",
"patch_count": 14,
"pinned": false,
"state": "active",
"use_count": 9,
"view_count": 9
"use_count": 17,
"view_count": 17
},
"github-repo-management": {
"archived_at": null,
"created_at": "2026-06-30T11:24:39.513614+00:00",
"created_by": null,
"last_patched_at": null,
"last_used_at": "2026-08-01T11:48:58.058238+00:00",
"last_viewed_at": "2026-08-01T11:48:58.054196+00:00",
"last_used_at": "2026-08-02T18:23:21.668886+00:00",
"last_viewed_at": "2026-08-02T18:23:21.655030+00:00",
"patch_count": 0,
"pinned": false,
"state": "active",
"use_count": 2,
"view_count": 2
"use_count": 5,
"view_count": 5
},
"go-learning": {
"archived_at": null,
@ -1017,14 +1030,14 @@
"archived_at": null,
"created_at": "2026-05-13T12:27:05.593125+00:00",
"created_by": null,
"last_patched_at": "2026-07-19T14:06:42.150955+00:00",
"last_used_at": "2026-07-26T01:00:46.496121+00:00",
"last_viewed_at": "2026-07-25T12:41:04.295275+00:00",
"patch_count": 78,
"last_patched_at": "2026-08-02T11:39:48.113545+00:00",
"last_used_at": "2026-08-02T17:46:14.064253+00:00",
"last_viewed_at": "2026-08-02T17:46:14.053177+00:00",
"patch_count": 80,
"pinned": false,
"state": "active",
"use_count": 112,
"view_count": 107
"use_count": 118,
"view_count": 112
},
"hermes-venv-dependency-safety": {
"archived_at": null,
@ -1186,14 +1199,14 @@
"archived_at": null,
"created_at": "2026-08-01T13:47:26.532313+00:00",
"created_by": "agent",
"last_patched_at": "2026-08-01T16:50:25.167129+00:00",
"last_used_at": "2026-08-01T17:12:32.828348+00:00",
"last_viewed_at": "2026-08-01T17:12:32.817004+00:00",
"patch_count": 3,
"last_patched_at": "2026-08-02T16:46:52.295411+00:00",
"last_used_at": "2026-08-02T16:46:44.045093+00:00",
"last_viewed_at": "2026-08-02T16:46:44.039236+00:00",
"patch_count": 4,
"pinned": false,
"state": "active",
"use_count": 3,
"view_count": 3
"use_count": 5,
"view_count": 5
},
"llm-wiki": {
"archived_at": null,
@ -1706,27 +1719,27 @@
"archived_at": null,
"created_at": "2026-07-08T18:13:02.034240+00:00",
"created_by": "agent",
"last_patched_at": "2026-08-01T12:52:39.447526+00:00",
"last_used_at": "2026-08-01T12:52:32.714172+00:00",
"last_viewed_at": "2026-08-01T12:52:32.703253+00:00",
"patch_count": 200,
"last_patched_at": "2026-08-02T15:20:41.501595+00:00",
"last_used_at": "2026-08-02T15:20:25.042403+00:00",
"last_viewed_at": "2026-08-02T15:20:25.024619+00:00",
"patch_count": 203,
"pinned": false,
"state": "active",
"use_count": 152,
"view_count": 152
"use_count": 155,
"view_count": 155
},
"self-hosted-tunneling": {
"archived_at": null,
"created_at": "2026-06-19T19:06:08.909729+00:00",
"created_by": "agent",
"last_patched_at": "2026-07-08T13:51:56.997028+00:00",
"last_used_at": "2026-07-08T13:51:29.387565+00:00",
"last_viewed_at": "2026-07-08T13:51:29.376414+00:00",
"last_used_at": "2026-08-02T18:23:21.672286+00:00",
"last_viewed_at": "2026-08-02T18:23:21.665575+00:00",
"patch_count": 10,
"pinned": false,
"state": "active",
"use_count": 12,
"view_count": 12
"use_count": 13,
"view_count": 13
},
"serving-llms-vllm": {
"archived_at": null,
@ -1836,14 +1849,14 @@
"archived_at": null,
"created_at": "2026-07-09T17:36:29.269531+00:00",
"created_by": "agent",
"last_patched_at": "2026-07-20T07:53:21.901753+00:00",
"last_used_at": "2026-07-20T07:52:12.152761+00:00",
"last_viewed_at": "2026-07-20T07:52:12.149565+00:00",
"patch_count": 21,
"last_patched_at": "2026-08-02T14:40:09.615607+00:00",
"last_used_at": "2026-08-02T15:20:08.440434+00:00",
"last_viewed_at": "2026-08-02T15:20:08.433000+00:00",
"patch_count": 22,
"pinned": false,
"state": "active",
"use_count": 21,
"view_count": 21
"use_count": 23,
"view_count": 23
},
"spike": {
"archived_at": null,
@ -1953,14 +1966,14 @@
"archived_at": null,
"created_at": "2026-05-13T16:02:06.347617+00:00",
"created_by": null,
"last_patched_at": "2026-05-23T07:36:35.113619+00:00",
"last_used_at": "2026-06-21T16:06:40.921285+00:00",
"last_viewed_at": "2026-06-21T16:06:40.918968+00:00",
"patch_count": 9,
"last_patched_at": "2026-08-02T18:47:10.025724+00:00",
"last_used_at": "2026-08-02T18:46:58.987740+00:00",
"last_viewed_at": "2026-08-02T18:46:58.975389+00:00",
"patch_count": 13,
"pinned": false,
"state": "active",
"use_count": 15,
"view_count": 15
"use_count": 17,
"view_count": 17
},
"web-content-capture": {
"archived_at": null,
@ -2027,6 +2040,32 @@
"use_count": 0,
"view_count": 0
},
"whisper-stt": {
"archived_at": null,
"created_at": "2026-08-02T18:46:00.920538+00:00",
"created_by": null,
"last_patched_at": "2026-08-02T18:46:53.592908+00:00",
"last_used_at": "2026-08-02T18:46:46.154338+00:00",
"last_viewed_at": "2026-08-02T18:46:46.143430+00:00",
"patch_count": 1,
"pinned": false,
"state": "active",
"use_count": 2,
"view_count": 2
},
"windows-home-server-ops": {
"archived_at": null,
"created_at": "2026-08-02T18:24:48.270464+00:00",
"created_by": "agent",
"last_patched_at": "2026-08-02T18:29:05.298341+00:00",
"last_used_at": "2026-08-02T18:46:00.923689+00:00",
"last_viewed_at": "2026-08-02T18:46:00.913991+00:00",
"patch_count": 2,
"pinned": false,
"state": "active",
"use_count": 3,
"view_count": 3
},
"windows-python-pip": {
"archived_at": null,
"created_at": "2026-05-22T18:46:06.408227+00:00",
@ -2109,14 +2148,14 @@
"archived_at": null,
"created_at": "2026-05-29T19:39:03.373231+00:00",
"created_by": null,
"last_patched_at": "2026-07-20T07:45:33.845863+00:00",
"last_used_at": "2026-07-30T01:24:05.576220+00:00",
"last_viewed_at": "2026-07-30T01:24:05.569692+00:00",
"patch_count": 711,
"last_patched_at": "2026-08-02T16:46:29.637110+00:00",
"last_used_at": "2026-08-02T16:46:23.029923+00:00",
"last_viewed_at": "2026-08-02T16:46:23.016679+00:00",
"patch_count": 729,
"pinned": false,
"state": "active",
"use_count": 376,
"view_count": 350
"use_count": 385,
"view_count": 359
},
"zhiyi-dev": {
"archived_at": null,

View File

@ -412,5 +412,19 @@ python3 ~/.hermes/scripts/cangjie_distill.py distill <text_file> <title>
## 与 curator 的配合
- `--clean` 模式会查找 `absorbed_into` 标记并自动处理
- 也会将无版本号 + 低分 + 小体积的技能移动到 `_archive/`
- 被吸收的 skill 移动到 `_quarantine/`(回收期 30 天)
- 也会将无版本号 + 低分 + 小体积的技能移动到 `.archive/`(注意是点开头,不是下划线)
- 被吸收的 skill 移动到 `.quarantine/`(回收期 30 天)
- **保护名单**:被 cron / SOUL.md / 系统组件引用的技能在 `skill-curator.py``PROTECTED_SKILLS` 中声明,任何情况不进入归档/删除建议。新增核心/应急技能后如被 curator 误判,把它加入保护名单。
### curator 报告不可盲信 — 删除前必须验证2026-08-02 教训)
curator 周报skill-curator-weekly cron**可能产生严重误判**,绝不能直接执行删除/归档建议。2026-08-02 实例:报告建议删除 8 个技能,其中 4 个是核心技能(`hermes-venv-dependency-safety` / `cbm-code-analysis` / `bge-embed-crash-loop-fix` / `daily-recap`),实际全部被 cron/SOUL 引用himalaya 被报"与 20+ 技能 100% 重叠"实际是通用词available/readiness/status没被 stopwords 过滤的幻觉。
**执行任何 curator 清理前,按序验证**
1. **拉真实文件状态**`find ~/.hermes/skills -type d -name "<技能名>"` — 确认技能是否真的存在、是否已在 `.archive/`(在 archive 里 = 早已归档,报告重复计数,忽略)
2. **查引用**`grep -rln "<技能名>" ~/.hermes/SOUL.md ~/.hermes/AGENTS.md ~/.hermes/cron/` — 被 cron/系统文件引用 = 核心,绝不删
3. **低频 ≠ 可删**:运维/应急技能(崩溃修复、铁律、复盘)低频使用是正常属性,不是删除理由
4. **重叠报告看 common_terms**Jaccard 打满但 common_terms 是通用词 = 幻觉,不是真重叠
5. **只读优先**:默认 `--report`dry run确认无损后再谈 `--clean`
**已修的 curator bug**2026-08-02① 加 `PROTECTED_SKILLS` 保护名单 ② stopwords 扩充available/readiness/status 等)③ 修复 `.archive`vs `_archive`(下划线)扫描 bug——已归档技能被重复扫描 ④ himalaya 补 version。修复后归档候选 8→0。

View File

@ -680,7 +680,7 @@ journalctl --user -u xiaowei-startup.service
| `references/gaokao-site/` | 116 个 session 参考文件(按主题分类的 bug 修复记录) |
| `references/gaokao-site.md` | 旧版精简参考(保留向后兼容) |
| `references/tencent-cloud-ssl-cert-20260618.md` | 腾讯云 DNSPod 免费 SSL 证书申请、HTTPS nginx 配置、外部 443 被封限制 |
| `references/gitea-operations.md` | Gitea 上传项目、Token 认证、shallow clone 陷阱 |
| `references/gitea-operations.md` | Gitea 操作全流程 — 认证(.netrc/API)、全量历史镜像(GitHub→Gitea)、shallow/deepen 陷阱、镜像代理、--all/--tags 拆分、RSSHub 本地验收2026-08-03 15项目实战 |
| `references/infra-state.md` | Current system infrastructure state (ports, services) |
| `references/tailscale-install.md` | Tailscale 安装:正确 GPG 密钥 URL、静态二进制订用方案、Deepin 25 坑点 |
| `references/sudo-password-pattern.md` | sudo 密码传递模式heredoc 中 pipe 失效的原因和三种替代写法 |

View File

@ -1,56 +1,160 @@
# Gitea Operations Reference
> 本地 Gitea 实例操作注意事项。
> 本地 Gitea 实例操作注意事项。2026-08-03 更新:批量镜像 15 个 GitHub 项目实战RSSHub/Folo/xLog/DPlayer/APlayer 等),补全全量历史镜像流程。
## 本地 Gitea 信息
- **地址**http://192.168.123.11:3000
- **Token**:见 `~/mc/小唯/记忆/MemoryFabric/技术细节.md`Token: 9380e8e6...
- **Token**:见 `~/mc/小唯/记忆/MemoryFabric/技术细节.md`Token: 9380e8e6...`~/.netrc``machine 192.168.123.11 login xiaoxue_admin password <token>`
- **用户**xiaoxue_admin非 muchen
## 上传已有 Git 项目到 Gitea
## 认证(两种等价方式)
### 常见陷阱Shallow Clone 问题
```bash
# 从 ~/.netrc 提取 token单行格式不要用 getline 分行读)
TOKEN=$(awk '/^machine 192.168.123.11/{for(i=1;i<=NF;i++) if($i=="password") print $(i+1)}' ~/.netrc)
从 GitHub clone 的项目可能是 shallow clone`--depth` 参数),导致:
# API Basic authtoken 当密码,验证连通):
curl -u "xiaoxue_admin:$TOKEN" "http://192.168.123.11:3000/api/v1/user" # 200 = OK
# git push URL 嵌入:
git push "http://$OWNER:$TOKEN@$HOST/$OWNER/$name.git" --all
```
## 上传已有 Git 项目到 Gitea保留完整历史 ✅)
> 镜像场景(把 GitHub 项目归档到 Gitea**必须保留完整 git 历史**。Gitea 拒绝浅克隆推送,但**不要用 `rm -rf .git` 重来**(那会丢掉历史!)。正确做法:
### 1. 全量 clone或把浅克隆补成全量
**浅克隆推送会报错:**
```
remote: shallow update not allowed
```
或 force push 时失败。
**解决步骤**
**方案 A全量 clone直接**
```bash
git clone https://github.com/OWNER/REPO.git # 不带 --depth
```
**方案 B浅克隆已存在 → 补成全量**
```bash
# 一次拉全(网络好时):
git fetch --unshallow origin
# 网络不稳时:分段 deepen每轮独立可续传shallow 文件消失 = 完成)
for i in 1 2 3 4 5 6 7 8; do
timeout 240 git fetch --deepen=2000 origin 2>&1 | tail -2
[ ! -f .git/shallow ] && break
done
[ -f .git/shallow ] && echo "STILL SHALLOW" || echo "FULL OK: $(git rev-list --count HEAD) commits"
# 实测Folo (7011 commits) 第 8 轮才成功 —— 多轮重试是预期,不是 bug
```
### 2. GitHub 直连不稳 → 用镜像代理
本机实测2026-08-03github.com git 协议反复 `curl 28 Failed to connect ... port 443 after 133xxx ms`,但镜像代理可用:
```bash
# ✅ 实测可用:
git clone https://gh-proxy.com/https://github.com/OWNER/REPO.git
git clone https://ghproxy.net/https://github.com/OWNER/REPO.git
# ❌ 当时超时ghfast.top / mirror.ghproxy.com
# 先探测哪个通info/refs 返回 200 = 可用):
curl -s -o /dev/null -w "%{http_code}" "https://gh-proxy.com/https://github.com/OWNER/REPO.git/info/refs?service=git-upload-pack"
```
大仓库全量 clone 失败重试模式:
```bash
for i in 1 2 3 4 5; do
rm -rf REPO
timeout 500 git clone <url> 2>&1 | tail -2
[ -d REPO/.git ] && break
sleep 20
done
```
### 3. 创建远端仓库Gitea API
```bash
curl -s -u "xiaoxue_admin:$TOKEN" -X POST \
"http://192.168.123.11:3000/api/v1/user/repos" \
-d "{\"name\":\"$name\",\"private\":true,\"auto_init\":false}"
# ⚠️ JSON 转义坑description 带引号/emoji 会破坏 -d 参数 → 用固定值
```
### 4. 推送(⚠️ --all 和 --tags 不能同时用)
```bash
# ❌ fatal: options '--all' and '--tags' cannot be used together
git push URL --all --tags
# ✅ 分两次:
git push "http://$OWNER:$TOKEN@$HOST/$OWNER/$name.git" --all
git push "http://$OWNER:$TOKEN@$HOST/$OWNER/$name.git" --tags
```
批量脚本骨架:
```bash
for d in BASE/*/; do
name=$(basename "$d")
[ -f "$d/.git/shallow" ] && { echo "SKIP $name (STILL SHALLOW)"; continue; } # 必须全量才能推
(cd "$d" && git push "http://$OWNER:$TOKEN@$HOST/$OWNER/$name.git" --all \
&& git push "http://$OWNER:$TOKEN@$HOST/$OWNER/$name.git" --tags) \
&& echo "OK $name" || echo "FAIL $name"
done
```
### 5. 验证(推完必须查)
```bash
curl -s -u "xiaoxue_admin:$TOKEN" "http://192.168.123.11:3000/api/v1/repos/$OWNER/$name" \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('size'), d.get('default_branch'))"
# 对比本地 git rev-list --count HEAD 确认提交数一致
```
## 性能参考2026-08-03 实测)
| 项目 | Commits | 备注 |
|------|---------|------|
| RSSHub | 17,321 | 镜像代理 clone 成功(直连 5 次全挂) |
| Folo | 7,011 | deepen 8 轮 |
| xLog | 2,731 | 直连成功 |
| DPlayer / APlayer | ~1,300 / 916 | 直连 unshallow 成功 |
## RSSHub 本地安装测试(镜像后验收)
```bash
npm install -g pnpm@9 # RSSHub 需要 pnpm本机原本没有
cd RSSHub && pnpm install # ~4minpeer 警告可忽略
npm run build # 生成 dist/index.mjs5seval 警告是项目自身代码)
PORT=1200 npm run start # 服务起来
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:1200/ # 200
curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:1200/healthz # 200
# ⚠️ 新版本路由已变:/github/release、/github/trending 已移除404 是正常的)
# 用现存路由验证:/github/issue/:owner/:repo → 200
```
纯前端项目DPlayer/APlayer验收`python3 -m http.server <port>` 起静态服务curl 检查 demo 页 + dist 产物 200。
## 快速路径(历史无所谓时)
如果确实不需要历史(普通上传小项目),旧方法仍可用:
```bash
cd /path/to/repo
rm -rf .git # 删除原 Git 历史
git init -b main # 重新初始化
git add -A
git commit -m "Initial commit"
rm -rf .git && git init -b main
git add -A && git commit -m "Initial commit"
git remote add origin http://TOKEN@192.168.123.11:3000/xiaoxue_admin/REPO.git
git push -u origin main
```
### Token 认证
URL 中嵌入 Token 避免交互式输入:
```
http://TOKEN@192.168.123.11:3000/xiaoxue_admin/REPO.git
```
### 创建仓库
```bash
curl -s -X POST "http://192.168.123.11:3000/api/v1/user/repos" \
-H "Authorization: token TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"REPO_NAME","description":"描述","private":false}'
```
返回 JSON 中 `clone_url` 字段含完整 URL注意用户名前缀
## 关键教训
| 问题 | 教训 |
|------|------|
| shallow clone 无法 push | 从 GitHub 克隆后必须 `rm -rf .git` 重新初始化 |
| 交互式输入失败 | URL 中嵌入 Token |
| 仓库用户不对 | API 创建时用 `xiaoxue_admin`,不是 muchen |
| shallow clone 无法 push | **保留历史**`git fetch --unshallow` 或 `--deepen=2000` 循环;**不要** `rm -rf .git`(丢历史) |
| GitHub 直连反复超时 | 用镜像代理 `gh-proxy.com` / `ghproxy.net`URL 前加前缀) |
| `--all --tags` 同时用报错 | 分两次 push |
| 大仓库 clone 中断 | 重试循环 + 多轮 deepen可续传 |
| 交互式输入失败 | URL 中嵌入 Token / `.netrc` Basic auth |
| 仓库用户不对 | API 创建时用 `xiaoxue_admin`,不是 muchen |

View File

@ -0,0 +1,92 @@
---
name: gitea-repo-mirroring
description: "把 GitHub/上游开源项目镜像到自建 Gitea完整 git 历史)— clone→全量历史→建仓库→push 全流程含浅克隆推送被拒、镜像加速、push 拆分等坑。"
version: 1.0.0
author: 小唯 A06
tags: [gitea, mirror, git, github, 镜像, 存档]
trigger: "推到gitea / 镜像到gitea / 把GitHub项目搬到gitea / 存档到gitea / mirror repo"
created: 2026-08-03
updated: 2026-08-03
---
# Gitea 仓库镜像GitHub → 自建 Gitea完整历史
把上游开源项目GitHub 等)镜像到自建 Gitea本环境`192.168.123.11:3000`,用户 `xiaoxue_admin`),保留完整 git 历史。
## 核心铁律
1. **浅克隆不能推 Gitea**`git clone --depth 1` 后 push 报 `shallow update not allowed`。Gitea 默认拒绝浅推送,必须完整历史。
2. **`git push --all``--tags` 不能合并**`fatal: options '--all' and '--tags' cannot be used together`。必须拆两次 push。
3. **Gitea API 用 Basic auth**`-u 用户名:token`,不是 `Authorization: token`Gitea 返回 401
## 标准流程
### 1. 全量 clone不要 --depth
```bash
mkdir -p ~/projects/diygod && cd ~/projects/diygod
git clone https://github.com/OWNER/REPO.git # 不加深度的完整克隆
```
### 2. 已是浅克隆 → 转全量
```bash
cd REPO
git fetch --unshallow origin # 一次拉全
# 网络不稳时用增量 deepen 循环(每次加深 2000 commit断了续传
for i in 1 2 3 4 5 6 7 8; do
timeout 240 git fetch --deepen=2000 origin 2>&1 | tail -2
[ ! -f .git/shallow ] && break
done
# 验证
git rev-list --count HEAD # 完整 commit 数
[ -f .git/shallow ] && echo "STILL SHALLOW" || echo "FULL HISTORY OK"
```
### 3. 创建 Gitea 仓库 + push
```bash
# token 从 ~/.netrc 提取(注意 awk 遍历字段,不是 getline
TOKEN=$(awk '/^machine 192.168.123.11/{for(i=1;i<=NF;i++) if($i=="password") print $(i+1)}' ~/.netrc)
# 创建仓库API Basic auth
curl -s -u "xiaoxue_admin:$TOKEN" -X POST \
"http://192.168.123.11:3000/api/v1/user/repos" \
-H "Content-Type: application/json" \
-d '{"name":"REPO","description":"mirror of OWNER/REPO","private":false}'
# push--all 和 --tags 分开!)
git push "http://xiaoxue_admin:$TOKEN@192.168.123.11:3000/xiaoxue_admin/REPO.git" --all
git push "http://xiaoxue_admin:$TOKEN@192.168.123.11:3000/xiaoxue_admin/REPO.git" --tags
```
### 4. 验证
```bash
curl -s -u "xiaoxue_admin:$TOKEN" \
"http://192.168.123.11:3000/api/v1/repos/xiaoxue_admin/REPO" | python3 -c \
"import sys,json; d=json.load(sys.stdin); print(d.get('size'), d.get('default_branch'), d.get('created_at','')[:10])"
```
## 批量镜像模式
循环处理 N 个项目:写 `unshallow_all.sh`(逐个 unshallow+ `push_all.sh`(逐个 push`--all` 与 `--tags` 分两次),日志写 `push.log`,用 `grep -E "^(OK|FAIL)"` 汇总。后台跑(`background=true` + `notify_on_complete=true`)。
## Pitfalls
1. **`shallow update not allowed`** — 浅克隆推送被拒。解法:`git fetch --unshallow origin`,确认 `.git/shallow` 消失再推。
2. **GitHub 直连不稳定** — 表现为 `Failed to connect to github.com port 443 after 133xxx ms`。对策:
- 先 `git ls-remote https://github.com/... HEAD` 测连通
- 直连不行换镜像:`git clone https://gh-proxy.com/https://github.com/OWNER/REPO.git`(实测可用)或 `https://ghproxy.net/...`
- `codeload.github.com`HTTP 下载)常比 git 协议通,但下载的是无历史的 tar.gz
3. **`--all --tags` 合并报错** — 必须拆成两次 push。
4. **Gitea API 401** — 用了 `Authorization: token` 头。改 `-u 用户名:token` Basic auth。
5. **Gitea 仓库列表分页 50/页** — 仓库多时第 2 页起才有目标,`?limit=100&page=2` 翻页,别误判"仓库没建成功"。
6. **README 含引号/emoji 导致创建 JSON 转义坏** — 创建仓库时 description 用固定值,不塞 README 内容。
7. **Windows 上 git 命令管道** — 目标机是 Windows 时 `tail`/`findstr` 管道会吞输出,先不加过滤器看原始输出。
## 参考
- `references/gitea-api-notes.md` — Gitea API 细节、.netrc token 提取、验证命令
- `references/diygod-batch-mirror-2026-08.md` — 15 项目批量镜像实录(镜像站实测对比、批量脚本模式、安装测试分层)
- 家庭服务器 Windows 部署流程见 `windows-home-server-ops` skill

View File

@ -0,0 +1,51 @@
# DIYgod 15 项目批量镜像实录2026-08-03
批量把 DIYgod 的 15 个开源项目镜像到家庭服务器 Gitea 的完整实战记录。作为 gitea-repo-mirroring 的批量案例参考。
## 项目清单与规模
| 项目 | Commits | 备注 |
|------|---------|------|
| RSSHub | 17,321 | 最大45.5K★,历史超长需镜像站 |
| Folo | 7,011 | RSSNext 组织项目38.7K★) |
| xLog | 2,731 | Crossbell-Box 组织项目 |
| RSSHub-Radar | 1,331 | 浏览器扩展 |
| DPlayer | 1,302 | 弹幕播放器 |
| APlayer | 916 | 音乐播放器 |
| cloudflare-rsshub-deploy | 388 | |
| download-webhook | 39 | |
| edge-image-transformer | 23 | |
| cloudflare-edge-tts | 18 | |
| OwO / ttrss-theme-rsshub | 14 / 14 | |
| GoodNight / DIYgod-Obsidian-Starter | 6 / 5 | |
| ttrss-plugin-remove-iframe-sandbox | 3 | |
## 关键经验
### 1. 网络策略GitHub 直连 vs 镜像
- GitHub 直连**时好时坏**:有时 `git ls-remote` 通、大仓库 clone 却挂133s 超时)
- **镜像加速站实测**2026-08-03
- `https://gh-proxy.com/https://github.com/...` ✅ 通clone RSSHub 17K commits 成功)
- `https://ghproxy.net/https://github.com/...` ✅ 通refs 探测 200
- `https://ghfast.top/...` ❌ 超时、`https://mirror.ghproxy.com/...` ❌ 超时
- **决策规则**:小仓库直连优先;大仓库(历史 >2000 commits或直连连续失败 → 直接换 gh-proxy.com
### 2. 批量脚本模式
- `unshallow_all.sh`:循环 `git fetch --unshallow`Folo 网络不稳用 `--deepen=2000` 增量重试 8 轮成功
- `push_all.sh`:循环 `git push --all` + `git push --tags` 分开推,日志写 push.log
- 后台跑 + notify_on_complete`grep -E "^(OK|FAIL)"` 汇总
### 3. Gitea 仓库创建 JSON 陷阱
- README 含引号/emoji 会破坏 `-d '{"description":"..."}'` 转义 → description 用固定值
- 15 个仓库全部 `HTTP 200` 创建成功,但**第 1 页只显示 50 个**旧仓库DIYgod 的 15 个在第 2 页(`?limit=100&page=2`)→ 验证时别误判"没建成功"
### 4. 安装测试分层
- **轻量项目**(纯前端 DPlayer/APlayer直接 `python3 -m http.server` 起静态服务 + curl 验证 200
- **有测试套件**cloudflare-edge-tts`npm install` + `npm run test` → 22/22 通过
- **重量级**RSSHub`pnpm install`3m55s`npm run build`5.4s)→ `npm start` → 路由实测
- **RSSHub v1.0 路由变化**`/github/release`、`/zhihu/hotlist`、`/github/trending` 已删404 预期);现存 `/github/issue/DIYgod/RSSHub`、`/github/repos/DIYgod` 返回 200 + 真实 RSS 2.0
## 部署去向
- RSSHub → 家庭服务器 Node 部署(见 windows-home-server-ops skill
- cloudflare-edge-tts → 本地 wrangler dev --local 常驻TTS API
- 小唯语音 → Hermes 内置 edge TTSzh-CN-XiaoxiaoNeural

View File

@ -0,0 +1,49 @@
# Gitea API 笔记2026-08-03 实测)
## Token 提取(~/.netrc 单行格式)
```bash
# ✅ awk 遍历字段提取(不要用 getline —— .netrc 是单行)
TOKEN=$(awk '/^machine 192.168.123.11/{for(i=1;i<=NF;i++) if($i=="password") print $(i+1)}' ~/.netrc)
```
## 认证方式
- ✅ **Basic auth**`curl -u "xiaoxue_admin:$TOKEN"` → 200
- ❌ `Authorization: token $TOKEN` 头 → **401**Gitea 不认这种写法)
## 常用 API
```bash
# 创建仓库
curl -s -u "user:$TOKEN" -X POST http://HOST:3000/api/v1/user/repos \
-H "Content-Type: application/json" \
-d '{"name":"REPO","description":"固定值(避免转义)","private":false}'
# 查仓库(含 size/默认分支/创建时间)
curl -s -u "user:$TOKEN" http://HOST:3000/api/v1/repos/xiaoxue_admin/REPO
# 列用户仓库 —— ⚠️ 分页 50/页!仓库多时目标在 page 2+
curl -s -u "user:$TOKEN" "http://HOST:3000/api/v1/users/xiaoxue_admin/repos?limit=100&page=2"
# 查用户
curl -s -u "user:$TOKEN" http://HOST:3000/api/v1/user
```
## Push URL 格式
```bash
# Basic auth 内嵌 URL注意 --all 和 --tags 必须分开)
git push "http://xiaoxue_admin:$TOKEN@192.168.123.11:3000/xiaoxue_admin/REPO.git" --all
git push "http://xiaoxue_admin:$TOKEN@192.168.123.11:3000/xiaoxue_admin/REPO.git" --tags
```
## 创建仓库 JSON 转义坑
README/description 含引号、emoji、换行会导致 `-d '{"name":"...","description":"..."}'` 转义坏(创建失败或字段错乱)。
**解法description 用固定值,不塞 README 内容。** 仓库建好后内容由 push 提供。
## 浅克隆 → Gitea
- 现象:`git push` → `fatal: remote ... : shallow update not allowed`
- 解法:`git fetch --unshallow origin`(或 `--deepen=2000` 循环续传),`.git/shallow` 消失后再 push

View File

@ -139,5 +139,39 @@ cronjob action=update job_id=XXX model={"model": "openai/gpt-oss-120b", "provide
- 修完 cron 后验证:`cronjob action=run job_id=XXX` → `execution_success: true`,或等下一个调度周期看 `last_status`
- 排查 cron 失败第一动作:`cronjob action=list` 找 `last_status: error`,再读 `~/.hermes/cron/output/{job_id}/{date}*.md` 的 Error 段——504 类 SSE 超时一眼可见
## ⚠️ 免费模型池会整体过期skill 白名单记录会 stale2026-08-02 实测)
**模型池会整体大换血**2026-07-27 当天 m2.7/step-flash/qwen3.5 全部 EOLm3 空响应gpt-oss 是 reasoning 模型。**skill/文档里的"可用模型"记录会过期**——任何模型判断都必须实测,不能信旧白名单。
**蒸馏任务 vs 对话任务的判定标准不同**
- 对话任务:`choices[0].message.content` 非空即可
- **蒸馏任务content 必须是非空且可解析的 JSON**(剥离 ```json code fence 后)——"能对话 ≠ 能蒸馏"
- **reasoning 模型gpt-oss 系)排除**`content=null`,答案全在 `reasoning`/`reasoning_content` 字段——除非调用方显式读取该字段,否则 distill 永远 parse 失败降级 keyword
**模型验证命令(候选模型上线前必跑)**
```bash
KEY=$(grep -oP 'LLM_API_KEY=\K.*' ~/.config/systemd/user/zhiyid.service)
curl -s -m 30 http://127.0.0.1:3000/v1/chat/completions -H "Content-Type: application/json" \
-H "Authorization: Bearer $KEY" -d '{"model":"<候选>","messages":[{"role":"system","content":"输出严格JSON"},{"role":"user","content":"提取实体:牧尘喜欢简洁。输出 {\"entities\":[],\"decisions\":[],\"conclusions\":[]} 格式"}],"max_tokens":150}'
# 期望: content 是纯 JSON或可剥离的 code fence且非空
# 失败特征: content=nullreasoning 模型)/ 400 EOL / No available channel / system_cpu_overloaded / 空响应
```
## 蒸馏模型双层看门狗2026-08-02 上线,解决"免费模型挂了没人换"
免费模型经常挂,单层 6h 巡检太慢 + 探针类型不对(测对话不测 JSON。方案**双层**
1. **30min 轻量探针**no-agent cron只测当前蒸馏模型的 JSON 输出能力(剥离 code fence 后可解析才算通过)→ 挂了立即按候选池切换 + 更新配置 + 重启 + 飞书报警
- 参考实现:`~/.hermes/scripts/distill-model-watchdog.py`cron `89de35dc35a7`
2. **6h 深度巡检**model-health.py 的 `_heal_distill_models`):同步守护蒸馏配置,识别 reasoning 模型
**候选池设计**:按优先级排序的可用模型列表(实测 JSON 可用),挂了顺序测下一个。当前蒸馏候选池:`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`
**⚠️ 自愈机制必须实测"失败路径"**(牧尘"都测试过了吧?"教训):
- 手动 `cronjob run <id>` 触发一次确认 `execution_success: true`
- **模拟失败场景**(把配置改成已知坏模型)→ 跑机制 → 确认切换+配置更新+服务重启+通知全链路
- dry-run 单测判断逻辑(好模型判健康、坏模型判需替换、原文件未动)
- **陷阱:模型不在测试列表 ≠ 模型挂了**。探针主判content 非空+JSON 可解析),巡检结果仅作辅助覆盖(明确 dead 才覆盖探针——否则会把健康模型误替换gemma 不在 ALL_MODELS → found=None → 误判需替换2026-08-02 抓到并修复)
## 参考
- `references/omniroute-notes.md` — 本次部署/踩坑细节

View File

@ -7,6 +7,7 @@ author: 小唯 A06
tags: [self-healing, monitoring, auto-rollback, evolution, watchdog, config-protection, daemon, backup, recovery]
category: devops
trigger: 系统部署、开机自启、配置更改、故障恢复场景、备份验证、恢复演练
**2026-08-02 端到端验证法(核心)**:组件在跑 ≠ 链路在工作。zhiyid/sidecar/bge-embed 全 active 但 distill 一直 fallbackzhiyid.service 缺 LLM_ENDPOINT/MODEL/KEY 环境变量)→ commit 返回 201 但 20 分钟 recall 查不到。判"健康"必须验证写→蒸馏→检索全链路;判 systemd 服务正常要看 NRestarts 不是端口在听tdai-gateway 曾崩溃循环 2534 次被手动进程掩盖)。记忆系统是四套(织忆/Soulful/TencentDB/CBM不是一套。详见 references/memory-system-e2e-verification-20260802.md。
**2026-07-29 model-health.py 全覆盖**:自愈脚本覆盖 3 个配置格式——主(YAML) + prof-b(YAML) + OpenClaw(JSON)。死模型自动替补。gateway 内部无法 restart强保护需用户手动 systemctl restart。详见 references/model-health-multi-config-coverage.md。
**2026-08-01 model-health.py v3**:两个致命缺陷——①从不验证实际生效的 model.default只查 providers 列表)→ prof-b 被写成 NewAPI 不存在的模型全挂 503②排名公式丢 context_score → 1M 长上下文排不上。v3 新增 `_verify_model_usable()` 替换前真实调用验证 + 探针 3 次取平均。铁律:修复必须闭环测试(故意改坏→跑→确认)。详见 references/model-health-v3-fixes-20260801.md。
**2026-08-01 ⚠️ model.default 铁律(牧尘连续 3 次手动改回,最高优先级)**`_auto_promote_config` 的 B 段曾把 `model.default`(日常对话主模型)自动切成 NewAPI 排名第一的模型 → 对话直接挂。**model.default 是用户锁定的付费主模型deepseek-v4-flash + api.deepseek.com任何自动化脚本model-health.py / self-evolve.py / optimizer.py都不得修改**NewAPI 免费模型只用于 cron/自动化。修复B 段整体删除(只打印保护信息)、`_heal_config` 双重池内保护model.default 不在 CANDIDATE_POOL 就跳过)。闭环测试 3 项:模拟排名切换/死模型config.yaml 字节级未变hash 一致。commit 5bb8043。

View File

@ -0,0 +1,60 @@
# 记忆系统端到端验证法2026-08-02
> 触发:牧尘问"织忆很成熟么?",深挖发现组件全 active 但核心链路是断的。
> 核心教训:**组件在跑 ≠ 链路在工作**。判断"健康/成熟"必须验证端到端链路。
## 事故还原
当时 zhiyid/sidecar/bge-embed 全部 active`/api/v1/health` 全 ok
- `POST /api/v1/commit` 返回 201 + episode_id看似成功
- **20 分钟后 recall 检索不到新写入内容**
- 日志铁证:`LLMEndpoint empty, fallback for ep_...` + `facts=1 entities=0`
- 根因:`~/.config/systemd/user/zhiyid.service` **缺少 `LLM_ENDPOINT` / `LLM_MODEL` / `LLM_API_KEY` 环境变量** → distill 每次走关键词提取 fallback → 产出低质记忆永远排不上检索
## 端到端验证 5 步
```
1. 写POST /api/v1/commit → 返回 episode_id201≠ 已入库可用
2. 等distill 是异步队列batch<10 <5min flush 5-10s 或查日志 flush START
3. 验:日志出现 "endpoint=... model=..."(真 LLM而非 "LLMEndpoint empty, fallback"
4. 查recall 同主题能命中新写入内容
5. 量total_memories 增长memories 持久化total_episodes 重启会归零Rust sidecar 内存,非权威)
```
## 关键信号对照
| 信号 | 含义 |
|------|------|
| `LLMEndpoint empty, fallback` + `facts=1 entities=0` | **假健康**:写入成功但蒸馏=关键词提取recall 排不上 |
| `LLM entities: N` + `score=0.8x` + `decisions/conclusions` | 真 LLM 蒸馏,记忆质量可用 |
| 进程/端口/health 全绿 | 只是"组件活着",不证明链路工作 |
## systemd 服务崩溃循环 vs 手动进程撑场TencentDB 案例)
**症状**`tdai-gateway.service` ExecStart 被写坏成 `/src/gateway/server.ts`(不存在)→ systemd 崩溃循环 **2534 次**,但**手动进程撑在 8420 端口**让服务"看起来活着"。
**诊断**`systemctl --user show tdai-gateway -p NRestarts` → 重启计数几千 = 崩溃循环。**端口在听 ≠ systemd 服务正常**。
**修复**:修正 ExecStart 路径(`--require .../tsx/dist/preflight.cjs --import .../loader.mjs src/gateway/server.ts`)→ `systemctl --user daemon-reload` → 杀手动进程 → systemd 接管。验证:`systemctl --user is-active` + 端口 PID 变化 + `curl /health` uptime 从 5s 起跳。
## 四套记忆系统全景(牧尘纠正)
| 系统 | 职责 | 端口/位置 | 数据量(2026-08-02) |
|------|------|----------|--------------------|
| 织忆 ZhiYi | 语义记忆 | :7821 | 5054 memories / 9075 图谱节点 |
| Soulful | 关系记忆 | daemon, ~/.hermes/soulful/ | 心迹13 / 牵挂 / 画像 |
| TencentDB TDAI | 人格蒸馏 | :8420 | L0 85K / L1 220.03% 是设计如此) |
| TencentDB TDAI | 人格蒸馏 | :8420 | L0 85K / **L1 2245 条JSONL 真相源)** |
- 四套独立进程,默认互不影响,诊断先确认哪一套
- **L1 数据量测量铁律2026-08-02 晚间修正)**:判 L1 是否工作**不要查 `l1_records` 表**(那是同步缓存,仅 19 行),真相源是 `~/.memory-tencentdb/memory-tdai/records/*.jsonl`(全量 2245 条persona 459 / instruction 543 / episodic 1243覆盖 15 天,每天正常产出)。查询:`sqlite3 ~/.memory-tencentdb/memory-tdai/vectors.db "SELECT COUNT(*) FROM l0_conversations"` 看 L0L1 用 python 扫 `records/*.jsonl` 统计。曾因此误判"85K L0 只蒸馏 22 条 = 管道坏了",实际提取器每天健康运行。
- **锁冲突 ≠ 故障**pipeline 日志 `lock conflict 11 / success 5` 只是瞬时竞争worker concurrency=10 + per-session 锁),无积压无丢任务——验证方式是看 records 每日产出,不是看冲突计数。
- L0 60%+ 是 zhiyi-sync 自动同步的心迹3834/6438 当日),这是"设计如此"L1 从心迹提取 episodic 反而有质量(如"7-10 上线每日复盘机制"
- **教训**:评估"记忆系统"时必须四套一起看(牧尘原话:"记忆系统可不止织忆"、"你还少了cbm"
## 修复记录
- zhiyid.service 补 LLM 环境变量LLM_ENDPOINT=http://127.0.0.1:3000/v1/chat/completions, LLM_MODEL=openai/gpt-oss-120b, LLM_API_KEY=<NewAPI key>
- tdai-gateway.service ExecStart 修正
- learner.py 轨迹学习门禁支持度≥2 才写织忆)+ daemon.py 程序记忆分类procedural
- Soulful cares stale 即删pending→14天→stale→下轮删除

View File

@ -0,0 +1,124 @@
---
name: windows-home-server-ops
description: "家庭服务器 (192.168.123.11 Windows) 部署与运维 — SSH 管理、Node 服务常驻schtasks、防火墙放行、Windows cmd/PowerShell 坑。替代 Docker服务器没装。"
version: 1.0.0
author: 小唯 A06
tags: [windows, server, schtasks, ssh, deploy, node, 家庭服务器, firewall]
trigger: "部署到家庭服务器 / 192.168.123.11 / Windows服务器上跑服务 / 服务器常驻服务 / schtasks"
created: 2026-08-03
updated: 2026-08-03
---
# Windows 家庭服务器部署与运维
家庭服务器 `192.168.123.11`**Windows Server 2022**(不是 Linux账号 `administrator`(密码 xue.2538)。**没有 Docker**,但有 Node v24.14.1 + npm 11 + git 2.53 + Python 3.12。
## 环境事实(实测 2026-08-03
| 项 | 值 |
|----|----|
| OS | Windows Server 2022 (10.0.20348) |
| SSH | OpenSSH`sshpass -p 'xue.2538' ssh administrator@192.168.123.11` |
| Docker | ❌ 无(`docker` 命令不存在) |
| Node | ✅ v24.14.1RSSHub engines ^22.22.2 || ^24.15.0 勉强满足) |
| Gitea | ✅ 3000 端口 |
| SMB 共享 | ✅ `beifen` 等挂载于 `/mnt/server-backup` |
## SSH 连接模板
```bash
# Windows OpenSSH 可用 sshpass 连接(需先装 sshpass
sshpass -p 'xue.2538' ssh -o StrictHostKeyChecking=no -o ConnectTimeout=8 \
-o UserKnownHostsFile=/dev/null administrator@192.168.123.11 "命令"
# 中文输出乱码GBK先 chcp 65001
"chcp 65001 >nul & 命令"
```
## 部署 Node 服务核心流程schtasks 常驻)
**关键教训SSH 会话里 `start /b` 或 PowerShell Start-Process 启动的子进程SSH 断开后会被杀。** 必须用 Windows 任务计划程序schtasks托管才能常驻。
### 1. 克隆代码(走本地 Gitea 快)
```bash
sshpass -p 'xue.2538' ssh ... administrator@192.168.123.11 \
"cd C:\ && git clone http://xiaoxue_admin:TOKEN@192.168.123.11:3000/xiaoxue_admin/REPO.git rsshub"
```
### 2. 安装依赖 + 构建Windows 无 tail用 findstr
```bash
# pnpm 全局装 + installnative 模块缺 VS 构建工具会报 gyp 错,可选依赖可忽略)
"cd C:\rsshub && npm install -g pnpm@9 & pnpm install 2>&1 | findstr /C:Done /C:ERR /C:error"
# 构建(成功标志 Build complete
"cd C:\rsshub && npm run build 2>&1 | findstr /C:\"Build complete\" /C:error"
```
### 3. 写启动 bat用 PowerShell Set-Content别用 echo 重定向——SSH 转义会截断)
```bash
# ✅ 可靠写法PowerShell 数组写文件echo > 会被 SSH 转义吃掉 > 和 &
sshpass ... "powershell -Command \"Set-Content -Path 'C:\rsshub\start-rsshub.bat' -Value @('@echo off','cd /d C:\rsshub','set PORT=1200','set NODE_ENV=production','node dist\index.mjs > C:\rsshub\rsshub.log 2>&1') -Encoding Ascii\""
```
### 4. 创建并运行 schtasks 任务
```bash
# 创建(/sc once /st 00:00 占位,/f 覆盖)+ 运行
sshpass ... "schtasks /create /tn RSSHub /tr \"C:\rsshub\start-rsshub.bat\" /sc once /st 00:00 /f & schtasks /run /tn RSSHub"
# 验证进程
sshpass ... "tasklist | findstr /i node & netstat -ano | findstr :1200"
```
schtasks 起的进程跑在 **Services 会话**`tasklist` 显示 `Services 0`SSH 断开不掉。
### 4b. 开机自启schtasks onstart常驻服务必做
```bash
# 一次性任务 → 开机触发:删旧建新(/sc onstart + /ru SYSTEM
schtasks /delete /tn RSSHub /f
schtasks /create /tn RSSHub /tr "C:\rsshub\start-rsshub.bat" /sc onstart /ru SYSTEM /f
# 验证类型(英文输出看这两个字段)
schtasks /query /tn RSSHub /fo list /v | findstr /C:"Schedule Type" /C:"Run As User"
# 期望: Schedule Type: At system start up / Run As User: SYSTEM
# 立即测试(杀掉当前实例 → 手动触发 → 验证新进程 + 外部访问)
taskkill /f /im node.exe & schtasks /run /tn RSSHub
tasklist | findstr /i node # 看到新 PIDServices 会话)即成功
# 外部验证
curl -s -o /dev/null -w "%{http_code}" http://192.168.123.11:1200/healthz # 200
```
注意:`/ru SYSTEM` 让任务以系统身份运行(开机即起、无需登录);`/sc once /st 00:00` 是一次性占位任务(手动 /run 用),**持久部署要重建为 onstart**。实测 2026-08-03杀旧 node PID → onstart 任务触发 → 新 node 起来、外部 200全部通过。
### 5. 防火墙放行(外部访问必需)
```bash
# 本机 127.0.0.1 能访问但外部 192.168.123.131 不行 → 防火墙拦截
netsh advfirewall firewall add rule name=\"RSSHub 1200\" dir=in action=allow protocol=TCP localport=1200
```
### 6. 验证
```bash
# 服务器本机验证curl.exe Windows 自带)
curl.exe -s -o NUL -w \"LOCAL: %{http_code}\" http://127.0.0.1:1200/healthz
# 从本机验证外部访问
curl -s -o /dev/null -w "external: %{http_code}" http://192.168.123.11:1200/healthz
```
## Pitfalls
1. **SSH 断开杀子进程**`start /b`、PowerShell `Start-Process` 都不行。必须 schtasks。
2. **echo 重定向被 SSH 转义截断**`echo node dist\index.mjs > log 2>&1` 里的 `>``&` 被吞。用 PowerShell `Set-Content -Value @('...','...')`
3. **Windows 没有 `tail`** — 用 `findstr /C:...` 过滤;不加过滤器先看原始输出更可靠。
4. **中文乱码** — Windows cmd 输出 GBK`chcp 65001`,或接受乱码只看 ASCII 关键词OK/FAIL/Done
5. **缺 VS 构建工具 → node-gyp 失败**`bufferutil`/`ws` 等 native 模块报 `Could not find any Visual Studio installation`。可选依赖可忽略,服务照常跑。
6. **防火墙拦外部** — 本机 200 外部 000 时,加 `netsh advfirewall` 规则(注意 sshpass 里引号转义 `\"`)。
7. **schtasks 创建报 `/ST 超出当前时间` 警告** — 用 `/sc once /st 00:00` 占位 + `/run` 手动触发即可,警告无害。
8. **RSSHub v1.0 路由已删**`/github/release`、`/zhihu/hotlist`、`/github/trending` 返回 404 `The route does not exist or has been deleted`。测路由用现存路径:`/github/issue/DIYgod/RSSHub`、`/github/repos/DIYgod` 返回 200。RSSHub 需要 `npm run build` 后才有 `dist/index.mjs`(直接 `npm start` 报 MODULE_NOT_FOUND
## 参考
- `references/rsshub-windows-deploy-2026-08.md` — RSSHub 部署全程实录(命令、日志、验证)
- Gitea 镜像流程见 `gitea-repo-mirroring` skill

View File

@ -0,0 +1,82 @@
# RSSHub 部署 Windows 家庭服务器实录2026-08-03
完整命令链与验证证据,从零到外部可访问。
## 环境
- 服务器192.168.123.11Windows Server 2022administrator / xue.2538
- 无 DockerNode v24.14.1npm 11.11.0git 2.53
- 本机192.168.123.131Node v24.16.0Docker 29.1.3(无 compose
## 1. 克隆(走本地 Gitea
```bash
sshpass -p 'xue.2538' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null administrator@192.168.123.11 \
"cd C:\ && git clone http://xiaoxue_admin:TOKEN@192.168.123.11:3000/xiaoxue_admin/RSSHub.git rsshub"
# 结果Cloning into 'rsshub'... Updating files: 100% (6655/6655) — CLONE_OK
```
## 2. 依赖安装2m28s
```bash
"cd C:\rsshub && npm install -g pnpm@9 & pnpm install 2>&1 | findstr /C:Done /C:ERR /C:error"
# bufferutil/ws native 报 gyp ERR! Could not find any Visual Studio — 可选依赖,忽略
# 结果Done in 2m 28.7s using pnpm v9.15.9
```
## 3. 构建17.6s
```bash
"cd C:\rsshub && npm run build 2>&1 | findstr /C:\"Build complete\" /C:error"
# 结果:✔ Build complete in 17599ms
```
## 4. 启动脚本PowerShell 写 bat避免 SSH 转义截断)
```bash
"powershell -Command \"Set-Content -Path 'C:\rsshub\start-rsshub.bat' -Value @('@echo off','cd /d C:\rsshub','set PORT=1200','set NODE_ENV=production','node dist\index.mjs > C:\rsshub\rsshub.log 2>&1') -Encoding Ascii\""
```
## 5. schtasks 常驻
```bash
"schtasks /create /tn RSSHub /tr \"C:\rsshub\start-rsshub.bat\" /sc once /st 00:00 /f & schtasks /run /tn RSSHub"
# 结果:成功创建计划任务 "RSSHub" + 成功尝试运行
# 验证tasklist | findstr /i node → node.exe 11384 Services 0Services 会话SSH 断开不掉)
```
## 6. 防火墙
```bash
# 本机 127.0.0.1:1200 200 OK 但外部 000 → 加规则
"netsh advfirewall firewall add rule name=\"RSSHub 1200\" dir=in action=allow protocol=TCP localport=1200"
# 结果确定OK
```
## 7. 验证(外部访问)
```bash
curl -s -o /dev/null -w "%{http_code}" http://192.168.123.11:1200/healthz # 200
curl -s -o /dev/null -w "%{http_code}" http://192.168.123.11:1200/ # 200 (Welcome to RSSHub!)
curl -s -o /dev/null -w "%{http_code}" http://192.168.123.11:1200/github/issue/DIYgod/RSSHub # 200
# RSS 内容真实:<rss> + <item> 含 DIYgod 仓库列表
```
## 本机 Linux 对照systemd
```bash
# ~/.config/systemd/user/rsshub.service
# ⚠️ 用户级 systemd 不要写 User=muc —— 会报 status=216/GROUP (Failed to determine supplementary groups)
# 用默认当前用户WorkingDirectory + Environment 即可
systemctl --user daemon-reload && systemctl --user enable --now rsshub.service
```
## 关键日志/错误锚点
| 症状 | 原因 | 解法 |
|------|------|------|
| `Cannot find module dist/index.mjs` | 没 build | `npm run build` |
| node 进程没起 | SSH 断开杀子进程 | schtasks |
| bat 最后一行 `2>&` 被截断 | SSH 转义吃 `&` | PowerShell Set-Content |
| `status=216/GROUP` | 用户级 systemd 写 User= | 删掉 User 行 |
| 外部 000 / 本机 200 | Windows 防火墙 | netsh advfirewall |
| `/github/release` 404 | RSSHub v1.0 删路由 | 用 `/github/issue` `/github/repos` |

View File

@ -1,5 +1,6 @@
---
name: himalaya
version: 1.2.0
tags: [himalaya, email]
description: "Himalaya CLI: 终端IMAP/SMTP邮件客户端 — 收件箱管理、邮件发送、搜索、附件下载。与Hermes Email Gateway互补Gateway收邮件给AgentHimalaya让Agent操作邮箱。安装: cargo install himalaya。"
related_skills:

View File

@ -1,7 +1,7 @@
---
name: cangjie-distill
version: 1.6.0
date: 2026-07-18
version: 1.7.0
date: 2026-08-02
description: |
把书籍/视频/播客/课程/长内容蒸馏成一组可执行 skills 的元 skill。
触发词:拆书/蒸馏/把XX做成skill/turn a book into skills/把视频/播客/课程蒸馏成skill
@ -184,17 +184,36 @@ Stage5 交付 → 输出为 skill/overview/digest/index
2. 书库有 → 下载 epub/pdf启动蒸馏
3. 书库没有 + 是公版经典 → 找公版来源(《资本论》《共产党宣言》等均为公版)
4. 书库没有 + 非公版 → **停下来问用户提供文件**
5. **GitHub 开源书**2026-08-02 实测新路径git clone 常因国内网络超时(直连/ghfast.top 镜像都不稳),但 **`api.github.com` 可直连(~0.3s 响应)**。用 contents API 逐文件拉取正文:
```bash
# 列目录 → 拿文件名和大小
curl -s -H "User-Agent: Mozilla/5.0" "https://api.github.com/repos/{owner}/{repo}/contents/book"
# 逐文件拉取(返回 base64需解码
for f in chapter1.md chapter2.md; do
curl -s -H "User-Agent: Mozilla/5.0" "https://api.github.com/repos/{owner}/{repo}/contents/book/$f" \
| python3 -c "import json,sys,base64; d=json.load(sys.stdin); open('$f','w').write(base64.b64decode(d['content']).decode('utf-8','ignore'))"
done
# 验证字符数wc -c *.md | tail -1
```
**实测**ai-agent-book 12 个正文文件introduction + chapter1-10 + afterword共 1.1M 字符,用此方法约 1 分钟拉完。MCP GitHub 工具mcp_github_get_file_contents也可拉单文件但大量文件用 curl 循环更快。README 走 `mcp_github_get_file_contents` 或 contents API 都行。
> ⚠️ 没有文本就不启动流水线。仓颉不凭记忆蒸馏。
### 模型选择策略2026-07-18 实测更新)
### 模型选择策略2026-08-02 实测更新)
> ⚠️ **2026-08-02 重要更新**`qwen/qwen3.5-122b-a10b` 已于 **2026-07-20 EOL**、`qwen/qwen3-next-80b-a3b-instruct` 已于 **2026-07-27 EOL**,调用返回 410/end-of-life 错误。中文蒸馏首选改为 `openai/gpt-oss-120b`(实测 3 批蒸馏全部成功输出质量高probe=100 稳定)。
| 模型 | 响应速度 | 可用性 | 适用场景 |
|------|---------|--------|---------|
| `qwen/qwen3.5-122b-a10b` | ~7-18s | ✅ **首选** | 中文深度推理、Stage0概览、skill构造稳定实测 5/5 成功) |
| `openai/gpt-oss-120b` | ~5-15s | ✅ **首选** | 中文深度推理、Stage0概览、skill构造2026-08-02 实测 3/3 成功ai-agent-book 17 skills |
| `nvidia/nemotron-3-super-120b-a12b` | ~1s | ✅ 可用 | 1M ctx 大上下文、delegation |
| `stepfun-ai/step-3.5-flash` | ~1s | ✅ 可用 | 快速问答、简单提炼(输出较短) |
| `minimaxai/minimax-m2.7` | ~3-4s | ⚠️ 有风险 | 大段中文 content 有 60s 超时风险,**慎用长文本** |
| `mistralai/mistral-large-3-675b` | ~1s | ❌ 常超时 | NewAPI 路径经常 `exit code 28`,不推荐通过 NewAPI 调用 |
| ~~`qwen/qwen3.5-122b-a10b`~~ | — | ❌ **已EOL 2026-07-20** | 历史首选已不可用410 |
| ~~`qwen/qwen3-next-80b-a3b-instruct`~~ | — | ❌ **已EOL 2026-07-27** | 已不可用410 |
**Token 限制**:单次 prompt + 系统 prompt + 输出 ≤ context window 的 80%,超长书分段。
@ -207,18 +226,19 @@ Stage5 交付 → 输出为 skill/overview/digest/index
### 流水线实际执行顺序2026-07-18 实测验证)
> 完整8阶段适合出版级蒸馏。日常使用**Stage0 + 直接 skill 构造**10分钟出可用结果。今天2026-07-18实测5本书成功蒸馏模型全部用 qwen3.5-122b-a10b。
> 完整8阶段适合出版级蒸馏。日常使用**Stage0 + 直接 skill 构造**10分钟出可用结果。今天2026-08-02实测ai-agent-book 成功蒸馏 17 skills模型用 openai/gpt-oss-120b。
**实测推荐工作流**
```
1. Calibre OPDS 搜索书名 → 获取 id
2. /get/epub/<id>/<library> 下载 epub → ~/.hermes/cangjie-inputs/
3. zipfile 提取 epub → 转 txt → 检查字符数(<5K PDF>50K 继续)
4. Stage0qwen3.5-122b-a10b 跑一次 LLM输出结构化 BOOK_OVERVIEW
1. 确认书源Calibre OPDS 或 GitHub contents API见上
2. 下载/拉取正文 → 检查字符数(<5K PDF>50K 继续)
3. 按章分 3 批(每批 3-4 章,每章截 12-15K 字符)构造 skill
4. Stage0openai/gpt-oss-120b 跑 LLM输出结构化 BOOK_OVERVIEW
5. 直接构造 skill基于 overview 让 LLM 输出 3-N 个完整 skillR/I/A1/A2/E/B
6. 写 INDEX.md
7. git add + commit + push 到 Gitea每本书完成后单独 push
6. 合并三批 → 拆分成独立 skill 目录(每个含 SKILL.md + test-prompts.json
7. 写 INDEX.md / BOOK_OVERVIEW.md / PIPELINE_STATE.md
8. git add + commit + push 到 Gitea每本书完成后单独 push
```
**实测工具选择**

34
skills/media/tts-stt-tools/SKILL.md Executable file → Normal file
View File

@ -1,13 +1,13 @@
---
name: tts-stt-tools
description: "TTS 和 STT 工具封装 — edge-tts 语音合成 + 模力方舟 GLM-ASR 语音转文字,无需 HuggingFace 下载"
version: 1.3.0
version: 1.4.0
author: 小唯 A06
tags: [tts, stt, edge-tts, faster-whisper, voice, speech, GLM-ASR, 模力方舟]
tags: [tts, stt, edge-tts, faster-whisper, voice, speech, GLM-ASR, 模力方舟, cloudflare-edge-tts]
trigger: "转语音 / 转文字 / text to speech / speech to text / 语音合成 / 语音转写 / 说出来 / 把我说的转成文字"
trigger_fallback: true
created: 2026-05-13
updated: 2026-05-23
updated: 2026-08-03
---
# TTS & STT 工具封装
@ -40,6 +40,24 @@ edge-tts -t "低沉的声音" -v "zh-CN-YunxiNeural" --pitch=-50Hz --write-media
| zh-CN-XiaoyiNeural | 女 | 活泼 |
| zh-CN-YunyangNeural | 男 | 新闻播报 |
### Hermes 内置 TTS 通道最省事2026-08-03 验证)
`~/.hermes/config.yaml` 已配置 `tts.provider: edge` + `voice: zh-CN-XiaoxiaoNeural`
直接用 `text_to_speech` 工具即可合成中文女声,输出真实 MP348kbps 24kHz
### cloudflare-edge-ttsWorker 版,可作独立 HTTP TTS API
DIYgod 的开源项目 `cloudflare-edge-tts`(本地路径 `~/projects/diygod/cloudflare-edge-tts/`
- 端点:`GET /health`、`GET /voices`、`POST /tts`body `{"text":"你好","voice":"可选"}` → audio/mpeg
- **本地跑不需要 Cloudflare 认证**`npx wrangler dev --local --port 8787`
- 测试:`npm test` 22/22 通过2026-08-03
- 用处:想要独立 TTS API 服务(非 Hermes 通道)时起这个
```bash
cd ~/projects/diygod/cloudflare-edge-tts && npx wrangler dev --local --port 8787
curl -s -H 'Content-Type: application/json' -d '{"text":"你好"}' http://127.0.0.1:8787/tts -o out.mp3
```
### Python 调用
> 参考:`references/edge-tts-venv-pattern.md` — 当系统 `pip` 无法直接安装时externally-managed-environment如何在项目 venv 中调用 edge-tts。
@ -92,12 +110,10 @@ def transcribe(audio_path: str) -> str:
### 方案2faster-whisper本地需模型
> ⚠️ **服务器 HuggingFace 网络不通时无法下载模型**。优先用方案1。
服务器只有国内网络访问权baidu.com、ai.gitee.com 可达HuggingFace、jina.ai、firecrawl 等国际服务均不通。
> ✅ **2026-08-03 实测hf-mirror.com 镜像可下载成功**。直连 HuggingFace 超时(`ConnectTimeout: [Errno 110]`),但 `HF_ENDPOINT=https://hf-mirror.com` 后 base 模型 (~150MB) 正常下载并缓存到 `~/.cache/huggingface/hub/models--Systran--faster-whisper-base`1-3 分钟)。该 env 已持久化到 `~/.hermes/.env`
```bash
# 方案A配置 HF 镜像(如果 hf-mirror.com 可达
# 方案A配置 HF 镜像(✅ 已验证可下载2026-08-03
HF_ENDPOINT=https://hf-mirror.com python3 -c "from faster_whisper import WhisperModel; model = WhisperModel('base', device='cpu', compute_type='int8')"
# 方案B回家后用家里网络下载或用 Ollama whisper 替代
@ -131,8 +147,8 @@ hermes-stt audio.wav
|------|------|------|
| edge-tts | ✅ 已安装 | 7.2.8 |
| faster-whisper | ✅ 已安装 | 1.2.1 |
| ffmpeg | ✅ 已安装 | /usr/bin/ffmpeg |
| whisper 模型 | ✅ 已下载 | `~/.cache/huggingface/modules/faster_whisper_modules/` |
| ffmpeg | **未安装**2026-08-03 实测 `which ffmpeg` 无结果faster-whisper 用 PyAV 直接解码 OGG/Opus不需要 ffmpeg | - |
| whisper 模型 | ✅ 已缓存 | `~/.cache/huggingface/hub/models--Systran--faster-whisper-base`(经 hf-mirror.com 下载) |
| 模力方舟 GLM-ASR | ✅ STT 生产方案 | API 调用 |
| espeak-ng | ⬜ 建议安装NeuTTS 用) | - |

View File

@ -0,0 +1,14 @@
## 示例报告20260802
```
今日完成:
- 织忆健康检查通过 ✅
- Daemon 正常启动,无异常日志
明日待办:
- 继续监控 Daemon 与织忆组件 24h 健康状态
- 若有新任务,使用 `session_search` 捕获并记录
- 如产生心迹,写入 `~/.hermes/soulful/heart-traces.jsonl`
情绪状态:
- neutral保持平稳
```

View File

@ -11,6 +11,43 @@ trigger: 用户分享一个 GitHub 仓库名/产品名(如 "XX开源了"、"
牧尘会不定时丢项目名过来Qwen Audio Agent、OmniRoute、各种开源工具。**铁律:先查证再说话**——不凭印象编造 stars/功能,一切以 api.github.com 实时数据为准。
## 工具链2026-08-02 实测MCP 优先)
**首选:原生 GitHub MCP 工具**——本环境最可靠,免 curl/浏览器/网络代理:
- `mcp_github_search_repositories(query="repo:{owner}/{repo}")` → 元数据full_name/desc/stars 可用性/created/updated/default_branch——注意返回值里**没有 stargazers_count 字段**,要 stars 用 repo API 或接受缺失
- `mcp_github_get_file_contents(owner, repo, path="README.md")` → 拿 READMEbase64 content 字段,需解码后读)
- `mcp_github_get_file_contents` 列目录path 传目录名即可
**2026-08-02 实测降级顺序**GitHub MCP 工具 → web_search可能限流→ web_extractddgs 后端只支持搜索,不支持提取,会报 "search-only backend")→ 浏览器agent-browser 首次启动可能超时)→ terminal curl可能被安全拦截 BLOCKED
**经验**:不要一条路走到黑——`web_extract` 报 ddgs-only、browser 超时、execute_code/terminal 被 BLOCKED 时,**立即切 MCP 工具**,它没失败过。
## 源码/正文拉取git clone 超时的正解2026-08-02 实测)
**场景**:要研究一个开源书的正文 / 代码文件,但 `git clone` 直连和 ghfast.top 等镜像都超时(本环境实测)。**`api.github.com` 可直连(~0.3s**,用 contents API 逐文件拉:
```bash
# 列目录 → 拿文件名和大小
curl -s -H "User-Agent: Mozilla/5.0" "https://api.github.com/repos/{owner}/{repo}/contents/book"
# 逐文件拉取(返回 base64 content 字段,需解码)
for f in chapter1.md chapter2.md; do
curl -s -H "User-Agent: Mozilla/5.0" "https://api.github.com/repos/{owner}/{repo}/contents/book/$f" \
| python3 -c "import json,sys,base64; d=json.load(sys.stdin); open('$f','w').write(base64.b64decode(d['content']).decode('utf-8','ignore'))"
done
# 验证wc -c *.md | tail -1
```
**实测**ai-agent-book 12 个文件 1.1M 字符约 1 分钟拉完。README 也可走此 API或 MCP。**GitHub release 直链下载releases/download/latest/xxx.pdf本环境也超时**——要 PDF/二进制同样走 contents API 拿源码,或换代理。
## Go 工具安装2026-08-02 实测)
`go install` 直连 proxy.golang.org 超时i/o timeout。**先设 GOPROXY 再装**
```bash
export GOPROXY=https://goproxy.cn,direct && go install github.com/{owner}/{repo}/v10@latest
```
实测 croc v10.7.0 用此法装成功goproxy.cn 国内可达)。
## 标准流程3 步 + 收尾)
### ① 验证存在 + 元数据API免认证
@ -68,7 +105,18 @@ content = base64.b64decode(d2['content']).decode('utf-8', 'ignore')
3. **给明确结论而非模糊建议**(例:"不替代,做第二网关"——新项目跑 :3001 专供 cron现有 :3000 不动,核心生产链路付费模型绝不动 + 观察期 2-4 周)
4. **评估维度补充**:项目年龄(<6 个月太年轻)、open issues 数百 = 需谨慎)、最近提交时间(今天 = 活跃)。年轻但活跃 适合并行观察不适合直接替换生产
## 调研要点速查
## 调研单个作者的仓库全景2026-08-02 新增)
用户说"研究 XX 作者/组织的项目"时DIYgod不是单项目调研是**作者全景**
1. **用户信息 + profile README**`api.github.com/users/{login}`bio/company/blog/followers→ profile README 常自报家门DIYgod 写 "Founder of Folo, RSSHub, xLog and DPlayer"——**直接点名了四个项目,其中两个不在他名下**
2. **仓库列表按 stars 排序**`api.github.com/users/{login}/repos?per_page=100&sort=stars`——注意 100 条可能含 fork`fork` 字段过滤
3. **⚠️ 作者名下 ≠ 全部作品**大项目常放组织DIYgod 的 Folo→RSSNext、xLog→Crossbell-Box。从 profile README 的 founder 声明里抓组织名,再用 `search/repositories?q={关键词}` 定位真实归属
4. **文章/他人转述的归因要核实**:用户转发的文章说 "RSSHub + Reeder + DPlayer + Watermark + Social-Image 是 DIYgod 工具链"——实测 Watermark/Social-Image/Reeder **都不是他的**(在 DIYgod 名下搜不到,是泛指的独立开源工具)。**不核实归因,报告就会传播错误信息**
5. **区分活跃 vs 停更**:看 `pushed_at`RSSHub 昨天推=活跃GoodNight 2023 停更README 里的 badge 有时比 description 信息量大docker pulls / requests/month
6. **给"对我们系统有什么用"的落地建议**,不只是罗列 star 数DIYgod 案例 → RSSHub 可接入信息采集体系)
- **同名项目很多时**`api.github.com/search/repositories?q={query}&sort=stars&per_page=5` 按 stars 找主导者OmniRoute 曾有多个同名小项目,主导者 36k stars
- **搜索会跑偏2026-08-01 教训)**:搜 "grok-build" 按 stars 排序返回的是 `farion1231/cc-switch`123k stars 的切换器,名字里含 grok-build 但根本不是 xAI 官方)——**搜索命中 ≠ 目标项目**。官方/大厂项目直接试 `api.github.com/repos/{org}/{repo}`org 候选按记忆试xai-org、x-ai、QwenAudio、HKUDS…命中即真。搜索只能辅助定位不能作为存在性证据
@ -82,5 +130,7 @@ content = base64.b64decode(d2['content']).decode('utf-8', 'ignore')
## 已调研案例
- `references/2026-08-02-research-diygod.md` — DIYgod 作者仓库全景RSSHub/Folo/DPlayer/xLog star 表、组织归属、文章归因纠偏、RSSHub 落地建议)
- `references/2026-08-01-research-cases.md` — Qwen Audio Agent实时语音运行时、OmniRouteAI 网关、system_prompts_leaks大厂提示词库完整调研记录 + 深度评估方法论 + 借鉴产出5 个提示词改进点)
- `references/2026-08-01-research-cases-batch2.md` — strixAI 渗透、grok-build编码 Agent含搜索跑偏案例 + 源码深读模式、Vibe-Trading量化交易
- `references/2026-08-02-research-cases-batch3.md` — ai-agent-book李博杰 Agent 书ch3/ch8 对标织忆、ui-skillsUI 质量技能集、croc安全文件传输+ MCP 工具全流程方法论

View File

@ -0,0 +1,51 @@
# 2026-08-02 调研案例batch 3
牧尘一次性丢 3 个项目。全部用 GitHub MCP 工具查证(本环境实测最快路径)。
## 1. bojieli/ai-agent-book — 《深入理解 AI Agent》
| 项 | 值 |
|---|---|
| 作者 | 李博杰(前华为 AI 专家) |
| License | Apache-2.0 |
| 创建 | 2025-09-09~11 个月成熟持续更新2026-08-02 仍有 push |
| 形态 | 开源书10 章正文 + 95 个配套实验 + PDF/EPUB 离线版 + 13 种语言 |
| 核心公式 | **Agent = LLM + 上下文 + 工具** |
| 章节亮点 | ch3 用户记忆和知识库RAG/知识图谱)· ch4 工具/MCP · ch6 评估 · ch7 模型后训练 · ch8 持续进化 · ch10 多 Agent 协作 |
| 实验运行 | Python 3.10+`uv sync --locked --extra ch1`(本机 uv 0.11.14 ✅) |
| 语言版本 | 中文原版在 `book/`,英文 `book-en/` 等社区翻译可能滞后 |
**与织忆的契合**ch3记忆/知识库)直接对标织忆 MemoryWeavech8持续进化对标 learner/self-evolve。建议精读 ch3+ch8可蒸馏成仓颉 skill。
## 2. ibelick/ui-skills — Design Engineers 技能集
| 项 | 值 |
|---|---|
| License | MIT |
| 创建 | 2026-01-07~7 个月,活跃) |
| 定位 | Agent 的 UI 质量技能包accessibility / motion / frontend craft / interface quality |
| 用法 | `npx ui-skills start` / `npx ui-skills list --category motion` / `npx ui-skills get baseline-ui` |
| 官网 | ui-skills.com带 Agent 引导页) |
| 本地 | npx 已装node v24✅ |
**契合**:与 creative 类技能claude-design / popular-web-designs / p5js互补——那些是"生成",这个是"打磨质量"。
## 3. schollz/croc — 安全文件传输
| 项 | 值 |
|---|---|
| License | MIT |
| 创建 | 2017-10-179 年非常成熟2026-08-01 仍有 push |
| 定位 | 任意两台电脑安全传文件/文件夹,**唯一同时具备**端到端加密PAKE+ 断点续传 + 跨平台 + 多文件 + 免端口转发 + IPv6-first + Tor 代理 |
| 用法 | 发:`croc send 文件` → 得到 code phrase`croc 验证码` |
| 进阶 | `--store` 加密暂存 24hCROC_STORE_TOKEN 防进程列表泄露)· `--qr` 手机收 · `--relay` 自建中继(默认 9009-9013· `--socks5` 代理 |
| Linux 安全坑 | CVE-2023-43621`CROC_SECRET=xxx croc` 而非明文参数(防 /proc 泄露);`croc --classic` 可永久开启单用户模式 |
| 本地 | 未装Go 1.22.2 ✅(要求 1.22+`go install github.com/schollz/croc/v10@latest` |
**契合**与服务器192.168.123.11)和云服务器传文件,比 rsync 更适合一次性安全传输(加密+断点续传);自建 relay 可内网直连。与现有 SMB/rsync 互补。
## 调研方法论沉淀
1. **MCP 工具全流程**`mcp_github_search_repositories(query="repo:o/r")` 拿元数据 → `mcp_github_get_file_contents(path="README.md")` 拿 README → `terminal which/go version` 检查本地。三个项目 ~5 次调用完成。
2. **search_repositories 的 stars 缺失**:返回 JSON 无 stargazers_count 字段,需要 stars 时用 repo API 或说明缺失——不要编造。
3. **README 大小差异**croc 13.5KB全量读、ai-agent-book 22.9KB含超长附录读关键段落、ui-skills 466B极简。小 README 全读,大 README 分段。

View File

@ -0,0 +1,39 @@
# DIYgod 开源项目全景调研2026-08-02
调研触发:牧尘转来一篇文章("DIYgod 工具链RSSHub+Reeder+DPlayer+Watermark+Social-Image"),要求研究 DIYgod 作者仓库。
## 作者档案
- login: DIYgod新加坡 Web 开发者15,911 followers2014-07 加入
- bio: "写代码是热爱,写到世界充满爱!"
- company: Natural Selection Labs
- profile README 自报:**Founder and Developer of Folo, RSSHub, xLog and DPlayer**
## 核心项目(按 star 排序2026-08-02 实测)
| 项目 | Star | 归属 | 语言 | 状态 | 说明 |
|------|------|------|------|------|------|
| RSSHub | 45,525 | DIYgod | TS | 活跃(当日推) | 万物转 RSS全球 5000+ 实例 |
| Folo | 38,749 | **RSSNext 组织** | TS | 活跃 | AI RSS Reader跨平台 |
| DPlayer | 16,466 | DIYgod现 MoePlayer org | JS | 维护 | HTML5 弹幕视频播放器 |
| RSSHub-Radar | 7,286 | DIYgod | TS | 维护 | 浏览器扩展,一键发现 RSS |
| APlayer | 7,700 | DIYgod | JS | 维护 | HTML5 音乐播放器 |
| xLog | 2,672 | **Crossbell-Box 组织** | TS | 维护 | 链上Crossbell 区块链)创作社区 |
| cloudflare-edge-tts | 199 | DIYgod | TS | 新2026-04 | Cloudflare Worker TTS |
| GoodNight | 167 | DIYgod | JS | 停更2023 | 自动给女朋友说晚安 |
| hexo-theme-sagiri | 488 | DIYgod | HTML | 停更 | Hexo 主题 |
2RSS 系列前身2016-2018Weibo2RSS / bilibili2RSS / NetEaseCloudMusic2RSS / Juejin2RSS / Ziroom2RSS——**RSSHub 正是从这些单站转 RSS 工具合并长出来的**"一行代码起步"的实证)。
## 文章归因纠偏
文章称 "RSSHub + Reeder + DPlayer + Watermark + Social-Image 是 DIYgod 工具链"
- ✅ 真正 DIYgodRSSHub、DPlayer/APlayer
- ❌ **Reeder / Watermark / Social-Image 不是他的项目**——在 DIYgod 名下搜不到(`search/repositories?q=user:DIYgod+watermark` 空结果),是泛指独立开源工具
- 文章核心观点("别一开始做平台从小工具开始60K 星起点是一行代码")成立,但归因有误
## 对我们的落地价值
- RSSHub 可接入信息采集:`product-research` / `community-ops` 现在只监控博客 RSS接 RSSHub 能覆盖 B站/小红书/微博等平台源
- 路径验证RSSHub 从"自己需要订阅微博"起步Weibo2RSS → RSSHub与织忆从"记不住东西"起步同构
- 社区驱动5000 实例靠社区贡献路由——开源项目杠杆在"让用户帮你建生态"

View File

@ -75,6 +75,8 @@ detect_changes(project="project-name")
- `trace_path` 对跨包/跨语言的调用链可能返回 0 结果(索引深度不够,重试有时能解决)
- `search_graph``total_results` 字段可能显示为 `?`,看 `results[]` 数组长度更可靠
- 项目名是路径自动生成的(如 `/tmp/memoryweave``tmp-memoryweave`),用 `list_projects` 确认
- **MCP unreachable 先查进程数再怀疑坏了2026-08-02**CBM 是 hermes gateway 的子进程(`ps -eo pid,ppid,etime,cmd | grep codebase-memory-mcp`PPid 是 gateway 的 python 进程,不是 systemd——gateway 可能短暂拉起第二个实例,两个进程抢同一个 `~/.cache/codebase-memory-mcp/home-muc-.hermes.db` sqlite 锁导致 MCP 瞬时 unreachable新进程退出后单进程即恢复**不需要任何修复**。诊断顺序:① ps 看进程数 ② 直接调一个 CBM 工具(如 `get_graph_schema`)重试 ③ 全挂再查 db 文件锁
- **`home-muc-.hermes.db.corrupt` 是正常备份**CBM 索引 db 目录里 `.corrupt` 后缀文件是旧备份机制(非故障),主库 `home-muc-.hermes.db` 一直在更新就是健康
## 边界
- ❌ 不做:运行时诊断、日志分析、数据库查询

View File

@ -212,6 +212,28 @@ snippets = [f"{prefix}{behavior_rules[key]}" for key, prefix in snippet_prefixes
让模型"更聪明"的最快路径:不改模型,只改上下文注入方式。
把行为规范变成可直接执行的文本片段,模型无需自己从元数据推导。
## 2026-08-02 牵挂 stale 生命周期 bug 修复
**症状**cares-queue.json 里 3 条 `status=stale` 的牵挂长期残留,`_cleanup_expired_cares()` 只标记 stale 从不删除。
**根因**daemon.py `_cleanup_expired_cares`
- 原逻辑:`follow_up < today-7天` 删除否则保留
- stale 的 3 条 follow_up=07-31today=08-02 → `07-31 > 07-26` 不满足删除条件 → 永远残留
- 且代码只对 `pending` 做"超14天标记 stale"**stale 状态本身没有任何删除规则**
**修复**stale 状态直接物理删除stale 不再需要保留记录):
```python
# stale 状态 → 物理删除stale 不再需要保留记录)
if c.get("status") == "stale":
continue
```
**教训**:标记 stale 只是"软删除"第一步,必须有配套的**物理清理规则**,否则 stale 堆积。生命周期必须是完整的pending →超14天→ stale →(下轮清理)→ 删除。
**验证**`python3 -c "import json; d=json.load(open('~/.hermes/soulful/cares-queue.json')); print(len(d.get('cares',[])))"` → 应输出 0清理后
---
## 脏数据检查项
- `done` 状态残留(应删除)
- 已过期 `follow_up_date` 的 pending 项2026-07-10 已有3条

View File

@ -1,12 +1,12 @@
---
name: whisper-stt
description: "语音转文字 — 基于 faster-whisper离线本地运行。base模型(~150MB)CPU推理中文/英文识别。"
version: 1.0.0
description: "语音转文字 — 基于 faster-whisper离线本地运行。base模型(~150MB)CPU推理中文/英文识别。含首次使用预检、HF镜像、模型缓存路径。"
version: 1.1.0
category: media
last_reviewed: 2026-07-09
last_reviewed: 2026-08-03
tags: [stt, whisper, voice, speech-recognition]
related_skills:
- hermes-tts: "文字转语音 — whisper的互补技能"
- tts-stt-tools: "TTS + 模力方舟 GLM-ASR 的封装(无需本地模型下载)"
required_commands:
- python3
readiness_status: available
@ -14,27 +14,46 @@ readiness_status: available
# Whisper STT — 离线语音转文字
## 使用条件
当需要把用户语音/音频文件转成文字时使用(飞书语音消息、录音文件等)。本机已装 faster-whisper 1.2.1。
当需要语音输入转文字时使用。本机已安装 faster-whisper 1.2.1base 模型已缓存。
## ⚠️ 首次使用必读2026-08-03 教训)
**用户视角:语音对话第一次特别费劲 = 模型没缓存 + HuggingFace 直连超时,等了 5 分钟才失败。**
1. **先查模型缓存**(秒级判断,别直接跑转录):
```bash
ls ~/.cache/huggingface/hub/ | grep -i whisper
# 看到 models--Systran--faster-whisper-base 才是已缓存
```
2. **没缓存必须先设镜像**HuggingFace 直连在本网络环境必超时 `ConnectTimeout: [Errno 110]`
```bash
export HF_ENDPOINT=https://hf-mirror.com # 已写入 ~/.hermes/.env新 shell 也生效
```
3. **首次下载 ~150MB 需要 1-3 分钟**:用 `background=true` + `notify_on_complete=true` 跑,别前台干等。
## 环境
- 模型: `faster_whisper` with `base` (150MB, CPU int8)
- 缓存路径: `/tmp/whisper-models/`
- HF 镜像: `HF_ENDPOINT=https://hf-mirror.com`
- 支持的音频格式: WAV (16kHz, mono, 16-bit)
- 模型: `faster_whisper` `base` (150MB, CPU int8)
- **真实缓存路径**: `~/.cache/huggingface/hub/models--Systran--faster-whisper-base`(❌ 不是 `/tmp/whisper-models/`,旧文档写错了)
- HF 镜像: `HF_ENDPOINT=https://hf-mirror.com`(已持久化到 `~/.hermes/.env`
- 支持格式: **OGG/Opus 直接转faster-whisper 用 PyAV 解码,无需 ffmpeg**、WAV 16kHz mono
- 音频太长/格式怪异才需要 ffmpeg 转 WAV本机未装 ffmpeg用 PyAV 兜底)
## 使用方式
### 转写音频文件
### 转写音频文件(含预检,推荐直接跑这段)
```python
```bash
# 预检缓存 + 转写一步到位(缓存没命中会自动走镜像下载)
export HF_ENDPOINT=https://hf-mirror.com
python3 -c "
from faster_whisper import WhisperModel
model = WhisperModel('base', device='cpu', compute_type='int8',
download_root='/tmp/whisper-models')
segments, info = model.transcribe('input.wav', language='zh')
text = ' '.join(seg.text for seg in segments)
model = WhisperModel('base', device='cpu', compute_type='int8')
segments, info = model.transcribe('INPUT.ogg', language='zh')
print(f'LANG: {info.language} prob={info.language_probability:.2f} dur={info.duration:.1f}s')
for seg in segments:
print(f'[{seg.start:.1f}-{seg.end:.1f}] {seg.text}')
"
```
### 中文优化
@ -49,14 +68,8 @@ segments, info = model.transcribe('input.wav', language='zh',
```bash
# 先用 arecord 录一段
arecord -d 5 -f S16_LE -r 16000 -c 1 /tmp/recording.wav
# 再转写
python3 -c "
from faster_whisper import WhisperModel
model = WhisperModel('base', device='cpu', compute_type='int8', download_root='/tmp/whisper-models')
segments, info = model.transcribe('/tmp/recording.wav', language='zh')
for seg in segments:
print(seg.text)
"
# 再转写(同上代码,路径换成 wav
python3 -c "from faster_whisper import WhisperModel; ..."
```
## 模型选项
@ -69,13 +82,16 @@ for seg in segments:
## 注意事项
- 首次使用会自动从 HuggingFace 下载模型(已设 HF_ENDPOINT 国内镜像加速)
- 模型缓存到 `/tmp/whisper-models/`,重启用没了需要重下
- 建议用 `language='zh'` 指定中文以提升精度
- ✅ **首次使用自动从 HuggingFace 下载模型**:直连会超时,必须 `HF_ENDPOINT=https://hf-mirror.com`(已写 `~/.hermes/.env`
- ✅ **模型缓存** `~/.cache/huggingface/hub/`(持久,不随重启丢失)
- ✅ **OGG/Opus 直接转**,不需要 ffmpeg
- 建议 `language='zh'` 提升中文精度
- 背景噪声大的环境效果下降
- 本机 hermes 内置 STT provider=local(base) 走同一套缓存TTS 语音合成见 `tts-stt-tools`
## 文件
| 文件 | 说明 |
|------|------|
| `/tmp/whisper-models/` | 模型缓存目录 |
| `~/.cache/huggingface/hub/models--Systran--faster-whisper-base` | 模型缓存(真实位置) |
| `~/.hermes/.env` | `HF_ENDPOINT=https://hf-mirror.com` 持久配置 |

View File

@ -148,7 +148,7 @@ json.dump(d, open('cares-queue.json','w'), ensure_ascii=False, indent=2)
> 🛑 **新会话必读**:本 skill 顶部「快速状态」表是**当前真实部署状态**2026-06-25 全链路验证通过)。任何关于织忆的判断,先看此表 + 跑下方「系统全面检查步骤」10 秒内拿真实状态)。**绝对不要从 AGENTS.md / MEMORY.md 里过去 1 个月以上的描述直接判断织忆状态**。
**最后一次实地拉状态2026-07-20记忆系统统一合并后)**
**最后一次实地拉状态2026-08-02四系统体检 + episodes 持久化修复后)**
| 项目 | 状态 | 路径/值 |
|------|------|---------|
@ -157,7 +157,7 @@ json.dump(d, open('cares-queue.json','w'), ensure_ascii=False, indent=2)
| bge-embed | ✅ active | 端口 8000 |
| 织忆 API | ✅ health=ok | `http://localhost:7821` |
| 后端 | ✅ lancedb (Rust IPC) | `STORAGE_BACKEND=lancedb` 环境变量 |
| 数据规模 | **4285 memories / 243 episodes** | LanceDB |
| 数据规模 | **5063 memories / episodes 已持久化**2026-08-02 修复后重启不丢) | LanceDB |
| Graph 图谱 | **8397 节点 / 53081 边** | `~/.hermes/graph.db`pattern 节点=20新增 daemon-distill namespace |
| Phase A (Go骨架+认证) | ✅ 完成 | `go/cmd/zhiyid/` |
| Phase B (Rust sidecar+LanceDB) | ✅ 完成 | `rust/src/` |
@ -209,6 +209,39 @@ API key: `zhiyi-dev-key-2026`
**下次任何 cron/任务引用"实施计划第 X 章"前,`search_files` 路径先验证再用结论,禁止沿用过期的版本文件名。**
## ⚠️ 记忆系统全景不是一套是四套2026-08-02 牧尘纠正)
> **牧尘原话**"记忆系统可不止织忆,还有其他系统"、"你还少了cbm"。评估/汇报"记忆系统"时必须**四套一起看**,缺一不可:
| 系统 | 职责 | 端口/位置 | 数据量(2026-08-02 实测) | 健康判定 |
|------|------|----------|------------------------|---------|
| **织忆 ZhiYi** | 语义记忆(项目/技术/对话) | :7821 | 5054 memories / 9075 图谱节点 | commit→distill→recall 链路通 |
| **Soulful** | 关系记忆(心迹/牵挂/画像) | daemon, ~/.hermes/soulful/ | 心迹13 / 牵挂 / 画像完整 | 牵挂 stale 自动清理 |
| **TencentDB TDAI** | 人格蒸馏L0对话→L1 persona | :8420 | L0 85K / L1 22 | Gateway 活 + L1 提取在跑 |
| **CBM** | 代码知识图谱 | MCP + ~/.cache/codebase-memory-mcp/ | 5 项目(.hermes 389M | MCP 可达 + 索引完整 |
**四套独立进程,默认互不影响**——诊断"记忆系统"问题先确认是哪一套,再独立排查(同织忆 4 组件铁律:不假设"a 挂了是 b 升级造成的")。
**TencentDB 特殊性**L0 是 raw 日志什么都收85K 里大部分是 zhiyi-sync 心迹自动同步 52K + soulful-profile-sync 17K + l3-distill 15KL1 按 everyN=5 或 idle 600s 触发、每次只处理 10 条新消息 → **L0/L1 比例 3876:1 是设计如此**,不是故障。判断"蒸馏是否工作"看日志 `L1-search DONE` 出现,不是看 L1 条数暴涨。
## ⚠️ 端到端链路验证法2026-08-02 核心教训)
> 牧尘反问"织忆很成熟么?"之后深挖发现:**组件都在跑 ≠ 链路在工作**。当时 zhiyid/sidecar/bge-embed 全 active但 commit 写入的内容 20 分钟 recall 查不到——因为 distill 管道一直走 fallbackLLM 配置缺失),产出低质记忆根本排不上检索。
**判断记忆系统"健康/成熟"必须验证端到端链路,不是只看进程/端口**
```
1. 写POST /api/v1/commit → 返回 episode_id201≠ 已入库可用
2. 等distill 是异步队列batch<10 <5min flush 5-10s 或查日志 flush START
3. 验:日志出现 "endpoint=... model=..."(真 LLM而非 "LLMEndpoint empty, fallback"
4. 查recall 同主题能命中新写入内容
5. 量total_memories 增长memories 持久化total_episodes 重启会归零Rust sidecar 内存,非权威)
```
**警惕 fallback 假象**:日志里 `LLMEndpoint empty, fallback` + `facts=1 entities=0` 就是"写入成功了但蒸馏质量=关键词提取"recall 永远排不上。真 LLM 蒸馏特征:`LLM entities: N` + `score=0.8x` + `decisions/conclusions` 结构化字段。
**systemd 路径漂移陷阱2026-08-02 TencentDB 实测)**`tdai-gateway.service` 的 ExecStart 被写坏成 `/src/gateway/server.ts`不存在systemd 崩溃循环 2534 次,但**手动进程撑在 8420 端口让服务"看起来活着"**。修复ExecStart 改回 `--require .../tsx/dist/preflight.cjs --import .../loader.mjs src/gateway/server.ts`杀手动进程systemd 接管。教训:**端口在听 ≠ systemd 服务正常**——查 `systemctl --user show <svc> -p NRestarts` 看重启计数。
## 系统全面检查步骤
当牧尘说"全面检查织忆系统"时按以下步骤执行。核心原则从外到内从进程到API。**先拉现状再判因** — 子系统互相独立时不要假设"是 X 升级造成的"。完整触发清单见 `references/diagnostic-trigger.md`
@ -361,8 +394,8 @@ echo "=== consolidate ===" && grep 'consolidation.*完成' /tmp/zhiyi-sidecar.lo
| `memory.provider: zhiyi` 不生效 | 插件代码不存在于 `plugins/memory/` 目录 | 复制源码并补装依赖 |
| **commit 报 `agent_id and content required`** | API 必传字段,硬性拒绝 | body 加 `"agent_id": "a06"`(或任意非空字符串)|
| **commit 返回判断写成 `resp.get("id")` 恒为 False**2026-08-02 踩坑) | commit 成功返回 `{"episode_id": "ep_...", "status": "ok", "memory_id": ""}`**没有 `id` 字段** | 判断成功应检查 `resp.get("episode_id")``resp.get("status") == "ok"`;且 distill 是**异步队列**,写入后立即 recall 可能查不到,等 5-10s 或用 stats 验证 total_episodes/total_memories 增长 |
| **蒸馏一直 fallback、记忆质量低facts=1 entities=0**2026-08-02 修复) | 实际运行的 `~/.config/systemd/user/zhiyid.service` **缺少 `LLM_ENDPOINT` / `LLM_MODEL` / `LLM_API_KEY` 环境变量** → 日志 `LLMEndpoint empty, fallback`每次蒸馏走关键词提取,产出低质记忆 | systemd unit 补上:`Environment=LLM_ENDPOINT=http://127.0.0.1:3000/v1/chat/completions` + `Environment=LLM_MODEL=openai/gpt-oss-120b` + `Environment=LLM_API_KEY=<NewAPI key>``systemctl --user daemon-reload && restart zhiyid`;验证日志出现 `endpoint=... model=...` + `LLM entities: N`(真 LLM而非 fallback |
| **重启后 total_episodes 归零**2026-08-02 发现 | episodes 存在 Rust sidecar **内存**中lancedb_ipc.go `_local.episodes`zhiyid 重启即清零memories 持久化不受影响 | 已知弱点memories 才是权威数据源;如需 episodes 持久化需改 Rust sidecar 落盘 |
| **蒸馏一直 fallback、记忆质量低facts=1 entities=0**2026-08-02 修复,两次根因 | 实际运行的 `~/.config/systemd/user/zhiyid.service` **缺少 `LLM_ENDPOINT` / `LLM_MODEL` / `LLM_API_KEY` 环境变量** → 日志 `LLMEndpoint empty, fallback`关键词提取;② **模型选错**`openai/gpt-oss-120b` 是 reasoning 模型(`content=null`,答案在 reasoning 字段),即使配了 LLM 也永远 `LLM JSON parse error``facts=1 entities=0` | systemd unit 补上三个 `Environment=`**LLM_MODEL 用 `google/gemma-4-31b-it`**2026-08-02 实测唯一蒸馏可用,勿用 gpt-oss 系)`systemctl --user daemon-reload && restart zhiyid`;验证日志出现 `endpoint=... model=...` + `LLM entities: N`(真 LLM而非 fallback/parse error。若再遇模型挂看门狗 `distill-model-watchdog.py` 会自动切换,或手动 `curl` 验证候选池(见模型白名单节) |
| **重启后 total_episodes 归零**2026-08-02 发现**已修复 2026-08-02** | episodes 存在 Go 进程**内存**中lancedb_ipc.go `_local.episodes`zhiyid 重启即清零memories 持久化不受影响。修复后:`InsertEpisode` 增加 IPC 写入 LanceDB episodes 表 + `Stats()` 改从 Rust 读真实计数 | ✅ 已修复commit `21bc777`):验证=提交测试 episode → stats episodes=1 → `systemctl --user restart zhiyid` → 仍=1。详见 `references/zhiyi-episodes-persistence-20260802.md`。注意:`lancedb_insert` 的 Rust IPC 已支持任意表table="episodes"Go 侧缺的只是调用它 |
| `/search/memories` 输出逐字 `[F][o][u][n][d]` | `results` 是 markdown 字符串,代码按 `\n` 拆分逐字遍历 | `isinstance(results, str)` 判断后整段输出或解析 markdown 格式 |
| 牵挂 due 字段为空 | 字段名是 `follow_up_date` 不是 `due` | `item.get("follow_up_date") or item.get("due") or "null"` |
| **bge-embed systemd restart counter 刷到几千次** | `/tmp/memoryweave/deploy/` 脚本丢失 | 从 Gitea 重建:`git clone http://192.168.123.11:3000/xiaoxue_admin/memoryweave.git /tmp/memoryweave` 然后 `systemctl --user restart bge-embed` |
@ -818,7 +851,61 @@ python3 -c "from plugins.memory.zhiyi import HermesZhiYiMemoryProvider; \
---
> ⚠️ **NewAPI 可用模型白名单2026-07-13 逐一测试)**:绝大多数模型返回 400 或空响应。**唯一确认可用的 LLM 是 `minimaxai/minimax-m3`**,它能结构化 JSON 输出,是 TencentDB L1 提取的唯一选择。`minimax-m2.7` 可对话但 choices 有时为空。`yi-large` / `deepseek-v3.1-terminus` / `glm4.7` / `qwen2.5-coder-32b` 全部返回 400。**任何新模型上线前必须先手动 curl 验证**。
**蒸馏模型看门狗2026-08-02 上线,解决"免费模型挂了没人换"**
- **30min 轻量探针**`~/.hermes/scripts/distill-model-watchdog.py`cron `89de35dc35a7`)——只测当前蒸馏模型的 JSON 输出能力(剥离 code fence 后可解析才算通过),挂了立即按候选池切换 + 更新 zhiyid.service + tdai-gateway.yaml + 重启 + 飞书报警
- **6h 深度巡检**model-health.py 新增 `_heal_distill_models()`——同步守护蒸馏配置,识别 reasoning 模型content=null不适合蒸馏
- **候选池2026-08-02 实测 JSON 可用,优先级降序)**`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`
- **蒸馏模型关键判定**:能对话 ≠ 能蒸馏。蒸馏必须 JSON 输出content 非空且可解析reasoning 模型gpt-oss 系 content=null直接排除
- **手动验证**`python3 ~/.hermes/scripts/distill-model-watchdog.py`(健康静默,异常自动切换)
## ⚠️ 机制建设铁律2026-08-02 牧尘两次纠正 + 一次追问)
### 1. 建任何监控/自动化机制前,先摸清现状,别重复造轮子
牧尘原话:"**先摸清现状,看看与之相关的定时任务等,别重复工作**"。本次差点重复建了 tdai-gateway 看门狗——**memory-system-check.sh每小时早就覆盖 4 系统全检 + health-watchdog.sh30min早就做进程自愈**。已有机制清单:
- `memory-system-check.sh`(每小时 cron— 统一层+织忆+Soulful+TencentDB+CBM 全查
- `health-watchdog.sh`30min— 进程自愈+磁盘/内存/CPU/GPU+config-protector 联动+防自杀
- `memory-system-self-upgrade.py`每日4点— 牵挂清理+画像+心迹去重+报告
- `config-protector.sh` / `anti-suicide-check.sh` / `dual-backup.sh` / `startup.sh`
动作:先 `cronjob list` + `ls ~/.hermes/scripts/` 盘点 → 已有则只补缺口(改检查对象/加检查深度),没有才新建。新建后如与已有 cron 重复,删掉自己的,把逻辑并入已有脚本。
### 2. 自愈/自动化机制必须实测"失败路径",不只编译通过
牧尘问"**都测试过了吧?**"——暴露我只 py_compile 了 `_heal_distill_models`,没跑真实路径。实测后**立刻抓到一个真 bug**gemma 不在 ALL_MODELS 测试列表 → found=None → 被判"需替换" → 每 6h 会把健康模型换掉。
铁律:任何会主动改系统的机制,交付前必须:
- 手动 `cronjob run <id>` 触发一次(确认 last_status=ok / execution_success=true
- **模拟失败场景**(把配置改成已知坏模型)→ 跑机制 → 确认"切换+配置更新+服务重启+通知"全链路
- 判断逻辑做 dry-run 单测(当前好模型应判健康、坏模型应判需替换、原文件未动)
- 陷阱:**模型不在测试列表 ≠ 模型挂了**。探针主判content 非空+JSON 可解析),巡检结果仅作辅助覆盖(明确 dead 才覆盖探针)。
### 3. systemd is-active 会被 auto-restart 循环骗过
tencentdb.service 与 tdai-gateway.service 同源(同一个 server.ts端口被占后**崩溃循环 278 次**`systemctl --user is-active` 在重启间隙返回 active → memory-system-check 一直以为它健康。真相靠 `systemctl --user status <svc>``Active: activating (auto-restart)` + `restart counter is at N`
教训:查服务健康用 `systemctl --user show <svc> -p NRestarts` 或 status 看 restart counter别只信 is-active发现两个服务同源时先确认哪个真在听端口`ss -tlnp`),停用另一个(`systemctl --user disable --now`)。
### 4. 免费模型池会整体过期skill 记录会 stale
2026-07-27 模型池大换血m2.7/step-flash/qwen3.5 全部 EOLm3 空响应gpt-oss 是 reasoning 模型content=null。**skill 里的模型白名单记录会过期,任何"可用模型"判断都必须实测**(新模型先 curl 验证 JSON 输出,见下方蒸馏模型看门狗节的验证命令)。
> ⚠️ **NewAPI 可用模型白名单2026-08-02 实测更新,旧记录 7-27 已全部失效)**
> **模型池 2026-07-27 大换血,以下旧记录全部 EOL/失效**
> - ~~`minimaxai/minimax-m3`~~ / ~~`minimax-m2.7`~~**m2.7 EOL 2026-07-27**m3 用户反馈不可用
> - ~~`mistral-large-3-675b`~~ → 无渠道;~~`mistral-large-3-675b-instruct-2512`~~ → EOL
> - ~~`step-3.5-flash`~~ → EOL 2026-07-27~~`qwen3.5-122b`~~ → EOL 2026-07-20
> - ~~`gpt-oss-120b/20b`~~ → reasoning 模型content=null答案在 reasoning 字段),**不能用于 distill**(除非代码支持 reasoning 字段——engine.go 2026-08-02 已加)
>
> **✅ 蒸馏唯一可用模型2026-08-02 实测):`google/gemma-4-31b-it`**
> - content 直接是纯 JSON带 ```json code fenceengine.go 已支持剥离)
> - 5D 评分正确:`{"is": 8, "su": 9, ...}` 0-10 整数 → prompt 已改为明确要求 0-1 浮点
> - 实测 distill 全链路通过entities=2, overall=1.000, recall 命中 0.765
> - **任何新模型上线前必须先手动 curl 验证 JSON 输出能力**(见下方测试命令)
>
> **蒸馏模型验证命令**
> ```bash
> KEY=$(grep -oP 'LLM_API_KEY=\K.*' ~/.config/systemd/user/zhiyid.service)
> curl -s -m 30 http://127.0.0.1:3000/v1/chat/completions -H "Content-Type: application/json" \
> -H "Authorization: Bearer $KEY" -d '{"model":"<候选模型>","messages":[{"role":"user","content":"输出严格JSON {\"entities\":[]}"}],"max_tokens":150}'
> # 期望: choices[0].message.content 是纯 JSON或可剥离的 code fence且非空
> # 失败特征: content=nullreasoning 模型)/ 400 EOL / No available channel / system_cpu_overloaded
> ```
> **完整模型池列表**`curl -s http://127.0.0.1:3000/v1/models -H "Authorization: Bearer $KEY"`136 个2026-08-02
>
> 更新2026-07-12**TencentDB Agent Memory 安装研究 + 三层记忆架构梳理**
> - TencentDB8603 stars4层渐进管道补的是 Soulful 的「自动人格蒸馏」那块,不是织忆的语义检索
@ -850,17 +937,17 @@ TencentDB 自动从对话蒸馏 → Persona人格文件
效果:我说"牧尘不喜欢废话"不需要每次解释
```
**TencentDB Agent Memory 集成状态2026-07-13 — L0/L1 全通**
**TencentDB Agent Memory 集成状态2026-08-02 更新 — L0/L1 全通,模型已切 gemma**
- npm 安装npmmirror 镜像16s
- Gateway 进程:✅(:8420独立 Node.js
- Gateway 进程:✅(:8420独立 Node.jssystemd `tdai-gateway.service`
- embedding走 bge-m3 8000 端口,`sendDimensions: false`
- LLM**`minimaxai/minimax-m3`** via NewAPI 3000唯一可用模型
- **L1 提取:✅(minimax-m3 结构化输出正常,已验证 persona/instruction 两种记忆)**
- LLM**`google/gemma-4-31b-it`** via NewAPI 30002026-08-02 从 minimax-m3 切换——m3 实测连续空响应/非 JSON不可用
- **L1 提取:✅(gemma-4-31b-it 结构化输出正常extracted=1 stored=1,已验证 persona/instruction 两种记忆)**
- BM25 搜索:✅(能搜到对话,`/search/conversations`
- **注意**TencentDB `/search/memories``/search/conversations` 均可用(返回 markdown 字符串,需 `isinstance(results, str)` 判断);只有 `/scenes` 返回 404详见 `references/tencentdb-api-endpoints-20260720.md`
- recall API495 chars 上下文注入)
- systemd 服务:✅(开机自启,`~/.config/systemd/user/tdai-gateway.service`
- config 文件:`~/.memory-tencentdb/memory-tdai/tdai-gateway.yaml`
- config 文件:`~/.memory-tencentdb/memory-tdai/tdai-gateway.yaml`llm.model 字段;备份 `.bak-watchdog` / `.bak-health`
**关键修复记录2026-07-13逐一踩坑最终全部通过**
1. ❌→✅ `apiKey: not-needed`**必须填真实 NewAPI token**`0ExNiLblJvIWBDpkS50fwOBw4MmqLyKdHJK5iQtlw9dOMWBP`)否则 `Invalid token`
@ -1346,12 +1433,15 @@ python3 ~/.hermes/scripts/wiki_curator.py --dir ~/mc/小唯/ --llm --dry-run
- **⭐ 竞品架构对比2026-07-01**`references/memory-os-7-layer-comparison.md` — Memory-OS 7 层记忆架构 vs 织忆完整对照。含信任评分、4 级降级、自动注入钩子、CREATIVE.md 隔离、强制注入 prompt 共 5 个可直接借鉴的设计点。
- **⭐ 记忆系统对比分析2026-07-13**`references/memory-system-comparison.md` — 克隆分析 yantrikdb/memos/honcho/agent-memory-skill 等 9 个参考项目,输出 P0-P2 优先级建议Ebbinghaus遗忘/冲突检测/多信号评分/think Consolidation/主动触发器)用于织忆迭代时对标参考。
- **⭐ 织忆提升:轨迹学习门禁+程序记忆分类2026-08-02**`references/zhiyi-enhancement-trajectory-learning-20260802.md` — 从《深入理解 AI Agent》蒸馏方法论落地的 learner.py 门禁 + daemon.py 分类改动,含 commit API 返回字段陷阱episode_id 非 id和异步 distill 延迟验证法。
- **⭐ episodes 持久化修复 + 四系统体检2026-08-02**`references/zhiyi-episodes-persistence-20260802.md` — episodes 重启清零的根因Go 内存 + Stats 覆盖与修复IPC 写 LanceDB episodes 表),含 Rust IPC 手动调试协议4字节大端长度前缀、L1 蒸馏率误读教训(真数据在 records/*.jsonl 不在 DB 表、端口在听≠systemd 正常、tdai-gateway 看门狗。
- **⭐ 模型池轮换 + 蒸馏双层守护2026-08-02**`references/model-pool-rotation-20260802.md` — 2026-07-27 模型池大换血 EOL 对照表、蒸馏 vs 对话判定标准、30min 看门狗 + 6h 巡检双层架构、候选池、验证命令、失败特征速查。
- **⭐ 自启动架构2026-07-02**`references/systemd-auto-start.md` — 4 组件启动串行、binary 持久化位置、service 文件配置、ExecStartPre 自愈、重启后验证方法
- **⭐ /tmp/memoryweave 丢失恢复指南2026-06-25**`references/tmp-memoryweave-recovery.md`
- **⭐ 织忆代码健康度审计 2026-06-20**`references/code-health-audit-20260620.md` — Go daemon 6 个问题 + Python 插件 4 个 bug修复详情、编译部署、Gitea push
- **⭐ Gitea push 完整流程**`references/zhiyi-gitea-push.md`(含标准开发 + 多源同步 + 批量全量 三种模式token 查找路径、编译错误修复、常见坑)
- **⭐ GitHub → Gitea 镜像踩坑2026-08-02**`references/gitea-mirroring-20260802.md`(浅克隆 `--depth 1` 不能推shallow update not allowed/ github.com 被限时 codeload 快照方案 / Gitea API 建仓库 description 特殊字符破坏 JSON / 批量镜像 15 仓库流程)
- 设计文档:`~/mc/小唯/07-Wiki/concepts/织忆(MemoryWeave)-v3.8-完整定稿.md`v2.6/v3.8-实施计划等历史文件已删除)
- 实施进度:`~/mc/小唯/记忆/织忆/进度-*.md`
- **⭐ systemd 部署流程**`references/systemd-zhiyi-binary-update.md`

View File

@ -0,0 +1,65 @@
# GitHub → Gitea 镜像踩坑2026-08-02 实测)
镜像 DIYgod 等 GitHub 仓库到自建 Gitea192.168.123.11:3000时实测的三个坑。
Gitea 基础 push 流程见 `zhiyi-gitea-push.md`;本文件只记镜像特有坑。
## 坑 1浅克隆不能推shallow update not allowed
```bash
git clone --depth 1 https://github.com/owner/repo.git # ❌ 快但推不了
git push -f gitea HEAD:master
# ! [remote rejected] HEAD -> master (shallow update not allowed)
```
- `git fetch --unshallow` **不一定修好**——只拉默认分支时 `.git/shallow` 残留标记;
删掉 `.git/shallow` 再推可能触发 `remote end hung up`(历史仍不完整)
- 干净解法:**全量 clone**(保留完整历史)或**快照方案**(见坑 2镜像存档无需历史
## 坑 2github.com git 协议被限时codeload 常可用
GitHub 主站 `github.com` 的 git 协议可能超时/连不上,但 **`codeload.github.com`HTTP 下载)经常通**
```bash
# 诊断:主站挂起但 codeload 200 → 用快照方案
curl -sI https://github.com # 可能超时
curl -sI https://codeload.github.com/owner/repo/tar.gz/refs/heads/main # 200
# 快照方案:下载 tar.gz → 解压 → 推 Gitea适合镜像无历史
curl -sL -o /tmp/repo.tar.gz "https://codeload.github.com/owner/repo/tar.gz/refs/heads/main"
tar xzf /tmp/repo.tar.gz -C ~/projects/
cd ~/projects/repo-main && git init && git add . && git commit -m "snapshot"
git remote add gitea "http://USERNAME:TOKEN@host:3000/owner/repo.git"
git push -f gitea HEAD:master
```
## 坑 3Gitea API 建仓库description 别放特殊字符
```bash
# ❌ README 首行有 emoji/引号会破坏 JSON → "expected comma after object element"
curl -X POST http://host:3000/api/v1/user/repos \
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
-d "{\"name\":\"$name\",\"description\":\"$(head -1 README.md)\"}"
# ✅ description 用固定值
curl -X POST http://host:3000/api/v1/user/repos \
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
-d "{\"name\":\"$name\",\"description\":\"mirror\",\"private\":false}"
```
- 认证:`Authorization: token $TOKEN` 建仓库git push 用 `http://用户名:token@host/...`
token 当密码,不能只有 token 当用户名——会提示输密码)
- Gitea token 位置:`~/mc/牧尘/claw/key.md` → `gitea令牌<40位hex>`
## Gitea API 端点速查
- 建仓库:`POST /api/v1/user/repos`body: name/description/private
- 搜索/验证:`GET /api/v1/repos/search?limit=N`(返回 data[] 的 name
- 服务端迁移Gitea 自己从 GitHub 拉,绕开本地网络):`POST /api/v1/repos/migrate`
body: clone_addr/repo_name/repo_owner/service——⚠ 有些版本返回非 JSON先小仓库试
## 批量镜像流程15 仓库实测)
1. `GET /users/DIYgod/repos?per_page=100&sort=stars` 拉全量 → 按 star/活跃度分类
2. 分类Tier1 核心(下载+测试)/ Tier2 生态(存档)/ Tier3 趣味(可选)
3. 批量 `curl codeload` 下载 tar.gz → 解压 → `git init + commit`
4. 批量 `POST /api/v1/user/repos` 建空仓库description 固定值)
5. 逐个 `git push -f gitea HEAD:master`

View File

@ -0,0 +1,83 @@
# 模型池轮换 + 蒸馏模型双层守护2026-08-02
## 背景:免费模型经常挂,且模型池会整体 EOL
2026-07-27 NewAPI 模型池大换血,旧 skill 记录全部失效:
| 旧记录2026-07-13 skill 白名单) | 2026-08-02 实测状态 |
|----------------------------------|--------------------|
| `minimaxai/minimax-m3`"唯一可用" | 连续 3 次空响应 / 超时,用户早已发现不可用 |
| `minimaxai/minimax-m2.7` | **EOL 2026-07-27** |
| `stepfun-ai/step-3.5-flash` | **EOL 2026-07-27** |
| `qwen/qwen3.5-122b-a10b` | **EOL 2026-07-20** |
| `mistral-large-3-675b` / `-instruct-2512` | 无渠道 / EOL |
| `openai/gpt-oss-120b` / `gpt-oss-20b` | reasoning 模型,`content=null`(答案在 `reasoning` 字段),**不能用于 distill** |
| `nvidia/nemotron-3-super-120b-a12b` | reasoning 回显content 是思考过程 |
| `mistralai/mistral-medium-3.5-128b` | 非 JSON 输出 |
| `moonshotai/kimi-k2-instruct` / `mistral-small-4-119b-2603` / `qwen3-next-80b` | EOL |
| **`google/gemma-4-31b-it`** | ✅ **蒸馏唯一可用**content 纯 JSON + 5D 评分 |
## 蒸馏 vs 对话:判定标准不同
**能对话 ≠ 能蒸馏**。model-health.py 的 `_verify_model_usable` 只测"有内容返回",但蒸馏需要:
1. `choices[0].message.content` 非空reasoning 模型 content=null 直接排除)
2. 剥离 ```json code fence 后可 `json.loads` 成功
3. 能输出 5D 评分字段is/su/pa/vd/ru 0-1 浮点)
## 双层守护架构
### 第一层30min 轻量看门狗 `distill-model-watchdog.py`cron `89de35dc35a7`
- 只测当前蒸馏模型的 JSON 输出能力content 非空 + code fence 剥离后可解析)
- 挂了 → 按候选池优先级逐个测 → 第一个可用顶上
- 自动更新两处配置 + 重启 + 飞书报警:
- `~/.config/systemd/user/zhiyid.service``LLM_MODEL=`
- `~/.memory-tencentdb/memory-tdai/tdai-gateway.yaml``model:`
- 全部候选失败 → 飞书报警人工介入
- 健康时静默no-agent cron 空输出 = 不发送)
### 第二层6h 深度巡检 `model-health.py` 新增 `_heal_distill_models()`
- 与第一层相同的候选池,补充 reasoning 模型识别
- **关键陷阱(测试中抓到的真 bug**:当前模型不在 ALL_MODELS 测试列表时(如 gemma 是后加的),`found=None` 会被误判"需替换"→ 每 6h 把健康模型换掉。
- 修复:判断改为 **JSON 探针为主**content 非空+可解析 → 健康),巡检结果仅作辅助覆盖(明确 dead 才覆盖探针)。
- 教训:**模型不在测试列表 ≠ 模型挂了**。
### 候选池2026-08-02 实测 JSON 可用,优先级降序)
```
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
```
## 验证命令
```bash
# 单模型 JSON 能力测试(新模型上线前必跑)
KEY=$(grep -oP 'LLM_API_KEY=\K.*' ~/.config/systemd/user/zhiyid.service)
curl -s -m 30 http://127.0.0.1:3000/v1/chat/completions -H "Content-Type: application/json" \
-H "Authorization: Bearer $KEY" \
-d '{"model":"<候选>","messages":[{"role":"system","content":"输出严格JSON"},{"role":"user","content":"提取实体:牧尘喜欢简洁。输出 {\"entities\":[],\"decisions\":[],\"conclusions\":[]} 格式"}],"max_tokens":150}'
# 完整模型池
curl -s http://127.0.0.1:3000/v1/models -H "Authorization: Bearer $KEY"
# 看门狗手动跑(健康静默,异常自动切换+飞书)
python3 ~/.hermes/scripts/distill-model-watchdog.py
# 看门狗 cron 手动触发
hermes cron run 89de35dc35a7 # 或 cronjob action=run
# 验证当前蒸馏模型确实生效
grep LLM_MODEL ~/.config/systemd/user/zhiyid.service
grep "^ model:" ~/.memory-tencentdb/memory-tdai/tdai-gateway.yaml
journalctl --user -u zhiyid --no-pager -n 20 | grep "\[distill\]" | tail # 期望 model=google/gemma-4-31b-it + LLM entities: N
```
## 失败特征速查
| 现象 | 含义 | 处理 |
|------|------|------|
| `content=null` | reasoning 模型gpt-oss 系) | 排除,换 gemma 系 |
| `content` 带 ```json 包裹 | 正常但需 code fence 剥离 | engine.go 已支持2026-08-02 |
| `The model ... reached its end of life` | EOL | 从候选池换 |
| `No available channel` | 渠道失效 | 从候选池换 |
| `system_cpu_overloaded` | NewAPI 过载 | 等几秒重试 |
| `LLMEndpoint empty, fallback` + `facts=1 entities=0` | distill 走关键词降级 | 查 zhiyid.service 的 LLM 三件套 env |

View File

@ -0,0 +1,51 @@
# 织忆提升:轨迹学习门禁 + 程序记忆分类2026-08-02
> 来源:《深入理解 AI Agent》仓颉蒸馏方法论skill-14 轨迹学习四类更新 + skill-05 记忆分层)
> 仓库:`/tmp/memoryweave/织忆提升实施计划-v2.md`
## 背景校准(重要教训)
审计时**先假设"冲突检测缺失"**,实测织忆**早已实现**
- ✅ `governance.ConflictDetector`governance.go:32
- ✅ 写入路径已调用 `DetectContradiction`core.go:130
- ✅ API: GET /api/v1/conflicts + POST /api/v1/conflicts/resolve
**教训**:做记忆系统改进前先 `memory_graph_stats` + 拉真实状态,不要凭蒸馏出的"最佳实践"假设现状。织忆已相当成熟。
## 实际落地的提升点
### 提升点 1learner.py 轨迹学习门禁(~/.hermes/scripts/learner.py
书中第8章方法论只有支持度≥2 且无冲突的结论才升为正式知识。
改动:
1. `extract_patterns()` 加通用归纳门禁:
- 每个 pattern 带 `support_count`
- 末尾统一过滤:`support >= 2` 才保留,否则 `log("门禁拦截")`
2. `cmd_learn()` 中把达标 patterns 写入织忆:
- `write_pattern_to_zhiyi(pattern)` → POST /api/v1/commit
- content 格式:`[learner模式] {desc} | 建议: {action} | 支持度: {n}`
- category=distilled, agent_id=learner
验证:单例观察 → patterns=0三次观察 → patterns=1 (support=3)。
### 提升点 2daemon.py 程序记忆分类(~/.hermes/scripts/daemon.py
书中第3章方法论记忆分情景/语义/程序三类,程序记忆存"如何做"。
改动:`_distill_l1_to_l2()` 的 session 消息 topic 提取处(约 line 927
- 检测 topic 是否含流程性词(步骤/流程/方法/操作/命令/脚本/配置/工作流/pipeline/workflow/script/command/steps
- 命中 → props["category"] = "procedural",否则 "pattern"
## 织忆 commit API 实测要点
- 必传:`agent_id` + `content`(缺 agent_id 400
- 成功返回:`{"episode_id": "ep_...", "status": "ok", "memory_id": ""}` — **没有 id 字段**
- 判断成功:检查 `episode_id``status == "ok"`,不是 `resp.get("id")`
- distill 是**异步队列**:写入后立即 recall 查不到,等 5-10s 或查 statstotal_episodes/total_memories 增长)
## 验证结果
- episodes 52→70+18memories 5040→5046+6
- daemon 重启 activegraph.db 9083 节点就绪
- Gitea push: `0d607c8`2 files, +62/-2

View File

@ -0,0 +1,125 @@
# 织忆 episodes 持久化修复 + 四系统体检2026-08-02
## 背景
牧尘要求"全面检查记忆系统",指出"记忆系统可不止织忆,还有其他系统"、"你还少了cbm"。
结论:记忆系统是**四套**(织忆 / Soulful / TencentDB / CBM各自独立进程默认互不影响。
## 核心修复episodes 重启清零commit 21bc777
### 根因(两层问题叠加)
1. **`RustLanceDBClient.InsertEpisode` 只写 Go 进程内存**`lancedb_ipc.go` 的 `_local.episodes`
从不通过 IPC 持久化。Rust LanceDB 的 episodes 表是空表Rust stats 返回 `total_episodes: 0`)。
2. **`Stats()` 用内存值覆盖 Rust 真实计数**
```go
s["total_episodes"] = len(_local.episodes) // 覆盖了 Rust 返回的真实值
```
所以 stats 显示 45 条但 LanceDB 里 0 条,重启 zhiyid 后内存清空 → 归零(曾观察到 70→3
### 修复内容
```go
// 1. InsertEpisode 增加 IPC 持久化(照 InsertMemory 模式)
record := map[string]interface{}{
"id": id, "agent_id": agentID, "namespace": namespace,
"content": content, "category": category,
"tier": "episode", "importance": 1.0, "quality_score": 0.0,
"recall_count": 0, "useful_count": 0, "not_useful_count": 0,
"freshness": "fresh", "version": 1, "version_history": "[]",
"source": "episode", "volatile_flag": false, "is_deleted": false,
"depends_on": "[]", "derived_from": "", "last_recalled_at": "",
"created_at": now.Format(time.RFC3339),
"updated_at": now.Format(time.RFC3339),
}
recJSON, _ := json.Marshal([]interface{}{record})
if _, err := rc.rpc(ipcReq{Type: "lancedb_insert", Table: "episodes", Records: string(recJSON)}); err != nil {
log.Printf("[ipc] InsertEpisode persist to LanceDB failed (id=%s): %v", id, err) // 只记日志不阻断
}
// 2. Stats() 优先 Rust 真实计数,缺失才回退内存
if _, ok := s["total_episodes"]; !ok {
_local.mu.RLock()
s["total_episodes"] = len(_local.episodes)
_local.mu.RUnlock()
}
```
### 关键知识Rust IPC 协议(手动调试用)
IPC socket`/tmp/zhiyi-ipc.sock`,协议是 **4 字节大端长度前缀 + JSON body**(不是纯 JSON 行流):
```python
import socket, json, struct
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect('/tmp/zhiyi-ipc.sock')
req = json.dumps({'type':'lancedb_stats'}).encode()
s.sendall(struct.pack('>I', len(req)) + req)
lenbuf = b''
while len(lenbuf) < 4:
lenbuf += s.recv(4 - len(lenbuf))
msg_len = struct.unpack('>I', lenbuf)[0]
resp = b''
while len(resp) < msg_len:
chunk = s.recv(msg_len - len(resp))
if not chunk: break
resp += chunk
print(resp.decode())
```
Rust IPC 已支持的类型:`encode` / `lancedb_search` / `lancedb_insert`**任意表**,含 episodes/
`lancedb_stats` / `lancedb_update` / `lancedb_query`(只查 memories 表。Go 侧 `rpc()` 实现同协议。
### 验证方法(改完必跑)
```bash
# 1. 提交测试 episode → stats episodes=1
curl -s -X POST -H "X-API-Key: zhiyi-dev-key-2026" -H "Content-Type: application/json" \
-d '{"agent_id":"hermes-main","namespace":"test-persist","content":"持久化验证","category":"test"}' \
http://localhost:7821/api/v1/commit
curl -s -H "X-API-Key: zhiyi-dev-key-2026" http://localhost:7821/api/v1/stats # episodes: 1
# 2. 重启 → 仍=1修复前会归零
systemctl --user restart zhiyid && sleep 3
curl -s -H "X-API-Key: zhiyi-dev-key-2026" http://localhost:7821/api/v1/stats # episodes: 1 ✅
```
编译部署(注意 Text file busy`cd /tmp/memoryweave/go && go build -o /home/muc/bin/zhiyid-new ./cmd/zhiyid/`
`systemctl --user stop zhiyid` 再 cp 再 start。旧 binary 备份为 `zhiyid-new.bak-0802`
## 教训 1L1 蒸馏率"22 条"是误读
判断 TencentDB L1 蒸馏是否工作,**不要看 DB 表条数**
- `vectors.db``l1_records` 表只有 19 条——那是同步缓存
- **真正的 L1 数据在 `records/*.jsonl`**:全量 2245 条persona 459 / instruction 543 / episodic 1243每天更新
- "85K L0 只蒸馏 22 条"0.03%)是错误结论,实际提取器工作正常
正确判断:`ls -la ~/.memory-tencentdb/memory-tdai/records/ | tail`(看每天 jsonl 更新)+ 日志 `L1-search DONE`
锁冲突 11:5pipeline-worker 的 lock conflicts是瞬时竞争**无积压就不算故障**——看 records 是否每天增长。
## 教训 2端口在听 ≠ systemd 服务正常
`tdai-gateway.service` ExecStart 被写坏成 `/src/gateway/server.ts`不存在systemd 崩溃循环
2534 次,但**手动进程撑在 8420 端口让服务"看起来活着"**。
检查:`systemctl --user show tdai-gateway -p NRestarts`(重启计数)> 100 就是循环。
修复ExecStart 改回 `--require .../tsx/dist/preflight.cjs --import .../loader.mjs src/gateway/server.ts`
杀手动进程(`pkill -f "server.ts"` 会误杀 shell用精确 PID 或 `pgrep -f` 先查systemd 接管。
## 教训 3Soulful 牵挂 stale 清理逻辑缺陷
`_cleanup_expired_cares` 原来只把 pending 标记 stale**从不删除 stale** → stale 堆积。
修复stale 即删staled_at 超过阈值就物理删除。3 条 stale 牵挂手动清理cares: 3→0
## 看门狗新增
- `~/.hermes/scripts/tdai-gateway-watchdog.sh`:检查 `systemctl --user is-active tdai-gateway` + 8420 端口监听,
正常静默空输出、异常输出报警no-agent cron 空输出=静默,非空=发送)
- cron `fd14dc936e31`every 30mno_agent=true
## 四系统体检结果2026-08-02 终态)
| 系统 | 状态 | 动作 |
|------|------|------|
| 织忆 | ✅ | distill LLM 修复 + episodes 持久化修复(本次) |
| Soulful | ✅ | 3 条 stale 牵挂清理 + 清理逻辑修复 |
| TencentDB | ✅ | systemd ExecStart 修复 + 30min 看门狗 |
| CBM | ✅ | 瞬态故障自愈(双进程抢锁,新进程已退出),图谱完好 140万+ 边 |