Files
HomeAgent/docs/ARCHITECTURE.md
root e450edf865 docs: rewrite DESIGN.md and ARCHITECTURE.md matching current architecture
- Plugin = container with embedded IO channel
- OneBot QQ protocol support
- Output channel capability validation
- Atomic hot-reload (plgreload)
- Three-layer memory (TF-IDF relevance pruning)
- Remove all Docker/snapshot/multi-agent outdated content
2026-07-02 12:18:46 +08:00

285 lines
9.7 KiB
Markdown
Raw 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.

# HomeAgent 架构参考
> 基于 NextAgent 认知解耦架构 + TrulyMEM 自主图记忆 + OneBot 协议。
## 一、分层架构
```
┌──────────────────────────────────────────────────────────┐
│ IO 抽象层(唯一输入路径) │
│ Device(Mic/Speaker/Camera/GPIO/OneBot-QQ/PluginDevice) │
│ 所有外部输入 → InputEvent → inputCh │
│ 输出通道: 能力声明(text/file/image/audio/structured) │
│ 路由表: 输入源 → 默认输出通道 │
└──────────────────────────┬───────────────────────────────┘
┌──────────────────────────▼───────────────────────────────┐
│ Agent 操作层(核心编排器) │
│ eventLoop() consume inputCh │
│ ├─ RelevanceContextTF-IDF 相关性管理) │
│ ├─ 工具循环Provider.Chat → tool_calls → Execute → ...) │
│ ├─ 记忆索引注入(图索引 + 文档摘要) │
│ └─ 心跳蒸馏30min向量同步 + 冷归档 + 同义合并) │
└──────────────────────────┬───────────────────────────────┘
┌──────────────────────────▼───────────────────────────────┐
│ API 抽象层(唯一输出路径) │
│ Provider.Chat() → DeepSeek API / OpenAI / Ollama │
│ LuaAdapter 做请求/响应格式转换 │
└──────────────────────────────────────────────────────────┘
```
**三条核心规则:**
1. **所有外部输入** → 必须通过 `IOManager.InjectInput()` / `InjectText()` 注入
2. **所有 LLM 调用** → 必须通过 `Provider.Chat()` 发出
3. **Agent 不直接操作记忆系统**,只发射 `memory_candidate` 事件,由 Memory Pipeline 异步消费
## 二、子系统详解
### 2.1 IO 抽象层(唯一输入路径)
所有外部输入必须通过此层进入系统。
```
Device(Microphone) ─┐
Device(OneBot-QQ) ─┤
Device(Plugin) ─┤──→ IOManager → InputEvent → inputCh → Agent
Device(GPIO) ─┤
HTTP API ─┘
```
**核心类型:**
| 类型 | 说明 |
|------|------|
| `InputEvent` | Source + Type + Payload — 所有外部输入的标准化格式 |
| `OutputEvent` | Target + Type + Payload + OutputChannel — 输出路由 |
| `Device` | 接口Name/Type/Description/Tools/Execute/Start/Stop/OutputCapabilities |
| `DeviceType` | Input / Output / IO |
| `ToolDef` | Name + Description + Parameters + Handler — 与 LLM 函数调用同构 |
| `OutputCapability` | 位掩码text, file, image, audio, structured |
**内置设备:**
| 设备 | 方向 | 工具 |
|------|------|------|
| Microphone | Input | capture — 录音 |
| Speaker | Output | speak — 语音播放 |
| Camera | Input | capture 拍照 |
| OneBot QQ | IO | send_private/send_group/get_group_member_info/get_group_list |
| PluginDevice | IO | 插件声明工具 |
| GPIO | IO | gpio_write/gpio_read |
**输出通道能力校验:**
- 每个 Device 声明 `OutputCapabilities()` → 位掩码
- `output_send` 工具发送前校验通道是否支持文本
- `output_list_channels` 只列出有输出能力的通道
### 2.2 API 抽象层(唯一输出路径)
```
Agent Core → Provider.Chat()
┌───────┴───────┐
▼ ▼
OpenAIProvider LuaAdapter
(DeepSeek API) (格式转换)
```
| 实现 | 说明 |
|------|------|
| `OpenAIProvider` | 标准 OpenAI API 格式DeepSeek v4 flash 默认 |
| `LuaAdaptedProvider` | 通过 Lua 脚本转换请求/响应的适配 wrapper |
Lua 适配器位于 `{dataDir}/adapters/*.lua`,每个适配器返回 `name` + `transform_request` + `transform_response`
### 2.3 Agent 操作层(核心编排器)
```
eventLoop() → select on inputCh
handleInput(evt) → processTextInput(input)
├─ 1. RelevanceContext.Append(input)
├─ 2. 构建 prompt: personal.md + 图索引 + 文档摘要 + 上下文 + 工具
├─ 3. 工具循环(最多 10 轮)
│ LLM → tool_calls → Execute → 结果注入 → 下一轮
├─ 4. 追加响应到上下文
├─ 5. RelevanceContext.Prune() → 低分事件→文档记忆归档
├─ 6. OutputEvent → 输出通道
└─ 7. memory_candidate → TextMemory + Distiller → GraphDB
```
**人格注入:** personal.md 加载一次,固定在 system prompt 最前,永不漂移。
**工具分发:**
```
executeToolCall(tc)
├─ memory_* → executeMemoryTool
├─ knowledge_* → executeKnowledgeTool
├─ doc_* → executeDocTool
├─ output_* → executeOutputChannel/Send/ListChannels
└─ 其他 → io.ExecuteTool → Device.Execute
```
### 2.4 记忆系统
三层分级,自顶向下逐渐持久化、抽象化:
```
Layer 1: 上下文RelevanceContext
内存环形缓冲TF-IDF 余弦相似度排序
每次响应后保留 top 30低分→文档记忆
Layer 2: 文档记忆document.Store
JSON 文件 + TF-IDF 向量索引(字符 bigram
冷文档72h 未访问 + ≤2 次)→ 图数据库
Layer 3: 图数据库memory.GraphDB
SQLite 三元组(实体-关系-实体)
只注入索引(实体名+类型+提及次数)到 prompt
定期重整:向量同步 + bigram Jaccard 同义合并
```
### 2.5 知识系统
独立于记忆agent 主动学习。
```
knowledge/{category}/content.md
TF-IDF 向量索引(字符 bigram
工具: knowledge_search / knowledge_create / knowledge_list
```
### 2.6 插件系统
OpenClaw SKILL.md 兼容。
```
Plugin容器
├─ 元数据: name, version, author
├─ IOConfig可选: 声明 IO 端口
├─ Device可选: 原生 Go 设备
└─ Tools: LLM 工具定义
Registry:
├─ NativeFactory: "qq" → onebot.NewDevice
├─ SetIOManager: 绑定 IO 管理器
└─ Reload(): 原子化重载
```
**热插拔流程:**
1. 扫描 `plugins/` 目录
2. 原生工厂优先,无工厂则 LoadSKILL.md
3. 新设备 Start预先启动
4. `IOManager.AtomicSwapDevices()` 原子替换设备表 + 路由表
5. 旧设备 Stop后台 goroutine
### 2.7 OneBot QQ 通道
```
OneBot 前端go-cqhttp/Lagrange
│ Reverse WebSocket
OneBot Clientinternal/onebot/
├─ 事件: message/notice/request → IO InputEvent
├─ 动作: send_private_msg / send_group_msg / get_group_info / ...
├─ 自动重连(指数退避 1s→30s
└─ 事件 handler 注入 IO 层
Deviceinternal/onebot/device.go
├─ Tools: qq_send_private_msg, qq_send_group_msg, etc.
├─ Execute → Client.SendAction
└─ Start → Connect + 注册事件 handler
```
### 2.8 变更追踪器
Overlayfs 文件变更追踪:
```
PreAction(tool) → 记录文件 hash
PostAction(tool) → diff → ChangeSet{ID, Tool, Files[]SHA256}
Rollback() → 用 overlayfs 下层恢复
```
健康检查失败 → `tracker.Rollback()`
### 2.9 Supervisor 守护进程
```
Daemon:
├─ SetTracker() → 绑定变更追踪器
├─ RegisterAgent("main") → 注册主 agent
└─ 健康检查周期 → LLM API 可达性
└─ 连续失败 → tracker.Rollback()
```
## 三、配置
```yaml
daemon:
listen_addr: ":8080"
data_dir: "/var/lib/homeagent"
heartbeat_interval: 15s
check_interval: 30s
llm:
provider: "openai"
model: "deepseek-v4-flash"
base_url: "https://api.deepseek.com/v1"
api_key: "${DEEPSEEK_API_KEY}"
temperature: 0.7
max_tokens: 4096
```
## 四、数据目录
```
{dataDir}/
├── memory/
│ ├── graph.db # SQLite 图数据库
│ ├── text/ # JSONL 文本记忆
│ ├── documents/ # JSON 文档记忆
│ └── raw/ # 原始记录(蒸馏后删除)
├── knowledge/ # 知识库
│ └── {name}/content.md
├── plugins/ # 插件
│ └── {name}/
│ ├── SKILL.md
│ └── skill.json
├── skills/ # 技能
├── adapters/ # Lua 适配器
├── personal/ # 人格
│ └── personal.md
├── changesets/ # 变更追踪记录
└── snapshots/ # 快照
```
## 五、HTTP API
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/v1/chat/completions` | OpenAI 兼容对话 |
| GET | `/api/v1/knowledge` | 知识查询/列表 |
| POST | `/api/v1/knowledge` | 创建知识 |
| DELETE | `/api/v1/knowledge?name=` | 删除知识 |
| GET | `/api/v1/status` | 系统状态 |
| GET | `/api/v1/config` | 配置查看 |
## 六、构建与部署
```bash
make build # 编译主二进制
make run # 编译 + 启动(数据 /tmp/homeagent
make install # 安装到系统
make test # 运行测试
```
依赖Go 1.19+ (CGo enabled for go-sqlite3)。单二进制部署。