Lab 7 學習導引與技術解析#
本 Lab 深入探討如何讓 Agent 在自動化寫入資料庫時,進行「自動合規校驗」與「資料庫約束自我修正閉環」。
💡 核心學習重點#
1. 資料庫物理防線 (Database Constraints)#
- 概念:最安全的系統不能只依賴 Prompt 去約束 Agent。我們必須將防線下移至資料庫層,利用 SQLite 的 DDL 強約束(外鍵約束
FOREIGN KEY、欄位值檢查CHECK、唯一性限制UNIQUE)來物理阻斷違規寫入。 - 物理防禦代碼:
- 外鍵約束:
PRAGMA foreign_keys = ON; - 經緯度範圍
CHECK約束:latitude REAL CHECK(latitude BETWEEN 21.0 AND 26.0)
- 外鍵約束:
2. 應用層安全 Hook (PreToolCallDecideHook)#
- 概念:在工具調用執行之前進行稽核攔截。
- 實作技術:
繼承
PreToolCallDecideHook並實作async def run(self, context: HookContext, data: ToolCall) -> HookResult。 在本 Lab 中,ComplianceVerifierHook用來檢查地名是否含有簡體中文字元。如果包含,Hook 直接攔截並拒絕(回傳allow=False),不調用資料庫,向 Agent 回傳合規政策拒絕訊息。
3. Stateful Loop 自我修正閉環#
- 概念:當寫入失敗時,Agent 絕不能直接崩潰,而必須具備「解析錯誤原因」並「重新規劃 thoughts」以自我修正的能力。
- Agent 的修正策略:
- 簡體字攔截(Hook 拒絕):Agent 接收到 Hook 傳回的繁體正體中文合規要求,主動將地名轉換為繁體(如「台南孔庙」 $\rightarrow$ 「臺南孔廟」)重新試寫。
- 外鍵約束失敗:說明該行政區代碼(如
TW-TNN-99)無效。Agent 查閱失敗 payload,主動呼叫query_valid_districts查詢合法代碼,找到最相近的'TW-TNN-01'修正後重新試寫。 - 唯一性約束失敗:說明資料已導入。Agent 自動判定無須重複寫入,在 thought 中記錄並安全跳過。
🛠️ 工程踩坑與解決方案 (SQLite Multi-Threading)#
- 問題:在背景多執行緒運行中,Python 常會拋出 SQLite 跨執行緒操作錯誤。
- 解決方案:在初始化 SQLite 連線時,加入
check_same_thread=False:sqlite3.connect(":memory:", check_same_thread=False)