23 KiB
MOMO PRO — AI 競價情報模組 Single Source of Truth
最後更新: 2026-04-30 (台北時間) 狀態: 🟢 四 AI Agent 自動化閉環已落地 — EventRouter / AutoHeal / OpenClaw Memory / ElephantAlpha bridge / Prometheus metrics / Smoke Dashboard / Smoke Trend Management / Telegram Summary / Grafana provisioning / Prometheus scrape / CD Gunicorn 掛載具測試覆蓋 適用版本: V10.20 ElephantAlpha transient fallback 版
一、四 AI Agent 路由架構
SQL漏斗(~300筆)
↓
[Hermes 3 8B] — 分析師 (本地 Ollama, 零成本)
模型: hermes3:latest @ 192.168.0.111:11434
任務: 競價威脅分類 → TOP 20 HIGH/MED/LOW
↓
[NemoTron NIM] — 派發器 (雲端, 免費配額)
模型: meta/llama-3.1-8b-instruct @ NVIDIA NIM
任務: Tool Calling → Telegram 告警 / DB 寫入
↓
[OpenClaw / Gemini] — 策略師 (費用審批制)
任務: 週策略報告、洞察報告、L3 HITL 建議
↓
[ElephantAlpha] — 編排者 (L3 Orchestrator)
任務: 跨 Agent orchestration、HITL、AutoHeal bridge、受控 log scan
| 角色 | 模型 | 主機 | 成本 | 每日限額 |
|---|---|---|---|---|
| Hermes 分析師 | hermes3:latest / embedding model | 192.168.0.111:11434 或 188 Ollama | 零 | 無限 |
| NemoTron 派發器 | meta/llama-3.1-8b-instruct | NVIDIA NIM | 免費 80/天 | 80 |
| OpenClaw 策略師 | 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_insightsinsert 必須接enqueue_insight_embedding()或可被 backfill。 - ElephantAlpha 只做編排與 bridge,不可繞過 ADR-011 / ADR-012 / ADR-013。
可觀測性:
/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_total與momo_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 會將最近快檢結果保存到 JSONL,dashboard 顯示最近狀態趨勢。
- 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.yml的momo-appjob scrapemomo-pro-system:80/metrics;Prometheus container 需加入momo-network。 /metrics對realtime_sales_monthly只用 rawSELECT 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 保持一致。- CD rebuild 模式必須先 build image 成功,再短暫 stop/rm/recreate 三應用容器,避免 no-cache build 造成長時間 502。
- ElephantAlpha 使用 NVIDIA NIM hosted API;production 預設模型為
nvidia/llama-3.3-nemotron-super-49b-v1.5,ELEPHANT_ALPHA_FALLBACK_MODELS需保留至少一個可呼叫備援;403/404、408/409/425/429、5xx、timeout 與 connection error 必須嘗試下一個模型。 - OpenClaw/Hermes embedding 優先呼叫 Ollama
/api/embed,只在舊節點不支援時 fallback/api/embeddings;timeout 由EMBEDDING_TIMEOUT/OLLAMA_EMBED_TIMEOUT控制。
二、真實資料庫 Schema(已校對確認)
2.1 products 表(SQLAlchemy ORM,SQLite/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_prices 表(Migration 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_recommendations 表(Migration 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.py → fetch_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_code↔daily_sales_snapshot."商品ID"— 均為 MOMO 商品代碼,格式相同
四、競品價格補給線架構(已實裝)
生產者-消費者解耦設計
[competitor_price_feeder.py Worker] ←← 每 4 小時獨立運行
↓ 搜尋 PChome(search_products)
↓ 模糊比對(price_comparison.py)
↓ 提取語意標籤
↓ UPSERT competitor_prices(TTL 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 核心原則
- 語意化排版 (Semantic Formatting) — Emoji 作為視覺標籤,0.5 秒判斷嚴重性
- 倒金字塔結構 — 結論先行 → 核心數據 → AI 洞察 → 建議行動 → 運算足跡
- 收斂行動呼籲 (Call to Action) — 每則訊息只有一個明確的 👉 建議行動
- 底部運算足跡 — 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 (本地 111) | 耗時: 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 (本地 111) | 耗時: 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 (本地 111) | 耗時: 34.2s | Tokens: 512 | $0 成本
• ⚡ 決策: NemoTron NIM | 185 Tokens | $0 (配額內 2/80)
類別四(未來):Gemini 雲端推理週報
... (前文省略) ...
─────────────────────
⚙️ 運算足跡:
• 🔍 彙整: Hermes 3 8B (本地 111) | 耗時: 12s | $0 成本
• 🧠 推理: Gemini 1.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 策略師] (未來) |
三種告警類型
| Tool | 觸發條件 | Telegram 格式 |
|---|---|---|
trigger_price_alert |
HIGH 風險 (gap>15% + 銷量跌>20%) | 🔴/🟡 競價威脅告警 |
add_to_recommendation |
我方價格低於競品且銷量正成長 | ⭐ 推薦商品候選 |
flag_for_human_review |
信心 < 0.6 或情況複雜 | ⚠️ 需要人工審核 |
六、已驗證的服務參數
Hermes 分析師
| 參數 | 值 |
|---|---|
| 模型 | hermes3:latest |
| Ollama URL | http://192.168.0.111:11434 |
| Timeout | 120s |
| Temperature | 0.1 |
| 實測推理時間 | 19.3s(3筆,實彈 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 佔用 5001,docker-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 策略師 | 週報生成(需費用審批後實作) |
八、部署拓撲(2026-04-17 確認)
實體機器對應
| 服務 | 主機 | 容器名 | 說明 |
|---|---|---|---|
| PostgreSQL | 192.168.0.188 | momo-db |
pgvector/pgvector:pg14,含所有 AI 相關表 |
| momo-app | 192.168.0.188 | momo-pro-system |
Up healthy,port 5002:80(5001 被 docker-registry 佔用,已改 5002) |
| momo-scheduler | 192.168.0.188 | momo-scheduler |
常駐排程容器 |
| Hermes 3 8B | 192.168.0.111 | Ollama 原生 | hermes3:latest,E2E 可達 |
| 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 深夜修正為正確 token8610496165。
九、校對歷程
| 日期 | 問題 | 修正 |
|---|---|---|
| 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_text(Telegram 顯示)與 footprint_data(DB 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 mount,docker cp 臨時解 |
重建 image(COPY . . bake 進新代碼);port 5001 衝突記錄為技術債 |
| 2026-04-17 | 188 .env Telegram token 不正確(split-brain) | 修正為 8610496165,188→Telegram message_id=282 確認 |
| 2026-04-17 | NIM Tool Calling E2E | 真實 NVIDIA_API_KEY 驗證:dispatched=3, errors=[] |