docs: 添加 ARCHITECTURE.md 代码调用图谱
包含 8 个 Mermaid 图表,覆盖: 1. 全局架构总览 — 所有模块及调用关系 2. 消息处理全链路 — Sequence Diagram 完整流程 3. 模块依赖关系 — 分层依赖图 4. 数据流(消息生命周期) 5. 关键函数调用关系(工具执行/审批/上下文构建) 6. 文件依赖矩阵 7. 启动流程 8. 消费者架构(三消费者)
This commit is contained in:
+445
@@ -0,0 +1,445 @@
|
||||
# iAs 代码调用图谱
|
||||
|
||||
> 微信 AI 智能助手 —— 完整架构与调用关系
|
||||
|
||||
---
|
||||
|
||||
## 1. 全局架构总览
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph CLI["CLI 入口 (main.rs)"]
|
||||
A1["clap::Parser Cli 解析"]
|
||||
A2["cmd_login"]
|
||||
A3["cmd_listen"]
|
||||
A4["cmd_send"]
|
||||
A5["cmd_whoami"]
|
||||
A6["cmd_usage"]
|
||||
A7["cmd_tool"]
|
||||
A8["cmd_daemon"]
|
||||
end
|
||||
subgraph DAEMON["守护进程 (daemon.rs)"]
|
||||
B0["run()"]
|
||||
B1["spawn_consumers()"]
|
||||
B2["llm_consumer_loop"]
|
||||
B3["tool_consumer_loop"]
|
||||
B4["send_consumer_loop"]
|
||||
B5["run_llm_round / resume_llm_round"]
|
||||
B6["handle_chat_result"]
|
||||
B7["execute_tool"]
|
||||
end
|
||||
subgraph QUEUE["消息队列 (queue/)"]
|
||||
C1["MessageQueue 公平轮转"]
|
||||
C2["QueueRunner 路由调度"]
|
||||
C3["EnqueueHandle"]
|
||||
C4["ConsumerChannels"]
|
||||
end
|
||||
subgraph LLM["LLM 对话系统 (llm/)"]
|
||||
D1["Conversation 对话管理器"]
|
||||
D2["chat_with_tools() / run_tool_loop()"]
|
||||
D3["DeepSeekProvider"]
|
||||
D4["LlmProvider trait"]
|
||||
D5["StreamReceiver"]
|
||||
end
|
||||
subgraph CONTEXT["上下文管理 (context/)"]
|
||||
E1["ChatSession 消息历史+摘要"]
|
||||
E2["builder Token估算+上下文构建"]
|
||||
E3["MemoryStore 长期记忆"]
|
||||
E4["read_summaries"]
|
||||
end
|
||||
subgraph TOOLS["工具系统 (tools/)"]
|
||||
F1["BuiltinRegistry 工具注册表"]
|
||||
F2["ApprovalManager 审批管理"]
|
||||
F3["build_capability_guide"]
|
||||
F4["unpack_call_params"]
|
||||
subgraph BUILTINS["内置工具 (builtins/)"]
|
||||
G1["datetime"]
|
||||
G2["weather"]
|
||||
G3["web_search"]
|
||||
G4["fetch_page"]
|
||||
G5["memos"]
|
||||
G6["amap"]
|
||||
end
|
||||
end
|
||||
subgraph WECHAT["微信通道 (wechat/)"]
|
||||
H1["WeChatClient"]
|
||||
H2["receive_messages()"]
|
||||
H3["send_text()"]
|
||||
H4["login()"]
|
||||
H5["notify_start/stop"]
|
||||
end
|
||||
subgraph DB["数据库 (db/)"]
|
||||
I1["Database::connect()"]
|
||||
I2["models CRUD 操作"]
|
||||
end
|
||||
subgraph OTHER["其他模块"]
|
||||
J1["state.rs 文件状态回退"]
|
||||
J2["scheduler.rs 定时任务"]
|
||||
J3["logger.rs 日志初始化"]
|
||||
J4["channel/mod.rs ChannelId"]
|
||||
J5["ipc.rs UDS 协议(已废弃)"]
|
||||
J6["worker.rs 旧架构(已废弃)"]
|
||||
end
|
||||
|
||||
A1 --> A2 & A3 & A4 & A5 & A6 & A7 & A8
|
||||
A3 --> B0
|
||||
A8 --> B0
|
||||
B0 --> B1
|
||||
B1 --> B2 & B3 & B4
|
||||
B2 --> B5 & B6
|
||||
B3 --> B7
|
||||
B0 --> C1 & C2 & C3
|
||||
C2 --> C4
|
||||
C4 --> B2 & B3 & B4
|
||||
B2 --> D1
|
||||
D1 --> D2
|
||||
D2 --> D3
|
||||
D3 --> D4
|
||||
D4 --> D5
|
||||
D1 --> E1
|
||||
D2 --> E2
|
||||
B2 --> E3 & E4
|
||||
D2 --> F1
|
||||
B3 --> F1 & F2
|
||||
B7 --> F1 & F3 & F4
|
||||
F1 --> G1 & G2 & G3 & G4 & G5 & G6
|
||||
B4 --> H1
|
||||
H1 --> H2 & H3
|
||||
B0 --> I1
|
||||
B2 --> I2
|
||||
B4 --> I2
|
||||
A2 --> I2 & J1
|
||||
A3 --> J1
|
||||
B0 --> J1 & J2
|
||||
A1 --> J3
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 消息处理全链路
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant WX as 微信用户
|
||||
participant WC as WeChatClient
|
||||
participant MQ as MessageQueue
|
||||
participant QR as QueueRunner
|
||||
participant LC as LLM Consumer
|
||||
participant TC as Tool Consumer
|
||||
participant SC as Send Consumer
|
||||
participant LLM as DeepSeek API
|
||||
participant BT as BuiltinRegistry
|
||||
|
||||
WX->>WC: 发送消息
|
||||
WC->>MQ: enqueue(UserMessage)
|
||||
MQ->>QR: dequeue (公平轮转)
|
||||
QR->>LC: llm_tx.send(UserMessage)
|
||||
LC->>LC: 加载历史/记忆/摘要
|
||||
LC->>LLM: chat_stream(上下文)
|
||||
LLM-->>LC: 流式回复 + tool_calls
|
||||
|
||||
alt 有工具调用
|
||||
LC->>MQ: enqueue(ToolCall)
|
||||
MQ->>QR: dequeue
|
||||
QR->>TC: tool_tx.send(ToolCall)
|
||||
|
||||
alt 高风险工具
|
||||
TC->>TC: ApprovalManager.create()
|
||||
TC->>MQ: enqueue(LLMReply: 确认码)
|
||||
MQ->>QR: dequeue
|
||||
QR->>SC: send_tx.send(LLMReply)
|
||||
SC->>WC: send_text(确认码)
|
||||
WX-->>WC: 回复确认码
|
||||
WC->>MQ: enqueue(UserMessage: 确认码)
|
||||
MQ->>QR: dequeue
|
||||
QR->>LC: llm_tx.send(确认码)
|
||||
LC->>TC: ApprovalManager.handle_reply()
|
||||
TC-->>LC: Approved
|
||||
LC->>MQ: enqueue(ToolCall + approved=true)
|
||||
MQ->>QR: dequeue
|
||||
QR->>TC: tool_tx.send(ToolCall)
|
||||
end
|
||||
|
||||
TC->>BT: execute(工具名, 参数)
|
||||
BT-->>TC: SkillResult
|
||||
TC->>MQ: enqueue(ToolResult)
|
||||
MQ->>QR: dequeue
|
||||
QR->>LC: llm_tx.send(ToolResult)
|
||||
LC->>LLM: resume_tool_loop()
|
||||
LLM-->>LC: 最终回复
|
||||
end
|
||||
|
||||
LC->>MQ: enqueue(LLMReply)
|
||||
MQ->>QR: dequeue
|
||||
QR->>SC: send_tx.send(LLMReply)
|
||||
SC->>WC: send_text(回复)
|
||||
WC->>WX: 显示回复
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 模块依赖关系
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph CORE["核心层"]
|
||||
MAIN["main.rs"]
|
||||
DAEMON["daemon.rs"]
|
||||
CLI["cli.rs"]
|
||||
end
|
||||
subgraph PIPELINE["消息管线"]
|
||||
QUEUE["queue/"]
|
||||
CHANNEL["channel/"]
|
||||
end
|
||||
subgraph AI["AI 层"]
|
||||
LLM["llm/"]
|
||||
CTX["context/"]
|
||||
end
|
||||
subgraph TOOL["工具层"]
|
||||
TOOLS["tools/"]
|
||||
BUILTINS["tools/builtins/"]
|
||||
APPROVAL["tools/approval.rs"]
|
||||
end
|
||||
subgraph IO["IO 层"]
|
||||
WECHAT["wechat/"]
|
||||
DB["db/"]
|
||||
STATE["state.rs"]
|
||||
SCHED["scheduler.rs"]
|
||||
end
|
||||
subgraph UTIL["工具层"]
|
||||
LOG["logger.rs"]
|
||||
IPC["ipc.rs"]
|
||||
WORKER["worker.rs"]
|
||||
end
|
||||
|
||||
MAIN --> CLI & DAEMON & LOG & STATE & DB & CTX & LLM & TOOLS & WECHAT & SCHED
|
||||
DAEMON --> QUEUE & CHANNEL & WECHAT & DB & STATE & LLM & CTX & TOOLS & SCHED
|
||||
QUEUE --> CHANNEL
|
||||
LLM --> CTX & TOOLS
|
||||
TOOLS --> BUILTINS & APPROVAL
|
||||
CTX --> DB
|
||||
TOOLS --> DB
|
||||
APPROVAL --> DB
|
||||
DB --> STATE
|
||||
WORKER --> IPC & LLM & TOOLS
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 数据流(消息生命周期)
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
START(["📱 用户发消息"]) --> A["WeChatClient receive_messages()"]
|
||||
A --> B["入库: chat_records (inbound)"]
|
||||
B --> C["PipelineMessage kind: UserMessage"]
|
||||
C --> D["MessageQueue 公平轮转"]
|
||||
D --> E["加载历史消息 (最近20条)"]
|
||||
E --> F["加载长期记忆 (MemoryStore)"]
|
||||
F --> G["加载摘要 (read_summaries)"]
|
||||
G --> H["构建上下文 (builder)"]
|
||||
H --> I["Conversation chat_with_tools()"]
|
||||
I --> J{"LLM 调用了工具?"}
|
||||
J -->|"是"| K["Tool Consumer 执行工具"]
|
||||
K --> L{"高风险?→ 审批流程"}
|
||||
L --> M["结果回喂 LLM"]
|
||||
M --> I
|
||||
J -->|"否"| N["LLM 生成最终回复"]
|
||||
N --> O["Send Consumer send_text()"]
|
||||
O --> P["入库: chat_records (outbound)"]
|
||||
P --> ENDD(["📱 用户收到回复"])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 关键函数调用关系
|
||||
|
||||
### 5.1 工具执行链路
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph LLM_SIDE["LLM 侧"]
|
||||
A["LLM 调用 call_capability()"]
|
||||
B["ToolExecutor (闭包)"]
|
||||
C["返回 ASYNC_MARKER + 工具名"]
|
||||
end
|
||||
subgraph QUEUE_SIDE["队列侧"]
|
||||
D["PipelineMessage::tool_call()"]
|
||||
E["MessageQueue.enqueue()"]
|
||||
F["QueueRunner → Tool Consumer"]
|
||||
end
|
||||
subgraph TOOL_SIDE["工具侧"]
|
||||
G["tool_consumer_loop()"]
|
||||
H{"高风险?"}
|
||||
I["ApprovalManager 审批流程"]
|
||||
J["execute_tool()"]
|
||||
K{"工具类型?"}
|
||||
L["BuiltinRegistry.execute()"]
|
||||
M["上下文工具 直接处理"]
|
||||
N["unpack_call_params()"]
|
||||
end
|
||||
subgraph RESULT["结果回喂"]
|
||||
O["PipelineMessage::tool_result()"]
|
||||
P["LLM Consumer resume_llm_round()"]
|
||||
Q["Conversation resume_tool_loop()"]
|
||||
end
|
||||
|
||||
A --> B --> C --> D --> E --> F --> G
|
||||
G --> H
|
||||
H -->|"是"| I --> J
|
||||
H -->|"否"| J
|
||||
J --> K
|
||||
K -->|"内置工具"| L
|
||||
K -->|"上下文工具"| M
|
||||
K -->|"call_capability"| N --> K
|
||||
J --> O --> P --> Q
|
||||
```
|
||||
|
||||
### 5.2 审批流程
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
A["LLM 请求高风险工具"] --> B["ApprovalManager.create(user_id, tool)"]
|
||||
B --> C["生成 6 位确认码 SHA-256 哈希存储"]
|
||||
B --> D["创建 oneshot channel"]
|
||||
C --> E["发送消息给用户 ⚠️ 操作确认"]
|
||||
D --> F["等待用户回复 超时 5 分钟"]
|
||||
F --> G{"用户回复"}
|
||||
G -->|"匹配确认码"| H["ApprovalDecision::Approved"]
|
||||
G -->|"输入 0/取消"| I["ApprovalDecision::Rejected"]
|
||||
G -->|"不匹配(最多3次)"| J["减少尝试次数"]
|
||||
G -->|"超时"| K["ApprovalDecision::Expired"]
|
||||
J --> F
|
||||
H --> L["重新入队 UserMessage + approved_tool"]
|
||||
I --> M["回复用户: 已取消"]
|
||||
K --> N["回复用户: 已超时"]
|
||||
```
|
||||
|
||||
### 5.3 上下文构建流程
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
A["ChatSession (消息历史)"] --> B["estimate_tokens()"]
|
||||
B --> C{"Token 超 budget? (默认 28000)"}
|
||||
C -->|"是"| D{"checkpoint 之前有未摘要消息?"}
|
||||
D -->|"是"| E["trigger_overflow_summary() → 调用 LLM 生成摘要"]
|
||||
D -->|"否"| F["裁剪最早的消息 直到符合 budget"]
|
||||
C -->|"否"| G{"空闲超时? (12h 无消息)"}
|
||||
G -->|"是"| H["trigger_idle_summary() → 清空消息, 保留摘要"]
|
||||
G -->|"否"| I["build_context() → 组装最终上下文"]
|
||||
E --> I
|
||||
F --> I
|
||||
H --> I
|
||||
I --> J["发送给 LLM"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 文件依赖矩阵
|
||||
|
||||
| 文件 | 依赖的关键模块 |
|
||||
|------|---------------|
|
||||
| `main.rs` | cli, daemon, db, llm, context, tools, wechat, state, scheduler, logger |
|
||||
| `daemon.rs` | queue, channel, wechat, db, state, llm, context, tools, scheduler |
|
||||
| `cli.rs` | clap (独立) |
|
||||
| `llm/conversation.rs` | context/builder, context/types, llm/provider, llm/types |
|
||||
| `llm/deepseek.rs` | llm/provider, llm/types |
|
||||
| `llm/provider.rs` | llm/types |
|
||||
| `llm/types.rs` | serde (独立) |
|
||||
| `context/types.rs` | llm/types |
|
||||
| `context/builder.rs` | context/types, llm/types |
|
||||
| `context/tools.rs` | db/models |
|
||||
| `queue/message_queue.rs` | channel/mod |
|
||||
| `queue/runner.rs` | queue/message_queue |
|
||||
| `tools/builtin.rs` | tools/types, tools/builtins/* |
|
||||
| `tools/approval.rs` | db/models |
|
||||
| `tools/mod.rs` | tools/types |
|
||||
| `wechat/client.rs` | wechat/types |
|
||||
| `wechat/types.rs` | serde (独立) |
|
||||
| `db/mod.rs` | db/models |
|
||||
| `db/models.rs` | sqlx (独立) |
|
||||
| `state.rs` | serde (独立) |
|
||||
| `scheduler.rs` | db/models |
|
||||
| `worker.rs` | ipc, llm, tools (已废弃) |
|
||||
| `ipc.rs` | serde (已废弃) |
|
||||
|
||||
---
|
||||
|
||||
## 7. 启动流程
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
START(["ias listen --llm"]) --> A["main()"]
|
||||
A --> B["clap::Parser::parse()"]
|
||||
B --> C{"命令类型"}
|
||||
C -->|"Tool"| D["cmd_tool() 直接执行工具"]
|
||||
C -->|"Login"| E["cmd_login() 扫码登录"]
|
||||
C -->|"Listen/Service"| F["cmd_listen()"]
|
||||
|
||||
F --> G["加载 .env"]
|
||||
F --> H["Database::connect()"]
|
||||
H --> I{"数据库可用?"}
|
||||
I -->|"是"| J["创建 MemoryStore (DB 模式)"]
|
||||
I -->|"否"| K["创建 MemoryStore (文件模式)"]
|
||||
|
||||
F --> L["加载认证信息"]
|
||||
L --> M{"已登录?"}
|
||||
M -->|"否"| N["报错退出"]
|
||||
M -->|"是"| O["WeChatClient.set_auth()"]
|
||||
|
||||
O --> P["WeChatClient.notify_start()"]
|
||||
P --> Q["创建 ApprovalManager"]
|
||||
Q --> R["创建 Conversation + ToolExecutor"]
|
||||
R --> S["启动 Scheduler (定时任务)"]
|
||||
S --> T["启动 listen_loop()"]
|
||||
|
||||
T --> U["WeChatClient.receive_messages()"]
|
||||
U --> V{"收到消息?"}
|
||||
V -->|"是"| W["enqueue PipelineMessage"]
|
||||
W --> X["LLM/Tool/Send 消费者处理"]
|
||||
V -->|"否/超时"| U
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 消费者架构(三消费者)
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph QUEUE2["消息队列"]
|
||||
Q["MessageQueue 公平轮转"]
|
||||
R["QueueRunner 路由"]
|
||||
end
|
||||
subgraph LLM_C["LLM Consumer"]
|
||||
L1["接收: UserMessage / ToolResult / ScheduledTask"]
|
||||
L2["加载用户历史 + 记忆 + 摘要"]
|
||||
L3["创建/恢复 Conversation"]
|
||||
L4["chat_with_tools() / resume_tool_loop()"]
|
||||
L5{"有异步工具等待?"}
|
||||
L6["发送 LLMReply"]
|
||||
L7["保留 session"]
|
||||
L8["清理 session"]
|
||||
end
|
||||
subgraph TOOL_C["Tool Consumer"]
|
||||
T1["接收: ToolCall / ApprovalRequest"]
|
||||
T2{"高风险 + 未审批?"}
|
||||
T3["ApprovalManager.create()"]
|
||||
T4["发送确认码"]
|
||||
T5["execute_tool()"]
|
||||
T6["发送 ToolResult"]
|
||||
end
|
||||
subgraph SEND_C["Send Consumer"]
|
||||
S1["接收: LLMReply"]
|
||||
S2["WeChatClient.send_text()"]
|
||||
S3["入库: chat_records (outbound)"]
|
||||
end
|
||||
|
||||
Q --> R
|
||||
R -->|"UserMessage / ToolResult"| L1
|
||||
R -->|"ToolCall"| T1
|
||||
R -->|"LLMReply"| S1
|
||||
L1 --> L2 --> L3 --> L4
|
||||
L4 --> L5
|
||||
L5 -->|"是"| L7
|
||||
L5 -->|"否"| L6
|
||||
```
|
||||
Reference in New Issue
Block a user