-- ============================================================================= -- Migration 026: ai_insights.embedding_signature — BGE-M3 一致性護欄 -- Operation Ollama-First v5.0 — Phase 1 / 護欄 #3 -- 日期: 2026-05-03 台北 -- 對應: docs/phase0_audit_report_20260503.md Section 3 BGE-M3 一致性現況報告 -- ============================================================================= -- 風險背景: -- bge-m3:latest 為 floating tag,Ollama upgrade 會悄悄跳版本,且程式未顯式 -- 傳遞 normalize / pooling 參數。RAG 召回率會無告警地退化。 -- -- 護欄設計: -- 每筆 ai_insights.embedding 寫入時,同步記錄 signature: -- SHA1("{model}|{normalize}|{dim}|{ollama_digest_前12碼}") 取前 12 碼 -- 範例: bge-m3:latest|true|1024|7907646426 → SHA1 → e3b0c44298fc -- -- Phase 11 啟動前,先批次補齊既有資料: -- UPDATE ai_insights -- SET embedding_signature = '' -- WHERE embedding IS NOT NULL AND embedding_signature IS NULL; -- 並由 ai_calls.meta.embedding_signature 與 ai_insights.embedding_signature -- 做 cross-check(簽名漂移時觸發 Telegram 告警)。 -- -- ALTER TABLE 安全性: -- PostgreSQL 11+ 新增 NULL 預設值欄位為 metadata-only 變更(不重寫表,不鎖表)。 -- 生產環境 (PostgreSQL 14) 確認安全。 -- -- 回滾腳本: -- DROP INDEX IF EXISTS idx_ai_insights_embedding_signature; -- ALTER TABLE ai_insights DROP COLUMN IF EXISTS embedding_signature; -- -- critic-A11 修補(B2): -- pgcrypto extension 由本 migration 啟用;附錄 SHA1 範例不再缺前置條件。 -- ============================================================================= -- (0) critic-A11 B2 修補:pgcrypto 用於附錄 SHA1 簽名計算(IF NOT EXISTS 冪等) CREATE EXTENSION IF NOT EXISTS pgcrypto; -- (1) 新增欄位(無 DEFAULT,metadata-only,不鎖表) ALTER TABLE ai_insights ADD COLUMN IF NOT EXISTS embedding_signature VARCHAR(64); COMMENT ON COLUMN ai_insights.embedding_signature IS 'BGE-M3 一致性簽名:SHA1({model}|{normalize}|{dim}|{ollama_digest})[:12],' 'Phase 11 RAG 召回前必檢查;NULL = 既有未回填資料(待批次補)'; -- (2) Partial index:只索引有 embedding 且簽名非空的列 -- 用 CONCURRENTLY 避免阻塞既有 ai_insights 寫入 -- 注意: CONCURRENTLY 不能在 transaction block 內執行;本 migration 採 PostgreSQL -- psql 直接執行(無外層 BEGIN/COMMIT) CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_ai_insights_embedding_signature ON ai_insights (embedding_signature) WHERE embedding IS NOT NULL; -- 註: Phase 11 啟動前批次補簽名範例(不在本 migration 執行): -- WITH sig AS ( -- SELECT 'bge-m3:latest|true|1024|' AS raw -- ) -- UPDATE ai_insights -- SET embedding_signature = SUBSTRING(ENCODE(DIGEST(sig.raw, 'sha1'), 'hex'), 1, 12) -- FROM sig -- WHERE embedding IS NOT NULL AND embedding_signature IS NULL; DO $$ BEGIN RAISE NOTICE 'Migration 026 done: ai_insights.embedding_signature + partial index (Operation Ollama-First v5.0 P1)'; END $$;