iT邦幫忙

2026 iThome 鐵人賽

DAY 7
0
Build on Google AI

打造零成本企業級 AI Agent:以 Gemini 2.5 Flash 構建金融分析助手與維運實戰系列 第 7

【Day 07】非同步背景學習:LearningModule 自動提煉金融知識與向量庫去重

  • 分享至 

  • xImage
  •  

「最好的 AI Agent 不是固定不變的系統,而是在每一次與使用者的對話中,自動汲取經驗並寫回知識庫、自我進化的系統。」

在 Day 06 中,我們介紹了 SQLite 持久化長效記憶(conversation_memory.py)。今天我們將深入探討 AI 核心架構的最後一塊拼圖——背景自動學習模組 app/services/learning_module.py。

為了不增加使用者的等待時間,Angelina AI Agent 採用了 Non-blocking 架構:對話回應生成後立即交付給前端,隨後在背景觸發 LearningModule,透過 Gemini API 提煉該輪對話中的金融知識點,經由 ChromaDB Deduplication 後,自動存入向量知識庫中。

本篇重點摘要

  1. 為什麼學習模組必須採用背景無阻塞(Non-blocking)設計呢?
  2. 拆解 _EXTRACTION_SYSTEM_PROMPT 金融知識抽取規格與 JSON 格式化解析。
  3. 實作 ChromaDB 語意去重機制 (DEDUP_SIMILARITY_THRESHOLD = 0.85) 與 Fail-open 設計。
  4. 解析累積 50 筆新知識點自動觸發 RAG 索引重建 (REBUILD_THRESHOLD = 50) 的cycle。

一、背景學習模組架構與設計理念

傳統的知識庫更新通常需要人工手動匯入檔案,而 LearningModule 實現了對話即學習(Conversation-driven Learning):
1. 非阻塞式背景任務:透過 asyncio.create_task(_learning_module.extract_and_store(...)) 觸發,完全獨立於 API 響應流程外執行。
2. Silent Error Handling:背景任務若遇到網路波動或解析失敗,僅記錄結構化日誌(log.error),絕不干擾或崩潰主應用程式。
3. 領域聚焦萃取:限定僅萃取「投資策略、稅務規則、預算原則、風險管理指引與市場數據」等五大金融領域知識點。

二、app/services/learning_module.py 核心原始碼解析

  1. 金融知識點萃取與 JSON 格式解析 (_extract_knowledge_points)
    我們透過動態 Prompt 要求 Gemini 分析對話內容,並嚴格輸出 JSON 陣列格式:
Python
async def _extract_knowledge_points(self, turn: Turn) -> list[dict]:
    """呼叫 Gemini API 識別對話中的金融知識點"""
    try:
        response = await self._gemini_gateway.generate(
            system_prompt=_EXTRACTION_SYSTEM_PROMPT,
            context_turns=[],
            knowledge_chunks=[],
            user_message=turn.content,
            language="en",  # 使用英文 Prompt 保持 extraction 指令穩定度
        )
        return self._parse_extraction_response(response.text, turn)
    except Exception as exc:
        log.warning("Knowledge extraction Gemini call failed", error=str(exc))
        return []
  1. ChromaDB 語意去重機制 (_is_duplicate)
    為了避免資料庫充斥重複或高度相似的敘述,提取出知識點後,系統會先對 ChromaDB 發起 top_k=1 的語意搜尋。

    若最大相似度得分大於等於 0.85(DEDUP_SIMILARITY_THRESHOLD),則認定該知識點已存在並自動過濾;若比對過程中發生異常,則採 Fail-open 策略(允許寫入),優先保證知識不遺漏:

Python
DEDUP_SIMILARITY_THRESHOLD = 0.85

async def _is_duplicate(self, text: str) -> bool:
    """檢查知識點是否與 ChromaDB 既有內容重複 (相似度 >= 0.85)"""
    try:
        results = await self._rag_engine.search(query=text, top_k=1)
        if not results:
            return False

        max_similarity = results[0].similarity
        return max_similarity >= DEDUP_SIMILARITY_THRESHOLD
    except Exception as exc:
        log.warning("Deduplication check failed, allowing write", error=str(exc))
        # Fail-open 策略:發生異常時仍允許寫入,避免阻斷學習
        return False
  1. 自動累積與索引重建觸發 (_trigger_rebuild)
    當背景學習累積新增的新知識點達到 50 筆(REBUILD_THRESHOLD = 50) 時,LearningModule 會自動尋找 data/notebooklm 底下最新的 Export 檔案,並自動調用 RAGEngine.rebuild_index() 進行向量庫重新整合與重構:
Python
REBUILD_THRESHOLD = 50

async def extract_and_store(self, turn: Turn, session_id: str) -> None:
    # 1. 提煉知識點...
    # 2. 去重並批次新增新 Chunk...
    if new_chunks:
        await self._rag_engine.add_chunks(new_chunks)
        added_count = len(new_chunks)
        self._new_points_since_rebuild += added_count

        # 3. 累積滿 50 筆,自動觸發向量索引重構
        if self._new_points_since_rebuild >= REBUILD_THRESHOLD:
            await self._trigger_rebuild()

三、目前總結與核心架構回顧

到這裡,「AI 核心推理、記憶與 RAG 檢索」已大致實作完畢!我們建立了一套高可用、低成本且自我演化的完整架構:
1. gemini_gateway.py:Sliding Window Rate Limit (15 RPM) 與 429 配額 UTC Midnight 自動復原。
2. rag_engine.py:ChromaDB + sentence-transformers 本地端零成本語意檢索,asyncio.to_thread 解耦 CPU 密集運算。
3. conversation_memory.py:aiosqlite 持久化記憶,百輪對話 Transaction 原子化摘要壓縮。
4. learning_module.py:非同步背景萃取、0.85 門檻語意去重與 50 筆門檻自動索引重構。

下週開始,我們將進入 數據管線自動化與周邊服務整合——實作 Google Drive 知識自動同步 (drive_sync.py)、TWSE/美股每日分析 Telegram 播報 (daily_analysis.py) 與 Google Sheets 追蹤 (sheets_tracker.py)!

明日預告:【Day 08】知識管線自動化:Google Drive 檔案同步與 /learn 指令排程注入 (drive_sync.py)


上一篇
【Day 06】長效對話記憶:aiosqlite 持久化儲存與自動對話摘要壓縮
系列文
打造零成本企業級 AI Agent:以 Gemini 2.5 Flash 構建金融分析助手與維運實戰7
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言