docs: 根据最新代码架构更新 README
- 更新命令列表:移除已废弃的 listen/service,新增 daemon/task/tools - 重写架构描述:从旧版单进程改为三消费者 + 公平队列架构 - 更新源码结构:新增 queue/、channel/ 模块,工具抽象层 - 补充完整工具清单(24 个内置工具) - 更新配置项、数据库表、依赖列表
This commit is contained in:
@@ -12,26 +12,29 @@ export DATABASE_URL="postgresql://..." # PostgreSQL 可选
|
|||||||
# 2. 扫码登录微信
|
# 2. 扫码登录微信
|
||||||
ias login
|
ias login
|
||||||
|
|
||||||
# 3. 启动 AI 自动回复
|
# 3. 启动守护进程(AI 自动回复)
|
||||||
ias listen --llm
|
ias daemon
|
||||||
|
|
||||||
# 4. 后台运行(配合 systemd)
|
# 4. 后台运行(配合 systemd)
|
||||||
ias service
|
ias daemon --log-file
|
||||||
```
|
```
|
||||||
|
|
||||||
## 命令一览
|
## 命令一览
|
||||||
|
|
||||||
| 命令 | 说明 |
|
| 命令 | 说明 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| `ias login` | 扫码登录微信,认证信息存入 PostgreSQL / 本地文件 |
|
| `ias login` | 扫码登录微信,认证信息存入 PostgreSQL |
|
||||||
| `ias listen --llm` | 启动长轮询 + AI 自动回复 |
|
| `ias daemon` | 守护进程模式(主运行模式,长轮询 + 三消费者架构) |
|
||||||
| `ias listen --echo` | 启动长轮询 + 原样回显 |
|
| `ias daemon --log-file` | 守护进程 + 文件日志(配合 systemd) |
|
||||||
| `ias listen` | 仅监听,不做回复 |
|
|
||||||
| `ias send --to <id> --text <msg>` | 手动发送消息 |
|
| `ias send --to <id> --text <msg>` | 手动发送消息 |
|
||||||
| `ias whoami` | 查看登录状态 |
|
| `ias whoami` | 查看登录状态 |
|
||||||
| `ias usage` | Token 用量统计(默认 7 天) |
|
| `ias usage` | Token 用量统计(默认 7 天) |
|
||||||
| `ias service` | 后台服务模式(日志 + systemd) |
|
| `ias task list` | 列出所有定时任务 |
|
||||||
| `ias daemon` | 守护进程模式(daemon + worker 分离架构) |
|
| `ias task add --name ...` | 添加定时任务 |
|
||||||
|
| `ias task update <uuid>` | 更新定时任务 |
|
||||||
|
| `ias task delete <uuid>` | 删除定时任务 |
|
||||||
|
| `ias task toggle <uuid>` | 启用/禁用定时任务 |
|
||||||
|
| `ias tools` | 列出所有可用的 LLM 工具 |
|
||||||
| `ias tool datetime` | 获取当前时间 |
|
| `ias tool datetime` | 获取当前时间 |
|
||||||
| `ias tool weather <城市>` | 查询天气 |
|
| `ias tool weather <城市>` | 查询天气 |
|
||||||
| `ias tool search <关键词>` | 联网搜索 |
|
| `ias tool search <关键词>` | 联网搜索 |
|
||||||
@@ -45,7 +48,8 @@ ias service
|
|||||||
|------|------|------|
|
|------|------|------|
|
||||||
| `DEEPSEEK_API_KEY` | ✅ | DeepSeek API 密钥 |
|
| `DEEPSEEK_API_KEY` | ✅ | DeepSeek API 密钥 |
|
||||||
| `DEEPSEEK_MODEL` | — | 模型名,默认 `deepseek-v4-flash` |
|
| `DEEPSEEK_MODEL` | — | 模型名,默认 `deepseek-v4-flash` |
|
||||||
| `DATABASE_URL` | — | PostgreSQL 连接串,无则降级文件存储 |
|
| `DEEPSEEK_BASE_URL` | — | API 地址,默认 `https://api.deepseek.com/v1` |
|
||||||
|
| `DATABASE_URL` | ✅ | PostgreSQL 连接串 |
|
||||||
| `WEIXIN_LLM_SYSTEM_PROMPT` | — | 自定义系统提示词 |
|
| `WEIXIN_LLM_SYSTEM_PROMPT` | — | 自定义系统提示词 |
|
||||||
| `TAVILY_API_KEY` | — | Tavily 搜索 API Key |
|
| `TAVILY_API_KEY` | — | Tavily 搜索 API Key |
|
||||||
| `QWEATHER_API_HOST` | — | 和风天气 API 地址 |
|
| `QWEATHER_API_HOST` | — | 和风天气 API 地址 |
|
||||||
@@ -59,114 +63,140 @@ ias service
|
|||||||
## 架构
|
## 架构
|
||||||
|
|
||||||
```
|
```
|
||||||
┌─────────────────────────────────────────────────┐
|
┌──────────────────────────────────────────────────────────────┐
|
||||||
│ iAs CLI │
|
│ iAs CLI (main.rs) │
|
||||||
│ main.rs → clap 子命令路由 │
|
│ clap 子命令路由 → login / daemon / send / tool / task / ... │
|
||||||
├─────────────────────────────────────────────────┤
|
├──────────────────────────────────────────────────────────────┤
|
||||||
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
|
│ Daemon (daemon.rs) │
|
||||||
│ │ WeChat │ │ LLM │ │ Tools │ │
|
│ 持有 WeChat 长连接 + 数据库 + 审批管理器 + 长期记忆 │
|
||||||
│ │ 长轮询 │ │ DeepSeek │ │ 内置工具 │ │
|
├──────────────────────────────────────────────────────────────┤
|
||||||
│ │ HTTP API │ │ 流式对话 │ │ 审批管理 │ │
|
│ MessageQueue (公平轮转队列) │
|
||||||
│ └────┬─────┘ └────┬─────┘ └──────┬────────┘ │
|
│ 按用户轮转出队,防止一个用户刷屏饿死其他人 │
|
||||||
│ │ │ │ │
|
├────────────────┬────────────────┬───────────────────────────┤
|
||||||
│ ┌────┴──────────────┴───────────────┴────────┐ │
|
│ LLM Consumer │ Tool Consumer │ Send Consumer │
|
||||||
│ │ Context / Memory │ │
|
│ Conversation │ execute_tool │ WeChatClient.send_text() │
|
||||||
│ │ ChatSession · Token Budget · 摘要压缩 │ │
|
│ DeepSeek 流式 │ ApprovalMgr │ 入库 chat_records │
|
||||||
│ │ MemoryStore · 长期记忆 │ │
|
│ 上下文管理 │ 内置工具执行 │ │
|
||||||
│ └──────────────────────┬──────────────────────┘ │
|
├────────────────┴────────────────┴───────────────────────────┤
|
||||||
│ │ │
|
│ Context / Memory │
|
||||||
│ ┌──────────────────────┴──────────────────────┐ │
|
│ ChatSession · Token Budget · 摘要压缩 · MemoryStore │
|
||||||
│ │ Database (PostgreSQL) │ │
|
├──────────────────────────────────────────────────────────────┤
|
||||||
│ │ auth · chat_records · llm_usage │ │
|
│ Database (PostgreSQL) │
|
||||||
│ │ user_memories · pending_approvals │ │
|
│ app_state · chat_records · llm_usage · user_memories │
|
||||||
│ │ session_summaries · scheduled_tasks │ │
|
│ pending_approvals · session_summaries · scheduled_tasks │
|
||||||
│ └─────────────────────────────────────────────┘ │
|
└──────────────────────────────────────────────────────────────┘
|
||||||
├─────────────────────────────────────────────────┤
|
|
||||||
│ Daemon / Worker IPC (可选) │
|
|
||||||
│ Unix Domain Socket · 帧协议 · 进程隔离 │
|
|
||||||
└─────────────────────────────────────────────────┘
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 核心数据流
|
## 核心数据流
|
||||||
|
|
||||||
```
|
```
|
||||||
微信消息到达
|
微信消息到达
|
||||||
→ 保存 inbound chat_records
|
→ 存 inbound chat_records
|
||||||
→ 用户切换:加载历史 + 记忆
|
→ enqueue PipelineMessage → MessageQueue 公平轮转
|
||||||
→ 构建 LLM 上下文(token budget + 摘要注入)
|
→ LLM Consumer 消费
|
||||||
→ Conversation.chat_with_tools()
|
→ 加载用户历史 + 记忆 + 摘要
|
||||||
├── LLM 流式回复
|
→ 构建 LLM 上下文(token budget + 摘要注入)
|
||||||
├── 工具调用 → query_capabilities / call_capability
|
→ Conversation.chat_with_tools()
|
||||||
│ ├── 上下文工具:read_memories / write_memory / read_summaries
|
├── LLM 流式回复
|
||||||
│ ├── 内置工具:datetime / weather / search / memos / fetch_page / amap
|
├── 工具调用 → enqueue ToolCall → Tool Consumer
|
||||||
│ └── High 风险工具 → 审批流程
|
│ ├── 高风险工具 → ApprovalManager 审批流程
|
||||||
└── 工具结果注入对话 → LLM 继续
|
│ └── 执行工具 → 结果回喂 LLM
|
||||||
→ 保存 outbound chat_records + LLM usage
|
└── 最终回复 → enqueue LLMReply → Send Consumer
|
||||||
→ 微信发送回复
|
→ Send Consumer 发送微信消息 + 入库 outbound chat_records
|
||||||
```
|
```
|
||||||
|
|
||||||
## 源码结构
|
## 源码结构
|
||||||
|
|
||||||
```
|
```
|
||||||
src/
|
src/
|
||||||
├── main.rs CLI 入口 + 命令实现 + 监听循环 + 工具执行器
|
├── main.rs CLI 入口 + 命令实现
|
||||||
├── cli.rs clap 子命令定义(login/listen/send/tool 等)
|
├── cli.rs clap 子命令定义(login/daemon/send/tool/task/tools)
|
||||||
├── logger.rs 日志初始化(终端 + 文件滚动)
|
├── logger.rs 日志初始化(终端 + 文件日滚)
|
||||||
├── state.rs 本地文件状态(auth.json / runtime.json,无DB时降级)
|
├── daemon.rs 守护进程核心(长轮询 + 三消费者 + 调度器)
|
||||||
├── scheduler.rs 定时任务调度器
|
├── scheduler.rs 定时任务调度器(每 5s 轮询到期任务)
|
||||||
├── context/ 上下文管理
|
├── channel/
|
||||||
│ ├── types.rs ChatSession(checkpoint/messages/summaries)
|
│ └── mod.rs ChannelId(平台+用户标识)、IncomingMessage
|
||||||
│ ├── builder.rs Token budget 估算 + 上下文构建 + 摘要触发
|
├── queue/
|
||||||
│ └── tools.rs MemoryStore(HashMap<user_id, Vec<mem>>)
|
│ ├── message_queue.rs 公平轮转队列(按用户轮转出队)
|
||||||
├── db/ 数据库
|
│ └── runner.rs QueueRunner(出队 → 按类型路由到消费者)
|
||||||
|
├── context/
|
||||||
|
│ ├── types.rs ChatSession(消息历史、摘要、checkpoint、token budget)
|
||||||
|
│ ├── builder.rs Token 估算、上下文构建、摘要触发
|
||||||
|
│ └── tools.rs MemoryStore(长期记忆管理器)
|
||||||
|
├── db/
|
||||||
│ ├── mod.rs Database 连接池 + 迁移
|
│ ├── mod.rs Database 连接池 + 迁移
|
||||||
│ └── models.rs CRUD(auth/chat/usage/summary)
|
│ └── models.rs CRUD(auth/chat/usage/summary/memory/task)
|
||||||
├── llm/ 对话系统
|
├── llm/
|
||||||
│ ├── types.rs Message / Role / ToolCall / StreamChunk / Usage
|
│ ├── types.rs Message / Role / ToolCall / StreamChunk / Usage
|
||||||
│ ├── provider.rs LlmProvider trait + SSE 解析
|
│ ├── provider.rs LlmProvider trait + SSE 解析 + 工厂函数
|
||||||
│ ├── deepseek.rs DeepSeek 流式客户端
|
│ ├── deepseek.rs DeepSeek 流式客户端实现
|
||||||
│ └── conversation.rs Conversation(chat + chat_with_tools 工具循环)
|
│ └── conversation.rs Conversation(chat + chat_with_tools 工具循环)
|
||||||
├── tools/ 工具系统
|
├── tools/
|
||||||
│ ├── types.rs RiskLevel / SkillSpec / SkillResult / ExecutionContext
|
│ ├── types.rs RiskLevel / SkillSpec / SkillResult / ExecutionContext
|
||||||
│ ├── builtin.rs BuiltinRegistry 路由
|
│ ├── tool.rs Tool trait + ToolRegistry(统一注册表)
|
||||||
|
│ ├── api_tool.rs ApiTool(Rust 闭包实现的工具)
|
||||||
|
│ ├── shell_tool.rs ShellTool(shell 命令执行的工具)
|
||||||
|
│ ├── stdio_tool.rs StdioTool(子进程 stdin/stdout 通信的工具)
|
||||||
|
│ ├── builtin.rs BuiltinRegistry(旧接口兼容层)
|
||||||
│ ├── approval.rs ApprovalManager(确认码 + oneshot 通道)
|
│ ├── approval.rs ApprovalManager(确认码 + oneshot 通道)
|
||||||
|
│ ├── mod.rs 全局注册表 + unpack_call_params + build_capability_guide
|
||||||
│ └── builtins/ 内置工具实现
|
│ └── builtins/ 内置工具实现
|
||||||
│ ├── datetime.rs 日期时间
|
│ ├── datetime.rs 日期时间
|
||||||
│ ├── weather.rs 和风天气(JWT + reqwest)
|
│ ├── weather.rs 和风天气(实时/每日预报/逐时预报)
|
||||||
│ ├── web_search.rs Tavily 搜索
|
│ ├── web_search.rs Tavily 搜索
|
||||||
│ ├── fetch_page.rs 网页抓取
|
│ ├── fetch_page.rs 网页抓取(可读性算法)
|
||||||
│ ├── memos.rs 备忘录
|
│ ├── memos.rs 备忘录(文件存储,增删查)
|
||||||
│ └── amap.rs 高德地图(POI/地理编码/路径/旅游规划)
|
│ ├── amap.rs 高德地图(POI/地理编码/路径规划/旅游规划/地图链接)
|
||||||
├── wechat/ 微信通道
|
│ └── scheduled_task.rs 定时任务管理(增删改查切换)
|
||||||
│ ├── types.rs iLink API 协议类型
|
└── wechat/
|
||||||
│ └── client.rs HTTP 客户端(login/poll/send/notify)
|
├── types.rs iLink API 协议类型
|
||||||
├── daemon.rs 守护进程(持有 WeChat + DB,spawn worker)
|
└── client.rs HTTP 客户端(login/poll/send/notify)
|
||||||
├── worker.rs Worker 进程(无状态 LLM 执行)
|
|
||||||
└── ipc.rs Unix Domain Socket 帧协议
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 工具系统
|
## 工具系统
|
||||||
|
|
||||||
### LLM 可见工具
|
### 架构设计(两层元工具)
|
||||||
|
|
||||||
| 工具名 | 说明 |
|
LLM 不直接感知每个具体工具,而是通过两个**元工具**间接调用:
|
||||||
|--------|------|
|
|
||||||
| `query_capabilities` | 列出所有可用工具及参数说明 |
|
1. **`query_capabilities`** — 列出所有可用工具的名称、描述、参数格式
|
||||||
| `call_capability` | 按名称调用任意工具 |
|
2. **`call_capability`** — 按名称调用工具,参数通过 JSON 传递
|
||||||
| `read_memories` | 读取用户长期记忆 |
|
|
||||||
| `write_memory` | 写入长期记忆 |
|
### 工具抽象
|
||||||
| `read_summaries` | 读取历史会话摘要 |
|
|
||||||
|
所有工具分为三种类型:
|
||||||
|
|
||||||
|
| 类型 | 说明 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| `ApiTool` | Rust 闭包实现的工具(HTTP API / 本地计算 / 文件 I/O) | 天气、搜索、高德地图 |
|
||||||
|
| `ShellTool` | 通过 shell 命令执行的工具 | 定时任务、系统命令 |
|
||||||
|
| `StdioTool` | 通过子进程 stdin/stdout 通信的工具 | 外部脚本、可执行程序 |
|
||||||
|
|
||||||
### 内置工具
|
### 内置工具
|
||||||
|
|
||||||
| 工具 | 风险 | 说明 |
|
| 工具名 | 风险 | 说明 |
|
||||||
|------|------|------|
|
|--------|------|------|
|
||||||
| `get_current_datetime` | Low | 获取北京时间 |
|
| `get_current_datetime` | Low | 获取北京时间 |
|
||||||
| `query_weather` | Low | 和风天气查询 |
|
| `weather_now` | Low | 实时天气(和风天气) |
|
||||||
|
| `weather_forecast` | Low | 每日天气预报 |
|
||||||
|
| `weather_hourly` | Low | 逐时天气预报 |
|
||||||
| `web_search` | Low | Tavily 联网搜索 |
|
| `web_search` | Low | Tavily 联网搜索 |
|
||||||
| `fetch_page` | Low | 网页正文提取 |
|
| `fetch_page` | Low | 网页正文提取(可读性算法) |
|
||||||
| `manage_memos` | Low | 备忘录增删查 |
|
| `memos_list` | Low | 列出备忘录 |
|
||||||
| `amap_*` | Low | 高德地图系列 |
|
| `memos_add` | Low | 添加备忘录 |
|
||||||
|
| `memos_get` | Low | 查看指定备忘录 |
|
||||||
|
| `memos_delete` | Low | 删除备忘录 |
|
||||||
|
| `amap_poi_search` | Low | POI 搜索 + 周边搜索 |
|
||||||
|
| `amap_geocode` | Low | 地理编码(地址→坐标) |
|
||||||
|
| `amap_reverse_geocode` | Low | 逆地理编码(坐标→地址) |
|
||||||
|
| `amap_route_plan` | Low | 路径规划(步行/驾车/骑行/电动车/公交) |
|
||||||
|
| `amap_travel_plan` | Low | 智能旅游规划 |
|
||||||
|
| `amap_map_link` | Low | 生成地图可视化链接 |
|
||||||
|
| `scheduled_task_list` | Low | 列出定时任务 |
|
||||||
|
| `scheduled_task_add` | Low | 添加定时任务 |
|
||||||
|
| `scheduled_task_update` | Low | 更新定时任务 |
|
||||||
|
| `scheduled_task_delete` | Low | 删除定时任务 |
|
||||||
|
| `scheduled_task_toggle` | Low | 启用/禁用定时任务 |
|
||||||
|
|
||||||
### 审批流程
|
### 审批流程
|
||||||
|
|
||||||
@@ -191,6 +221,28 @@ LLM 不感知确认码和审批过程,只看到最终的执行结果。
|
|||||||
- **长期记忆**:LLM 按需通过 `read_memories` / `write_memory` 读写
|
- **长期记忆**:LLM 按需通过 `read_memories` / `write_memory` 读写
|
||||||
- **用户隔离**:切换用户时清空 session,按需加载新用户历史
|
- **用户隔离**:切换用户时清空 session,按需加载新用户历史
|
||||||
|
|
||||||
|
## 消息队列(三消费者架构)
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────┐
|
||||||
|
enqueue ──────→ │ MessageQueue │ ← 公平轮转(按用户)
|
||||||
|
└──────┬───────┘
|
||||||
|
│ dequeue
|
||||||
|
▼
|
||||||
|
┌──────────────┐
|
||||||
|
│ QueueRunner │ ← 路由循环
|
||||||
|
└──┬───┬───┬──┘
|
||||||
|
┌─┘ │ └─┐
|
||||||
|
▼ ▼ ▼
|
||||||
|
LLM Tool Send
|
||||||
|
Consumer Consumer Consumer
|
||||||
|
```
|
||||||
|
|
||||||
|
消息路由规则:
|
||||||
|
- `UserMessage` / `ToolResult` / `ScheduledTask` → **LLM Consumer**
|
||||||
|
- `ToolCall` / `ApprovalRequest` → **Tool Consumer**
|
||||||
|
- `LLMReply` → **Send Consumer**
|
||||||
|
|
||||||
## 数据库表
|
## 数据库表
|
||||||
|
|
||||||
| 表 | 用途 |
|
| 表 | 用途 |
|
||||||
@@ -201,7 +253,7 @@ LLM 不感知确认码和审批过程,只看到最终的执行结果。
|
|||||||
| `user_memories` | 长期记忆(按 user_id) |
|
| `user_memories` | 长期记忆(按 user_id) |
|
||||||
| `pending_approvals` | 待审批记录(SHA-256 确认码) |
|
| `pending_approvals` | 待审批记录(SHA-256 确认码) |
|
||||||
| `session_summaries` | 会话摘要 |
|
| `session_summaries` | 会话摘要 |
|
||||||
| `scheduled_tasks` | 定时任务 |
|
| `scheduled_tasks` | 定时任务(支持 model/system 类型) |
|
||||||
|
|
||||||
## 部署
|
## 部署
|
||||||
|
|
||||||
@@ -215,10 +267,10 @@ sudo systemctl enable --now ias
|
|||||||
|
|
||||||
### 天气 API 密钥
|
### 天气 API 密钥
|
||||||
|
|
||||||
将和风天气 Ed25519 密钥对放入 `qweather/` 目录:
|
将和风天气 Ed25519 密钥对放入 `~/.ias/qweather/` 目录:
|
||||||
|
|
||||||
```
|
```
|
||||||
qweather/
|
~/.ias/qweather/
|
||||||
├── ed25519-private.pem
|
├── ed25519-private.pem
|
||||||
└── ed25519-public.pem
|
└── ed25519-public.pem
|
||||||
```
|
```
|
||||||
@@ -236,5 +288,11 @@ qweather/
|
|||||||
| tracing | 结构化日志 |
|
| tracing | 结构化日志 |
|
||||||
| async-trait | 异步 trait |
|
| async-trait | 异步 trait |
|
||||||
| ed25519-dalek | 天气 API JWT 签名 |
|
| ed25519-dalek | 天气 API JWT 签名 |
|
||||||
| scraper | 网页正文提取 |
|
| scraper | 网页正文提取(可读性算法) |
|
||||||
| sha2 / hex / rand | 审批确认码加密 |
|
| sha2 / hex / rand | 审批确认码加密 |
|
||||||
|
| uuid | 会话/任务唯一标识 |
|
||||||
|
| base64 | Base64 编码 |
|
||||||
|
| qrcode / image | 二维码生成 |
|
||||||
|
| rustyline / dialoguer / console | 终端交互 |
|
||||||
|
| futures-util | 流式处理工具 |
|
||||||
|
| dirs | 系统目录路径 |
|
||||||
|
|||||||
Reference in New Issue
Block a user