69ba8887ff6a28f7d7f41f5548c832ec253c5f66
- 新建 README.md,整合项目架构、命令、配置、数据流 - 删除 6 个冗余/过时 md 文档 - save_summary_to_db 委托 db::models::save_summary,避免 SQL 重复 - #[allow(dead_code)] 标注 serde 反序列化字段和预留 API - 移除未使用的 re-export (Summarizer, Message, Role, StreamChunk) - 修复 README 中 manage_memos 风险等级和缺失的 AMAP_KEY 配置
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 listen --llm
# 4. 后台运行(配合 systemd)
ias service
命令一览
| 命令 | 说明 |
|---|---|
ias login |
扫码登录微信,认证信息存入 PostgreSQL / 本地文件 |
ias listen --llm |
启动长轮询 + AI 自动回复 |
ias listen --echo |
启动长轮询 + 原样回显 |
ias listen |
仅监听,不做回复 |
ias send --to <id> --text <msg> |
手动发送消息 |
ias whoami |
查看登录状态 |
ias usage |
Token 用量统计(默认 7 天) |
ias service |
后台服务模式(日志 + systemd) |
ias daemon |
守护进程模式(daemon + worker 分离架构) |
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 |
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 子命令路由 │
├─────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ WeChat │ │ LLM │ │ Tools │ │
│ │ 长轮询 │ │ DeepSeek │ │ 内置工具 │ │
│ │ HTTP API │ │ 流式对话 │ │ 审批管理 │ │
│ └────┬─────┘ └────┬─────┘ └──────┬────────┘ │
│ │ │ │ │
│ ┌────┴──────────────┴───────────────┴────────┐ │
│ │ Context / Memory │ │
│ │ ChatSession · Token Budget · 摘要压缩 │ │
│ │ MemoryStore · 长期记忆 │ │
│ └──────────────────────┬──────────────────────┘ │
│ │ │
│ ┌──────────────────────┴──────────────────────┐ │
│ │ Database (PostgreSQL) │ │
│ │ auth · chat_records · llm_usage │ │
│ │ user_memories · pending_approvals │ │
│ │ session_summaries · scheduled_tasks │ │
│ └─────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────┤
│ Daemon / Worker IPC (可选) │
│ Unix Domain Socket · 帧协议 · 进程隔离 │
└─────────────────────────────────────────────────┘
核心数据流
微信消息到达
→ 保存 inbound chat_records
→ 用户切换:加载历史 + 记忆
→ 构建 LLM 上下文(token budget + 摘要注入)
→ Conversation.chat_with_tools()
├── LLM 流式回复
├── 工具调用 → query_capabilities / call_capability
│ ├── 上下文工具:read_memories / write_memory / read_summaries
│ ├── 内置工具:datetime / weather / search / memos / fetch_page / amap
│ └── High 风险工具 → 审批流程
└── 工具结果注入对话 → LLM 继续
→ 保存 outbound chat_records + LLM usage
→ 微信发送回复
源码结构
src/
├── main.rs CLI 入口 + 命令实现 + 监听循环 + 工具执行器
├── cli.rs clap 子命令定义(login/listen/send/tool 等)
├── logger.rs 日志初始化(终端 + 文件滚动)
├── state.rs 本地文件状态(auth.json / runtime.json,无DB时降级)
├── scheduler.rs 定时任务调度器
├── context/ 上下文管理
│ ├── types.rs ChatSession(checkpoint/messages/summaries)
│ ├── builder.rs Token budget 估算 + 上下文构建 + 摘要触发
│ └── tools.rs MemoryStore(HashMap<user_id, Vec<mem>>)
├── db/ 数据库
│ ├── mod.rs Database 连接池 + 迁移
│ └── models.rs CRUD(auth/chat/usage/summary)
├── 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
│ ├── builtin.rs BuiltinRegistry 路由
│ ├── approval.rs ApprovalManager(确认码 + oneshot 通道)
│ └── builtins/ 内置工具实现
│ ├── datetime.rs 日期时间
│ ├── weather.rs 和风天气(JWT + reqwest)
│ ├── web_search.rs Tavily 搜索
│ ├── fetch_page.rs 网页抓取
│ ├── memos.rs 备忘录
│ └── amap.rs 高德地图(POI/地理编码/路径/旅游规划)
├── wechat/ 微信通道
│ ├── types.rs iLink API 协议类型
│ └── client.rs HTTP 客户端(login/poll/send/notify)
├── daemon.rs 守护进程(持有 WeChat + DB,spawn worker)
├── worker.rs Worker 进程(无状态 LLM 执行)
└── ipc.rs Unix Domain Socket 帧协议
工具系统
LLM 可见工具
| 工具名 | 说明 |
|---|---|
query_capabilities |
列出所有可用工具及参数说明 |
call_capability |
按名称调用任意工具 |
read_memories |
读取用户长期记忆 |
write_memory |
写入长期记忆 |
read_summaries |
读取历史会话摘要 |
内置工具
| 工具 | 风险 | 说明 |
|---|---|---|
get_current_datetime |
Low | 获取北京时间 |
query_weather |
Low | 和风天气查询 |
web_search |
Low | Tavily 联网搜索 |
fetch_page |
Low | 网页正文提取 |
manage_memos |
Low | 备忘录增删查 |
amap_* |
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,按需加载新用户历史
数据库表
| 表 | 用途 |
|---|---|
app_state |
认证信息 KV 存储 |
chat_records |
收发消息记录(message_id 去重) |
llm_usage |
Token 用量统计(含缓存命中率) |
user_memories |
长期记忆(按 user_id) |
pending_approvals |
待审批记录(SHA-256 确认码) |
session_summaries |
会话摘要 |
scheduled_tasks |
定时任务 |
部署
systemd 服务
sudo cp systemd/ias.service /etc/systemd/system/
# 编辑 .env 文件确保 API Key 等环境变量已配置
sudo systemctl enable --now ias
天气 API 密钥
将和风天气 Ed25519 密钥对放入 qweather/ 目录:
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 | 审批确认码加密 |
Description
Languages
Rust
99.7%
Shell
0.3%