feat: 记忆体系统 v0.3.0 完成
Some checks failed
Release / build (push) Failing after 4m28s

## 核心功能
- 双记忆系统合并:picoclaw MEMORY.md + hxclaw 会话摘要
- 独立上下文系统:不依赖 picoclaw session
- 向量检索:硅基流动 BGE-M3 API
- 三重检测:关键词/向量相似度/命令

## 数据库
- libSQL (TursoDB) 存储
- sessions + chats 表设计
- 向量存储使用 binary 编码

## 查询场景
- RecallHistory: 查询所有会话摘要
- RecallTopic: 按话题向量检索
- RecallSession: 指定会话详情
- RecallWithinSession: 会话内检索

## 导出
- MongoDB 风格:~/.config/hxclaw/export-data.json
- chats 嵌套在 sessions 下
- 增量导出,同 session 累加

## UI 优化
- 合并状态显示(耗时 · 状态 · 消息数)
- 颜色设计:金色图标 + 暗绿色/暗红色状态

## 配置项
- memory.recall: keywords, auto_recall, similarity_threshold
- memory.vector: max_search_results
- memory.auto_export
This commit is contained in:
2026-04-27 06:16:19 +08:00
parent 88a110e87e
commit 5d9498f687
12 changed files with 1583 additions and 52 deletions

461
docs/architecture.md Normal file
View File

@@ -0,0 +1,461 @@
# hxclaw 记忆体系统架构图
## 一、数据流向总图
```mermaid
flowchart TB
subgraph 用户输入
A[用户输入]
A1[普通对话]
A2[查询历史]
A3[/recall 命令]
end
subgraph 上下文注入
B[GetContextPrompt]
B0[读取 picoclaw MEMORY.md]
B1[获取当前 Session 摘要]
B2[检测查询意图]
B3[按需调用 Recall]
end
subgraph AI 处理
C[ProcessDirect]
C1[工具调用]
C2[多轮对话]
end
subgraph 保存流程
D[SaveChat]
D1[INSERT chat]
D2[UPDATE chat 摘要+向量]
D3[UPDATE session 摘要+向量]
end
subgraph 数据库
E[sessions 表]
F[chats 表]
end
subgraph 向量服务
G[硅基流动 API]
end
subgraph 外部记忆
H[picoclaw MEMORY.md]
end
A --> B
B0 --> B
H --> B0
B --> C
C --> D
D --> F
D --> E
F --> G
E --> G
A1 -->|普通对话| B1
A2 -->|检测关键词| B2
A3 -->|强制触发| B3
```
---
## 二、对话流程(默认模式)
```mermaid
sequenceDiagram
participant U as 用户
participant M as main.go
participant CP as GetContextPrompt
participant PicoMem as picoclaw MEMORY.md
participant AI as ProcessDirect
participant SC as SaveChat
participant DB as libSQL
participant VS as 向量服务
U->>M: 用户输入
M->>CP: GetContextPrompt(userInput)
CP->>PicoMem: 读取长期记忆
PicoMem-->>CP: 长期记忆内容
CP->>DB: 获取 currentSession
DB->>CP: session.Summary
Note over CP: 合并:长期记忆 + 会话摘要
CP->>M: 返回上下文
M->>AI: ProcessDirect(context + input)
AI->>U: 返回 AI 回复
U->>SC: SaveChat(userInput, aiReply)
SC->>DB: INSERT chat
SC->>DB: UPDATE session
Note over SC: 更新摘要和向量
SC->>VS: 异步生成向量
VS-->>SC: embedding
SC->>DB: 保存到 chats.summary_embedding
SC->>DB: 保存到 sessions.summary_embedding
```
---
## 三、四种查询场景
```mermaid
flowchart LR
subgraph 查询场景
Q1[场景1: 历史摘要]
Q2[场景2: 话题检索]
Q3[场景3: 会话详情]
Q4[场景4: 会话内检索]
end
subgraph 触发条件
T1["之前聊过什么?"]
T2["谈论过 xxx?"]
T3["那次还说过什么?"]
T4["xxx 呢?"]
end
subgraph 查询逻辑
L1[查 sessions 表]
L2[chats 向量检索<br/>Group By session_id]
L3[查 sessions 表<br/>WHERE id = ?]
L4[chats 向量检索<br/>WHERE session_id = ?]
end
subgraph 返回
R1[所有会话摘要]
R2[按 session 分组<br/>top5 摘要拼接]
R3[指定 session 摘要]
R4[同 session 内相关摘要]
end
T1 --> Q1
T2 --> Q2
T3 --> Q3
T4 --> Q4
Q1 --> L1
Q2 --> L2
Q3 --> L3
Q4 --> L4
L1 --> R1
L2 --> R2
L3 --> R3
L4 --> R4
```
---
## 四、三重检测机制
```mermaid
flowchart TB
I[用户输入]
subgraph 检测层
D1[/recall 命令]
D2[关键词匹配]
D3[向量相似度]
end
subgraph 配置
C1[keywords]
C2[auto_recall]
C3[similarity_threshold]
end
I --> D1
I --> D2
I --> D3
D2 --> C1
D3 --> C3
C1 -->|匹配成功| R[强制 Recall]
D3 --> C2
C2 -->|开启| C3
C3 -->|阈值判断| R
D1 -->|触发| R
```
---
## 五、数据库表结构
```mermaid
erDiagram
sessions {
int id PK
string uuid
text summary
blob summary_embedding
string chat_ids
int created_at
int updated_at
}
chats {
int id PK
int session_id FK
text user_input
text ai_replies
text summary
blob summary_embedding
int created_at
int updated_at
}
sessions ||--o{ chats : "has many"
```
---
## 六、上下文演变
```mermaid
flowchart LR
subgraph 时间线
T1[开始]
T2[第1次对话]
T3[第2次对话]
T4[第N次对话]
T5[第1000次对话]
end
subgraph 上下文状态
S1[空]
S2[摘要1]
S3[摘要1+摘要2]
SN[摘要N]
S1000[摘要1000]
end
subgraph 实际状态
A1["context = 空 + 长期记忆"]
A2["context = 摘要1 + 长期记忆"]
A3["context = 摘要2 + 长期记忆"]
AN["context = 摘要N + 长期记忆"]
A1000["context = 摘要1000 + 长期记忆"]
end
T1 --> S1 --> A1
T2 --> S2 --> A2
T3 --> S3 -->|覆盖| A3
T4 --> SN -->|覆盖| AN
T5 --> S1000 -->|覆盖| A1000
Note over A1000: 始终只有1条会话摘要 + 长期记忆
```
**注意**:长期记忆来自 `~/.picoclaw/workspace/memory/MEMORY.md`,不受会话影响,会持续保留。
---
## 七、完整流程图
```mermaid
flowchart TB
subgraph 输入层
INPUT[用户输入]
CMD[/recall]
KW[关键词]
end
subgraph 检测层
CHECK{检测查询意图}
RECALL{Recall 触发?}
end
subgraph 上下文构建
CONTEXT[上下文]
SESSION_SUM[当前 Session 摘要]
RECALL_RES[Recall 结果]
end
subgraph AI 层
AI[ProcessDirect]
RESP[AI 回复]
end
subgraph 保存层
SAVE[SaveChat]
INSERT_CHAT[INSERT chat]
UPDATE_CHAT[UPDATE chat]
UPDATE_SESSION[UPDATE session]
end
subgraph 数据库
DB[(libSQL)]
SESSIONS[sessions 表]
CHATS[chats 表]
end
subgraph 向量服务
VS[向量服务]
EMB[Generate Embedding]
end
INPUT --> CHECK
CMD --> CHECK
KW --> CHECK
CHECK -->|普通对话| RECALL
CHECK -->|是查询| RECALL_RES
RECALL -->|否| SESSION_SUM
RECALL_RES --> CONTEXT
SESSION_SUM --> CONTEXT
CONTEXT --> AI
INPUT --> AI
AI --> RESP
RESP --> SAVE
SAVE --> INSERT_CHAT
INSERT_CHAT --> DB
DB --> CHATS
SAVE --> UPDATE_CHAT
UPDATE_CHAT --> DB
SAVE --> UPDATE_SESSION
UPDATE_SESSION --> DB
CHATS --> EMB
SESSIONS --> EMB
EMB --> VS
VS --> CHATS
VS --> SESSIONS
```
---
## 八、关键文件对应关系
| 模块 | 文件 | 职责 |
|------|------|------|
| 主流程 | `main.go` | 调用 GetContextPrompt、SaveChat |
| 配置 | `internal/config.go` | RecallConfig、VectorConfig |
| 数据库 | `internal/memory/db.go` | CRUD 操作 |
| 模型 | `internal/memory/model.go` | Session、Chat 结构体 |
| 向量 | `internal/memory/vector.go` | 硅基流动 API 调用 |
| 保存 | `internal/memory/save.go` | SaveChat、三重检测、长期记忆读取 |
| 查询 | `internal/memory/skill.go` | 4 个 Recall 函数 |
| 导出 | `internal/memory/export.go` | JSON 导出 |
---
## 九、双记忆系统合并
### 记忆来源
| 类型 | 来源 | 持久性 |
|------|------|--------|
| **长期记忆** | `~/.picoclaw/workspace/memory/MEMORY.md` | 跨会话AI 自动更新 |
| **会话摘要** | `~/.config/hxclaw/hxclaw.db` sessions 表 | 当前会话,动态更新 |
| **聊天详情** | `~/.config/hxclaw/hxclaw.db` chats 表 | 所有历史,支持向量检索 |
### 上下文注入格式
```markdown
=== 长期记忆 ===
picoclaw MEMORY.md 内容)
=== 当前会话摘要 ===
hxclaw sessions 表中的摘要)
用户新问题: xxx
```
### 实现原理
`GetContextPrompt()` 函数在构建上下文时:
1. 读取 picoclaw 的 `MEMORY.md` 文件
2. 解析并提取有效内容(跳过 Markdown 标题)
3. 合并到上下文顶部
4. 追加会话摘要
5. 如有 recall 结果,继续追加
### 数据流向
```
picoclaw MEMORY.md ──┐
├──→ GetContextPrompt ──→ AI 上下文
hxclaw sessions ────┘
```
---
## 十、配置项说明
```yaml
memory:
recall:
keywords: ["之前", "聊过", "记得", "找找", "曾经", "谈论过", "提过"]
auto_recall: true # 自动相似度检测
similarity_threshold: 0.7 # 相似度阈值
max_results: 5 # 最大检索结果
vector:
max_search_results: 10 # 向量检索最大结果
```
---
## 十一、MongoDB 风格导出
### 导出文件
- 路径:`~/.config/hxclaw/export-data.json`
- 格式:每次退出时自动增量导出
### JSON 结构
```json
{
"version": 1,
"exported_at": "2026-04-27T06:12:22+08:00",
"sessions": [
{
"id": 1,
"uuid": "session-uuid",
"summary": "会话摘要...",
"chat_ids": [1, 2, 3],
"created_at": 1740000000,
"updated_at": 1740000000,
"chats": [
{
"id": 1,
"session_id": 1,
"user_input": "用户输入",
"ai_replies": ["AI回复1", "AI回复2"],
"summary": "摘要",
"created_at": 1740000000,
"updated_at": 1740000000
}
]
}
]
}
```
### 设计特点
| 特性 | 说明 |
|------|------|
| 嵌套结构 | chats 嵌套在 sessions 下,类似 MongoDB 文档 |
| 增量导出 | 同 session 的 chats 累加,不重复创建 |
| UUID 匹配 | 按 UUID 判断是新建还是更新 |
| 版本控制 | version 字段支持格式演进 |
```

260
docs/memory-plan.md Normal file
View File

@@ -0,0 +1,260 @@
# hxclaw 聊天记忆体实现计划
## 概述
hxclaw 聊天记忆体是一个基于 libSQL (TursoDB) 的对话上下文管理系统,用于替代 picoclaw 原有的 memory.md 文件,实现更灵活、可控的会话历史管理。
**注意**:本计划文档已实现完成,详细功能请参考 `docs/discussion.md`
## 技术选型
| 组件 | 选型 | 说明 |
|------|------|------|
| 数据库 | libSQL (嵌入式) | 本地文件数据库 `~/.config/hxclaw/hxclaw.db` |
| 向量模型 | BAAI/bge-m3 | 1024 维,硅基流动 API |
| UUID | github.com/google/uuid | 生成唯一会话 ID |
| 第三方库 | go_modules/ | 本地化方案解决网络问题 |
## 数据库设计
### sessions 表
```sql
CREATE TABLE IF NOT EXISTS sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
uuid TEXT UNIQUE NOT NULL,
summary TEXT,
summary_embedding BLOB,
chat_ids TEXT,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL
);
```
### chats 表
```sql
CREATE TABLE IF NOT EXISTS chats (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id INTEGER NOT NULL,
user_input TEXT NOT NULL,
ai_replies TEXT,
summary TEXT,
summary_embedding BLOB,
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
FOREIGN KEY(session_id) REFERENCES sessions(id)
);
```
## 核心流程
1. **Session 管理**:自动创建(首次输入)+ 手动创建(`/new`
2. **消息保存**:在 AI 返回后调用 `SaveChat()` 保存到数据库
3. **查询命令**`/memory`, `/sessions`, `/new`
## 配置
- **启用**:默认启用
- **数据库路径**`~/.config/hxclaw/hxclaw.db`
- **用户配置**`~/.config/hxclaw/config.yml`
## 实现状态
| 功能 | 状态 |
|------|------|
| 数据库 CRUD | ✅ 完成 |
| 聊天记录保存 | ✅ 完成 |
| 命令支持 | ✅ 完成 |
| JSON 导出 | ✅ 完成 |
| 向量服务 | ⚠️ 框架完成,待完善 |
| 向量查询 | ⏳ 待实现 |
hxclaw 聊天记忆体是一个基于 TursoDB (libSQL) 的对话上下文管理系统,用于替代 picoclaw 原有的 memory.md 文件,实现更灵活、可控的会话历史管理。
核心目标:
1. 保留 picoclaw 的 memory.md 作为 AI 长期记忆
2. 新增对话记忆体作为会话维度的短期记忆
3. 支持向量检索和多场景查询
## 技术选型
| 组件 | 选型 | 说明 |
|------|------|------|
| 数据库 | libSQL (嵌入式) | 本地文件数据库,支持 JSON 导出 |
| 向量模型 | BAAI/bge-m3 | 1024 维,硅基流动 API |
| UUID | github.com/google/uuid | 生成唯一会话 ID |
| libSQL 驱动 | github.com/tursodatabase/go-libsql | CGO 需启用 |
## 数据库设计
### 表结构
```sql
-- sessions 表(会话维度)
CREATE TABLE IF NOT EXISTS sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
uuid TEXT UNIQUE NOT NULL, -- 外键引用用 UUID
summary TEXT, -- 会话压缩后的摘要
summary_embedding BLOB, -- 1024维向量二进制
chat_ids TEXT, -- JSON数组 ["id1","id2",...]
created_at INTEGER NOT NULL, -- Unix时间戳
updated_at INTEGER NOT NULL
);
-- chats 表(消息维度)
CREATE TABLE IF NOT EXISTS chats (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id INTEGER NOT NULL, -- 外键到 sessions.id
user_input TEXT NOT NULL, -- 用户输入
ai_replies TEXT, -- JSON数组 [{"role":"assistant","content":"..."},...]
summary TEXT, -- 单条消息摘要
summary_embedding BLOB, -- 1024维向量
created_at INTEGER NOT NULL,
updated_at INTEGER NOT NULL,
FOREIGN KEY(session_id) REFERENCES sessions(id)
);
-- 索引
CREATE INDEX IF NOT EXISTS idx_chats_session_id ON chats(session_id);
CREATE INDEX IF NOT EXISTS idx_sessions_uuid ON sessions(uuid);
```
### 数据模型
```go
// Session 会话记录
type Session struct {
ID int64 `json:"id"`
UUID string `json:"uuid"`
Summary string `json:"summary"`
SummaryEmbedding []byte `json:"-"`
ChatIDs []int64 `json:"chat_ids"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
// Chat 聊天记录
type Chat struct {
ID int64 `json:"id"`
SessionID int64 `json:"session_id"`
UserInput string `json:"user_input"`
AIReplies []string `json:"ai_replies"`
Summary string `json:"summary"`
SummaryEmbedding []byte `json:"-"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
```
## 核心流程
### 1. Session 管理
#### 自动开始(模式 A
- 用户首次输入内容时,检查是否存在活跃 Session
- 若无,则自动创建新 Session
#### 手动开始(模式 B
- 用户输入 `/new` 命令,强制创建新 Session
### 2. 消息处理流程
```
用户输入
[可选] 创建新 Session首次输入时
chats 表插入记录 (session_id, user_input, created_at)
AI 处理
AI 返回后:
1. 生成摘要 + 向量
2. chats 表更新 (ai_replies, summary, summary_embedding)
3. sessions 表更新 (chat_ids 追加, summary 压缩, summary_embedding 更新)
将 Session 摘要作为上下文注入 AI
```
### 3. 上下文注入
```
=== 当前会话摘要 ===
[最新摘要内容]
===
```
### 4. 查询场景4种
| 场景 | 用户意图 | 查询方式 |
|------|----------|----------|
| 1 | "之前聊过什么" | 查询最新 Session 的 summary |
| 2 | "某某某相关内容" | 向量搜索 top 5 |
| 3 | "某次谈论时的详情" | 定位 Session ID返回 summary |
| 4 | 同 Session 内其他相关内容 | session_id 过滤 + 向量搜索 |
## 模块设计
### 目录结构
```
cmd/hxclaw/internal/memory/
├── db.go # 数据库初始化和 CRUD 操作
├── model.go # 数据模型定义
├── vector.go # 向量服务(硅基流动 API
├── skill.go # 内置 Skill查询逻辑
└── export.go # 导出功能
```
## 配置项
`project.config.yml` 中新增:
```yaml
# 聊天记忆体配置
memory:
enabled: true # 启用开关
db_path: "./hxclaw.db" # 数据库路径
auto_session: true # 自动创建 Session
export_on_exit: true # 退出时导出
# 向量服务配置
vector:
api_key: "sk-xxx" # 硅基流动 API Key
base_url: "https://api.siliconflow.cn/v1"
model: "BAAI/bge-m3" # 向量模型
dimensions: 1024 # 向量维度
```
## 实现步骤
### 阶段一:基础设施
1. 新增依赖并测试连接go-libsql, google/uuid
2. 创建 `memory/model.go` - 数据模型
3. 创建 `memory/db.go` - CRUD 操作
### 阶段二:向量服务
4. 创建 `memory/vector.go` - 硅基流动 Embedding API
### 阶段三:核心逻辑
5. 修改 `main.go` - 集成 Session
6. 修改消息处理流程 - 存储和摘要
7. 创建 `memory/skill.go` - 查询逻辑
### 阶段四UI 和导出
8. 添加命令支持(`/memory`, `/sessions`
9. 创建 `memory/export.go` - JSON 导出
## 依赖
```bash
go get github.com/tursodatabase/go-libsql
go get github.com/google/uuid
go get github.com/sjzsdu/langchaingo-cn/llms/siliconflow
```
## 注意事项
1. **CGO 要求**`go-libsql` 需要 CGO 启用
2. **向量维度**BGE-M3 默认 1024 维
3. **摘要生成**:使用 AI 返回内容的前 N 字符作为摘要
4. **错误处理**:向量服务失败时降级为纯文本搜索

238
docs/picoclaw-research.md Normal file
View File

@@ -0,0 +1,238 @@
# picoclaw 技术研究报告
## 概述
本报告基于对 picoclaw v0.2.6 源代码的研究,详细分析其核心机制。
---
## 1. 系统架构
### 1.1 核心模块
```
picoclaw/
├── pkg/
│ ├── agent/ # AI 代理核心逻辑
│ ├── providers # LLM 提供者
│ ├── config/ # 配置管理
│ ├── tools/ # 工具注册与执行
│ ├── skills/ # Skill 加载器
│ ├── bus/ # 消息总线
│ └── channels/ # 消息通道
└── web/ # Web 界面
```
### 1.2 依赖关系
- **agent**:核心模块,依赖 providers、tools、skills、bus
- **providers**LLM API 调用OpenAI、Anthropic 等)
- **tools**工具执行exec、read_file、web_fetch 等)
- **skills**:通过 SKILL.md 加载技能定义
---
## 2. Skill 机制
### 2.1 加载机制
**位置**`pkg/skills/loader.go`
Skill 存储在三个位置,优先级:
1. `workspace/skills/` - 项目级
2. `~/.picoclaw/skills/` - 全局
3. 内置 skills 目录
每个 skill 必须是 `SKILL.md` 文件,包含:
- Frontmatter (YAML/JSON) 定义 `name``description`
- Markdown 主体内容(操作指导)
### 2.2 执行机制
**关键发现**Skill 本质是 Markdown 文档,不是可执行代码
AI 阅读 SKILL.md 后,调用实际工具执行任务:
```
加载 SKILL.md → AI 阅读 → 调用工具 → 执行结果
```
---
## 3. 工具执行机制
### 3.1 执行流程
**位置**`pkg/agent/loop.go:runTurn` (约 2332-2899 行)
```go
// 串行执行每个工具调用
for i, tc := range normalizedToolCalls {
toolName := tc.Name
toolArgs := cloneStringAnyMap(tc.Arguments)
// 执行工具
toolResult := ts.agent.Tools.ExecuteWithContext(
execCtx, toolName, toolArgs, ts.channel, ts.chatID, asyncCallback,
)
// 结果添加到消息历史
toolResultMsg := providers.Message{
Role: "tool",
Content: contentForLLM,
ToolCallID: toolCallID,
}
messages = append(messages, toolResultMsg)
}
```
### 3.2 关键特性
| 特性 | 说明 |
|------|------|
| 执行方式 | **串行执行**,非并行 |
| 结果收集 | 通过 `providers.Message` 添加到上下文 |
| 用户显示 | `ForUser` 字段非空时发送给用户 |
| 静默结果 | `SilentResult()` 不显示给用户,但发给 LLM |
### 3.3 工具结果标志
```go
// Silent: 不发送消息给用户,但发送给 LLM
Silent bool `json:"silent"`
// ResponseHandled: 工具已处理响应,不生成独立消息
ResponseHandled bool `json:"response_handled,omitempty"`
// IsError: 标记为错误结果
IsError bool `json:"is_error,omitempty"`
```
---
## 4. 消息处理
### 4.1 消息总线
**位置**`pkg/bus/bus.go`
```
用户输入 → AgentLoop.ProcessDirect() → AI 处理 → 工具执行 ←
bus.PublishOutbound() → 输出
```
### 4.2 消息类型
| 类型 | 说明 |
|------|------|
| InboundMessage | 用户输入 |
| OutboundMessage | AI 输出 |
| ToolResult | 工具结果 |
---
## 5. 异步执行
### 5.1 AsyncExecutor 接口
**位置**`pkg/tools/base.go:107`
```go
type AsyncExecutor interface {
Tool
ExecuteAsync(ctx context.Context, args map[string]any, cb AsyncCallback) *ToolResult
}
```
### 5.2 使用方式
```go
// 执行时传入回调函数
toolResult := ts.agent.Tools.ExecuteWithContext(
execCtx, toolName, toolArgs, ts.channel, ts.chatID,
asyncCallback, // 异步回调
)
```
---
## 6. TTS 工具分析
### 6.1 文件位置
- 主文件:`pkg/tools/tts_send.go`
- TTS 提供者:`pkg/audio/tts/tts.go`
### 6.2 实现方式
1. 通过 `SendTTSTool` 执行 TTS 合成
2. 调用 `tts.SynthesizeAndStore()` 生成音频
3. 返回文件路径或直接播放
### 6.3 已知问题
| 问题 | 原因 |
|------|------|
| 播放内容不一致 | 异步回调竞争 |
| 结果不显示 | 使用了 `SilentResult()` |
| 多条记录只显示一条 | 串行执行中的状态竞争 |
---
## 7. 配置系统
### 7.1 配置文件
- 项目级:`config.yaml`
- 用户级:`~/.picoclaw/config.json`
- 环境变量:`PICOCLAW_*` 前缀
### 7.2 配置结构
```go
type Config struct {
Agents AgentsConfig `json:"agents"`
Tools ToolsConfig `json:"tools"`
Channels ChannelsConfig `json:"channels"`
Voice VoiceConfig `json:"voice"`
}
```
---
## 8. hxclaw 集成方式
### 8.1 复用策略
hxclaw 通过 Go replace 机制复用 picoclaw
```go
// go.mod
replace github.com/sipeed/picoclaw => ./path/to/picoclaw
```
### 8.2 核心依赖
- `pkg/agent` - AI 代理核心
- `pkg/providers` - LLM 提供者
- `pkg/config` - 配置加载
- `pkg/bus` - 消息总线
---
## 9. 总结
| 模块 | 机制 | 阻塞 |
|------|------|------|
| Skill | Markdown 文档 | 否 |
| 工具 | 串行执行 | 是 |
| 异步工具 | 回调机制 | 可选 |
| 消息总线 | 非阻塞 | 否 |
---
## 10. 建议
1. **避免阻塞**:长时间任务使用 AsyncExecutor
2. **结果显示**:检查 Silent/ResponseHandled 标志
3. **并发控制**:使用 SubTurn 的 concurrencySem