Files
HomeAgent/README.md
JianFeeeee 5e10f012cb docs(license): 核心仓采用 AGPL-3.0-only,并写进包内与安装器
本仓此前**没有任何许可文件**,README 里也没有许可声明,而 rpm 元数据里甚至写着
`--license "Proprietary"`(与我们实际的分发意图相反)。

## 选择了什么

`LICENSE`:GNU Affero 通用公共许可证第 3 版官方全文(gnu.org 正本,
661 行 / 34523 字节,
sha256 0d96a4ff68ad6d4b6f1f30f713b18d5184912ba8dd389f86aa7710db079abcb0)。

选 AGPL-3.0-only 的理由:GPL 家族里**传染性最强**的一档,并且不允许选后续版本。
它比 GPL-3.0 多出 §13(Remote Network Interaction)——通过网络提供服务时也要向
使用者提供源码。这正是「最严格」在 GPL 家族里的落点。

依赖许可已核对为全部宽松且兼容:go-sqlite3 / gojieba / gopher-lua / bubbletea /
bubbles / lipgloss / yaml.v3(MIT)、golang.org/x/{sys,text}(BSD-3)、
Chinese-CLIP 产物(Apache-2.0,与 GPLv3+/AGPLv3 双向兼容)、ONNX Runtime(MIT)。
没有 GPL-2.0-only 这类与 AGPL 不兼容的依赖。

## 落在哪些地方

- `README.md` / `README_EN.md`:新增「许可 / License」章节,写明 §13 的含义、
  插件因**静态链接 SDK 源码**而成为衍生作品须同许可发布、以及随包第三方组件清单
- `deploy/packaging/package-linux.sh`:
  · 新增 `stage_license()`,**四个变体(full/server/client/tar)全带**
    `/usr/share/doc/homeagent/{LICENSE,copyright}`(copyright 为 DEP-5 机器可读格式,
    含第三方条目)
  · fpm 的 `--license "Proprietary"` → `"AGPL-3.0-only"`
- `deploy/packaging/installer.nsi`:新增 MUI 许可页
  (`..\..\LICENSE`,NSIS 以 .nsi 所在目录解析相对路径)
- `third_party/homeagent-sdk/LICENSE`:vendored SDK 的许可一并入库 —— 本仓
  `.gitignore` 有意不镜像 SDK 的 README/tools/package/example,但依赖的许可
  应当随依赖可见

## 待办(下一步)

README 的「项目状态」仍停在 v1.1.1,且写着已被 v1.2.0 **删除**的机制
(引用计数式 GC、`[<mime> <digest>] <描述>` 描述式索引)——单独一个提交修。
2026-09-12 09:17:03 +08:00

14 KiB
Raw Blame History

⚠️ AI 辅助编程声明:本项目代码、文档及提交历史中,部分内容由 AI 辅助生成或修改。人工已审阅关键改动,但使用时请自行评估与验证。

HomeAgent

English: README_EN.md

核心域与应用域分离为设计原则的 Agent 框架。内核执行零 IO 策略——所有外部交互WebUI、QQ、命令行、文件操作、网络搜索、备忘等均由插件层承载内核不直接处理任何 IO 操作。

配合三层记忆架构Context → Document → Graph通过分级存储与自动归档机制维持单会话长周期运行的上下文连贯性。

homed内核零 IO  PluginSDK  插件所有 IO 能力

v1.1.1 起媒体贯通插件边界:插件与模型都能读写记忆里的图片/音频(InsertWithMediaInjectInputMedia),媒体以 [<mime> <短digest>] <描述> 标记存在于纯文本记忆中——描述是可检索的语义记忆digest 是回到字节的钥匙。

v1.0.0 起外部插件是独立子进程:经 stdio JSON-RPC控制面+ 共享内存段(数据面)+ 事件环(通知面)与内核通信。插件崩溃不影响内核且自动重启,换 plugin.bin 即生效的真热重载。

设计要点

核心域与应用域分离 — 内核职责限定为 LLM 编排、记忆管理与知识检索;所有 IO 能力(消息收发、文件读写、网络请求、硬件交互等)由插件实现。这种划分在 Agent 框架层面进行领域边界界定,内核与插件各有其责任范围。

三层记忆架构 — 通过分级存储策略管理 Agent 长期运行中的信息留存:

  • Context 层:预训练词嵌入 / TF-IDF 回退的相关性评分事件窗口,保护最近 10 条,维护 topK 条上下文
  • Document 层:临时记忆,冷数据自动下沉,也支持用户主动提交
  • Graph 层SQLite 图数据库,持久化实体关系和语义记忆,支持蒸馏管道从原始对话中提取三元组

架构图

一、消息处理时序

sequenceDiagram
    participant U as 用户/插件
    participant IO as IOManager
    participant EV as eventLoop
    participant CTX as RelevanceContext
    participant LLM as LLM+工具循环
    participant ST as StageHost
    participant MEM as 三层记忆

    U->>IO: InjectInput(type, payload)
    IO->>EV: inputCh
    rect lavender
        Note over EV: processTextInput
        EV->>ST: StageOnInput  插件可改写/短路
        EV->>CTX: Prune(input,topK)  StaticEmbedder/TF-IDF余弦相似度裁剪
        CTX->>MEM: 低分事件归档 Document (原始时间戳)
        EV->>CTX: Append(input)  CleanTemplateText→三分支向量→5s写盘
    end
    rect lightgreen
        Note over EV,LLM: process()
        EV->>MEM: buildMemoryContext  Indexer召回Graph(向量+jieba→BFS depth=2)
        EV->>MEM: buildSystemPrompt  DocQuery摘要+Graph记忆索引+人格+技能
        EV->>ST: StagePreAction  插件可预拦截
        loop 工具循环
            LLM->>LLM: drainInterrupts
            LLM->>LLM: LLM Chat
            LLM->>ST: StagePostAction  插件可修改/短路
            alt 无tool call
                LLM-->>EV: 返回response
            else
                loop 每个tool
                    ST->>ST: StageBeforeToolcall  插件可拒绝
                    LLM->>LLM: executeToolCall
                    ST->>ST: StageAfterToolcall
                end
            end
        end
    end
    rect lightpink
        Note over EV: emitResponse
        CTX->>CTX: Append(response)
        ST->>ST: StageBeforeOutput  插件可改写
        EV-->>U: ResponseCh CLI同步
        EV-->>EV: 事件总线 WebUI SSE
        ST->>ST: StageAfterOutput  只读
        EV->>MEM: emitMemoryCandidate
    end

二、Stage 管道

flowchart LR
    S1[① on_input] --> S2[② pre_action]
    S2 --> S3[③ post_action]
    S3 --> Q{有tool?}
    Q -->|是| S4[④ before_toolcall]
    S4 --> T[executeToolCall]
    T --> S5[⑤ after_toolcall]
    S5 --> S3
    Q -->|否| S6[⑥ before_output]
    S6 --> S7[⑦ after_output]
    style S1 fill:#e1f5fe
    style S3 fill:#fff3e0
    style S6 fill:#e8f5e9

三、三层记忆

flowchart TB
    subgraph C[① Context 工作窗口]
        RC[RelevanceContext]
        A[Append] -->|CleanTemplateText→三分支向量| RC
        P[Prune StaticEmbedder/TF-IDF Cosine] -->|低分原始时间戳| D
        P -->|保留| TL[timeline→按时间排序→system prompt]
    end
    subgraph D[② Document 文件记忆]
        DS[DocStore JSON+TF-IDF]
        Q1[Query 摘要自动注入] -->|【相关记忆文档】| SP
        Q2[doc_query LLM主动召回] -->|Consume+删除源| DS
        Q2 -->|原始时间戳写入上下文| RC
        CD[FindColdDocs 72h] -->|docToTriples| G
    end
    subgraph G[③ Graph 图数据库]
        DB[(SQLite)]
        IDX[Indexer 向量+jieba→BFS depth=2] -->|【记忆索引】| SP
        MEM[memory_recall/commit/merge/purge/edit]
        SOC[person_query/set_trait]
    end
    subgraph H[④ 心跳蒸馏]
        REORG -->|Step3 冷文档| CD
        REORG -->|Step4 Bigram Jaccard| CONS[consolidation]
        PIPE[Pipeline 正则] -->|姓名/住址/喜好/年龄/职业| DB
    end
    SP[System Prompt] -->|顺序组装| LLM
    LLM[LLM] -->|doc_query| Q2
    LLM -->|memory_recall| MEM

详细说明见 assets/docs/zh/ARCHITECTURE.md

看板娘

HomeAgent 看板娘 小宅

小宅 — HomeAgent 看板娘

快速体验

make build build-cli
./build/homed -data /tmp/ha
# 交互模式
./build/waiter

# 或单条消息
echo "你好,记住我喜欢喝咖啡" | ./build/waiter

后台驻留模式daemon

waiter 也支持后台驻留,保持与 homed 的持久连接并等待 TUI 实例接入,适合让 agent 主动召唤用户/设备桥持续存活:

# 后台驻留(默认连 ~/.homeagent/cli.sock
./build/waiter --daemon

# 指定 socket
./build/waiter --socket /path/to/cli.sock --daemon

# 随后任意 TUI/一行实例都会自动接入正在运行的 daemon而不是直连 homed
./build/waiter

daemon 监听 ~/.homeagent/waiter.sock新客户端连入时会回放缓冲的最近对话256 行),断连后 daemon 持续存活、自动重连 homed并保持设备桥若配置了 device_gateway/device_token)。

API 密钥通过 WebUI http://localhost:8080 设置页配置,持久化在 SQLite 中。

代码结构

cmd/homed/          守护进程入口,组装所有子系统
cmd/waiter/         CLI 客户端Unix socket
internal/
├── agent/core/     Agent 核心事件循环、LLM 工具循环、7 阶段管道
├── agent/api/      LLM Provider + 8 个 Lua 适配器
├── memory/         三层记忆Graph(SQLite) / Document(JSON+TF-IDF) / Text(JSONL) + StaticEmbedder(预训练词嵌入/TF-IDF回退) + CleanTemplateText(去模版)
├── knowledge/      知识库(文件系统 + TF-IDF
├── plugin/         插件注册表 + 子进程加载器stdio RPC + 共享内存段 + 事件环)
├── plugins/        内置 11 个插件webui/cli/timer/cmd/mcp/clawhubadapter/agentcli/healthcheck/pluginmgr/files/cfgmgr
├── sdk/            PluginSDKTool/Stage/Event 三通道)
├── config/         SQLite 配置中心
├── events/         事件总线
└── internal/lua/adapters/   8 个 LLM 协议适配器脚本
外部插件开发见 [homeagent-sdk](https://gitcode.com/JianFeeeee/homeagent-sdk) 仓库,使用 `plugindev` 工具链开发,参考 `example/` 目录下的 Go 和 Lua 示例

项目状态

v1.1.1 — 多模态贯通插件边界。v1.1.0 让记忆系统支持了二进制多媒体节点,但那条链路只对内核自己开放;本版打通到插件与模型。公开 SDK 新增媒体字段与三个媒体注入接口(配套 SDK v1.1.0,整条 1.1.x 线共用),内核实现对应四个 RPC。桥接层此前在静默裁字段:插件交进来的 Confidence/类型/SentenceText 全被丢弃、Doc 只留三个字段、Remove 不解引用媒体永久算「被引用」GC 收不掉)。processTextInput/processMediaInput 归一成一条 processInput,媒体路径由此获得它一直缺的去重、no_memory、通道 Cleaner、中断语义、EventRawInput。修掉三处真实缺陷:用户发的图从来没出现在 WebUI 聊天记录里(媒体路径发布 map 而订阅方断言 stringmemory_commitsentence_text 从未暴露给模型(而它是媒体绑定链的必经环节)、PluginSDK 两处并发竞态-race 实测 11 处,插件重载瞬间偶发 nil 解引用崩溃)。

v1.1.0 — 记忆系统支持二进制多媒体节点。内容寻址媒体存储CAS + SQLite 元数据 + 磁盘 blobGet always 重校 digest贯通 L0上下文事件/L2文档/L3图谱句子三层引用计数式 GC有引用者绝不删。视觉模型生成的描述文本是持久语义记忆blob 只是可被容量 GC 淘汰的缓存。

v1.0.0 — 外部插件从 C ABI 动态库迁移到子进程 + 共享内存。首个不再加载 .so/.dll 的版本,与 0.9.x 不兼容(存量插件须用新版 plugindev 重编为 plugin.bin业务代码零改动)。消除 6 类此前在生产造成故障的缺陷:热重载失效(DF_1_NODELETEdlclose 成 no-op、崩溃隔离缺失插件 panic 带崩 homed、stage lost update副本模型丢失 35.8~36.8%、cgo 超时不可中断(线程线性泄漏)、output_send 假成功模型收到「已发送」而消息未送达、Windows 能力断层(只见 3 个 stage 字段且无法写回。三面通信stdio JSON-RPC控制+ 共享内存段(数据)+ 事件环通知权限梯度显式化为三道闸。RPC 往返 p50 24.1µs崩溃到恢复 <1s。

v0.9.0 — C ABI v2外部插件 Stage 回调支持写回(invoke_stage 增加 result 输出,插件可在 OnInput/AfterToolcall/PostAction 修改 RawMessage/LLMText/ToolResults 等并同步回内核ABI 版本随内核 minor 对齐v0.9.x → ABIVersion=2version_min=1 向后兼容旧插件)。同步修复工具循环 zen 兼容补位误伤首轮 system 上下文的问题。配套 SDK 提供增强版 sanitizer 示例(坏 UTF-8/U+FFFD/ANSI 转义全链路清洗)。该 ABI 已随 v1.0.0 退场。

v0.8.0 — 核心可用,插件系统增强。内置 20+ 插件,外部插件开发见 homeagent-sdk 仓库。新增输入通道 NoMemory/CleanerChannelDef、插件禁用/启用系统CLI + WebUIplugindev 工具链完成 C ABI ChannelDef 传递。

文档

下载

Releases 提供三种变体:

变体 内容 适用
full homed + waiter + 桌面 GUI + systemd unit 单机全功能
server homed + waiter + systemd unit 服务器(无桌面环境)
client waiter + 桌面 GUI 连接远程 HomeAgent
  • Linux.debamd64/arm64.rpmx86_64.tar.gz
  • WindowsHomeAgent_v1.1.1_{Full,Server,Client}_win64.exeNSIS 安装向导)
  • 免安装:homeagent-bin-<os>_<arch>.tar.gz(含 homed/waiter/initconfig
  • 校验:SHA256SUMS

macOS 的 homed 需在原生 macOS 构建CGO + sqlite3发布包仅含 waiter/initconfig

构建

make build build-cli    # 编译守护进程 + CLI
make test               # go test ./...
make install            # 安装到系统

依赖Go 1.25+, CGo (go-sqlite3), Linux/Windows。

许可

本项目以 GNU Affero 通用公共许可证第 3 版AGPL-3.0-only 发布,全文见 LICENSE

它是 GPL 家族里传染性最强的一档:不仅分发时须提供完整对应源码, 通过网络提供服务时也要向使用者提供源码§13 Remote Network Interaction。 即:任何人把改过的 HomeAgent 对外提供网络服务,都必须让该服务的使用者拿到改动后的源码。

插件与本项目通过公开 SDK 静态链接SDK 源码会进入插件二进制),因此插件是本项目的 衍生作品,需以相同许可发布;子进程隔离不改变这一点,因为被链接的是 SDK 代码本身。

随包分发的第三方组件

组件 许可 位置
Chinese-CLIP ViT-B/16ONNX 产物) Apache-2.0 /usr/lib/homeagent/models/chinese-clip-vit-b16-onnx/
ONNX Runtimelibonnxruntime.so MIT /usr/lib/homeagent/onnxruntime/
jieba 词库(内嵌进二进制) MIT 源码 internal/memory/jiebadict/
Go 依赖go-sqlite3、gojieba、bubbletea 等) MIT / BSD-3 / Apache-2.0 均为宽松许可,与 AGPL-3.0 兼容

这些组件保持各自原有许可,不在本项目的 AGPL 授权范围内;发行包把它们的许可全文放在 /usr/share/doc/homeagent/licenses/,并在 dep/rpm 元数据里声明本包许可为 AGPL-3.0-only