返回專案列表
市場情報

TMZ

Tracking Market Zeitgeist

一條正在原地重構的市場情報流水線:一個ReAct編排器調度五個可替換的專家——採集、富化、新穎度、評估、訊號——運作在同一條已經在生產環境跑著的確定性批次流水線之上,並把每一次決策都記錄成可回放的推理軌跡。一個受環境變數控制的A2A伺服器把結果暴露給生態系統裡的其他系統——在這個生態裡的第一次「反向資料流」中,TMZ還會讀回Trader Joe自己的自選股清單,讓它的掃描收斂到這個家庭真正持有的部位上,而不是一份靜態的股票清單。

分享這篇案例 →
5
市場情報專家
ReAct scheduling replaceable experts
編排方式
TraderJoe
消費方
難點所在

難點在於:原地重構一條正在生產環境運作的流水線——每個專家都先以行為完全一致的封裝形式上線,經過一致性測試驗證,然後才允許編排邏輯真正改變運作方式。

架構一覽
已上線 · 新一代架構已設計
截至 2026-07-14
ReAct orchestrator scheduling replaceable expertsConfig-driven LLM & agent configExternalized prompt storeReplayable reasoning-trace storeA2A protocol peer (market_signals, signal_accuracy)Pluggable collection-source registryMetadata-only A2A request audit
完整的內部 Agent 陣容
交接給交接給交接給交接給orchestratorcollection_expertenrichment_expertnovelty_expertevaluation_expertsignal_expert
Agent

ReAct orchestrator scheduling five replaceable Experts over the same deterministic batch pipeline already running in production

TMZ 在生態系統中
技術棧

Python, Postgres, Dagu (batch trigger), Grafana

01一條分階段的流水線,不是推倒重來

今天的生產環境循環已經是分階段的:main.py的循環驅動器依序運作schema初始化、股票代號解析、抓取校驗、落庫、富化、三個自癒式回填、評估、訊號匯出,每個階段都把結果寫進pipeline_runs表裡的一筆記錄。這套結構正是重構的地基,而不是被丟棄的東西——階段變成專家,循環驅動器變成編排器。但今天,這套結構擠在一個1047行的巨型模組裡,沒有穩定的介面:階段封裝函式接收的是具體函式作為參數,而不是一個可以被另一種實作滿足的介面。每個專家上線的第一步都是對同一個已驗證函式做純粹的重構——行為完全一致,在任何編排邏輯被打開之前先驗證過——這樣一個今晚還在生產環境跑著的系統,可以在不下線的情況下演進。

02五個專家,只有一層

採集、富化、新穎度、評估、訊號,這五個專家各自實作一個最精簡的專家協定,並封裝流水線裡已經驗證過的邏輯——採集專家負責抓取、校驗、落庫;富化專家負責L1情緒評分、L2深度閱讀,外加回填;新穎度專家負責指紋去重和評分;評估專家負責對照真實市場結果算T+1/T+5準確率;訊號專家負責Trader Joe今天就在直接從Postgres讀取的那份匯出契約。每一個都能獨立單元測試、獨立替換——未來接入Finnhub或RSS,只是多實作一個採集專家,而不是去改抓取腳本本身。它們刻意只保持一層:沒有專家會派生子專家,和這個作品集裡其他每一個系統一樣的「編排器加專家」結構。

03會推理、但不會亂跑的迴圈

編排器跑的是一個有邊界的「思考-行動-觀察」迴圈,預設策略就是今天這套固定的階段順序——ReAct在這裡只是機制,不是不確定性的許可證,一個一致性測試會驗證編排器開關狀態下寫入資料庫的結果完全一致。每一步都會寫進一張新的推理軌跡表:哪個專家跑的、它考慮了什麼、它做了什麼、一份去識別化後的觀察資料,還有一個和A2A層共用的關聯ID,讓一次跨系統呼叫和催生它的內部推理能透過同一個鍵對上。一個回放CLI可以從這張表裡把任意一個迴圈完整重建出來——這是真正的稽核能力,而今天,一次執行結束後只留得下計數和耗時,推理過程本身是留不下來的。

04一個A2A對等方,而不只是訊號來源

一個受環境變數控制的對等伺服器,把TMZ的訊號契約同時暴露給Trader Joe和Family CFO,把準確率契約暴露給Trader Joe,序列化時套用比底層匯出表更嚴格的隱私白名單——原始連結和原始資料永遠不會離開這個行程。它刻意做成雙通道:現有的Postgres直讀照常運作,HTTP介面是一層附加的、獨立開關的能力,在有對等方真正切換過去讀取之前,行為完全零變化。TMZ不只是提供方,也是消費方——它會讀回Trader Joe自己的自選股清單,這是這個生態裡的第一次「反向資料流」,讓它自己的掃描收斂到這個家庭真正持有的部位,而不是一份靜態的股票清單。

05設定和提示詞,搬出程式碼庫

TMZ今天所有LLM呼叫用的提示詞,都是寫死在富化模組裡的字串常數;重構把它們外置成一個按語言和名稱分類、有版本管理的提示詞庫,存放路徑可以用環境變數覆寫,還留著內嵌後備,這樣即便映像檔打包出錯也只是降級,而不是直接崩潰。同樣的原則也用在其他一切維運人員可能想調的東西上——每個agent用哪個LLM供應商和模型、評分權重公式、新穎度和評估閾值——統統從程式碼常數搬進一份YAML設定檔,遵循「環境變數優先於YAML、YAML優先於程式碼預設值」的順序,這樣金絲雀部署可以指向一份備用設定檔,一次閾值調整也變成一次可審閱的單行diff,而不用重新建置映像檔。它還順手根治了一個真實發生過、反覆中招的故障模式:新檔案因為Dockerfile和CI工作流程各自手寫了一份檔案清單而悄悄漏部署——套件結構重整之後,兩邊都改成了一次性的整目錄拷貝。

技術棧

Python、Postgres、OpenRouter(DeepSeek V4 Flash)、Dagu排程的批次週期、yfinance資料採集、自建Gitea Actions CI/CD。

— 履歷與聯絡方式

聊。