說明 Uedu 平台如何將學生與 AI 助教的對話訊息向量化,透過語意搜尋與相似度比對,支援對話歷史檢索、相似問題偵測與研究聚類分析。
Chat Embedding 是 Uedu 平台的對話語意向量化模組,屬於 Educational Omics 框架中 Cognomics(認知歷程)與 Linguomics(語言表達)維度的基礎設施。
系統會將學生發送給 AI 助教的每一則訊息(request)轉換為高維度語意向量,儲存於資料庫中。這些向量可用於:
Chat Embedding 複用了 RAG(教材檢索增強)模組的 embedding 基礎設施,包括相同的模型(text-embedding-3-small)與向量維度(1536 維)。RAG 嵌入的是教材 chunks,Chat Embedding 嵌入的是學生對話訊息。
系統僅嵌入學生發送的訊息(request),不嵌入 AI 的回應(response)。這是因為研究關注的是學生的提問行為與認知表達,而非 AI 的輸出。
訊息在嵌入前需經過以下前處理步驟:
cl100k_base tokenizer 計算 token 數,超過 8,000 tokens 的訊息會被截斷(並標記 was_truncated = 1)| 參數 | 值 | 說明 |
|---|---|---|
| 模型 | text-embedding-3-small | OpenAI embedding model |
| 向量維度 | 1536 | 輸出浮點數向量長度 |
| Tokenizer | cl100k_base | GPT-4 / embedding 共用 |
| 最大 Token | 8,000 | 超過即截斷 |
系統採用即時 + 批次回填的雙路徑架構,確保新訊息即時向量化,同時補齊歷史數據:
不符合嵌入條件的訊息(過短、無實質內容)會被寫入一筆 NULL embedding 記錄,以防止批次回填程序反覆嘗試處理。這確保每則訊息只被評估一次。
語意搜尋使用餘弦相似度(cosine similarity)計算查詢向量與資料庫中所有嵌入向量的相似程度。系統使用 numpy 矩陣運算進行高效計算:
similarity = (A · B) / (||A|| × ||B||)
搜尋支援三種範圍篩選,可依研究需求限縮搜尋範圍:
| 篩選範圍 | 說明 | 適用場景 |
|---|---|---|
| Classroom | 限定特定課程的所有對話 | 教師搜尋全班學生的提問 |
| User | 限定特定學生的對話 | 追蹤個別學生的認知軌跡 |
| Chat | 限定特定對話串 | 在單一對話中搜尋上下文 |
| 參數 | 預設值 | 範圍 | 說明 |
|---|---|---|---|
top_k | 10 | 1 ~ 50 | 回傳最相似的前 k 筆結果 |
threshold | 0.3 | 0.0 ~ 1.0 | 最低相似度門檻,低於此值的結果會被過濾 |
為提升搜尋效能,系統為每個範圍鍵(scope key)維護一組記憶體快取(in-memory cache),快取策略如下:
| 參數 | 值 | 說明 |
|---|---|---|
| Embedding Model | text-embedding-3-small | OpenAI embedding 模型 |
| 向量維度 | 1536 | 每則訊息產生的浮點數向量長度 |
| 最短訊息長度 | 2 字元 | 低於此長度的訊息不嵌入 |
| 最大 Token 數 | 8,000 | 超過即截斷(cl100k_base) |
| Content Hash | MD5 | 用於內容去重 |
| 即時嵌入 | daemon thread | 每則新訊息觸發一個背景執行緒 |
| 批次 Workers | 3 | 以 log_id % 3 分區 |
| 批次輪詢間隔 | 15 秒 | 每個 worker 的輪詢週期 |
| 批次大小 | 50 筆 | 每次輪詢處理的最大訊息數 |
| 搜尋 top_k | 10(最大 50) | 預設回傳筆數 |
| 搜尋門檻 | 0.3 | 最低 cosine similarity |
| 快取 TTL | 5 分鐘 | per scope key |
| 寫入策略 | INSERT IGNORE | 冪等性保證 |
批次回填程序負責處理即時嵌入遺漏的訊息(例如服務重啟期間產生的訊息),以及系統上線前的歷史訊息。
log_id % 3 分配訊息到不同 worker,避免重複處理資料庫以 log_id 作為 UNIQUE KEY,寫入時使用 INSERT IGNORE。即使即時路徑與批次路徑同時處理同一則訊息,也不會產生重複記錄。
即時路徑確保新訊息在送出後立即可被語意搜尋,提供最佳使用者體驗。批次路徑則負責補齊所有遺漏,確保資料完整性。兩者透過 INSERT IGNORE 協同運作,互不干擾。
嵌入結果儲存於 chat_message_embeddings 資料表:
| 欄位 | 型態 | 說明 |
|---|---|---|
id | INT AUTO_INCREMENT PK | 主鍵 |
log_id | INT, UNIQUE KEY | 對應 chat_log 的訊息 ID |
embedding | BLOB | 1536 維浮點數向量(二進位格式) |
content_hash | CHAR(32) | MD5 內容雜湊,用於去重 |
content_preview | VARCHAR(200) | 訊息前 200 字元預覽 |
token_count | INT | 訊息的 token 數量 |
was_truncated | TINYINT(1) | 是否經過截斷(0/1) |
created_at | DATETIME | 嵌入時間 |
不符合嵌入條件的訊息(長度不足、無實質內容)會寫入一筆 embedding = NULL 的記錄。這使得批次回填程序可以透過 LEFT JOIN 快速識別尚未處理的訊息,避免反覆嘗試。
每筆 embedding 為 1536 個 float32,佔用約 6 KB。以一門 50 人、每人平均 200 則訊息的課程計算,約需 60 MB 儲存空間。建議定期監控資料表大小。
學生與 AI 助教的對話訊息透過 Uedu 平台的 Chat Embedding 模組進行語意向量化。系統使用 OpenAI text-embedding-3-small 模型(1536 維),將每則學生訊息(request)轉換為語意向量。文本前處理包含最短長度檢查(2 字元)、cl100k_base tokenizer 截斷(上限 8,000 tokens)及 MD5 內容雜湊去重。系統採用即時嵌入(daemon thread)與批次回填(3 workers、log_id % 3 分區、15 秒輪詢、每批 50 筆)的雙路徑架構。語意搜尋採用餘弦相似度(cosine similarity),支援課程、使用者、對話串三種範圍篩選,預設回傳前 10 筆相似結果(門檻 0.3)。嵌入結果儲存於 chat_message_embeddings 資料表,以 INSERT IGNORE 確保冪等性。詳細方法論說明見 https://uedu.tw/doc/chat-embedding。
建議同時提供: