feat(telegram): ADR-019 Phase 2 - check_data_freshness tool for OpenClaw
Some checks failed
CD Pipeline / deploy (push) Has been cancelled

ADR-019 Phase 2:把資料新鮮度查詢註冊為 OpenClaw 的第 4 個 Function Calling
tool。Agent 在回答任何特定時段業績問題前可主動 probe,避免月初/季初時編造
「業績為零」這類因 ETL 尚未匯入造成的虛假結論。

新增:
- _FC_TOOLS 加入 check_data_freshness 宣告
- _execute_tool 對應分支:回傳 latest_data_date / available_months /
  current_month_has_data / data_freshness_warning
- 系統 prompt 更新:明示 4 個工具與「相對時間詞先 probe」決策規則

與 Phase 1 互補:Phase 1 是 PPT cmd 路徑寫死的補丁,Phase 2 讓 NL 對話路徑
透過 agent 自己決策,是 ADR-019「Agent-First」原則的真正起點。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
OoO
2026-05-02 12:58:06 +08:00
parent db02ecf2cf
commit b3348ae77d

View File

@@ -4148,6 +4148,16 @@ _FC_TOOLS = [{
},
"required": ["query"]
}
},
{
"name": "check_data_freshness",
"description": (
"查詢內部業績資料的最新可用日期與可用月份清單。"
"ADR-019 Phase 2在回答任何特定時段本月/本週/某月某日)業績問題前,"
"先呼叫此工具確認資料是否已涵蓋該期間,避免回覆「業績為零」這類因 ETL "
"尚未匯入造成的虛假結論。月初/季初、用戶用『本月/本週』等相對時間詞時務必先呼叫。"
),
"parameters": {"type": "OBJECT", "properties": {}, "required": []}
}
]
}]
@@ -4249,6 +4259,33 @@ def _execute_tool(name: str, args: dict) -> dict:
except Exception as e:
return {"results": [], "error": str(e)}
# ── check_data_freshness ──────────────────────────────────
elif name == "check_data_freshness":
# ADR-019 Phase 2讓 agent 在回答業績問題前 probe 資料缺口
latest = latest_date() # 'YYYY-MM-DD' 或 None
avail_months = query_available_months() or []
result = {
"latest_data_date": latest,
"today": today,
"available_months": [m["month"] for m in avail_months],
"month_count": len(avail_months),
}
if latest:
try:
latest_dt = datetime.strptime(latest.replace('/', '-'), '%Y-%m-%d')
gap_days = (now.date() - latest_dt.date()).days
result["gap_days"] = gap_days
result["current_month_has_data"] = (
latest_dt.year == now.year and latest_dt.month == now.month
)
result["data_freshness_warning"] = (
"⚠️ 當月尚無資料,請改詢問上月" if not result["current_month_has_data"]
else ("⚠️ 資料落後 " + str(gap_days) + "" if gap_days > 2 else None)
)
except (ValueError, AttributeError):
pass
return result
return {"error": f"unknown tool: {name}"}
@@ -4339,12 +4376,17 @@ def openclaw_answer(question: str):
sys_msg = (
f"你是 OpenClaw小O服務「小龍蝦」電商業務團隊的 AI 助理。\n"
f"今天是 {today_str}\n"
"你有個工具可以使用:\n"
"你有個工具可以使用:\n"
"1. query_sales — 查自家業績資料庫\n"
"2. get_market_intel — 取得外部市場情報(新聞/熱搜/PTT口碑/匯率/天氣/節慶)\n"
"3. get_knowledge — 查歷史分析知識庫\n\n"
"根據用戶問題,自主決定要呼叫哪些工具(可以同時呼叫多個)。\n"
"工具結果回來後,用繁體中文自然回答,不要開場白,不要多餘的客套話。"
"3. get_knowledge — 查歷史分析知識庫\n"
"4. check_data_freshness — 確認業績資料最新可用日期,回答任何特定時段問題前必先呼叫\n\n"
"決策規則ADR-019 Phase 2\n"
"- 用戶用『本月/本週/今天』等相對時間 → 先 check_data_freshness\n"
"- 若 data_freshness_warning 顯示當月無資料,禁止編造『業績為零』,"
"改主動問用戶是否要改看上月(並附 latest_data_date\n"
"- 工具結果回來後用繁體中文自然回答,不要開場白,不要多餘客套話\n"
"- 同時呼叫多個工具時請平行送出"
)
# 第一輪:讓 Gemini 判斷需要呼叫哪些工具