Files
ewoooc/docs/AI_INTELLIGENCE_MODULE_SOT.md

27 KiB
Raw Blame History

MOMO PRO — AI 競價情報模組 Single Source of Truth

最後更新: 2026-05-12 (台北時間) 狀態: 🟢 四 AI Agent 自動化閉環已落地LLM 路由紅線升級為 Ollama-first 三主機級聯Gemini 僅備援 / 鎖定場景 適用版本: V10.91


零、LLM 路由紅線2026-05-12

  • 所有 AI Agent、LLM 推理與 embedding 預設必須走 Ollama 三主機級聯GCP-A 34.143.170.20:11434 → GCP-B 34.21.145.224:11434 → 111 192.168.0.111:11434
  • services/ollama_service.resolve_ollama_host() 是主機解析契約;OLLAMA_HOSTHERMES_URLEMBEDDING_HOSTOLLAMA_API_BASE 只接受 GCP-A / GCP-B / 111 或 110 的核准轉發端口。
  • Gemini 只能作為 Ollama 主路徑失敗後的備援,或 ADR-028 明確鎖定的 MCP Grounding、PPT/vision、週/月報、Code Review、EA HITL、複雜 SKU 升級等低頻場景。
  • 188 192.168.0.188 僅是 App / DB / scheduler / Telegram bot 容器宿主與 AutoHeal target不可作為 Ollama 節點。
  • 通用 AI 文案、關鍵字、商品洞察與 Telegram Q&A 第一響應不得 Gemini-first。
  • Code Review pipeline 也必須 Ollama-firstHermes scan 與 OpenClaw assessment 都走 OllamaService 三主機 retryGemini telemetry 只能以 code_review_openclaw_gemini 出現,表示 Ollama/可選 Claude 備援都失敗後才啟用。
  • OpenClaw Telegram Q&A 主路徑也不得綁單一 host_call_qwen3_qa() 必須透過 OllamaService 跑 GCP-A → GCP-B → 111並把實際落點寫入 ai_calls.provider

一、四 AI Agent 路由架構

SQL漏斗(~300筆)
     ↓
[Hermes 3 8B] — 分析師 (Ollama 三主機級聯, 零成本)
  模型: hermes3:latest @ GCP-A → GCP-B → 111
  任務: 競價威脅分類 → TOP 20 HIGH/MED/LOW
     ↓
[NemoTron / qwen3] — 派發器
  主路徑: qwen3:14b @ Ollama 三主機級聯
  備援: NVIDIA NIM meta/llama-3.1-8b-instruct
  任務: Tool Calling → Telegram 告警 / DB 寫入
     ↓
[OpenClaw] — 策略師 (Ollama-firstGemini 僅備援 / 鎖定場景)
  任務: 週策略報告、洞察報告、L3 HITL 建議
     ↓
[ElephantAlpha] — 編排者 (L3 Orchestrator)
  任務: 跨 Agent orchestration、HITL、AutoHeal bridge、受控 log scan

1.1 PChome 挑品 Agent2026-05-01

services/ai_product_pick_agent.py 新增 PChome 銷售用挑品 Agent

  • 只讀真實資料表:productsprice_recordscompetitor_pricescompetitor_price_history,若 daily_sales_snapshot 可用則納入近 7 天銷售額、數量、毛利或成本推算毛利率。
  • 將 PChome 比 MOMO 有價格優勢、比對信心足夠、且有歷史快照或銷售動能的品項寫入 ai_price_recommendations。信心度不以固定倍率灌高,而是由商機分數與證據完整度共同決定,證據包含 PChome match score、歷史快照、銷售/毛利、PChome 商品 ID/名稱、抓取時間與促銷/評價/庫存標籤。每次重算只保留最新 50 品為 status='pending',未進榜舊品標為 superseded,避免統計與清單超量。
  • 寫入策略使用 strategy='product_pick',保留在既有 AI 決策表,不新增假頁面或暫存 JSON。
  • 後台入口:POST /api/ai/product-picks/generate/ai_intelligence 可手動產生清單。
  • 配對來源仍以 PChome crawler 真實搜尋結果為準;無競品資料時不生成挑品。
  • 比對覆蓋率補強入口:POST /api/ai/pchome-match/backfill,優先補抓仍無有效 PChome 配對的高價 ACTIVE 商品,完成後自動重算 AI 挑品清單。
  • 排程閉環:run_pchome_match_backfill_task 每日 10:30 執行,補抓 PChome 待比對商品、寫入歷史價格,再重算 strategy='product_pick' 清單。
  • 商品看板第一屏:/ 的 V2 看板直接以 productsprice_recordscompetitor_pricesai_price_recommendations 顯示比對覆蓋率、PChome 優勢、MOMO 威脅、AI 挑品與待比對優先清單;filter=ai_picks 可查看 50 品 AI 挑品列表,並在列表上方顯示平均信心、平均價差、最大價差與估算總價差空間,列表列內顯示 AI 排名與建議理由,且可透過 /api/export/excel/ai-picks 匯出 50 品 Excel 操作清單。商品看板深度快取同時寫入 data/dashboard_full_cache.pkl,供多個 Gunicorn worker 共用,避免部署後各 worker 重複重建 7,000+ 商品統計造成開頁變慢;所有資料異動與 AI 挑品重算都透過 clear_dashboard_cache() 同步清除記憶體與共享快取,手動重算 API 會立即預熱商品看板快取,避免第一位使用者承擔重建成本。
角色 模型 主機 成本 每日限額
Hermes 分析師 hermes3:latest / bge-m3 GCP-A → GCP-B → 111 Ollama 無限
NemoTron 派發器 qwen3:14bNIM fallback GCP-A → GCP-B → 111NVIDIA NIM 備援 Ollama 零NIM 配額內免費 NIM 80
OpenClaw 策略師 qwen3:14b / Gemini 鎖定場景 Ollama-firstGemini 備援 Ollama 零Gemini 需控管
ElephantAlpha 編排者 ElephantAlpha 依部署環境 受控 HITL / 任務制

一之一、AI 自動化閉環實況2026-04-29

事件 / 排程失敗 / code review finding
  → EventRouter 分流、去重、降級
  → Hermes L1 摘要或 NemoTron L2 tool calling
  → L2 SAFE_ACTIONS / AutoHeal / OpenClaw memory
  → Telegram 通知,失敗則 file queue成功後 replay
  → ai_insights + embedding_retry_queue
  → OpenClaw / ElephantAlpha 後續策略與 HITL

硬性邊界:

  • EventRouter 是告警與 L2 safe action 的入口。
  • AutoHeal 是自癒副作用入口。
  • momo-db / momo-postgres 不可被 AI 自動 restart / stop / recreate。
  • raw ai_insights insert 必須接 enqueue_insight_embedding() 或可被 backfill。
  • ElephantAlpha 只做編排與 bridge不可繞過 ADR-011 / ADR-012 / ADR-013。
  • ElephantAlpha / NemoTron 不可直接執行商品價格調整;execute_price_adjustmentadjust_price 等動作必須攔截並寫入 human_review,等待人工核准。

可觀測性:

  • /metrics 匯出 momo_ai_event_router_dispatch_total
  • /metrics 匯出 momo_ai_event_router_latency_ms_count/sum/max
  • /metrics 匯出 momo_ai_event_router_safe_action_total
  • /metrics 匯出 momo_ai_event_router_replay_total
  • /metrics 匯出 momo_ai_autoheal_action_totalmomo_ai_autoheal_duration_ms_count/sum/max
  • /metrics 在尚無事件時仍輸出 momo_ai_* zero-baseline series讓 Prometheus/Grafana 重啟後可立即看到 metric names。
  • /ai_automation_smoke 提供登入後 smoke dashboard。
  • /api/ai-automation/smoke 提供 read-only JSON 狀態,不做外部網路呼叫。
  • Smoke API 會將最近快檢結果保存到 JSONLdashboard 顯示最近狀態趨勢。
  • Smoke history 支援 JSONL 匯出、清理與每日 OK / Warning / Critical 摘要。
  • Smoke 每日摘要支援手動 Telegram 推播,並由 momo-scheduler 每日 09:10 呼叫 run_ai_smoke_daily_summary_task()
  • Grafana provisioning 新增 docker/grafana/provisioning/dashboards/json/ai-automation-overview.json,觀測 EventRouter dispatch/latency、safe action、Telegram replay 與 AutoHeal action/duration。
  • Active monitoring stack 使用 monitoring/prometheus.ymlmomo-app job scrape momo-pro-system:80/metricsPrometheus container 需加入 momo-network
  • Active Blackbox HTTP targets 必須探測 /health188 stack 目前 https://mo.wooo.work/healthhttp://momo-pro-system:80/health110 gateway stack 目前 https://mo.wooo.work/health),不可探測 Dashboard 首頁 /,避免監控流量觸發重型 DB 查詢。
  • /metricsrealtime_sales_monthly 只用 raw SELECT COUNT(*) 取得總筆數,避免 ORM schema drift 讓 Prometheus scrape 產生 warning。
  • momo-app 必須 bind mount ./gunicorn.conf.py:/app/gunicorn.conf.py:ro,讓 CD sync/rebuild 後的 Gunicorn runtime 設定與 repo 保持一致。
  • Gunicorn runtime 預設 worker_class = gthreadGUNICORN_THREADS=4preload_app = False;此組合讓 HUP 熱重載可用,也避免 Dashboard 長查詢完全阻塞 /health
  • CD rebuild 模式必須先 build image 成功,再短暫 stop/rm/recreate 三應用容器,避免 no-cache build 造成長時間 502。
  • ElephantAlpha 使用 NVIDIA NIM hosted APIproduction 預設模型為 nvidia/llama-3.3-nemotron-super-49b-v1.5ELEPHANT_ALPHA_FALLBACK_MODELS 需保留至少一個可呼叫備援403/404、408/409/425/429、5xx、timeout 與 connection error 必須嘗試下一個模型。
  • OpenClaw/Hermes embedding 優先呼叫 Ollama /api/embed,只在舊節點不支援時 fallback /api/embeddingstimeout 由 EMBEDDING_TIMEOUT / OLLAMA_EMBED_TIMEOUT 控制。

二、真實資料庫 Schema已校對確認

2.1 productsSQLAlchemy ORMSQLite/PostgreSQL 通用)

欄位 型別 說明
id Integer PK 主鍵
i_code String(50) UNIQUE MOMO 商品代碼(爬蟲來源,即商品 SKU
name String(255) 商品名稱
url String(500) MOMO 商品頁 URL
image_url Text 商品圖片 URL
category String(100) 分類名稱(直接欄位)
status String(20) 預設 'ACTIVE'
created_at DateTime 建立時間
updated_at DateTime 更新時間
category_id Integer FK → categories.id 分類關聯(可選)

重要: i_code = MOMO 網站上的商品 ID例如 I132467614

2.2 price_records

欄位 型別 說明
id Integer PK 主鍵
product_id Integer FK → products.id 商品關聯
price Float MOMO 自家售價(爬蟲抓取)
timestamp DateTime indexed 抓取時間戳

⚠️ 架構限制: price_records 只存 MOMO 自家售價,無 source 欄位無競品PChome價格。 PChome 比價資料必須由外部爬蟲即時抓取,以 pchome_prices: dict 形式注入 HermesAnalystService.run()

2.3 daily_sales_snapshot 表(動態表,從 Excel 匯入)

重要: 此表由 import_service.py 使用 df.to_sql() 動態建立。 欄位名稱完全繼承自匯入的 MOMO Excel 報表原始欄位,加上程式碼追加的 snapshot_date

已確認的關鍵欄位(實際 MOMO 報表欄位名稱)

欄位 型別 說明 備注
snapshot_date Date 資料所屬日期(程式追加) import_service.py 從「日期」欄位解析
商品ID VARCHAR 商品識別碼= products.i_code ⚠️商品編號
商品名稱 TEXT 商品名稱
銷售金額 NUMERIC 銷售業績金額 系統以 find_col 模糊比對,優先 銷售金額
數量 NUMERIC 銷售數量
總成本 NUMERIC 成本
廠商名稱 VARCHAR 廠商名稱
商品館 / 館別 VARCHAR 分類

欄位自動偵測邏輯(find_col

系統使用 keyword 模糊比對,不要求欄位名完全固定

SKU/商品ID   = find_col(['商品ID', 'Product ID', 'ID', 'i_code', 'Item Code'])
商品名稱     = find_col(['商品名稱', '品名', 'Name', 'Product'])
銷售金額     = find_col(['銷售金額', '業績', '金額', 'Amount', 'Sales', 'Total'])
成本         = find_col(['成本', 'Cost', '進價', '總成本'])
數量         = find_col(['銷售數量', '銷量', '數量', 'Qty', 'Quantity'])
日期         = find_col(['日期', '訂單日期', '交易日期', 'Date'])
分類         = find_col(['商品館', '館別', '分類', 'Category'])

2.4 competitor_pricesMigration 004 — 已建立)

競品價格快取表,由 competitor_price_feeder.py Worker 寫入AI Pipeline LEFT JOIN 消費。

欄位 型別 說明
id SERIAL PK 主鍵
sku VARCHAR(50) MOMO 商品代碼(= products.i_code
source VARCHAR(30) 競品來源:'pchome'(預留 shopee 等)
price NUMERIC(10,2) 競品售價
original_price NUMERIC(10,2) 競品原價
discount_pct INTEGER 折扣 %NULL=未折扣)
competitor_product_id VARCHAR(100) PChome 商品 ID
competitor_product_name TEXT PChome 商品名稱(核對用)
match_score NUMERIC(4,3) 模糊比對分數0~1< 0.45 不寫入
tags JSONB 語意標籤,如 ["on_sale","discount_20pct"]
crawled_at TIMESTAMP 爬取時間
expires_at TIMESTAMP TTL = crawled_at + 6h過期後 Hermes 忽略

UNIQUE: (sku, source) — 同一 SKU+來源只有一筆ON CONFLICT UPDATE

語意標籤字典

標籤 觸發條件
on_sale PChome is_on_sale = True
discount_10pct 折扣 10-19%
discount_20pct 折扣 20-29%
discount_30pct 折扣 ≥ 30%
low_stock 庫存 < 10
high_rating 評分 ≥ 4.5

2.5 ai_price_recommendationsMigration 003 — 已建立)

此表需執行 migrations/003_ai_price_recommendations.sql 才能完整寫入 DB

CREATE TABLE IF NOT EXISTS ai_price_recommendations (
    id          SERIAL PRIMARY KEY,
    sku         VARCHAR(50) UNIQUE NOT NULL,
    name        TEXT NOT NULL,
    reason      TEXT,
    status      VARCHAR(20) DEFAULT 'pending',  -- pending / approved / rejected
    created_at  TIMESTAMP DEFAULT NOW(),
    updated_at  TIMESTAMP DEFAULT NOW()
);

現狀: nemoton_dispatcher_service.py_exec_add_to_recommendation() 在 engine 注入且表存在時才寫入,否則只發 Telegram 通知,不會 crash。


三、SQL 漏斗設計(已修正欄位名稱)

hermes_analyst_service.pyfetch_candidates() 的核心 SQL

WITH latest_momo_price AS (
    -- 從爬蟲商品庫取最新 MOMO 售價
    SELECT
        p.i_code      AS sku,      -- MOMO 商品代碼
        p.name,
        p.category,
        pr.price      AS momo_price,
        ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY pr.timestamp DESC) AS rn
    FROM products p
    JOIN price_records pr ON pr.product_id = p.id
    WHERE p.status = 'ACTIVE'
),
recent_sales AS (
    -- 從每日業績快照計算近7天 vs 前7天銷售額
    SELECT
        "商品ID"     AS sku,      -- ⚠️ 實際欄位名為「商品ID」(非「商品編號」)
        SUM(CASE WHEN snapshot_date >= CURRENT_DATE - 7
                 THEN COALESCE("銷售金額"::numeric, 0) ELSE 0 END) AS sales_7d_curr,
        SUM(CASE WHEN snapshot_date >= CURRENT_DATE - 14
                  AND snapshot_date < CURRENT_DATE - 7
                 THEN COALESCE("銷售金額"::numeric, 0) ELSE 0 END) AS sales_7d_prev
    FROM daily_sales_snapshot
    GROUP BY "商品ID"
)
SELECT lmp.sku, lmp.name, lmp.category, lmp.momo_price,
       rs.sales_7d_curr, rs.sales_7d_prev
FROM latest_momo_price lmp
JOIN recent_sales rs ON rs.sku = lmp.sku
WHERE lmp.rn = 1
  AND rs.sales_7d_prev > 0
  AND (rs.sales_7d_curr - rs.sales_7d_prev) / rs.sales_7d_prev < -0.10
ORDER BY (rs.sales_7d_curr - rs.sales_7d_prev) / rs.sales_7d_prev ASC
LIMIT 300

漏斗效果: 226萬筆 price_records → ~300 筆近7天銷量跌幅 > 10% 的活躍商品)

JOIN 邏輯:

  • products.i_codedaily_sales_snapshot."商品ID" — 均為 MOMO 商品代碼,格式相同

四、競品價格補給線架構(已實裝)

生產者-消費者解耦設計

[competitor_price_feeder.py Worker]  ←← 每 4 小時獨立運行
  ↓ 搜尋 PChomesearch_products
  ↓ 模糊比對price_comparison.py
  ↓ 提取語意標籤
  ↓ UPSERT competitor_pricesTTL 6h
                ↓
[HermesAnalystService.fetch_candidates()]  ←← AI Pipeline 消費端
  ↓ LEFT JOIN competitor_prices零網路等待
  ↓ 有效期內expires_at > NOW()+ match_score ≥ 0.45 才 JOIN
  ↓ pchome_price + competitor_tags 一起傳給 Hermes

關鍵設計決策

決策 選擇 原因
解耦方式 DB 表快取(非 Redis PostgreSQL 已是核心,無需額外依賴;支援 JOIN
TTL 6 小時 與 AI Pipeline 排程週期對齊
比對算法 品牌(0.4) + 規格(0.3) + 關鍵字(0.3) 依賴現有 price_comparison.py
最低比對門檻 0.45 低於此分數不寫入,避免張冠李戴影響 AI 決策
語意標籤 JSONB 陣列 傳給 Hermes 提升情境感知品質

競品比對邏輯(competitor_price_feeder.py

MOMO 商品名稱[:20字] 
  → PChomeCrawler.search_products(keyword, limit=10)
  → _find_best_match(momo_name, results)
    → ProductNameParser品牌 + 規格 + 關鍵字)
    → _structural_similarity() → score
  → score ≥ 0.45 → _upsert_competitor_price()

fetch_candidates() v2 漏斗(已更新)

LEFT JOIN competitor_prices cp
       ON cp.sku = lmp.sku
      AND cp.source = 'pchome'
      AND cp.expires_at > NOW()
      AND cp.match_score >= 0.45

→ 無競品資料的商品仍回傳,pchome_price=NULL_batch_analyze 自動跳過

執行方式

# 手動觸發一輪抓取
python3 services/competitor_price_feeder.py

# 未來整合為 K3s CronJob每 4 小時)
# k8s/jobs/competitor-price-feeder-cronjob.yaml

五、Telegram 語意化訊息規範ChatOps 標準)

5.1 核心原則

  1. 語意化排版 (Semantic Formatting) — Emoji 作為視覺標籤0.5 秒判斷嚴重性
  2. 倒金字塔結構 — 結論先行 → 核心數據 → AI 洞察 → 建議行動 → 運算足跡
  3. 收斂行動呼籲 (Call to Action) — 每則訊息只有一個明確的 👉 建議行動
  4. 底部運算足跡 — FinOps + Observability用分隔線隔開主訊息

5.2 語意化 Emoji 字典

類別 Emoji 語意
身份識別 ⚡ NemoTron 派發器 Dispatcher 身份
身份識別 🔍 Hermes 3 8B Analyst 身份(僅出現在足跡)
風險級別 🚨 高危險,立即行動
風險級別 ⚠️ 中風險,人工覆核
風險級別 💡 低風險,策略建議
例行報告 📊 核心數據區塊標頭
業務屬性 💰 價格/毛利
業務屬性 📦 庫存/銷量
業務屬性 🏆 競品情報
AI 洞察 🧠 AI 分析結果
運算足跡 ⚙️ FinOps 底部區塊

5.3 三大類訊息模板(標準格式)

類別一:緊急告警(trigger_price_alert 觸發)

🚨 [⚡ NemoTron 派發器] 競價高危險預警

⚠️ 核心問題:[A003 舒特膚 AD 乳液] 價格大幅落後競品,訂單流失中!

📊 關鍵數據:
• 我方價格:$1,200
• 競品價格:$980 (價差 22.4%)
• 銷量變化:近七天銷量 -35.0%

🧠 AI 洞察 (信心度 85%)
價差已突破 20% 警戒線,且伴隨實質銷量下滑,高度判定為競品大力促銷攔截。

👉 建議行動:建議立即降價至 $1,000 迎戰,或發放 $200 專屬折價券

─────────────────────
⚙️ 運算足跡:
• 🔍 分析: Hermes 3 8B (GCP-A/GCP-B/111 Ollama) | 耗時: 34.2s | Tokens: 512 | $0 成本
• ⚡ 決策: NemoTron NIM | 185 Tokens | $0 (配額內 2/80)

類別二:人工覆核(flag_for_human_review 觸發)

⚠️ [⚡ NemoTron 派發器] 異常波動需人工覆核

🔍 待查商品:[A001 玻尿酸面膜10片裝]

📊 矛盾數據:
• 價格狀態:無明顯價差 (與競品齊平)
• 異常現象:過去 3 天銷量突然掛零 (平日日均 15 件)
• 庫存狀態:目前庫存充足 (500+ 件)

🧠 AI 洞察 (信心度 45%)
數據出現矛盾訊號AI 信心不足以自主決策,需人工走查確認。

👉 建議行動:請營運人員立即進行人工走查。

─────────────────────
⚙️ 運算足跡:
• 🔍 分析: Hermes 3 8B (GCP-A/GCP-B/111 Ollama) | 耗時: 34.2s | Tokens: 512 | $0 成本
• ⚡ 決策: NemoTron NIM | 185 Tokens | $0 (配額內 2/80)

類別三:策略執行通知(add_to_recommendation 觸發)

💡 [⚡ NemoTron 派發器] 潛力商品自動佈署

🏆 推薦品項:[A009 美白化妝水150ml] 已自動加入「首頁推薦區塊」

📊 決策依據:
我方價格低於市場 20%近7天銷量回升具備流量轉換潛力

🧠 AI 洞察 (信心度 82%)
具備價格競爭優勢NemoTron 主動提升曝光量以最大化業績。

👉 執行狀態:✅ 系統已自動寫入 ai_price_recommendations 推薦表

─────────────────────
⚙️ 運算足跡:
• 🔍 分析: Hermes 3 8B (GCP-A/GCP-B/111 Ollama) | 耗時: 34.2s | Tokens: 512 | $0 成本
• ⚡ 決策: NemoTron NIM | 185 Tokens | $0 (配額內 2/80)

類別四Gemini 備援 / 鎖定場景推理週報

... (前文省略) ...
─────────────────────
⚙️ 運算足跡:
• 🔍 彙整: Hermes 3 8B (GCP-A/GCP-B/111 Ollama) | 耗時: 12s | $0 成本
• 🧠 備援/鎖定場景: Gemini 2.5 Flash | 8,420 Tokens | 費用: 約 $0.003 USD

5.4 運算足跡資料來源

模型 API Response 欄位 說明
Hermes (Ollama) eval_count, total_duration 生成 tokens 數 + 推理耗時 (ns→s)
NemoTron (NIM) usage.total_tokens (OpenAI 格式) prompt + completion tokens 合計
Gemini usageMetadata.totalTokenCount 乘費率算 USD

程式碼位置: nemoton_dispatcher_service.py_build_footprint_block(hermes_stats, nim_stats)

5.5 Inline Keyboard 按鈕Level 2 互動,待實裝)

當收到類別一緊急告警時訊息底部附帶互動按鈕Telegram Bot API inline_keyboard

[ ✅ 批准降價 ]  [ ❌ 拒絕並忽略 ]  [ 🔗 查看報表 ]
  • ✅ 批准降價 → 呼叫 MOMO PRO 後台 API 改價 + 決策寫入知識庫
  • ❌ 拒絕並忽略 → 決策寫入知識庫(訓練未來在此品類保守點)
  • 🔗 查看報表 → 跳轉至 MOMO PRO 該商品數據分析頁

現狀: 尚未實裝Inline Keyboard 需搭配 Telegram Webhook + callback_query handler


六、Telegram 告警架構

告警群組

  • 群組: 小龍蝦 (業務情報專用,非 SRE 維運)
  • Chat ID: -1003940688311
  • Bot: 8610496165:AAFOlcWV4oRUSC2TI-fYux7JV97fjNzsYR8

單 Bot 多身份策略One Bot, Multiple Headers

模組 Telegram 標頭
Hermes 分析師 [Hermes 分析師]
NemoTron 派發器 [NemoTron 派發器]
Gemini 備援 [Gemini 備援](僅 Ollama 失敗或 ADR-028 鎖定場景)

三種告警類型

Tool 觸發條件 Telegram 格式
trigger_price_alert HIGH 風險 (gap>15% + 銷量跌>20%) 🔴/🟡 競價威脅告警
add_to_recommendation 我方價格低於競品且銷量正成長 推薦商品候選
flag_for_human_review 信心 < 0.6 或情況複雜 ⚠️ 需要人工審核

六、已驗證的服務參數

Hermes 分析師

參數
模型 hermes3:latest
Ollama URL GCP-A http://34.143.170.20:11434 → GCP-B http://34.21.145.224:11434 → 111 http://192.168.0.111:11434
Timeout 120s
Temperature 0.1
實測推理時間 19.3s3筆實彈 2026-04-17
TOP_N 20每次最多輸出威脅數

NemoTron 派發器

參數
模型 meta/llama-3.1-8b-instruct
NIM API URL https://integrate.api.nvidia.com/v1
Timeout 60s
每日配額上限 80留 20 給 AWOOOI
配額耗盡 fallback 直接派發 HIGH 風險告警,跳過 NIM
實測 token 消耗 1206 tokens/輪(實彈 2026-04-17

七、已知技術債與待辦

優先 項目 說明
Migration 003 + 004 competitor_prices + ai_price_recommendations 已在 188 momo_analytics 執行
188 生產容器實彈驗證 Hermes + NIM + PostgreSQL + Telegram 全通 (2026-04-17)
momo-app port 5001→5002 docker-registry 佔用 5001docker-compose.yml 改為 127.0.0.1:5002:80,已 Up healthy
momo-app 雙網路連線 同時連 momo-network + momo-pro_default(後者含 momo-db alias momo-postgres
P1 PChome Feeder CronJob competitor_price_feeder.py 每 4 小時排程 (Scheduler 整合)
P1 告警去重 TTL 同一 SKU 短期內重複告警未防範
P1 daily_sales_snapshot 欄位防禦 若 Excel 欄位名變更JOIN 條件會靜默失效
P2 Scheduler 整合 每6小時自動觸發 Hermes→NIM→Telegram 管線
P2 Gemini 備援治理 僅保留 ADR-028 鎖定場景與 Ollama 失敗備援,新增 caller 必須走 ADR

八、部署拓撲2026-04-17 確認)

實體機器對應

服務 主機 容器名 說明
PostgreSQL 192.168.0.188 momo-db pgvector/pgvector:pg14含所有 AI 相關表
momo-app 192.168.0.188 momo-pro-system Up healthyport 5002:805001 被 docker-registry 佔用,已改 5002
momo-scheduler 192.168.0.188 momo-scheduler 常駐排程容器
Ollama Primary 34.143.170.20 Ollama 原生 GCP-AAI/LLM/embedding 主路徑
Ollama Secondary 34.21.145.224 Ollama 原生 GCP-B同等備援
Ollama Fallback 192.168.0.111 Ollama 原生 最後一道本地防線
E2E 驗證容器 192.168.0.188 momo-e2e-test 臨時容器,含新服務模組

188 /home/ollama/momo-pro/.env 正確設定

TELEGRAM_BOT_TOKEN=8610496165:AAFOlcWV4oRUSC2TI-fYux7JV97fjNzsYR8  # ← 唯一正確 token
TELEGRAM_CHAT_IDS=["-1003940688311"]  # 小龍蝦群組
NVIDIA_API_KEY=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
USE_POSTGRESQL=true
POSTGRES_HOST=momo-db
# POSTGRES_DB / USER / PASSWORD 使用 docker-compose.yml 預設值

⚠️ Split-brain 陷阱188 容器環境曾存在舊 bot token 8569720657(不同 bot不在小龍蝦群組 已於 2026-04-17 深夜修正為正確 token 8610496165


九、校對歷程

日期 問題 修正
2026-04-17 fetch_candidates() SQL 使用 "商品編號" 修正為 "商品ID"(與 MOMO Excel 實際欄位名一致)
2026-04-17 Hermes gap_pct 由 LLM 計算 → 誤差大 改為 Python 預算 (momo-pchome)/pchome*100
2026-04-17 推理時間 52s 預算 gap_pct 後降至 19.3s (3筆)
2026-04-17 model_footprint DB 欄位寫入 {} 分離 footprint_textTelegram 顯示)與 footprint_dataDB JSON
2026-04-17 SQLite 語法 NOW() / datetime('now') / ::jsonb 全部改為 CURRENT_TIMESTAMP / Python 計算(跨 DB 相容)
2026-04-17 本機 SQLite 測試通過但 188 未同步任何檔案 rsync 推送 6 核心檔案 + 全站 dry-run 對帳 + migrations 跑通
2026-04-17 188 容器無 volume mountdocker cp 臨時解 重建 imageCOPY . . bake 進新代碼port 5001 衝突記錄為技術債
2026-04-17 188 .env Telegram token 不正確split-brain 修正為 8610496165188→Telegram message_id=282 確認
2026-04-17 NIM Tool Calling E2E 真實 NVIDIA_API_KEY 驗證dispatched=3, errors=[]