Files
HomeAgent/demo.md
root bc9ef15eb0 三层回退恢复机制(L0写前留档/L1恢复梯子/L2离线回滚)+ guard 父守护
- L0: files 插件写受保护系统路径(/etc 等)前自动留档,AbstractBeforeWrite 到 data/file_baseline
- L1: failback 受限 worker 执行恢复梯子 probe→还原DNS/proxy→还原LLM配置+ReloadFromConfig→probe,N轮有界
- L2: tracker changeset 持久化原文 blob,guard 离线 RollbackFromDisk 回滚 agentfs;SystemSnapshot 支撑
- guard 父守护: 心跳 IPC(PING/ACK unix socket, 文件心跳回退)、失败计数、退出码协议(42/43/44)、最后手段
- 发行版路径适配: system.protected_paths/network_paths 可注入,默认面向主流 Linux
- Windows 兼容: guard.go/failback.go 加 //go:build linux, guard_windows.go 提供 no-op 桩
- 修复: guard.yaml last_resort 键冲突、changeset Content 不落盘导致离线回滚丢原文

Build 全绿, vet 干净, system/recovery/ipc/tracker 单元测试全过
2026-08-05 16:00:08 +08:00

24 KiB
Raw Blame History

HomeAgent 自愈 / Failback 架构设计与讨论全程记录 (demo.md)

本文档按讨论演进顺序记录"守护 / 保活 / 文件追踪 / 崩溃自愈 / failback"整个设计过程, 含代码勘查结论、现实日志记录模式分析,以及最终定稿的架构与尚未落地的接口清单。


0. 背景与目标

框架目标:内核零 IO、插件承载所有 IOhomed 内核 ← PluginSDK → 插件),三层记忆 + 常用块。

Failback 的定位所有错误的一层兜底Safe-Mode 式),而非针对单一场景。

  • 主 agent全量 LLM agent是一切骚操作的执行者可能把自己搞到无法自愈的任意状态 LLM 源改坏 / 系统网络proxy、DNS、host破坏 / 配置文件损坏 / OOM / panic / 崩溃循环…… 这些错误无法在同一个被污染环境内用自身操作自救。
  • 故需要一层脱离主 agent 坏环境的、最小厚度且独立可控的恢复层—— 类似 Windows 安全模式 / 启动修复:只带最小驱动集合 + 干净 LLM 源(锚定 IP 单一职责:让主 agent 回到可用状态;若不可行,则做最后的系统级兜底(回滚快照 / 重启)。
  • 它不替代主 agent 的功能,只在主 agent 无法自愈时作为最后一道防线出现。能省则省、能判定就不推理、有底即主张。

1. 现状盘点(代码勘查结论)

1.1 守护进程(internal/supervisor/daemon.go

  • 主 agent in-process 常驻,agent.Start()cmd/homed/main.go:468 直接启动,无独立进程边界
  • healthLoopcheckAgent 判 LLM 是否可达,判定仅依赖 network.MonitorAggregateResult().LLMAPIReachabledaemon.go:132)。
  • failCount >= MaxRetries(默认 3handleFailure
    • 有 tracker → trk.Rollback();失败才降级 restartAgent
    • restartAgentdaemon.go:166只改内存状态再重新 Register不真重启任何进程,几乎空转。

关键问题:

  • 探测是系统级HTTP/DNS/TCP回滚只作用于 <data>/agentfs overlay 的 upper二者对象错位
  • AgregateResult 在无 LLM endpoint 时恒 healthy机制形同虚设。
  • lastHB 每轮都置 time.Now()Uptime 无意义。
  • RollbackPolicyHealthThreshold/CooldownPeriod/AutoRollback 都是死字段,只用 MaxRetries

1.2 文件追踪(internal/tracker

  • overlayfs 三层:lower/upper/work → mergedtracker.go:156)。
  • captureFSState(upperDir) 递归遍历 upper 并 sha256changeset.go:56PreAction/PostAction 前后 difftoolcall.go:86-94)。
  • lower 恒空InitMkdirAll,从不填充)→ 无 canonical 基线可回滚。
  • Rollback() = RemoveAll(upper) 清空全部 changesetsFileChange.Content(本应存回滚原文)从未回填

结论overlay/tracker 对"LLM 可达性"这主场景错位,只能作数据兜底。

1.3 通信插件真相(third_party/homeagent-sdk/example/qq/plugin.go

  • agent 对外通信全部由插件设置驱动,存于 ConfigRegistry / SQLite config.db qq.napcat_urlqq.listenqq.files_dirqq.remote_dirdm/group_policyplugin.go:120-130)。
  • 插件在 Start()getSetting(...) 读设置(plugin.go:134-143)→ 改动配置需重载插件才生效
  • cfgmgr 提供 config_set / config_batch_set 可运行时改任意 core/插件配置(cfgmgr/plugin.go:54,103)。

1.4 LLM 源与"恢复即生效"

internal/sdk/llm_impl.go:103 ReloadFromConfig() 已存在

  • cfg := cfgReg.ToConfig() 从 config.db 重建(含 core.llm.sources.*,见 registry.go:590
  • mgr.Reset() → 逐源 NewLuaAdaptedProvider → 重设默认。

即:LLM 源的"恢复即生效"钩子已经具备,缺的是"快照 + 探测 + 触发"三件事。


2. 现实环境:日志记录模式内参

看真实 systemd 托管的 HomeAgent/home/newqqagent)日志,目的是弄清现有的日志模型 (写哪、什么格式、工具调用打在哪),为 failback / recoveryDiag 的 diag_log_scan 提供准确的解析依据。

2.1 systemd 托管现状(样例)

homeagent.service: Type=simple, ExecStart=/usr/local/bin/homed -data /home/newqqagent, Restart=always, RestartSec=10
llm-mock.service:   ExecStart=/usr/bin/python3 /opt/llm-mock/mock_server.py, Restart=always, RestartSec=3
  • 实测数据区:/home/newqqagent/ 下有 log/config.dbagentfs/overlay mergedsnapshots/changesets/knowledge/memory/plugins/cli.sockadapters/homed.logmemos.json 等——日志以独立子目录 log/ 存放,与配置/快照/knowledge 分置
  • 启动段确认:[files] started, sandbox: /files 沙箱=全主机 / 实锤main agent started, model=mock-model base=http://127.0.0.1:18080/v1 sources=3 adapters=8LLM 走本地 mock

2.2 日志目录与格式(核心)

  • 目录配置core.log.path,默认 <dataDir>/loginternal/config/registry.go:415,508)。
  • 单次运行文件:每次启动新建 homed_<YYYY-MM-DD_HH-MM-SS>.logcmd/homed/main.go:75 写入 logDir 下;log.SetOutput(io.MultiWriter(os.Stderr, logFile))main.go:80)—— 同时进 stderrsystemd 捕获到 journald/journalctl -u)与文件
  • 格式:标准 Go log.Printf,即 YYYY/MM/DD HH:MM:SS file.go:line: [module] message。 用户可看文件,也可用 journalctl -u homeagent.service 看同一来源(同一行)。
  • 层级压缩 + 保留internal/log/manager.go:26-28 + compressor.go
    • 周度压缩 → week_<year>-W<ww>.tar.gz;月度 → month_<yyyy-mm>.tar.gz;年度 year_*.tar.gz; raw 文件正则 ^homed_(\d{4}-\d{2}-\d{2})_\d{2}-\d{2}-\d{2}\.log$compressor.go:16)。
    • 保留策略:core.log.retentiondefault forevercore.log.retention_monthsdefault 3 applyRetention 只留当前周 + 近 N 月(retention.go)。 实测:log/ 下即为 homed_2026-08-03_08-03-38.log + month_2026-*.tar.gz + week_2026-W31.tar.gz,与代码一致。

2.3 工具调用日志打在哪儿(进程主循环 internal/agent/core/process.go

位置 日志行内容 备注
process.go:36 [agent] tool call loop start, max_ctx=… target=… fixed=… mem=… ctx=… N tools, M events, personality=X, docs=K 每轮循环开头上下文统计
process.go:196 [agent] executing tool: <name> (plugin=<p>, id=<id>) 只记工具名/插件/id不记 args
process.go:226 [agent] tool <name> result: <截断100字符> 结果截断到 100 字符(truncateStr
process.go:218 [agent] skip tool <name>: plugin <name> unhealthy 插件崩溃态跳过
process.go:89/109/121/125 LLM fallbacktrying provider %q (#%d) / switched active provider / provider %q marked unavailable (HTTP %d) / provider %q failed 主循环内 LLM 商可观测
toolcall.go:20 [agent] tool %s panic: %v + debug.Stack() 工具 panic + 完整栈
toolcall.go:41 [agent] tool %s timed out after 60s 60s 超时
toolcall.go:92 [agent] tool %s changed %d files (changeset: %s) overlay changeset 摘要
插件侧 Lua 插件 sdk.logprint("[lua-plugin] <level>: <msg>") 模板见 cmd_debug.go:74/templates.go
  • 完整的工具入参/结果在 EventBus 事件 EventToolCall{tool, plugin, args, result, status}process.go:184/205)而非文件日志——文件日志只是执行/结果的摘要指针(结果被截断)。
  • 重要观察:日志里未见 shell/cmd 之类的操作系统执行类调用摘要落盘([cmd] 只在工具结果里), 需要的话由 diag_log_scanexecuting tool: cmd_* 前缀做签名匹配即可。

2.4 崩溃 / 重启观察

  • NRestarts=0MainPID 自 08-03 起稳定 3330844。曾出现真实重复 panicpid 3310036 [stage] handler panic: runtime error: invalid memory address or nil pointer dereference03:23 / 05:23 / 07:23约每 2hstages.go:139RunStage recover 吞掉 → 进程未真崩systemd 未见重启。
  • 08:03:38 有过一次干净 [homed] stopped → systemd Started → pid 3310036 → 3330844。
  • 对 failback 的意义:现有崩溃防护全赖 in-process recover,真实进程级崩溃从未被监督; 且当前 Restart=always 由 systemd 直绑 worker 且无 StartLimit——一旦真崩并陷入循环, systemd 每 10s 反复拉起,没有独立 failback/取证层。→ guard 取代点在此。

3. 设计演进(讨论全过程)

3.0 起点:internal/supervisor + internal/tracker 我是"保活 + 文件追踪"

  • 保活 = 网络健康感知 + 内存态重置;追踪 = overlayfs 变更集 + Rollback 清空。
  • 意图LLM 不可达 → 回滚 agent 文件改动 → 自愈。

3.1 第一次纠正:回滚对象错位

  • 回滚只作用于 overlayfs upper而真正能改坏网络的路径files 默认 /,可写 /etc/resolv.conf/etc/hosts、代理配置)与 LLM 配置config.db、adapters 目录)都不在 overlay 内
  • → 检测命中但回滚删错对象,闭环在"回滚"这一环断掉。

3.2 第二次纠正:授权不能靠外部插件主动配合

  • 阶段管道是被动通知(RunStage 收集 error不主动拒绝拒绝依赖各插件 handler。
  • 插件是外部不可控对象 → "安全 = 插件主动授权放行"不成立。
  • → 安全应做默认拒绝,由内核在 executeToolCall 分发点按 ToolDef 的 capability 裁决;配置快照 + replug 只兜底"可文件化"改动。
  • 中途又修正:真正的祸首不是 IO 组件,而是 LLM 源/系统网络配置IO 组件崩溃是正交偶发轴,不并进来。

3.3 第三次纠正LLM 源才是核心config.db + ReloadFromConfig 已具钩子)

  • llm_set_source 只切内存默认;真正改坏 LLM 源靠 cfgmgr.config_set 写 config.db core.llm.sources.*
  • ReloadFromConfig() 已能"恢复即生效" → 只需补:LLM 配置快照 + 真实 liveness 探测QuickChat+ 在 handleFailure 里触发 RFO 复检
  • 但用户进一步点明:重点是 agent 改了系统网络配置文件proxy/DNS —— 这类连救援 LLM 都连不上。

3.4 定稿架构一lastFailback独立进程第一道防线

  • 独立进程 + agent 碰不到的 root:0600 配置 + 最小插件集(文件读写 + cmd+ 单一任务。
  • 锚定 IP/干净 DNS 的 LLM 源绕开坏掉的 DNS/proxy。
  • 若 failback 也失败 → agentfs 回滚最近快照 + 重启计算机(应用快照前系统配置)。
  • 兼顾 systemd 托管冲突(主 agent 崩溃循环被 systemd 反复拉起 → failback 无限增殖)。

3.5 定稿架构二:去掉强 systemd 依赖 → 独立 guard 守护进程

  • systemd 只绑定静态、极小、永驻的 guardguard 作为父进程拉起 workerhomed 全量 agent
  • guard 通过 IPCunix socket / 匿名 pipe收 worker 心跳; 父进程 waitpid 天然 reap 崩溃/OOM/信号退出。
  • worker 可崩可换systemd 完全看不见 → failback 唯一性 + 无风暴天然成立
  • guard 抗 OOMoom_score_adj 拉低,优先杀 worker 而非 guard。

3.6 定稿架构三:更纯粹 —— 同一二进制的两个 role非独立二进制

  • 不新建二进制homed 拆两个入口:
    • homed --role=guard:父守护进程,先起,负责拉起/监测/探活/裁决/恢复。
    • homed --role=agent:主 agent工作进程guard 的子进程)。
    • homed --role=agent --boot=failback:恢复用 agent受限 bootstrap
  • guard 复用现有 homeagent 基础设置;检测到崩溃时拉起 failback agent只加载 webfetch + 文件读写 + cmd 三个插件,外加 恢复知识库插件常见错误检测插件 复用 agent 核心以 trigger_prompt 初始化,要求其"尝试恢复主 agent"。
  • guard 配置独立 YAML,不复用 config.db逃生舱知识必须脱离 agent 可达区)。

3.7 recoveryDiag崩溃取证 / 根因定位插件(省 token 关键)

  • 铁律:工具返回结论,不返回原文(签名式/统计式/确定性排序)。

  • 工具集:

    工具 作用
    diag_triage exit code/信号+uptime+头部嫌疑,快速粗分"进程死亡 vs 配置类不可达"
    diag_db config.db integrity_check + LLM 源解析校验,逐项 ok/fail
    diag_log_scan 时间窗内命中已知错误签名panic/provider failed/unreachable/sql/OOM
    diag_delta 崩溃前 config/agentfs 与 last-good 快照 diff"改了什么"
    diag_loc 综合正交,输出按因果强度排序的定位结论 + 推荐动作
  • 崩溃类别 → 恢复分支决策表:

    结论类 走分支
    配置损坏类 还原 config 快照 + ReloadFromConfig + 拉活主 agent无需 agent 推理)
    系统网络类 还原 DNS/proxy → 重载主 agent第一步小修命中即停
    进程失稳类OOM/panic 不还原配置,检查内存/泄漏 → 重建 worker
    未知/混合 放开 webfetch/知识库,用 rescue 源 + diag_loc 摘要最小推理
  • 只有"未知/混合"消耗 token前几类近乎 0 token。

  • 结论落盘 recovery_kb/diag_<ts>.json,回流知识库,同类崩溃下次直接命中,越用越省。

3.8 三层防御总览(最终)

L0 平时:核心只读探活 + 写前快照config_set 写 core.llm.* 前、files 写 /etc 前自动留档)
L1 failbackguard 拉起Safe-Mode 式兜底):按诊断分支逐类恢复——
   还原 DNS/proxy → 还原 config 快照 + ReloadFromConfig → QuickChat 复检 → 拉起主 agent
L2 最后手段agentfs 回滚最近快照 + 重启(应用快照前系统配置)
  • failback 是所有错误LLM 不可达 / 网络 / 配置损坏 / OOM / panic / 崩溃循环)的统一兜底层 并非只针对某一条;diag_* 决定它走哪条恢复路径。

4. 最终架构(定稿)

4.1 进程拓扑(同一二进制,两个 role

systemd ──▶ homed --role=guard          # 父守护进程,永驻、静态、极小
             ├─ exec ──▶ homed --role=agent              # 主 agent可崩
             └─ exec ──▶ homed --role=agent --boot=failback  # 恢复用 agent
  • guard先起持有恢复知识锚定源 / DNS/proxy 还原 / 配置快照 / failback 逻辑)。
  • workerguard 子进程,心跳经 IPC崩溃由 guard reap + 判型。
  • failback agent = 受限启动webfetch+files+cmd + 恢复知识库 + recoveryDiag单一任务"恢复主 agent"N 轮有界。

4.2 guard 独立 YAML 示例

现状实现§5 已完成):guard.yaml 已落地为 max_restarts / heartbeat_timeout / heartbeat_interval / llm_snapshot / failback_enabled / last_resort / restart_command / reboot_grace 子集(cmd/homed/guard.go),恢复梯子=重试→LLM 基线恢复→failback 受限启动→last_resort。下表的 rescue 源 / trigger_prompt / N 轮 failback 推理是目标态,未实现。

role: guard

llm:
  sources:
    - name: rescue
      base_url: http://1.2.3.4:8080      # 锚定 IP 直连,绕开被破坏的 DNS/代理
      api_key: ${GUARD_RESCUE_KEY}
  adapter: ...                            # 锚定/SNI 型适配器

recovery:
  max_attempts: 4                  # 可配置尝试轮次
  attempt_timeout: 120s
  knowledge_base: /opt/homeagent/recovery/
  trigger_prompt: "你是恢复 agent唯一任务让主 agent 恢复运行。优先还原 DNS/代理,再重载 LLM 源…"
  plugins: [webfetch, files, cmd]

last_resort:
  action: reboot                   # restart_app | reboot
  snapshot_before: true

4.3 guard 恢复状态机N 轮有界)

guard 检测( exit≠0 | OOM | 心跳超时 | guard 锚定源探活失败 )
  1. 固化追溯exit/信号、panic、journal、OOM 上下文 → 永久区
  2. 拉起 failback agent受限插件 + rescue 源 + trigger_prompt + 知识库 + recoveryDiag
     for attempt in 1..N:
         (可选先 diag_triage/diag_loc 判型)
         failback 尝试恢复
         guard 每轮复检主 agent 是否可达/存活
         ├─ 成功 → 结束,交回主 agent
         └─ 超时/失败 → kill 重建,进入下一轮
  3. N 轮未成 → 取消 failback agent
        → agentfs 回滚崩溃前最近快照
        → 依 yaml 执行最后手段restart_app 或 reboot

4.4 systemd 绑定(极简,杜绝风暴)

[Unit]  # guard
OnFailure=...            # 备用通常不触发guard 稳定)

[Service]                # guard
Restart=always           # guard 静态稳定 → 几乎不重启
ExecStart=/usr/local/bin/homed --role=guard ...
# No StartLimit needed for loop 情况guard 不崩
  • 主 agent 崩 → 只触发 guard 内部 failbacksystemd 仅看 guard看不到 worker 崩溃循环。
  • failback 唯一性 + 无启动风暴:由"guard 永驻、唯一裁决"天然保证。
  • guard 抗 OOMoom_score_adj 拉低。

5. 尚未落地的接口 / 下一步

已完成

recoverydiag 快速检查插件(third_party/homeagent-sdk/example/recoverydiag/,外部插件)。

  • 五件套全实现:diag_triage(退出码/信号/存活粗分)、diag_dbconfig.db integrity_check + LLM 源字段校验sqlite3 CLI 优先、缺失回退内核 Settingsdiag_log_scan(日志签名按类计数)、diag_deltabaseline vs 现状 diffdiag_loc(四项结论正交排序 + 推荐恢复动作)。
  • 全部确定性、返回结论非原文、NoMemory;工具实际名带插件前缀 recoverydiag_diag_*
  • 已通过 go vet + 6 个单测(对真实 config.db/日志跑通3 个 LLM 源全 ok、日志命中 228 行主导 provider/fatal并用仓库内重建的 plugindev 打出 dist/recovery_diagnostics_linux_amd64.hmap,装进运行实例(/home/newqqagent/plugins/recoverydiag/)加载成功、注册 5 工具。
  • 结论落盘 + 知识库回流diag_locpersist(缺省 true→ 写 <data_dir>/recovery_kb/diag_<ts>.json(可配 recovery_kb_dir),并经 sdk.Knowledge().Adddiag:<cause>:<ts> 回流知识库(同类崩溃下次直接命中,越用越省);失败不阻塞工具。新增 TestDiagLocPersist
  • 顺带修复:仓库内 plugindev 需重编译(/usr/local/bin/plugindev 是旧版、桥模板缺 InjectInputSync);重编译见 third_party/homeagent-sdk/tools/plugindevgo build -o ... .
  • 注意:本环境 snapshots/changesets/ 均为空direct 模式无基线)→ diag_delta 需显式传入 baseline_dir未来接 guard 时由快照解包目录提供。

ConfigRegistry 快照钩子(internal/config/registry.go)。

  • SnapshotCoreLLM():抓全部 core.llm.* 键值快照;RestoreCoreLLM(snap):精确还原(快照内键回写、快照外当前键删除)。
  • SetLLMSnapshotFile(path):写前自动留档——此后任意写 core.llm.* 键先把当前 LLM 配置整体快照到该文件guard 恢复的外部基线homed 启动即挂 <data>/llm_snapshot.json
  • 文件持久化对:SaveLLMSnapshot/LoadLLMSnapshot。新增 TestSnapshotRestoreCoreLLMTestLLMSnapshotFileTestSetLLMSnapshotFile

homed --role{guard,agent} 入口拆分 + --boot=failback 受限插件集(cmd/homed/)。

  • --role=guard 父守护(永驻):读独立 <data>/guard.yaml(避开被改坏的 config.db拉起 worker--role=agent)、心跳探活 + waitpid 收割、信号转发停机。
  • --role=agent 工作进程:默认启动全插件;--boot=failback 走插件白名单(core.agent.failback_plugins,缺省 webui,pluginmgr,recoverydiag),内核 webfetch/files/cmd 仍内置可用。
  • guard 恢复梯子(已端到端实测):连续 max_restarts 次 normal 崩溃 → restoreLLMBaseline(从 llm_snapshot.json 恢复 core.llm.*)→ failback 受限启动 → failback 也崩 → last_resortrestart_app / reboot
  • 心跳worker 每 5s 触碰 <data>/heartbeatagent 角色 goroutineguard 以 mtime 判定卡死(超 heartbeat_timeout 即 SIGKILL 计入崩溃)。
  • 插件注册表加 SetLoadAllowlist(names)白名单外插件含已注册工厂一律跳过failback 40 工具 → 4 工具实测通过。

现状 bug 修复supervisor/network/tracker

  • monitor 无 endpoint 恒 healthyinternal/network/monitor.go + pkg/typesNetworkCheckResultEndpointsConfigured;无探活端点时不再谎报 LLMAPIReachable=true(置 false + ErrorNewMonitor 初始化空切片消除启动竞态daemon 仅在配置了端点时才据此判定降级。探活端点新增 core.defaults.llm_endpoints(逗号分隔,留空自动取 LLM 源 base_url生产从此健康检查有真实目标。
  • lastHB 恒置 nowinternal/supervisor/daemon.gocheckAgent 接入真实存活源 SetHeartbeatSourcehomed 注册为 agent core GetKernelStatus),只在确认 agent 存活时更新 lastHB;无源置 HealthUnknown,存活源丢失置 HealthDown 且不再刷新 lastHB。
  • restartAgent 只改内存空转:增 SetRestartHandlerhomed 注册为"清理后以 exitRestartRequested=42 退出"不再假装成功guard 把 42 识别为"请求重建"workerRestartRequested,不计失败轮次直接重建),无 guard 时 systemd Restart=always 兜底。无 handler 时仅内存复位并打日志。
  • tracker 三缺陷internal/tracker/captureFSStateWithContent 为 before 基线捕获原文(上限 8MBdiffStates 对 modified/deleted 回填 FileChange.Content(回滚用原文);新增 RollbackLatest() 定向撤销最近一条 changesetRollback() 改为按时间逆序逐条逆应用(还原被改/被删文件原文、删除新增),无 changeset 时才退回整目录重置。新增 6 个测试覆盖。

剩余:

  • guard ↔ agent 心跳 IPC 升级为带自诊断上报的 PING/ACK(当前为文件心跳 + 退出码)。
  • supervisor 适配成 guard 的探测/裁决逻辑;ReloadFromConfig() 复用为"恢复即生效"。
  • 生产实例迁移:编译新 homed、改 systemd 只托管 guard--role=guard),确认 failback 插件recoverydiag就位。

附录真实日志节选systemd 托管示例,/home/newqqagent

# systemd unit
homeagent.service: Type=simple, ExecStart=/usr/local/bin/homed -data /home/newqqagent, Restart=always, RestartSec=10
llm-mock.service:   ExecStart=/usr/bin/python3 /opt/llm-mock/mock_server.py, Restart=always, RestartSec=3

# 日志文件与格式log.Printf 标准格式)
2026/08/03 08:03:38 main.go:80:  [homed] logging to /home/newqqagent/log/homed_2026-08-03_08-03-38.log
2026/08/03 08:03:38 daemon.go:61: [homed] daemon started successfully
2026/08/03 08:03:39 tracker.go:65: [tracker] initialized (work=/home/newqqagent/agentfs)

# 工具调用摘要process.go
2026/08/03 10:03:52 process.go:36:  [agent] tool call loop start, max_ctx=32768 target=26214 fixed=1306 mem=8302 ctx=16606 176 tools, 31 events, personality=true, docs=5589
... process.go:196: [agent] executing tool: <name> (plugin=<p>, id=<id>)
... process.go:226: [agent] tool <name> result: <截断100字符>

# 启动 & 沙箱
homed[3330844]: [files] started, sandbox: /
homed[3330844]: main agent started, model=mock-model base=http://127.0.0.1:18080/v1 sources=3 adapters=8

# 重复 in-process panic被 RunStage recover 吞掉,未进程级崩溃)
homed[3310036]: [stage] handler panic: runtime error: invalid memory address or nil pointer dereference   # 03:23 / 05:23 / 07:23

# 一次性干净重启systemd 手动/触发 Startedpid 3310036 → 3330844
homed[3310036]: [homed] stopped
systemd[1]: Stopped homeagent.service - HomeAgent - 24/7 AI Butler.
systemd[1]: Started  homeagent.service - HomeAgent - 24/7 AI Butler.

# 运行状态
systemctl show homeagent.service -p NRestarts   → 0
systemctl show homeagent.service -p MainPID     → 3330844自 08-03 起稳定)

# 归档
/home/newqqagent/log/: homed_2026-08-03_08-03-38.log + week_2026-W31.tar.gz + month_2026-*.tar.gz