常驻型个人 Agent 框架

记得住的管家
更是从不让你干等的搭档

内核只管编排、记忆与调度,消息 / 文件 / 网络 / 设备 一律交给插件。插件崩了不牵连内核 —— 换掉一个二进制就热重载。

真正的 AgentOS,长这样

隔离、调度、通信、资源。操作系统躲不开的四道题, 这里逐题给答案 —— 且每题都有能测的数字。

隔离

崩一个,不赔上全部

插件不在内核里,是另一个进程。崩了就把它注册的东西一并摘掉,其余照跑。

退避重启 1s / 2s / 3s;5 分钟内崩 3 次则停下等人
调度

拦得住,也接得回

输入分能等与不能等。不能等的可抢占,被打断的现场压栈,稍后原样恢复

L4 内核独占;外部插件声明 L4 会被夹到 L3
通信

三条道,各走各的

控制走 stdio,数据走共享内存,通知走事件环。变长内容只传偏移,两边映射到不同地址也能读。

整段写入 + 读回 3.5µs(实测)
资源

记忆不会越用越肿

上下文按相关性取舍,最近 10 条恒受保护。低分下沉成文档,冷文档再蒸馏成三元组。

有效工作区间上限 60 万 token
01

内核零 IO,只碰调度

内核不读文件、不发网络、不碰硬件。它只做三件事: 编排、记忆、调度。外面的一切 —— 消息、文件、网络、设备 —— 都由插件接管。于是「内核可信吗」和「这个插件安全吗」 成了两个可以分开回答的问题,而不是一次押上整块。

外部世界 内核 编排 · 记忆 · 调度 插件 插件 插件 插件

箭头只进出插件 —— 内核一列都没有

02

部署,从未如此便捷

插件是静态编译的单个文件:目标机上没有 Go、没有 libc、 没有容器、没有运行时,拷过去就能跑。 本体同样不要求你先装什么 —— 没有数据库、没有缓存、没有消息队列, 记忆与索引都在进程内。所谓部署,就是把文件放上去。

目标机 plugin.bin 单个文件 Go 工具链 libc / glibc Node / Python 容器运行时 都不需要

实测:statically linked,无动态依赖

03

数据如水,随流,随改,随走

控制信令走 stdio,真正的数据走一块共享内存。 变长内容只传一个相对偏移,两边 mmap 到不同地址也能各自解引用。 所以上下文在插件里是零拷贝改写的 —— 不是「序列化出去、传字符串、再反序列化回来」,而是两边看着同一块内存。

内核 homed 插件 plugin.bin 共享内存段(一块,两边同一物理页) header arena 变长数据 {off, len} 相对基址 零拷贝:不序列化、不复制

实测整段写入+读回 3.5µs

04

轻重缓急,各归其位

输入走两条路。排队的没有级别 —— 什么都能插它前面; 中断的带级别 L1–L4,级别高的可以抢占级别低的。 被抢占的现场压进栈,稍后原样恢复。 L4 内核独占,所以「停止」按下去就真的停。

中断 · 带级别 排队 · 无级别 L4 内核独占 L3 需及时处理 L2 消息类 L1 完全可等 先到先处理 任何中断都能插它前面 正在跑的任务 同一时刻只一个 被打断的现场压入中断栈,稍后原样恢复
05

忙时,有人替你接住

主 agent 被长任务占住、积压又够多时,内核把这些消息转给一个 临时驻留的分诊助手。能当场办的就办了; 非等主 agent 不可的,立刻回一句「忙碌中,请稍候」。 你不必对着对话框猜它还在不在。

主 agent 长任务 · 占住很久 积压消息 ×3 积压消息 ×4 转投 分诊助手 当场办 / 立刻答 不必干等

三层记忆:从「刚才说了什么」到「三年前说过什么」

不是一个大向量库包打天下,而是三层各司其职、逐层下沉。 蓝 / 青 / 金三色对应的就是这三层。

Context工作窗口

内存中的事件窗口。按与当前输入的相关性打分:优先比统一空间的稠密向量余弦, 未配置时退到稀疏词向量(TF-IDF / fastText)。最近 10 条受保护, 低分事件归档进 Document 层。

Document文件记忆

JSON + TF-IDF 索引的中间层。支持显式提交与隐式归档, 冷数据下沉后蒸馏成三元组进入图谱。

Graph图数据库

SQLite 持久化实体与关系,BFS 遍历召回。三元组从对话中蒸馏而来, 越用越准 —— 「几个月前的事还记得」靠的就是这层。

媒体也是一等节点

图片、音频不是附件,而是三层里的一类节点:内容寻址(相同字节只存一份)。 媒体不单独记引用账本 —— 删掉持有它的记忆块才删内容,与文本块同一套规则。

图片靠自己的向量被检索

图像是真正的记忆块,不是「描述文本 + 可淘汰的 blob」。 旧实现靠视觉模型生成的描述当索引,现已弃用 —— 文本标签只留 [mime digest],召回走统一空间的图像向量。

统一多模态空间

文本与图像落在同一向量空间(默认 Chinese-CLIP): 可以用一句话搜图,也可以用图找记忆。

一条消息进来之后

输入先过调度器,再进处理管道。全程 7 个阶段钩子,插件可改写或短路。

外部输入 QQ / WebUI / CLI / 邮件 / 设备
输入调度器 两类别 · 四级中断 L1–L4
  • 同级不抢占 → 入队列排队
  • 更高级别抢占,现场压入中断栈,稍后恢复
  • 忙得太久转投临时分诊助手
处理管道 记忆召回 + 人格注入 + LLM 调用 + 工具循环
每轮复用
  1. 1
    pre_action 构建消息与工具表 · 插件可在此短路
  2. 2
    LLM 调用 provider 回退 + 瞬时错误重试 · 流式累积
  3. 3
    post_action 插件可改写最终文本
  4. 4
    before_toolcall 逐个工具执行前 · 可拒
  5. 5
    执行工具 临界区:副作用不可回滚
  6. 6
    after_toolcall 上下文裁剪 · 相关记忆召回 · 结果入消息
三层记忆 Context → Document → Graph
输出通道 before_output · after_output · 可寻址到具体 agent

on_input 在进管道之前跑;before_output / after_output 在全部轮次结束后跑一次。

核心组件

homed常驻内核进程:LLM 编排、记忆管理、输入调度、插件生命周期
PluginSDK面向内核的接口:注册工具 / 挂阶段钩子 / 订阅事件 / 声明输出通道
inputch最基本的输入路由单位,可划给某个 agent(含驻留子)
Stage7 个处理阶段钩子(进管道前 1 个、轮次中 4 个、收尾 2 个),插件可改写或短路
resident驻留子 agent:独立调度器 + temp 图记忆;父可查看/发送/压缩/回收/销毁,子是父拉取而非推送
hmapdev插件工具链:生成工程、构建 .hmap、安装
36
在跑插件
16 内置 + 20 外部
340
可用工具
实测注册数
109k
Go 代码行
不含第三方
9
LLM 适配器
另有 1 个网关脚本

跑起来

依赖 Go 1.25+ 与 CGo(sqlite3)。内核需 Linux;Windows 上 homed 跑在 WSL2 里,仅需构建 waiter.exe

# 构建守护进程 + CLI make build build-cli # 启动内核(数据目录自定) ./build/homed -data /tmp/ha # 另开一个终端:交互模式,或单条消息 ./build/waiter echo "你好,记住我喜欢喝咖啡" | ./build/waiter

WebUI 与 API 密钥在 http://localhost:8080 配置,持久化到 SQLite。

开箱可用的插件

外部插件经 hmapdev 构建为独立二进制,可单独装卸、热重载。点任意插件看它能做什么。

点上方任一插件查看用途

a2av1.3.1

Agent 间通信。对外起 HTTP 服务暴露 /agent-card 与 /a2a(JSON-RPC)供他人发现与调用;对内提供工具去问别的 Agent。把监听地址设为空即只出站、不开端口。

SDKexample/a2a
acpv1.2.1

Agent Client Protocol 通信插件:充当 ACP 服务端接受其他 Agent 的任务请求,同时提供客户端工具向远程 ACP Agent(如 opencode)发起会话并读取回复

SDKexample/acp
biliv1.2.0

B站视频下载。需系统装 yt-dlp。不指定格式时先返回可用清晰度列表,选定后再下载;输出目录有路径校验,拒绝写成系统目录。

SDKexample/bili
browserv2.4.1

统一浏览器插件:搜索、HTTP抓取(quick)、无头渲染(normal)、交互式浏览器(interactive/CDP)

SDKexample/browser
calendarv1.1.0

日历事件管理,支持提醒和重复事件

SDKexample/calendar
deepsearchv1.1.2

为 agent 提供真正的联网信息检索:本地 SearXNG 聚合多引擎(返回标题/URL/摘要/时间),支持新闻、时间范围、指定引擎;并提供网页正文抽取与「搜索+读前K篇」的深检索

SDKexample/deepsearch
editdocv2.0.0

全能办公插件:新建/读取/编辑/转换 docx·xlsx·pptx·md·csv·txt(基于 python-docx / openpyxl / python-pptx / soffice / pandoc)

SDKexample/editdoc

公开仓中的 example 仍是 v1.0.0;v2.0.0 全能版源码尚未公开。

homeagent-mail-bridgev0.2.2

HomeAgent 接入 AgentMail:邮件驱动的多智能体协作

agentmailplugins/homeagent-mail-bridge
mcv0.1.8

基于 mineflayer 的虚拟 MC 客户端,作为 chan:mc 通道接入。「激活」分两个状态:想连着(意图)与确实连着(连接),所以 bridge 进程被杀后能自动重登恢复会话,而不是要人再喊一次。带移动/挖掘/合成/攻击等 11 个动作工具。

本地开发仓(无公开地址)
memov1.1.0

待办与备忘录刻意分两类:待办每 5 分钟检查未完成数、有则注入提醒;备忘录纯记事不提醒。混成一类要么天天弹、要么被忘掉。

SDKexample/memo
musicv0.1.0

搜歌与查歌词(网易云公开接口)。只读:不下载音频、不落文件。两段式用法 —— 先搜到歌曲 ID,再按 ID 取词。

SDKexample/music
ocrv1.0.0

图片文字识别。需系统装 tesseract(中文另需 chi_sim 语言包)。支持 URL 或 base64 输入,临时文件识别后自动清理。

SDKexample/ocr
plugindevv1.0.0

把 hmapdev 工具链封装成 Agent 可调用的工具:脚手架生成插件工程、构建打包 .hmap、管理 SDK 版本。配合 plugin_install 即可让 Agent 自己做完「新建插件 → 构建 → 安装」全流程。

SDKexample/plugindev
qqv1.4.1

经 NapCat 桥接 QQ:20 个工具覆盖消息、群/好友、文件传输。带权限模型 —— 身份绑在「帧」上而非插件全局(中断抢占恢复后不会丢身份),多来源合并取权限交集,敏感工具按前缀一律拒绝非所有者。

SDKexample/qq
recoverydiagv0.2.0

快速检查/崩溃取证工具集:diag_triage(退出码/信号/存活粗分)、diag_db(config.db 完整性 + LLM 源解析校验)、diag_log_scan(日志签名命中)、diag_delta(last-good 快照 vs 现状 diff)、diag_loc(正交综合定位)。全部返回结论而非原文,确定性、不消耗 LLM token,供 guard / failback 恢复决策使用。

SDKexample/recoverydiag
rssv1.1.0

RSS/Atom 订阅监控。按间隔轮询,发现新条目即以中断注入告知 agent;订阅时记下历史条目,所以订一个源不会把旧文章全推一遍。

SDKexample/rss
sanitizerv0.1.0

在三个阶段清洗文本:坏 UTF-8 / U+FFFD / ANSI 转义(会被模型复读)与 LLM 输出里的工具调用残留。不注册工具,只挂钩子。

SDKexample/sanitizer
vanblogv1.0.0

管理 VanBlog 开源博客系统:文章的增删改查、分类标签管理、草稿发布、备份导出等

SDKexample/vanblog
vikunjav1.0.1

Vikunja 待办/任务管理:任务增删改查、项目与看板桶、标签、指派、评论、关联、附件、保存筛选器、团队与分享、通知、订阅、Webhook、时间跟踪、数据导入、实例管理;并附通用 API 直通工具兜底

SDKexample/vikunja
weatherv1.0.0

查实时天气与预报(wttr.in,无需 API Key)。可设默认城市;结果标记为不进记忆计算 —— 天气是易变数据,反复写进记忆只会挤占预算。

SDKexample/weather

常见问题

最容易引起误解的六个地方。

「内核零 IO」是不是意味着内核很简单?

恰恰相反。零 IO 是为了让内核专注做难的部分:输入调度(四级中断、抢占与 现场保存)、上下文预算、三层记忆的蒸馏与召回。IO 挪出去之后,这些才有 清晰的所有权。

插件崩了会不会把 Agent 带崩?

不会。外部插件是独立子进程,与内核只通过 stdio JSON-RPC、共享内存段、 事件环通信。插件崩溃后,内核摘除它注册的工具、阶段与通道,按退避重启, 其余部分不受影响。

为什么消息会「排队」而不是立即处理?

因为同一时刻只应有一个任务在改上下文。同级抢占会让两边都做一半。 需要立刻插队时用更高级别的中断:插件可声明 L1–L3,L4 是内核保留的 「立即打断」(panic、内核事件),外部插件声明 L4 会被夹到 L3。 不该让所有消息都变成抢占者。

长任务会不会让用户等很久?

这正是「分诊助手」的用途。主 agent 忙超阈值且积压够多时,内核拉起临时 驻留子接手:能办的直接办,需要主 agent 的立刻回「忙碌中,请稍候」。

记忆会不会无限膨胀?

不会。三层是迁移而非复制:上下文事件裁剪后归档成文档,文档冷掉后蒸馏成 图谱三元组。图谱有去重与 UNIQUE 约束;媒体跟着记忆块走,块被永久删除时才回收字节。

能换 LLM 吗?

可以。内核不绑定厂商:每个 LLM 源对应一个 Lua 脚本负责请求与响应转换。 内置 9 个适配器(OpenAI、Anthropic、Gemini、DeepSeek、Groq、Mistral、 Ollama、GitHub、KimiCode),也可自己写一个接任意兼容 API。