跳至主要内容

助手(TenantAssistant)實現規格說明書

版本: v1.0
最後更新: 2026-06-13
服務範圍: aile-service-tenantaile-service-roomaile-service-admin


1. 概述

Aile 助手系統是跨三個微服務實現的 AI 輔助會話引擎。它支援租戶級別的 AI 助手配置、消息觸發、Webhook 分發和回覆管理。

1.1 架構分佈

層級服務職責
觸發管線aile-service-room攔截每條服務號消息 → 判斷是否觸發助手 → PubSub 發布
領域核心aile-service-tenantTenantAssistantModel 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 Modelaile-api/aile-tenant-api/.../model/assistant/TenantAssistantModel.java助手持久化模型
API Enumaile-api/aile-tenant-api/.../enums/assistant/TenantAssistantStatus.java狀態枚舉
API Enumaile-api/aile-tenant-api/.../enums/assistant/TenantAssistantResponseMode.java回應模式枚舉
API Enumaile-api/aile-tenant-api/.../enums/assistant/TenantAssistantPaymentStatus.java支付狀態枚舉
API Enumaile-api/aile-tenant-api/.../enums/assistant/TenantAssistantMessageType.java消息類型枚舉
API Enumaile-api/aile-tenant-api/.../enums/assistant/TenantAssistantSenderTypeEnum.java發送者類型枚舉
API Enumaile-api/aile-tenant-api/.../enums/assistant/TenantAssistantSource.java助手來源枚舉
API DTOaile-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.javaPubSub 觸發監聽器
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 Tokenaile-service/aile-service-room/.../service/assistant/impl/AssistantDispatchTokenServiceImpl.javaToken 服務
Room Batchaile-service/aile-service-room/.../task/OnceAssistantBatchTask.java批量任務
Room Batchaile-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 Webhookaile-service/aile-service-tenant/.../listener/PubSubTenantAssistantWebhookListener.javaWebhook 監聽器
Tenant Webhookaile-service/aile-service-tenant/.../service/assistant/impl/TenantAssistantWebhookDispatchServiceImpl.javaWebhook 分發服務
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用量服務