Files
iAs/README.md
wunianxiao 52f2593464 docs: 根据最新代码架构更新 README
- 更新命令列表:移除已废弃的 listen/service,新增 daemon/task/tools
- 重写架构描述:从旧版单进程改为三消费者 + 公平队列架构
- 更新源码结构:新增 queue/、channel/ 模块,工具抽象层
- 补充完整工具清单(24 个内置工具)
- 更新配置项、数据库表、依赖列表
2026-06-17 10:40:10 +08:00

299 lines
13 KiB
Markdown
Raw Permalink 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.
# iAs — 微信 AI 智能助手
Rust 实现的微信 iLink Bot,支持 DeepSeek AI 自动回复、内置工具调用、审批确认、定时任务和长期记忆。
## 快速开始
```bash
# 1. 配置环境变量(或创建 .env 文件)
export DEEPSEEK_API_KEY="sk-xxx"
export DATABASE_URL="postgresql://..." # PostgreSQL 可选
# 2. 扫码登录微信
ias login
# 3. 启动守护进程(AI 自动回复)
ias daemon
# 4. 后台运行(配合 systemd
ias daemon --log-file
```
## 命令一览
| 命令 | 说明 |
|------|------|
| `ias login` | 扫码登录微信,认证信息存入 PostgreSQL |
| `ias daemon` | 守护进程模式(主运行模式,长轮询 + 三消费者架构) |
| `ias daemon --log-file` | 守护进程 + 文件日志(配合 systemd) |
| `ias send --to <id> --text <msg>` | 手动发送消息 |
| `ias whoami` | 查看登录状态 |
| `ias usage` | Token 用量统计(默认 7 天) |
| `ias task list` | 列出所有定时任务 |
| `ias task add --name ...` | 添加定时任务 |
| `ias task update <uuid>` | 更新定时任务 |
| `ias task delete <uuid>` | 删除定时任务 |
| `ias task toggle <uuid>` | 启用/禁用定时任务 |
| `ias tools` | 列出所有可用的 LLM 工具 |
| `ias tool datetime` | 获取当前时间 |
| `ias tool weather <城市>` | 查询天气 |
| `ias tool search <关键词>` | 联网搜索 |
| `ias tool fetch <URL>` | 提取网页正文 |
| `ias tool memos list/add/delete` | 管理备忘录 |
| `ias tool amap poi-search/geocode/route-plan/travel-plan` | 高德地图服务 |
## 配置(环境变量)
| 变量 | 必须 | 说明 |
|------|------|------|
| `DEEPSEEK_API_KEY` | ✅ | DeepSeek API 密钥 |
| `DEEPSEEK_MODEL` | — | 模型名,默认 `deepseek-v4-flash` |
| `DEEPSEEK_BASE_URL` | — | API 地址,默认 `https://api.deepseek.com/v1` |
| `DATABASE_URL` | ✅ | PostgreSQL 连接串 |
| `WEIXIN_LLM_SYSTEM_PROMPT` | — | 自定义系统提示词 |
| `TAVILY_API_KEY` | — | Tavily 搜索 API Key |
| `QWEATHER_API_HOST` | — | 和风天气 API 地址 |
| `QWEATHER_JWT_KEY_ID` | — | 和风天气 JWT Key ID |
| `QWEATHER_JWT_PROJECT_ID` | — | 和风天气项目 ID |
| `QWEATHER_JWT_PRIVATE_KEY_FILE` | — | 和风天气 Ed25519 私钥路径 |
| `AMAP_WEBSERVICE_KEY` | — | 高德地图 Web 服务 Key(或 `AMAP_KEY` |
加载顺序:`./.env``~/.ias/.env` → 环境变量
## 架构
```
┌──────────────────────────────────────────────────────────────┐
│ iAs CLI (main.rs) │
│ clap 子命令路由 → login / daemon / send / tool / task / ... │
├──────────────────────────────────────────────────────────────┤
│ Daemon (daemon.rs) │
│ 持有 WeChat 长连接 + 数据库 + 审批管理器 + 长期记忆 │
├──────────────────────────────────────────────────────────────┤
│ MessageQueue (公平轮转队列) │
│ 按用户轮转出队,防止一个用户刷屏饿死其他人 │
├────────────────┬────────────────┬───────────────────────────┤
│ LLM Consumer │ Tool Consumer │ Send Consumer │
│ Conversation │ execute_tool │ WeChatClient.send_text() │
│ DeepSeek 流式 │ ApprovalMgr │ 入库 chat_records │
│ 上下文管理 │ 内置工具执行 │ │
├────────────────┴────────────────┴───────────────────────────┤
│ Context / Memory │
│ ChatSession · Token Budget · 摘要压缩 · MemoryStore │
├──────────────────────────────────────────────────────────────┤
│ Database (PostgreSQL) │
│ app_state · chat_records · llm_usage · user_memories │
│ pending_approvals · session_summaries · scheduled_tasks │
└──────────────────────────────────────────────────────────────┘
```
## 核心数据流
```
微信消息到达
→ 存 inbound chat_records
→ enqueue PipelineMessage → MessageQueue 公平轮转
→ LLM Consumer 消费
→ 加载用户历史 + 记忆 + 摘要
→ 构建 LLM 上下文(token budget + 摘要注入)
→ Conversation.chat_with_tools()
├── LLM 流式回复
├── 工具调用 → enqueue ToolCall → Tool Consumer
│ ├── 高风险工具 → ApprovalManager 审批流程
│ └── 执行工具 → 结果回喂 LLM
└── 最终回复 → enqueue LLMReply → Send Consumer
→ Send Consumer 发送微信消息 + 入库 outbound chat_records
```
## 源码结构
```
src/
├── main.rs CLI 入口 + 命令实现
├── cli.rs clap 子命令定义(login/daemon/send/tool/task/tools
├── logger.rs 日志初始化(终端 + 文件日滚)
├── daemon.rs 守护进程核心(长轮询 + 三消费者 + 调度器)
├── scheduler.rs 定时任务调度器(每 5s 轮询到期任务)
├── channel/
│ └── mod.rs ChannelId(平台+用户标识)、IncomingMessage
├── queue/
│ ├── message_queue.rs 公平轮转队列(按用户轮转出队)
│ └── runner.rs QueueRunner(出队 → 按类型路由到消费者)
├── context/
│ ├── types.rs ChatSession(消息历史、摘要、checkpoint、token budget
│ ├── builder.rs Token 估算、上下文构建、摘要触发
│ └── tools.rs MemoryStore(长期记忆管理器)
├── db/
│ ├── mod.rs Database 连接池 + 迁移
│ └── models.rs CRUDauth/chat/usage/summary/memory/task
├── llm/
│ ├── types.rs Message / Role / ToolCall / StreamChunk / Usage
│ ├── provider.rs LlmProvider trait + SSE 解析 + 工厂函数
│ ├── deepseek.rs DeepSeek 流式客户端实现
│ └── conversation.rs Conversationchat + chat_with_tools 工具循环)
├── tools/
│ ├── types.rs RiskLevel / SkillSpec / SkillResult / ExecutionContext
│ ├── tool.rs Tool trait + ToolRegistry(统一注册表)
│ ├── api_tool.rs ApiToolRust 闭包实现的工具)
│ ├── shell_tool.rs ShellToolshell 命令执行的工具)
│ ├── stdio_tool.rs StdioTool(子进程 stdin/stdout 通信的工具)
│ ├── builtin.rs BuiltinRegistry(旧接口兼容层)
│ ├── approval.rs ApprovalManager(确认码 + oneshot 通道)
│ ├── mod.rs 全局注册表 + unpack_call_params + build_capability_guide
│ └── builtins/ 内置工具实现
│ ├── datetime.rs 日期时间
│ ├── weather.rs 和风天气(实时/每日预报/逐时预报)
│ ├── web_search.rs Tavily 搜索
│ ├── fetch_page.rs 网页抓取(可读性算法)
│ ├── memos.rs 备忘录(文件存储,增删查)
│ ├── amap.rs 高德地图(POI/地理编码/路径规划/旅游规划/地图链接)
│ └── scheduled_task.rs 定时任务管理(增删改查切换)
└── wechat/
├── types.rs iLink API 协议类型
└── client.rs HTTP 客户端(login/poll/send/notify
```
## 工具系统
### 架构设计(两层元工具)
LLM 不直接感知每个具体工具,而是通过两个**元工具**间接调用:
1. **`query_capabilities`** — 列出所有可用工具的名称、描述、参数格式
2. **`call_capability`** — 按名称调用工具,参数通过 JSON 传递
### 工具抽象
所有工具分为三种类型:
| 类型 | 说明 | 示例 |
|------|------|------|
| `ApiTool` | Rust 闭包实现的工具(HTTP API / 本地计算 / 文件 I/O) | 天气、搜索、高德地图 |
| `ShellTool` | 通过 shell 命令执行的工具 | 定时任务、系统命令 |
| `StdioTool` | 通过子进程 stdin/stdout 通信的工具 | 外部脚本、可执行程序 |
### 内置工具
| 工具名 | 风险 | 说明 |
|--------|------|------|
| `get_current_datetime` | Low | 获取北京时间 |
| `weather_now` | Low | 实时天气(和风天气) |
| `weather_forecast` | Low | 每日天气预报 |
| `weather_hourly` | Low | 逐时天气预报 |
| `web_search` | Low | Tavily 联网搜索 |
| `fetch_page` | Low | 网页正文提取(可读性算法) |
| `memos_list` | 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 | 启用/禁用定时任务 |
### 审批流程
High 风险工具需要用户微信确认:
```
LLM 调用 High 工具
→ 生成 6 位确认码 → SHA-256 入库
→ 微信发送确认消息(含确认码)
→ 等待用户回复(最多 300s,3 次重试)
→ 匹配成功 → 执行工具 → 返回结果
→ 匹配失败 / 超时 → 返回拒绝信息
```
LLM 不感知确认码和审批过程,只看到最终的执行结果。
## 上下文管理
- **Token Budget**28K tokens,中/英文字符估算
- **Checkpoint**:摘要压缩点,之前的消息已压缩,之后完整保留
- **摘要触发**token 溢出(overflow)或 12h 空闲(timeout
- **长期记忆**LLM 按需通过 `read_memories` / `write_memory` 读写
- **用户隔离**:切换用户时清空 session,按需加载新用户历史
## 消息队列(三消费者架构)
```
┌──────────────┐
enqueue ──────→ │ MessageQueue │ ← 公平轮转(按用户)
└──────┬───────┘
│ dequeue
┌──────────────┐
│ QueueRunner │ ← 路由循环
└──┬───┬───┬──┘
┌─┘ │ └─┐
▼ ▼ ▼
LLM Tool Send
Consumer Consumer Consumer
```
消息路由规则:
- `UserMessage` / `ToolResult` / `ScheduledTask`**LLM Consumer**
- `ToolCall` / `ApprovalRequest`**Tool Consumer**
- `LLMReply`**Send Consumer**
## 数据库表
| 表 | 用途 |
|----|------|
| `app_state` | 认证信息 KV 存储 |
| `chat_records` | 收发消息记录(message_id 去重) |
| `llm_usage` | Token 用量统计(含缓存命中率) |
| `user_memories` | 长期记忆(按 user_id |
| `pending_approvals` | 待审批记录(SHA-256 确认码) |
| `session_summaries` | 会话摘要 |
| `scheduled_tasks` | 定时任务(支持 model/system 类型) |
## 部署
### systemd 服务
```bash
sudo cp systemd/ias.service /etc/systemd/system/
# 编辑 .env 文件确保 API Key 等环境变量已配置
sudo systemctl enable --now ias
```
### 天气 API 密钥
将和风天气 Ed25519 密钥对放入 `~/.ias/qweather/` 目录:
```
~/.ias/qweather/
├── ed25519-private.pem
└── ed25519-public.pem
```
## 依赖
| 依赖 | 用途 |
|------|------|
| tokio | 异步运行时 |
| clap | CLI 参数解析 |
| reqwest | HTTP 客户端 |
| sqlx | PostgreSQL 驱动 + 迁移 |
| serde / serde_json | 序列化 |
| chrono | 时间处理 |
| tracing | 结构化日志 |
| async-trait | 异步 trait |
| ed25519-dalek | 天气 API JWT 签名 |
| scraper | 网页正文提取(可读性算法) |
| sha2 / hex / rand | 审批确认码加密 |
| uuid | 会话/任务唯一标识 |
| base64 | Base64 编码 |
| qrcode / image | 二维码生成 |
| rustyline / dialoguer / console | 终端交互 |
| futures-util | 流式处理工具 |
| dirs | 系统目录路径 |