## 17 个插件源码零改动,全部重编为 plugin.bin 16 个 × 3 平台(linux/darwin/windows),qq 1 平台(plg.json 自己声明 bundle:false)。luademo 走 Lua 解释器不适用。 git status example/ 无输出 —— 这是「业务代码零改动」的硬证据。 批 3 那些预估高风险的插件(qq 2686 行双向通道、browser 12 工具 + InjectInterruptText、a2a/acp 的 InjectInputSync 同步注入)一次全过, 因为它们只碰公开 SDK 合同面,而合同面在 Part 2 已 51 个 method 全量平移。 唯一一次失败与迁移无关:rss 的 github.com/mmcdole/gofeed 不在本地模块 缓存且 proxy.golang.org 不通,换 GOPROXY=https://goproxy.cn 后通过。 ## 真实 homed 加载验证 15 个外部插件全部经 proc 通道建链(protocol=1 sdk=0.9.2,各自独立 PID), 31 个插件 loaded(15 外部 + 16 内置)。 ai_image / files 未走 proc 通道:同名内置插件优先(工厂编译期注册), 外部插件被遮蔽。这是既有行为,与迁移无关。 事件环与共享段均正常创建,且共享段是**一块** 256KB 服务全部 15 个插件。 ## 冒烟测试 4 项(internal/plugins/real_plugin_smoke_test.go) 用真实 example 产物而非 testdata 假插件;manifest 刻意写 "entry":"plugin.so" 验证工具链与内核都已不看 entry 值。未重编时 skip 而非 fail。 - ToolInvokeRoundTrip:工具真实调用往返(此前只验证到"注册")。 weather_current 返回结构化参数校验错误——这恰是链路通的证据。 - StageRewriteTakesEffect:sanitizer 清洗 ANSI 序列,改写经共享段回到 内核 StageContext - MultiPluginShareOneSegment:sanitizer + weather 并发,清洗结果不被覆盖 - CrashDoesNotKillKernel:SIGKILL 插件进程后 homed 存活、17 插件仍在 (对比 C ABI 下插件 panic 直接带崩 homed,§1.2 现网已发生) ## 开销实测与基线偏差 15 个插件进程 RSS=88.0MB PSS=87.9MB 线程=82,均摊 5.87MB / 5.5 线程。 RSS 88MB vs 实验 5 基线 29.1MB **不是回归,是基线不可比**:实验 5 用 2.68MB 最小插件,真实插件 3.1~14.8MB。可比的结构性指标: - 均摊线程 5.5 vs 4.9 —— 同量级,无线程膨胀 - PSS/RSS 99.9% vs 44% —— **明显差于基线** 第二项是真实发现:基线里 PSS 远低于 RSS 说明 Go runtime 只读代码页在 进程间共享;实测几乎不共享,因为 15 个插件是 15 个不同的二进制,没有 共同物理页可映射。这是「每插件独立二进制」的固有代价,意味着实际内存 开销高于 §4.3 的乐观估计。压这一项的方向是共享 launcher 二进制。 ## 工具脚本入 experiments/19-migration-verify scripts/ 被 .gitignore 排除,故放到已跟踪的 experiments 目录下, 与 01~18 的可复跑实验并列。 measure-plugin-overhead.sh 第一版有统计口径 bug:RSS 读 status 的 VmRSS、 PSS 读 smaps_rollup 的 Pss,输出 PSS(87.9MB) > RSS(69.1MB) —— 物理上不可能。 两者对共享内存段计入方式不同(smaps 的 Rss 含 Pss_Shmem)。已统一从 smaps_rollup 读。另修 bc 不可用导致 MB 全显示 0.0(改用 awk)。 Ref: docs/zh/plugin-migration-plan.md Part 6.3、docs/zh/架构迁移评估.md §4.3
⚠️ AI-Assisted Programming Notice: Parts of this project's code, documentation, and commit history were generated or modified with AI assistance. Key changes have been human-reviewed, but please evaluate and verify before use.
HomeAgent
中文: README.md
An Agent framework designed around separation of core domain and application domain. The kernel enforces a zero-IO policy — all external interaction (WebUI, QQ, CLI, file operations, web search, memos, etc.) is handled by the plugin layer; the kernel performs no direct IO operations.
Combined with a three-layer memory architecture (Context → Document → Graph), it maintains contextual coherence across long-running single-conversation sessions through tiered storage and automated archival.
homed (kernel, zero IO) ← PluginSDK → plugins (all IO capabilities)
Design Principles
Separation of Core Domain and Application Domain — The kernel's responsibilities are limited to LLM orchestration, memory management, and knowledge retrieval; all IO capabilities (message send/receive, file read/write, network requests, hardware interaction, etc.) are implemented by plugins. This separation defines domain boundaries at the Agent framework level, with distinct responsibility scopes for the kernel and plugins.
Three-Layer Memory Architecture — Manages information retention in long-running agents through a tiered storage strategy:
- Context Layer: Pretrained word embedding / TF-IDF fallback relevance-scored event window, protects last 10 entries, maintains topK context entries
- Document Layer: Temporary memory with automatic cold data sinking, also supports user-initiated submissions
- Graph Layer: SQLite graph database, persists entity relationships and semantic memory, supports distillation pipelines to extract triples from conversations
Architecture Diagrams
1. Message Processing Sequence
sequenceDiagram
participant U as User/Plugin
participant IO as IOManager
participant EV as eventLoop
participant CTX as RelevanceContext
participant LLM as LLM+Tool Loop
participant ST as StageHost
participant MEM as Three-Layer Memory
U->>IO: InjectInput(type, payload)
IO->>EV: inputCh
rect lavender
Note over EV: processTextInput
EV->>ST: StageOnInput Plugin can rewrite/short-circuit
EV->>CTX: Prune(input,topK) StaticEmbedder/TF-IDF cosine pruning
CTX->>MEM: Low-score events archived to Document (original timestamp)
EV->>CTX: Append(input) CleanTemplateText→three-branch vector→5s write
end
rect lightgreen
Note over EV,LLM: process()
EV->>MEM: buildMemoryContext Indexer recalls from Graph (vector+jieba→BFS depth=2)
EV->>MEM: buildSystemPrompt DocQuery summary+Graph memory index+Persona+Skills
EV->>ST: StagePreAction Plugin can pre-intercept
loop Tool loop
LLM->>LLM: drainInterrupts
LLM->>LLM: LLM Chat
LLM->>ST: StagePostAction Plugin can modify/short-circuit
alt No tool call
LLM-->>EV: Returns response
else
loop Each tool
ST->>ST: StageBeforeToolcall Plugin can reject
LLM->>LLM: executeToolCall
ST->>ST: StageAfterToolcall
end
end
end
end
rect lightpink
Note over EV: emitResponse
CTX->>CTX: Append(response)
ST->>ST: StageBeforeOutput Plugin can rewrite
EV-->>U: ResponseCh CLI sync
EV-->>EV: Event bus WebUI SSE
ST->>ST: StageAfterOutput Read-only
EV->>MEM: emitMemoryCandidate
end
2. Stage Pipeline
flowchart LR
S1[① on_input] --> S2[② pre_action]
S2 --> S3[③ post_action]
S3 --> Q{Has tool?}
Q -->|Yes| S4[④ before_toolcall]
S4 --> T[executeToolCall]
T --> S5[⑤ after_toolcall]
S5 --> S3
Q -->|No| S6[⑥ before_output]
S6 --> S7[⑦ after_output]
style S1 fill:#e1f5fe
style S3 fill:#fff3e0
style S6 fill:#e8f5e9
3. Three-Layer Memory
flowchart TB
subgraph C[① Context Working Window]
RC[RelevanceContext]
A[Append] -->|CleanTemplateText→three-branch vector| RC
P[Prune StaticEmbedder/TF-IDF Cosine] -->|Low score original timestamp| D
P -->|Keep| TL[timeline→chronological→system prompt]
end
subgraph D[② Document File Memory]
DS[DocStore JSON+TF-IDF]
Q1[Query summary auto-inject] -->|[Related Memory Docs]| SP
Q2[doc_query LLM active recall] -->|Consume+delete source| DS
Q2 -->|Original timestamp write to context| RC
CD[FindColdDocs 72h] -->|docToTriples| G
end
subgraph G[③ Graph Database]
DB[(SQLite)]
IDX[Indexer vector+jieba→BFS depth=2] -->|[Memory Index]| SP
MEM[memory_recall/commit/merge/purge/edit]
SOC[person_query/set_trait]
end
subgraph H[④ Heartbeat Distillation]
REORG -->|Step3 Cold docs| CD
REORG -->|Step4 Bigram Jaccard| CONS[consolidation]
PIPE[Pipeline regex] -->|Name/Address/Likes/Age/Job| DB
end
SP[System Prompt] -->|Sequential assembly| LLM
LLM[LLM] -->|doc_query| Q2
LLM -->|memory_recall| MEM
See assets/docs/en/ARCHITECTURE.md for details.
Web Mascot
Quick Start
make build build-cli
./build/homed -data /tmp/ha
# Interactive mode
./build/waiter
# Or single message
echo "Hello, remember that I like coffee" | ./build/waiter
API keys are configured via WebUI http://localhost:8080 settings page, persisted in SQLite.
Code Structure
cmd/homed/ Daemon entry, assembles all subsystems
cmd/waiter/ CLI client (Unix socket)
internal/
├── agent/core/ Agent core: event loop, LLM tool loop, 7-stage pipeline
├── agent/api/ LLM Provider + 8 Lua adapters
├── memory/ Three-layer memory: Graph(SQLite) / Document(JSON+TF-IDF) / Text(JSONL) + StaticEmbedder(pretrained word embedding/TF-IDF fallback) + CleanTemplateText(de-template)
├── knowledge/ Knowledge base (filesystem + TF-IDF)
├── plugin/ Plugin registry + .so/.dll dynamic loader
├── plugins/ 11 built-in plugins (webui/cli/timer/cmd/mcp/clawhubadapter/agentcli/healthcheck/pluginmgr/files/cfgmgr)
├── sdk/ PluginSDK (Tool/Stage/Event three channels)
├── config/ SQLite config center
├── events/ Event bus
└── internal/lua/adapters/ 8 LLM protocol adapter scripts
External plugin development: see [homeagent-sdk](https://gitcode.com/JianFeeeee/homeagent-sdk) repo, use `plugindev` toolchain, refer to Go and Lua examples in `example/`
Project Status
v0.9.0 — C ABI v2: external plugin Stage callbacks can now write back (invoke_stage gained a result out-param; plugins may mutate RawMessage/LLMText/ToolResults etc. in OnInput/AfterToolcall/PostAction and have them synced to the core). ABI version now tracks core minor releases (v0.9.x → ABIVersion=2, version_min=1 keeps old plugins loadable). Also fixes the tool-loop zen-compat placeholder that wrongly fired on first-turn system context tail. The SDK ships an enhanced sanitizer example (bad-UTF-8 / U+FFFD / ANSI-escape scrub across the whole pipeline).
v0.8.0 — Core is functional, plugin system enhanced. 20+ built-in plugins. External plugin development via homeagent-sdk repo. Added input channel NoMemory/Cleaner, ChannelDef, plugin disable/enable system (CLI + WebUI), plugindev toolchain C ABI ChannelDef support.
Documentation
- Project Overview | 中文
- Technical Architecture | 中文
- Plugin Development Guide | 中文
- Lua Adapter | 中文
- Knowledge Base Demo
Build
make build build-cli # Build daemon + CLI
make test # go test ./...
make install # Install to system
Dependencies: Go 1.25+, CGo (go-sqlite3), Linux/Windows.
