mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-01 23:07:30 +00:00
## ① 全面改名 HomeAgent → HologramAgent
仓库已改名,但代码与文档里仍有大量旧名。本次按"用户能看到的优先"全量替换:
- 用户可见:登录页标题/页脚、默认人格第一句、CLI 状态输出、启动日志、
plugin_install 的工具描述、AI 图片插件的 User-Agent
- 文档与脚本:README、assets/docs、docs/zh、deploy/*.sh、.github/workflows
- 鸿蒙工程:cmd/ohos/HomeAgent → cmd/ohos/HologramAgent(git mv)
目录内的 module/app 描述同步;**证书路径原样保留**
(default_HomeAgent_xxx.cer/p7b/p12 是签名材料的实际文件名,改了会找不到证书)
- 插件元数据:plugin.json 的 author
★ 必须保持原样的两处(改了会坏):
· legacySeededPromptSignature = "你是 HomeAgent 的看板娘「小宅」…"
—— 那是识别历史播种人格卡的**原文锚点**,改了就识别不出旧数据
· 公开 SDK 的 ProxyAuthHomeAgent = "homeagent"
—— 那是 SDK 契约里的值,属独立仓库,本仓不改
## ② 修 21 处乱码(U+FFFD)
这些是历史编辑留下的编码破坏,全在注释里,例如:
「赌注重下���遍」→「赌注重下一遍」
「「不��滤」」 →「「不过滤」」
「**待��退场**」→「**待退场**」
★ 保留 providers/chineseclip/tokenizer.go 里的 2 处:那是**故意**用
U+FFFD 演示"非法 UTF-8 字节被归一成 U+FFFD",不是乱码。
## ③ 提示词技术内容下沉(用户:技术性内容应该收敛到 skill 与 -help 中)
实测系统提示词 2309 字,其中两段几乎全是**模型无法据以行动的实现细节**:
【工具执行顺序】1272 字(ParallelSafe 声明、批内降级、batchRunnable 判据…)
【三层记忆】 1069 字(L1/L2/L3 编号、消费式删除、向量空间、指纹…)
收敛后 **2309 → 1723 字(-25%)**,保留的全是"模型据此做什么不同的事":
工具顺序:默认并行 / 不要依赖先后 / 同通道保序 / 写类工具可能串行
三层记忆:时序里能看最近 / doc_query 把历史事件按原始时间戳插回时序 /
关系用 memory_recall / 成文知识用 knowledge_search
判断口径写进判据:新加一段提示词前先问"模型会据此做什么不同的事",
答不上来就该进 skill 或工具描述。
## 判据
prompt_memory_test.go 新增 2 条:
- TestSystemPromptHasNoImplementationJargon
黑名单:ParallelSafe / batchRunnable / 消费式 / DenseCosine / fingerprint /
向量空间 / 批内降级 / 自激
- TestSystemPromptStaysCompact:上限 2000 字(当前 1723)
变异:把 "ParallelSafe 声明、批内降级" 加回工具顺序段 ⇒ 第一条立刻红。
## 验证
- go build ./... / go vet ./... 干净
- go test ./... -count=1:58 包 0 失败
- make check-client-versions:客户端与内核版本一致
106 lines
4.7 KiB
Bash
Executable File
106 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# HologramAgent 部署验证脚本:检查 healthcheck 残留 / 记忆去重 / archived 残留 / 嵌入规格
|
||
# 用法: verify_deploy.sh [data_dir] 默认 /home/newqqagent
|
||
set -u
|
||
DATA_DIR="${1:-/home/newqqagent}"
|
||
PASS=0; FAIL=0; SKIP=0
|
||
ok() { echo "[PASS] $1"; PASS=$((PASS+1)); }
|
||
bad() { echo "[FAIL] $1"; FAIL=$((FAIL+1)); }
|
||
skip() { echo "[SKIP] $1"; SKIP=$((SKIP+1)); }
|
||
|
||
echo "== HologramAgent 部署验证 =="
|
||
echo "数据目录: $DATA_DIR"
|
||
echo "时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||
echo "模式: 只读检测,不修改/删除任何数据"
|
||
echo
|
||
|
||
# ---- 0. 数据目录可用性 ----
|
||
if [ ! -d "$DATA_DIR" ]; then
|
||
echo "[FATAL] 数据目录不存在: $DATA_DIR"
|
||
exit 2
|
||
fi
|
||
|
||
# ---- 1. healthcheck 残留检查 ----
|
||
echo "--- 1. healthcheck 残留 ---"
|
||
hc_files=$(find "$DATA_DIR/knowledge" "$DATA_DIR/memory" -maxdepth 2 \
|
||
\( -name '*_hc_*' -o -name 'gotest' -o -name 'luatest' \) 2>/dev/null)
|
||
if [ -z "$hc_files" ]; then
|
||
ok "无 _hc_*/gotest/luatest 残留"
|
||
else
|
||
echo " 发现残留:"
|
||
echo "$hc_files" | sed 's/^/ /'
|
||
bad "存在 healthcheck 残留(上列,需人工确认清理)"
|
||
fi
|
||
|
||
# ---- 2. relations 去重检查 ----
|
||
echo "--- 2. relations 去重 ---"
|
||
GRAPH_DB="$DATA_DIR/memory/graph.db"
|
||
if [ -f "$GRAPH_DB" ] && command -v sqlite3 >/dev/null 2>&1; then
|
||
dup=$(sqlite3 "$GRAPH_DB" "SELECT count(*) - count(DISTINCT source_id||'|'||target_id||'|'||relation_type||'|'||COALESCE(session_id,'')) FROM relations;" 2>/dev/null)
|
||
total=$(sqlite3 "$GRAPH_DB" "SELECT count(*) FROM relations;" 2>/dev/null)
|
||
if [ -n "$dup" ] && [ "$dup" -le 0 ] 2>/dev/null; then
|
||
ok "relations 去重良好 (共 ${total:-0} 条, 重复 ${dup:-0})"
|
||
else
|
||
bad "relations 存在重复: 共 ${total:-?} 条, 重复 ${dup:-?}"
|
||
fi
|
||
# UNIQUE 索引存在性:查 relations 表 DDL 是否含 UNIQUE 约束
|
||
# (注意:UNIQUE 约束创建的 sqlite_autoindex_* 索引其 sql 字段为 NULL,
|
||
# 用 LIKE 查索引 sql 会漏报——须查表 DDL)
|
||
ddl=$(sqlite3 "$GRAPH_DB" "SELECT sql FROM sqlite_master WHERE type='table' AND name='relations';" 2>/dev/null)
|
||
if echo "$ddl" | grep -q 'UNIQUE'; then
|
||
# 进一步确认唯一约束覆盖的列
|
||
auto_idx=$(sqlite3 "$GRAPH_DB" "SELECT name FROM sqlite_master WHERE type='index' AND name LIKE 'sqlite_autoindex_relations%' AND tbl_name='relations';" 2>/dev/null | head -1)
|
||
if [ -n "$auto_idx" ]; then
|
||
cols=$(sqlite3 "$GRAPH_DB" "SELECT group_concat(name,',') FROM pragma_index_info('$auto_idx');" 2>/dev/null)
|
||
echo " UNIQUE 自动索引: $auto_idx, 覆盖列: ${cols:-?}"
|
||
fi
|
||
ok "relations 复合 UNIQUE 约束存在"
|
||
else
|
||
bad "relations 复合 UNIQUE 约束缺失(迁移未生效?)"
|
||
fi
|
||
else
|
||
skip "graph.db 不存在或 sqlite3 不可用 ($GRAPH_DB)"
|
||
fi
|
||
|
||
# ---- 3. archived 模板垃圾检查 ----
|
||
echo "--- 3. archived 残留 ---"
|
||
if [ -f "$GRAPH_DB" ] && command -v sqlite3 >/dev/null 2>&1; then
|
||
# 兜底检测:relation_type 直接为 context_archived,或 target_id 含 context_archived
|
||
arch=$(sqlite3 "$GRAPH_DB" "SELECT count(*) FROM relations WHERE relation_type='context_archived' OR relation_type='来源' AND target_id LIKE '%context_archived%';" 2>/dev/null)
|
||
if [ -n "$arch" ] && [ "$arch" -eq 0 ] 2>/dev/null; then
|
||
ok "无 context_archived 模板垃圾"
|
||
else
|
||
bad "context_archived 模板垃圾: ${arch:-?} 条"
|
||
fi
|
||
else
|
||
skip "graph.db 不存在或 sqlite3 不可用"
|
||
fi
|
||
|
||
# ---- 4. 嵌入规格检查 ----
|
||
echo "--- 4. 嵌入规格 ---"
|
||
CONFIG_DB="$DATA_DIR/config.db"
|
||
if [ -f "$CONFIG_DB" ] && command -v sqlite3 >/dev/null 2>&1; then
|
||
emb=$(sqlite3 "$CONFIG_DB" "SELECT value FROM config WHERE key='core.agent.embedding_model_path';" 2>/dev/null)
|
||
echo " embedding_model_path = ${emb:-(未配置)}"
|
||
if [ -n "$emb" ]; then
|
||
# 模型路径含 #topN 则裁剪生效;否则全量加载(300 维 ≈ 1.5G/模型)
|
||
if [[ "$emb" == *"#top"* ]]; then
|
||
ok "嵌入模型已启用 #topN 裁剪(内存预算受控)"
|
||
else
|
||
# 逗号分隔的模型个数估算内存
|
||
n=$(echo "$emb" | awk -F',' '{print NF}')
|
||
est=$(( n * 1500 ))
|
||
echo " 全量加载 ${n} 个模型,估算常驻 ≈ ${est}MB(未裁剪)"
|
||
bad "嵌入模型未启用 #topN 裁剪(内存预算偏高)"
|
||
fi
|
||
else
|
||
skip "embedding_model_path 未配置(可能是默认值)"
|
||
fi
|
||
else
|
||
skip "config.db 不存在或 sqlite3 不可用 ($CONFIG_DB)"
|
||
fi
|
||
|
||
# ---- 汇总 ----
|
||
echo
|
||
echo "== 汇总: PASS=$PASS FAIL=$FAIL SKIP=$SKIP =="
|
||
[ "$FAIL" -eq 0 ] && exit 0 || exit 1 |