助手(TenantAssistant)實現規格說明書
版本: v1.0
最後更新: 2026-06-13
服務範圍: aile-service-tenant、aile-service-room、aile-service-admin
1. 概述
Aile 助手系統是跨三個微服務實現的 AI 輔助會話引擎。它支援租戶級別的 AI 助手配置、消息觸發、Webhook 分發和回覆管理。
1.1 架構分佈
| 層級 | 服務 | 職責 |
|---|---|---|
| 觸發管線 | aile-service-room | 攔截每條服務號消息 → 判斷是否觸發助手 → PubSub 發布 |
| 領域核心 | aile-service-tenant | TenantAssistantModel CRUD、狀態生命週期、Webhook 分發、房間綁定 |
| 管理視圖 | aile-service-admin | 管理後台助手列表、訂單管理(透過 Feign 讀取 tenant 服務) |
1.2 核心設計原則
- 助手是服務號級別資源(歸屬於 serviceNumberId)
- 助手觸發管線在消息寫入後非同步執行
- 助手回應模式支援三種:
Qa(問答回覆)、CollectOnly(僅收集)、Batch(批量觸發)
2. TenantAssistantModel(助手領域模型)
2.1 資料結構
MongoDB 集合:aile.tenant.assistant
// aile-api/aile-tenant-api/.../model/assistant/TenantAssistantModel.java
@Document("aile.tenant.assistant")
@CompoundIndexes({
@CompoundIndex(name = "assistantId_1", def = "{'assistantId': 1}", unique = true, sparse = true),
@CompoundIndex(name = "tenantId_1_accountId_1_updateTime_1",
def = "{'tenantId': 1, 'accountId': 1, 'updateTime': -1}"),
@CompoundIndex(name = "tenantId_1_accountId_1_status_1",
def = "{'tenantId': 1, 'accountId': 1, 'status': 1}")
})
public class TenantAssistantModel extends BaseModel {
String assistantId; // 助手業務 ID,格式:Asst_xxx
String accountId; // 建立者帳號 ID
String tenantId; // 租戶 ID
String serviceNumberId; // 服務號 ID
String name; // 助手名稱
String description; // 助手描述
TenantAssistantStatus status; // Enable / Disable
TenantAssistantResponseMode responseMode; // Qa / CollectOnly / Batch
TenantAssistantPaymentStatus paymentStatus; // Unpaid / Paid
TenantAssistantSource source; // 助手來源
// Webhook 配置
String webhookUrl; // 外部助手回調地址
String webhookSecret; // 外部助手密鑰
// 過濾配置
TenantAssistantMessageType messageType; // 處理的消息類型
TenantAssistantSenderTypeEnum senderType; // 發送者類型過濾
// Room 綁定
List<String> roomIds; // 綁定的聊天室 ID 列表
// Reply 排除
TenantAssistantReplyExcludeTypeEnum replyExcludeType; // 回覆排除類型
}
2.2 狀態機
Enable ←──→ Disable
助手的狀態為簡單的二元開關,不支援複雜生命週期。
2.3 回應模式
| 模式 | 值 | 說明 |
|---|---|---|
| 問答回覆 | Qa | 標準 AI 問答模式,每次消息觸發後等待外部助手回覆 |
| 僅收集 | CollectOnly | 僅收集消息內容,不產生回覆 |
| 批量觸發 | Batch | 批量觸發模式,定時收集多條消息後統一處理 |
2.4 支付狀態
| 狀態 | 說明 |
|---|---|
Unpaid | 未支付,助手不可用 |
Paid | 已支付,助手可用 |
3. 觸發管線(Room 服務)
3.1 觸發入口
位置:aile-service/aile-service-room/.../message/service/impl/MessageServiceImpl.java
每條服務號消息寫入後,MessageServiceImpl 會調用 triggerAssistantIfNeeded():
MessageServiceImpl.saveMessage()
│
├── 消息寫入 Elasticsearch
├── 房間成員通知
└── triggerAssistantIfNeeded(message, room)
│
├── 判斷房間類型是否為 services(只有 services 房間觸發助手)
├── 查詢該服務號的啟用助手列表(透過 TenantAssistantFeign)
├── 組裝 AssistantTriggerCommandDto
└── AssistantTriggerPublishService.publish(command)
│
└── PubSub → assistantTriggerChannel
3.2 觸發命令
// aile-api/aile-room-api/.../dto/assistant/AssistantTriggerCommandDto.java
public class AssistantTriggerCommandDto {
MessageVO message; // 原始消息
RoomModel room; // 聊天室資訊
String sessionId; // 當前會話 ID
List<String> assistantIds; // 候選助手 ID 列表
}
3.3 PubSub 監聽器
位置:aile-service/aile-service-room/.../listener/PubSubAssistantTriggerListener.java
PubSubAssistantTriggerListener (inputChannel = "assistantTriggerChannel")
│
└── AssistantTriggerOrchestrator.orchestrate(command)
3.4 觸發編排器
位置:aile-service/aile-service-room/.../service/assistant/impl/AssistantTriggerOrchestratorImpl.java
public class AssistantTriggerOrchestratorImpl implements AssistantTriggerOrchestrator {
// 核心編排邏輯:
// 1. 逐一處理每個候選助手
// 2. 檢查助手狀態(Enable / Disable)
// 3. 檢查支付狀態(Paid / Unpaid)
// 4. 檢查房間綁定(若配置了 roomIds)
// 5. 依回應模式分流處理:
// - Qa: 組裝 Webhook 事件 → publish
// - CollectOnly: 記錄收集 → 不觸發 Webhook
// - Batch: 加入批量佇列 → 等待定時任務處理
// 6. 非 Qa 模式:建立 AssistantReplyDispatch 記錄
}
4. Webhook 分發(Tenant 服務)
4.1 分發流程
AssistantTriggerOrchestrator (room 服務)
│
├── 組裝 TenantAssistantWebhookEventDto
├── PubSub → assistantWebhookChannel
│
└── PubSubTenantAssistantWebhookListener (tenant 服務)
│
└── TenantAssistantWebhookDispatchService.dispatch(event)
│
├── 查詢 TenantAssistantModel 取得 webhookUrl + webhookSecret
├── 構建 HTTP 請求(HMAC 簽名可選)
├── POST → 外部助手平台
└── 接收回覆 → AssistantReplyDispatchService
4.2 Webhook 事件格式
// aile-api/aile-tenant-api/.../dto/assistant/TenantAssistantWebhookEventDto.java
public class TenantAssistantWebhookEventDto {
String assistantId; // 助手 ID
String sessionId; // 會話 ID
String roomId; // 聊天室 ID
String serviceNumberId; // 服務號 ID
TenantAssistantMessageType messageType; // 消息類型
List<TenantAssistantWebhookMessageDto> messages; // 消息列表
}
4.3 PubSub 監聽器
位置:aile-service/aile-service-tenant/.../listener/PubSubTenantAssistantWebhookListener.java
@Component
public class PubSubTenantAssistantWebhookListener extends AbstractPubSubConsumer {
@ServiceActivator(inputChannel = "assistantWebhookChannel")
public void receiveMessage(...) {
// 解析 OpDetail → TenantAssistantWebhookDispatchDto
// 調用 TenantAssistantWebhookDispatchService
}
}
5. 回覆管理(Room 服務)
5.1 回覆分發服務
位置:aile-service/aile-service-room/.../service/assistant/AssistantReplyDispatchService.java
外部助手平台回覆
│
└── AssistantReplyDispatchController (接收回覆)
│
└── AssistantReplyDispatchService.receiveReply()
│
├── 建立/更新 AssistantReplyDispatchModel 記錄
├── Token 校驗(透過 AssistantDispatchTokenService)
└── 寫入房間消息
5.2 AssistantReplyDispatchModel
記錄每次助手回覆的狀態:
| 狀態 | 說 明 |
|---|---|
Pending | 等待回覆 |
Replied | 已回覆 |
Failed | 回覆失敗 |
Timeout | 回覆超時 |
5.3 Token 機制
位置:aile-service/aile-service-room/.../service/assistant/AssistantDispatchTokenService.java
每次觸發助手時生成一個 dispatch token,用於驗證外部回覆的合法性:
- 生成:
AssistantDispatchTokenService.generateToken(assistantId, sessionId) - 驗證:
AssistantDispatchTokenService.validateToken(token) - 儲存:Redis(有過期時間)
6. 批量任務
6.1 OnceAssistantBatchTask
位置:aile-service/aile-service-room/.../task/OnceAssistantBatchTask.java
用於 Batch 模式的定時批量處理:
定時觸發(透過 OnceScheduleManager)
│
└── OnceAssistantBatchTask.execute()
│
├── 從 Redis 讀取批量收集的消息
├── 組裝批量 Webhook 事件
└── 推送至外部助手平台
6.2 批量狀態管理
位置:aile-service/aile-service-room/.../service/assistant/model/AssistantBatchStateData.java
public class AssistantBatchStateData {
String assistantId;
String serviceNumberId;
List<String> messageIds; // 收集的消息
Long firstMessageTime; // 第一批消息時間
Long lastMessageTime; // 最後一批消息時間
int retryCount; // 重試次數
}
Redis Key 管理:AssistantBatchStateRedisUtil / AssistantBatchRedisKey
7. 助手過期任務
7.1 TenantAssistantExpireTask
位置:aile-service/aile-service-tenant/.../task/TenantAssistantExpireTask.java
定時掃描過期的助手(基於訂單到期時間),自動停用:
定時觸發
│
└── TenantAssistantExpireTask.execute()
│
├── 查詢 paymentStatus=Paid 且訂單已過期的助手
├── 更新 paymentStatus → Unpaid
└── 更新 status → Disable
8. 管理後台視圖
8.1 AdminAssistantController
位置:aile-service/aile-service-admin/.../controller/AdminAssistantController.java
提供管理後台的助手列表和操作視圖:
| 功能 | 說明 |
|---|---|
| 助手列表 | 透過 TenantAssistantFeign 查詢 tenant 服務 |
| 助手詳情 | 包含訂單資訊(透過 TenantOrderFeign) |
| 狀態管理 | 啟用/停用助手 |
| 訂單管理 | 查詢關聯訂單 |
9. 助手 CRUD API(Tenant 服務)
9.1 TenantAssistantController
路由:/assistant/
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /assistant/create | 建立助手 |
POST | /assistant/save | 儲存/更新助手 |
POST | /assistant/status | 變更狀態(Enable/Disable) |
POST | /assistant/query | 分頁查詢助手列表 |
GET | /assistant/detail?assistantId= | 查詢助手詳情 |
POST | /assistant/room-bind | 綁定/解綁聊天室 |
9.2 建立助手請求示例
{
"tenantId": "T001",
"serviceNumberId": "SN001",
"name": "客服助手",
"description": "自動回覆常見問題",
"responseMode": "Qa",
"webhookUrl": "https://ai.example.com/webhook",
"webhookSecret": "secret_key",
"messageType": "Text",
"senderType": "Customer"
}
10. 回覆 API
10.1 TenantAssistantReplyController
路由:/assistant/reply/
| 方法 | 路徑 | 說明 |
|---|---|---|
POST | /assistant/reply/dispatch | 外部助手平台推送回覆 |
GET | /assistant/reply/status?dispatchId= | 查詢回覆狀態 |
11. 配額與扣點
11.1 配額檢查
助手觸發時會進行配額檢查(透過 TenantQuotaAccessGuardService):
- 檢查租戶的助手使用配額是否充足
- 檢查帳號的試用次數是否耗盡(
AccountBizTrialFeign) - 配額不足時拒絕觸發,不推送 Webhook
11.2 用量記錄
- 每次成功觸發助手後記錄用量(
TenantQuotaUsageService) - 配額消 耗支援按月/按年統計
12. 關鍵檔案索引
| 層級 | 檔案 | 說明 |
|---|---|---|
| API Model | aile-api/aile-tenant-api/.../model/assistant/TenantAssistantModel.java | 助手持久化模型 |
| API Enum | aile-api/aile-tenant-api/.../enums/assistant/TenantAssistantStatus.java | 狀態枚舉 |
| API Enum | aile-api/aile-tenant-api/.../enums/assistant/TenantAssistantResponseMode.java | 回應模式枚舉 |
| API Enum | aile-api/aile-tenant-api/.../enums/assistant/TenantAssistantPaymentStatus.java | 支付狀態枚舉 |
| API Enum | aile-api/aile-tenant-api/.../enums/assistant/TenantAssistantMessageType.java | 消息類型枚舉 |
| API Enum | aile-api/aile-tenant-api/.../enums/assistant/TenantAssistantSenderTypeEnum.java | 發送者類型枚舉 |
| API Enum | aile-api/aile-tenant-api/.../enums/assistant/TenantAssistantSource.java | 助手來源枚舉 |
| API DTO | aile-api/aile-room-api/.../dto/assistant/AssistantTriggerCommandDto.java | 觸發命令 DTO |
| Room 觸發 | aile-service/aile-service-room/.../message/service/impl/MessageServiceImpl.java | 消息攔截 + triggerAssistantIfNeeded |
| Room 觸發 | aile-service/aile-service-room/.../service/assistant/impl/AssistantTriggerOrchestratorImpl.java | 觸發編排器 |
| Room 觸發 | aile-service/aile-service-room/.../listener/PubSubAssistantTriggerListener.java | PubSub 觸發監聽器 |
| Room 觸發 | aile-service/aile-service-room/.../service/assistant/AssistantTriggerPublishService.java | 觸發發布服務 |
| Room 回覆 | aile-service/aile-service-room/.../service/assistant/impl/AssistantReplyDispatchServiceImpl.java | 回覆分發服務 |
| Room 回覆 | aile-service/aile-service-room/.../controller/AssistantReplyDispatchController.java | 回覆接收 API |
| Room Token | aile-service/aile-service-room/.../service/assistant/impl/AssistantDispatchTokenServiceImpl.java | Token 服務 |
| Room Batch | aile-service/aile-service-room/.../task/OnceAssistantBatchTask.java | 批量任務 |
| Room Batch | aile-service/aile-service-room/.../service/assistant/model/AssistantBatchStateData.java | 批量狀態 |
| Tenant 領域 | aile-service/aile-service-tenant/.../service/assistant/impl/TenantAssistantServiceImpl.java | 助手 CRUD 服務 |
| Tenant 領域 | aile-service/aile-service-tenant/.../controller/assistant/TenantAssistantController.java | 助手 API |
| Tenant 領域 | aile-service/aile-service-tenant/.../controller/assistant/TenantAssistantReplyController.java | 回覆 API |
| Tenant Webhook | aile-service/aile-service-tenant/.../listener/PubSubTenantAssistantWebhookListener.java | Webhook 監聽器 |
| Tenant Webhook | aile-service/aile-service-tenant/.../service/assistant/impl/TenantAssistantWebhookDispatchServiceImpl.java | Webhook 分發服務 |
| Tenant 後台 | aile-service/aile-service-tenant/.../task/TenantAssistantExpireTask.java | 過期停用任務 |
| Admin 視圖 | aile-service/aile-service-admin/.../controller/AdminAssistantController.java | 管理後台 API |
| Admin 視圖 | aile-service/aile-service-admin/.../service/impl/AdminAssistantServiceImpl.java | 管理後台服務 |
| 配額 | aile-service/aile-service-tenant/.../service/quota/impl/TenantQuotaAccessGuardServiceImpl.java | 配額守衛 |
| 配額 | aile-service/aile-service-tenant/.../service/quota/impl/TenantQuotaUsageServiceImpl.java | 用量服務 |