Blog

Codex CLI, structured JSON outputs, and cron-safe AI workers

Naly 工程筆記:Codex CLI、結構化 JSON 與 Cron 安全 AI 工作者

這篇筆記說明 Naly 如何透過結合 cron 排程、嚴格的 JSON 契約與外部化日誌,將 Codex CLI 從終端程式編碼代理轉變為可預測的生產工作者。它解釋了為何可靠性來自作業不變量——鎖定、重試與驗證——而模型則可被替換,

June 25, 20269 sources

摘要

Naly 將 Codex CLI 用作排程 AI 任務的控制平面:每一個 cron 項目都執行一個已納入版本控制的腳本,啟動一個有限界限的助理任務,搭配網路搜尋與嚴格輸出契約,接著寫入已驗證的 JSON 成果供下游發佈、重播與重試。這使模型工作行為更像一條營運流水線——同一指令、明確 schema、明確產物——而非可變的互動式流程。截至 2026-06-25,這個區別就是成長關鍵內容基礎設施的可靠性優勢。

在 Naly 中的位置

Naly 已有圍繞探索、留存與分發流程的活躍 GST 優先事項。此模式直接適配該執行層:

  • Cron 工作會為每個使用情境 tsx 只調用一個腳本,因此每次執行都位於版本化程式碼內,而非臨時的 shell 片段。
  • Codex CLI 負責推理與檢索工作,而 Naly 負責編排控制:排程、重試、鎖定與持久化產物。
  • 結構化輸出會流入以 Next.js、React、Drizzle ORM 與 Neon 建置的下游系統,避免下游再進行 schema 猜測。
  • 外部日誌與執行 metadata 寫入至 NALY_LOG_ROOT,使得事後檢討可重現,且不受程序輸出緩衝影響。

核心論點是:在生產使用情境中,LLM 品質僅是系統的一半;圍繞這個 LLM 的決定性邊界才是另一半。

技術機制

1)以契約為先的 worker 進入點

每個任務都從三個不可變輸入開始:

  • 一份代碼化的提示詞模板與任務意圖。
  • 一個必須驗證的回應 schema。
  • 一個執行封裝(run_id, source_query, attempt, env),在 API 呼叫前持久化。

Naly 從 cron 以批次模式呼叫 Codex CLI,而非互動模式。Codex 在文件中被定義為本地程式碼代理,並以獨立 CLI 形式發行,具備開源配發與持續發行版本,可在腳本化環境中執行 Codex CLI, OpenAI Codex repository

2)為何結構化輸出是不可妥協的

OpenAI 的結構化輸出指南描述了 parser 支援的 schema 擷取與機器流程所需的 strict 模式行為。在 Naly 中,模型輸出被視為中介產物,而非最終真相,因此 JSON 契約才是落實可靠性的地方:

  • 必填欄位(headline、evidence list、confidence、citations、failure reason)
  • 含預設值的選填欄位
  • 數值化信心分數與有界列舉值
  • 明確將解析器失敗顯示為執行錯誤,而非悄悄自動修正文字。

3)具並發控制的 Cron 到代理生命週期

Cron 依據標準的 5 欄位時間欄位執行排程行,當欄位對應時即啟動指令 crontab。 為了生產安全,Naly 會額外加入:

  • 鎖定防護(每個任務同一時間僅有一個活躍執行)
  • 冪等執行鍵
  • 含抖動的有限重試策略
  • 各階段外部日誌擷取
  • 在由 Drizzle/Neon 管理的資料表中進行執行後狀態更新。

flock 這正是為這類防護軌跡設計的:取得鎖、執行關鍵區段、若已被鎖定則乾淨退出 flock。由於鎖定狀態與檔案描述符綁定,重疊的 cron 視窗會被明確拒絕,而不會污染狀態。

4)為什麼 MCP 在這個模式很重要

模型上下文協定(Model Context Protocol)透過 JSON-RPC、能力協商與結構化工具呼叫,將 host/client/server 工具契約正式化 MCP。在 Naly 中,MCP 式邊界降低隱含耦合:網路搜尋可被表示為受控工具介面,具備明確能力,而非自由格式的 shell 層行為。

文獻觀點

近期研究顯示,可靠性不等同於原始能力。AI Agent Reliability 論文報告了任務準確率與跨次執行一致性之間存在顯著差距,並提出用於作業層級評估的明確可靠性維度(一致性、韌性、可預測性、安全性) Towards a Science of AI Agent Reliability。這支持 Naly 的 run-state-first 設計:若某次執行成功,但無法憑清楚產物重複,則不算生產等級。

針對結構化輸出,ToolPRM 指出結構化工具呼叫行為需要明確監督,而當建模著重於內部函式呼叫流程而不只是最終結果時,改善效果尤其顯著 ToolPRM: Fine-Grained Inference Scaling of Structured Outputs for Function Calling。這與 Naly 的 schema-first runner 迴圈一致:品質關卡在介面邊界,而不只是內容流暢度。

第三篇同一前沿的研究 SLOT 則提供了實務替代路徑:在 LLM 之上加入模型無關的輸出塑形層 SLOT: Structuring the Output of Large Language Models。它再次強化相同原則:即使基礎模型品質很高,結構可靠性仍是工程問題。

設計權衡

  1. 嚴格 schema 與模型可攜性:嚴格 schema 可降低下游歧義,但在供應端對限制條件詮釋不同時,可能提高偶發解析波動。
  2. Cron 簡易性與佇列彈性:Cron 很簡單且可見,但突發工作負載需要具鎖意識的退避機制或佇列層,以避免重疊執行與錯過時窗。
  3. 任務內搜尋與決定論重播:即時網路搜尋提升新鮮度,但會引入來源波動;因此 Naly 會在執行產物中儲存查詢文字、來源清單與原始參考。
  4. 外部日誌與僅 DB 日誌:檔案系統日誌可在程序重啟後存活,且易於攝取;DB 日誌雖能簡化查詢操作,但若未精細分區,可能在開放式迴圈中失敗。

失敗模式

  • Schema 漂移:供應端輸出違反 schema;緩解方法為嚴格驗證 fail-fast、schema 版本鎖定,以及 dead-letter 執行。
  • Cron 重疊執行:雙重寫入或重複外部操作;緩解方法為 advisory lock + 程序退出保護。
  • 搜尋不穩定:上游工具回應在多次嘗試間變動;緩解方法為重試上限、指數退避、以及保存上游參考。
  • 時間異常:DST 與主機時區差異可能影響排程語意;緩解方法為 UTC 排程政策與明確環境檢查。
  • 靜默部分寫入:解析成功但下游寫入失敗;緩解方法為交易式持久化順序與冪等 upsert。
  • 安全/情境外洩:任何具工具能力的代理路徑都可能越界,因此需採用類 MCP 的最小權限邊界與明確同意/授權假設,尤其在工具執行路徑涉及網路資源時 MCP 安全備註

實作建議

  • 對每個業務任務保留一個 worker 指令於 scripts/ ,並讓 cron 僅調用該進入點。
  • 將 schema 檔案雜湊存入執行 metadata,讓模型升級後解析預期可被稽核。
  • 在包裝腳本中設定 set -euo pipefail-style 行為,並在日誌名稱中始終包含 run ID。
  • 將三個檢查點寫入日誌: started, codex_result_parsed, artifact_persisted
  • 使用 NALY_LOG_ROOT 以確保執行追蹤不污染程式碼庫狀態,且在重啟情境中可持續存在。
  • 持久化 attempt, exit_code, retry_reason,以及 validation_errors ,以便 GST 與稽核儀表板將不穩定的基礎設施與真正的模型退化區分開來。

參考資料

Sources