Files
HomeAgent/README.md
JianFeeeee b15d0bd114 refactor(plugin)!: 重编提示与模板路径改用 hmapdev;文档全面对齐 1.2.0
工具链在 SDK 1.2.0 更名为 hmapdev(原 plugindev)。核心侧三处功能耦合同步:

1. 用户可见报错:旧 C ABI 产物 / 协议版本不匹配 / 共享段版本不匹配
   三处「请用配套 plugindev 重编」→ hmapdev(对应两条测试断言同步)
2. e2e_template_test 的模板路径改为 tools/hmapdev/templates,
   并保留旧路径回退(旧 SDK 检出仍能跑测试)
3. 注释与文档同步

文档更新(用户可见面):
- assets/docs/{zh,en}/PLUGIN_DEV.md:工具链章节整体改为 hmapdev,
  补改名说明与 SDK 存储目录迁移;命令示例全部更新
- assets/docs/{zh,en}/ARCHITECTURE.md:**流程图与章节对齐 v1.2.0** ——
  · 向量化章节改为三层降级:统一多模态空间(主)→ 词嵌入 → TF-IDF(回退),
    写明「同指纹且同维度才参与融合」
  · 媒体记忆章节重写:媒体是一等记忆块(无独立 GC / 无引用计数 / 无描述式索引 /
    正文不再写 media marker),并写明 reembedStaleMedia 的跨空间迁移与写回
- README{,_EN}.md、docs/zh/plugin-interface-matrix.md:工具名与模板路径同步
  (历史条目标注「当时名为 plugindev」)

验证:go test ./internal/plugin/ ./internal/plugin/proc/ ok,
含 4 条真实模板 E2E(模板路径切换后仍通过)。
2026-09-12 12:42:43 +08:00

292 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

> ⚠️ **AI 辅助编程声明**:本项目代码、文档及提交历史中,部分内容由 AI 辅助生成或修改。人工已审阅关键改动,但使用时请自行评估与验证。
# HomeAgent
> **English**: [README_EN.md](./README_EN.md)
以**核心域与应用域分离**为设计原则的 Agent 框架。内核执行零 IO 策略——所有外部交互WebUI、QQ、命令行、文件操作、网络搜索、备忘等均由插件层承载内核不直接处理任何 IO 操作。
配合**三层记忆架构**Context → Document → Graph通过分级存储与自动归档机制维持单会话长周期运行的上下文连贯性。
```go
homed内核零 IO PluginSDK 插件所有 IO 能力
```
**v1.1.1 起媒体贯通插件边界**:插件与模型都能读写记忆里的图片/音频(`InsertWithMedia``InjectInputMedia`),媒体以 `[<mime> <短digest>] <描述>` 标记存在于纯文本记忆中——描述是可检索的语义记忆digest 是回到字节的钥匙。
**v1.0.0 起外部插件是独立子进程**:经 stdio JSON-RPC控制面+ 共享内存段(数据面)+ 事件环(通知面)与内核通信。插件崩溃不影响内核且自动重启,换 `plugin.bin` 即生效的真热重载。
## 设计要点
**核心域与应用域分离** — 内核职责限定为 LLM 编排、记忆管理与知识检索;所有 IO 能力(消息收发、文件读写、网络请求、硬件交互等)由插件实现。这种划分在 Agent 框架层面进行领域边界界定,内核与插件各有其责任范围。
**三层记忆架构** — 通过分级存储策略管理 Agent 长期运行中的信息留存:
- **Context 层**:预训练词嵌入 / TF-IDF 回退的相关性评分事件窗口,保护最近 10 条,维护 topK 条上下文
- **Document 层**:临时记忆,冷数据自动下沉,也支持用户主动提交
- **Graph 层**SQLite 图数据库,持久化实体关系和语义记忆,支持蒸馏管道从原始对话中提取三元组
## 架构图
### 一、消息处理时序
```mermaid
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 管道
```mermaid
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
```
### 三、三层记忆
```mermaid
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`](assets/docs/zh/ARCHITECTURE.md)。
## 看板娘
<div align="center">
<img src="assets/branding/mascot-xiaozhai.webp" alt="HomeAgent 看板娘 小宅" width="200">
<p><strong>小宅</strong> — HomeAgent 看板娘</p>
</div>
## 快速体验
```bash
make build build-cli
./build/homed -data /tmp/ha
```
```bash
# 交互模式
./build/waiter
# 或单条消息
echo "你好,记住我喜欢喝咖啡" | ./build/waiter
```
### 后台驻留模式daemon
waiter 也支持后台驻留,保持与 homed 的持久连接并等待 TUI 实例接入,适合让 agent 主动召唤用户/设备桥持续存活:
```bash
# 后台驻留(默认连 ~/.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) 仓库,使用 `hmapdev` 工具链开发,参考 `example/` 目录下的 Go 和 Lua 示例
```
## 项目状态
**v1.2.0** — 统一多模态向量空间 + 媒体升为图记忆一等节点 + 数据面全量迁到共享内存。
- **模型中立的统一向量空间**:内核不再适配任何具体模型,只提供公共 provider SPI
`pkg/embedding``Modality` / `Input{Data,MIME}` / `Info{Dimension,Fingerprint,Modalities}`
+ 名字注册表),实现在 `providers/*`。默认 **Chinese-CLIP ViT-B/16** —— text 与 image
落在**同一空间**512 维、指纹 `cd2a495cf990`、Apache-2.0、独立实测常驻约 1.15GB
`qwen3vl` 保留2048 维、常驻约 9.4GB,供内存充足或将来要视频的机器切回)。
文本检索仍由既有词向量 / TF-IDF 兜底CLIP 双塔的**纯文本语义弱于 MLLM 型嵌入器**
这是已知并写进文档的代价。
- **媒体是图数据库的一等节点与边****彻底删除**「用文本描述式索引图片」这套将就机制,
以及 `media_refs` 与媒体引用计数。记忆块遵循单层不变量——Context → Document → Graph
是块的**迁移**,不是复制、也不靠引用保活。
- **数据面全部走共享内存**(工具调用帧 / Cleaner / 输入输出通道 / 媒体块 / 文档与知识正文),
RPC 只传偏移描述符;**RPC 协议升到 2**fd3 布局改变,**不支持滚动升级**——
内核与全部插件必须同批重建、同批安装,存量插件须用新版 `hmapdev` 重编。
- 注入可声明 `InjectOptions{NoMemory, ContextPolicy}`**默认仍记入记忆、默认不裁剪**
裁剪必须显式声明,且先经插件注册的 `Cleaner`。SDK 1.2.0 相对 1.1.0 **纯追加**
- **发行包默认启用** ONNX 向量空间并把模型754MB与 ONNX Runtime24MB
server/full 包发布;`homed` 放弃 Windows 原生支持改走 WSL2jieba 词库内嵌进二进制。
- 修掉三个**安装链静默失败**`initconfig``CGO_ENABLED=0` 是空操作(打印凭据却一个字节
没写)、全新安装被误判「已有配置」而整体跳过默认值播种(装完 0 插件、deb 的 `postinst`
查错 unit 路径导致 `enable` 从未执行。
- 自本版起以 **AGPL-3.0-only** 发布(含网络条款;插件静态链接 SDK 故须同许可,见「许可」)。
> 以下历史条目保留原文以呈现演进,其中两条机制**已在 v1.2.0 移除**
> 「媒体以 `[<mime> <短digest>] <描述>` 标记参与检索」(描述式索引)与「媒体引用计数式 GC」。
**v1.1.1** — 多模态贯通**插件边界**。v1.1.0 让记忆系统支持了二进制多媒体节点,但那条链路只对内核自己开放;本版打通到插件与模型。公开 SDK 新增媒体字段与三个媒体注入接口(配套 [SDK v1.1.0](https://gitcode.com/JianFeeeee/homeagent-sdk/releases/tag/v1.1.0),整条 1.1.x 线共用),内核实现对应四个 RPC。桥接层此前在**静默裁字段**:插件交进来的 `Confidence`/类型/`SentenceText` 全被丢弃、`Doc` 只留三个字段、`Remove` 不解引用媒体永久算「被引用」GC 收不掉)。`processTextInput`/`processMediaInput` 归一成一条 `processInput`,媒体路径由此获得它一直缺的去重、`no_memory`、通道 `Cleaner`、中断语义、`EventRawInput`。修掉三处真实缺陷:**用户发的图从来没出现在 WebUI 聊天记录里**(媒体路径发布 map 而订阅方断言 string、**`memory_commit``sentence_text` 从未暴露给模型**(而它是媒体绑定链的必经环节)、**`PluginSDK` 两处并发竞态**`-race` 实测 11 处,插件重载瞬间偶发 nil 解引用崩溃)。
**v1.1.0** — 记忆系统支持**二进制多媒体节点**。内容寻址媒体存储CAS + SQLite 元数据 + 磁盘 blob`Get` always 重校 digest贯通 L0上下文事件/L2文档/L3图谱句子三层引用计数式 GC有引用者绝不删。视觉模型生成的描述文本是持久语义记忆blob 只是可被容量 GC 淘汰的缓存。
**v1.0.0** — 外部插件从 C ABI 动态库迁移到**子进程 + 共享内存**。首个不再加载 `.so`/`.dll` 的版本,与 0.9.x 不兼容(存量插件须用新版工具链重编;该工具链当时名为 `plugindev`**现名 `hmapdev`**)。外部插件需重编为 `plugin.bin`**业务代码零改动**)。消除 6 类此前在生产造成故障的缺陷:热重载失效(`DF_1_NODELETE``dlclose` 成 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=2`version_min=1` 向后兼容旧插件)。同步修复工具循环 zen 兼容补位误伤首轮 system 上下文的问题配套 SDK 提供增强版 sanitizer 示例 UTF-8/U+FFFD/ANSI 转义全链路清洗)。** ABI 已随 v1.0.0 退场。**
**v0.8.0** 核心可用插件系统增强内置 20+ 插件外部插件开发见 [homeagent-sdk](https://gitcode.com/JianFeeeee/homeagent-sdk) 仓库新增输入通道 `NoMemory`/`Cleaner``ChannelDef`插件禁用/启用系统CLI + WebUI`plugindev` 工具链完成 C ABI `ChannelDef` 传递
## 文档
- [项目概览](assets/docs/zh/OVERVIEW.md) | [English](assets/docs/en/OVERVIEW.md)
- [技术架构](assets/docs/zh/ARCHITECTURE.md) | [English](assets/docs/en/ARCHITECTURE.md)
- [插件开发指南](assets/docs/zh/PLUGIN_DEV.md) | [English](assets/docs/en/PLUGIN_DEV.md)
- [Lua Adapter](assets/docs/zh/ADAPTER.md) | [English](assets/docs/en/ADAPTER.md)
- [知识库演示](assets/knowledge/homeagent_architecture/content.md)
## 下载
[Releases](https://gitcode.com/JianFeeeee/HomeAgent/releases) 提供三种变体
| 变体 | 内容 | 适用 |
|---|---|---|
| **full** | homed + waiter + 桌面 GUI + systemd unit | 单机全功能 |
| **server** | homed + waiter + systemd unit | 服务器无桌面环境 |
| **client** | waiter + 桌面 GUI | 连接远程 HomeAgent |
- Linux`.deb`amd64/arm64)、`.rpm`x86_64)、`.tar.gz`
- Windows`HomeAgent_v1.2.0_{Full,Server,Client}_win64.exe`NSIS 安装向导 AGPL 许可页)。 v1.2.0 起因 `homed` 不再支持 Windows 原生依赖 fd 继承与共享内存段内偏移解引用安装器改为引导到 **WSL2**并把 Linux 包送进发行版里按 Linux 方式安装
- 免安装`homeagent-bin-<os>_<arch>.tar.gz` homed/waiter/initconfig
- 校验`SHA256SUMS`
macOS `homed` 需在原生 macOS 构建CGO + sqlite3发布包仅含 `waiter`/`initconfig`
## 构建
```bash
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](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 Runtime`libonnxruntime.so` | MIT | `/usr/lib/homeagent/onnxruntime/` |
| jieba 词库内嵌进二进制 | MIT | 源码 `internal/memory/jiebadict/` |
| Go 依赖go-sqlite3gojiebabubbletea | MIT / BSD-3 / Apache-2.0 | 均为宽松许可 AGPL-3.0 兼容 |
这些组件**保持各自原有许可**不在本项目的 AGPL 授权范围内发行包把它们的许可全文放在
`/usr/share/doc/homeagent/licenses/`并在 dep/rpm 元数据里声明本包许可为 `AGPL-3.0-only`