4a5b21a69e73b5d223fc76562767eebb1fda393b
iAs — 微信 AI 智能助手
Rust 实现的微信 iLink Bot,支持 DeepSeek AI 自动回复、内置工具调用、审批确认、定时任务和长期记忆。
快速开始
# 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 CRUD(auth/chat/usage/summary/memory/task)
├── llm/
│ ├── types.rs Message / Role / ToolCall / StreamChunk / Usage
│ ├── provider.rs LlmProvider trait + SSE 解析 + 工厂函数
│ ├── deepseek.rs DeepSeek 流式客户端实现
│ └── conversation.rs Conversation(chat + chat_with_tools 工具循环)
├── tools/
│ ├── types.rs RiskLevel / SkillSpec / SkillResult / ExecutionContext
│ ├── 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 通道)
│ ├── 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 不直接感知每个具体工具,而是通过两个元工具间接调用:
query_capabilities— 列出所有可用工具的名称、描述、参数格式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 ConsumerToolCall/ApprovalRequest→ Tool ConsumerLLMReply→ 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 服务
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 | 系统目录路径 |
Description
Languages
Rust
99.7%
Shell
0.3%