MapleCheng

在浩瀚的網路世界中無限潛水欸少年郎!

0%

月營收 API 的日期陷阱:不是所有資料都適合用「最近幾天」查

最近維護一個自動化資料流程時,我踩到一個看起來很小、但其實很有代表性的坑:我想查某檔股票的近期月營收,直覺上就把查詢區間設成「最近幾天」。

聽起來合理對吧?近期資料嘛,不查最近幾天要查什麼。結果 API 很乾脆地回我空資料。沒有錯誤、沒有 warning、沒有爆炸,就只是空。這種安靜的失敗最討厭,因為它不像 bug,比較像系統用一種很禮貌的方式說:「你是不是根本問錯問題?」

日資料的腦袋,遇到月資料就會翻車

很多工程師在串資料 API 時,會不自覺用「日資料」的思維去看所有東西。股價、成交量、法人買賣超、融資融券,這些資料通常都有明確交易日,所以查最近一週、最近十天,很自然。

但月營收不是這樣。

月營收的資料粒度是「月」,不是「日」。它通常會被放在某個月份 bucket 裡,例如用 YYYY-MM-01 代表那個月的資料。這不表示公司在一號公布營收,也不表示一號那天發生了什麼交易事件;它只是資料表需要一個日期欄位,所以用月份的第一天當作索引。

問題就來了:如果今天是月底,我拿「最近五天」去查,很可能查詢區間根本沒有涵蓋到這個月的 bucket 日期。API 沒壞,資料也不是不存在,是我的時間區間設計錯了。

這種錯誤很容易被誤判成「API 今天沒資料」、「來源不穩」、「是不是 rate limit」之類。然後你就會開始加 retry、換來源、補 fallback,最後把一個本來很單純的時間粒度問題,包成一團豪華義大利麵。

空資料不一定是沒有資料

這次提醒我一件很重要的事:資料系統裡的 empty response,語意通常不夠清楚。

空資料可能代表很多意思:

  • 真的沒有資料
  • 查詢區間太窄
  • 日期欄位的粒度跟你想的不一樣
  • 權限或參數錯了,但 API 沒明講
  • 上游還沒更新
  • 來源暫時異常

如果程式只是看到空陣列就說「沒有最新月營收」,那其實是在亂翻譯。比較負責任的做法,是先問:我查的時間區間是否符合這種資料的發布與索引方式?

後來我把規則調整成:遇到月營收這類月粒度資料,不用「最近幾天」查,而是從今年初,或至少從前一季開始抓。拿回資料後,再由程式挑最新兩筆來算 MoM、YoY 或判斷趨勢。

概念大概像這樣:

1
2
3
4
5
6
7
8
9
10
# 錯誤直覺:拿最近幾天查月資料
start_date = today - timedelta(days=7)
end_date = today

# 比較穩的做法:用足夠寬的區間抓月 bucket
start_date = first_day_of_quarter(today - relativedelta(months=3))
end_date = today

rows = query_monthly_revenue(stock_id, start_date, end_date)
latest = sorted(rows, key=lambda r: r["date"])[-2:]

重點不是這段 code 多漂亮,而是它把「資料粒度」寫進查詢策略裡。這才是差別。

不要讓 fallback 掩蓋建模錯誤

技術人的通病是:一看到資料抓不到,就想補 fallback。

第一來源空了,那換第二來源。第二來源也空,那用搜尋。搜尋還沒有,那用快取。聽起來很可靠,但如果根本問題是查詢模型錯了,fallback 只會讓錯誤變得更難 debug。

這次如果我沒有回頭看資料集本身的日期規則,而是直接加更多來源,系統表面上可能「比較不容易空」,但內部其實已經開始腐爛。因為每個來源對月份、發布日、歸屬期的定義可能都不一樣,最後模型拿到的是混在一起的時間語意。

對自動化報告來說,這特別危險。人類看到表格可能會覺得「怪怪的」,但 AI 很可能會很順地把它寫成一段看似合理的分析。最可怕的不是沒有資料,而是用錯資料還講得很有自信。

所以我現在越來越覺得,AI workflow 的穩定性,不只取決於模型,也取決於資料查詢層有沒有把 domain knowledge 寫清楚。

API 串接其實是在做資料契約

從 CTO 或技術主管的角度看,這種小坑不只是工程細節,它其實是在提醒團隊:串 API 不是把 endpoint 接起來就好,而是在建立資料契約。

這個契約至少要回答幾件事:

  • 這份資料的時間粒度是日、週、月,還是事件?
  • 日期欄位代表發布日、歸屬期、交易日,還是資料庫索引日?
  • 空資料時,系統要判斷成「無資料」還是「查詢策略可能錯」?
  • 報告輸出前,有沒有檢查最新資料的日期是否合理?
  • 當資料延遲或缺漏時,要降級、提示,還是直接不產出?

這些問題如果沒有寫進程式,最後就會變成維運者腦中的潛規則。短期可以靠人記得,長期一定會出事。尤其當流程交給 AI agent 自動跑,每天固定產生報告時,這些潛規則如果沒有制度化,就等於把一顆小地雷埋在排程裡。

我後來加上的幾個保護

踩完這個坑後,我會傾向在資料流程裡加幾層很樸素的保護。

第一,查詢策略要依資料類型分開,不要所有 dataset 都套同一個「最近 N 天」。日資料可以短區間,月資料就要抓跨月或跨季,財報資料可能要抓更長。

第二,空資料要有原因分類。至少要在 log 裡區分「API 回空」、「查詢區間未涵蓋 bucket」、「最新資料日期落後」、「解析失敗」。這些對使用者可能都是「沒有資料」,但對維運完全不是同一件事。

第三,輸出報告時要帶資料日期,而不是只帶結論。例如「最新月營收資料為 2026-04」比「月營收成長」可靠多了。前者讓讀者知道資料新鮮度,後者如果沒有上下文,很容易變成一種假精準。

第四,AI 負責解讀,不要負責猜資料語意。日期粒度、欄位定義、fallback 順序、驗證規則,這些應該由程式和設定檔決定。模型可以整理觀點,但不該臨場猜「這個日期大概是什麼意思」。

小坑背後的大提醒

這件事很小,小到不像值得寫一篇文章。可是回頭看,我反而覺得它很典型。

現在很多團隊都在做 AI 自動化:自動摘要、自動報告、自動分析、自動提醒。大家很容易把注意力放在 prompt 寫得好不好、模型選哪個、輸出格式漂不漂亮。但真正決定系統可靠性的,常常是這種不起眼的地方:日期欄位到底代表什麼?空資料要怎麼解釋?資料粒度跟查詢區間有沒有對齊?

AI 讓報告變得很容易產生,但也讓錯誤變得更容易被包裝得很好看。

如果這次的小坑給我一個提醒,那就是:在讓 AI 開口之前,先確定資料真的站得住腳。不要只問模型會不會分析,要先問系統有沒有問對問題。