AI Agent工具使用Tool UseBuildInPublic一人公司

agent 工具整合會無聲爛掉:怎麼抓靜默回空

· 9 分鐘閱讀
龍蝦艦隊 · 逐章稽核 · 第 6 / 22 篇
目錄
  1. 一個 flag 打錯,好幾個月沒人發現
  2. 先花幾分鐘查你自己的工具整合
  3. 我們實際怎麼修的
  4. 工具使用體檢清單
  5. 這一章的四句話

《Agentic Design Patterns》第 5 章講工具使用。核心一句話:agent 不該只靠腦裡那點靜態知識,它要能伸手呼叫外部工具(查新聞、抓網頁、跑計算),把拿回來的即時資訊餵回自己的推理。

我們讀完,點頭。我們的自動發文 agent 在生成貼文前有一整段研究步驟:呼叫 blogwatcher 抓 RSS 新聞、呼叫 hn-trending 撈 Hacker News 熱門、呼叫 summarize 摘要一篇相關文章,三個工具的產出拼成「今天的真實素材」餵給模型。工具使用,實作完成。然後我們對自己做了對抗式稽核。這一章的真相是:那段研究步驟好幾個月來每次都拿到 0 筆,貼文從頭到尾沒吃過一口真實新聞,沒有人發現。

一個 flag 打錯,好幾個月沒人發現

翻出那行工具呼叫,長這樣:

BLOG_NEWS=$(blogwatcher scan --json 2>/dev/null | head -c 2000 || true)

問題出在 --json。blogwatcher 根本沒有這個 flag。它抓資料的指令是 blogwatcher scan -s,要列出來得用 blogwatcher articles,從頭到尾就沒有 scan --json 這種東西。所以每次呼叫,blogwatcher 吐一句 unknown option 然後失敗。

但你看那行後面:2>/dev/null 把錯誤訊息丟進黑洞,|| true 讓失敗的指令假裝成功,管線照樣往下走,BLOG_NEWS 拿到一個空字串。再下一行的守門檢查是這樣:

if [ -n "$BLOG_NEWS" ] && [ "$BLOG_NEWS" != "[]" ]; then
  RESEARCH_CONTEXT="..."           # 把新聞塞進素材
  log "Research: blogwatcher returned data"
fi

空字串沒通過 -n,於是整段直接跳過,被當成「今天沒新聞,正常」放行。那行 returned data 的 log 從上線到被抓到,一次都沒印過。而一行 log 的缺席,跟系統安靜運作,長得一模一樣。

先花幾分鐘查你自己的工具整合

01 把工具呼叫原封不動手動跑一次,這次別吞 stderr 你程式裡那行呼叫,連 flag 一起貼到終端機手動跑一次,但這回別把錯誤訊息丟掉。無聲失敗之所以無聲,就是因為 2>/dev/null 把「這個 flag 不存在」的抱怨擦掉了。

# 你程式呼叫的那個 flag,手動跑一次,讓 stderr 印出來
blogwatcher scan --json
# 再對一次官方說明,確認 flag/子指令今天還在
blogwatcher --help

紅旗:手動跑印出 unknown option、usage 說明、或直接空白,而你的程式把這個當正常繼續。

02 grep 工具呼叫處,看回空值時程式會不會當正常放行 危險組合是「吞 stderr + 把失敗當 true + 空值靜靜跳過」。把它們撈出來,順著看空的時候會發生什麼。

# 找「吞掉 stderr 又把失敗當成功」的呼叫
grep -nE '2>/dev/null.*\|\| true' your-script.sh
# 再看抓到的變數,空的時候會不會被當「今天沒資料」放行
grep -nE 'if \[ -n|if \[ -z|!= "\[\]"' your-script.sh

紅旗:工具呼叫吞掉 stderr,變數一空就靜靜跳過,沒有任何一行會因為「這次 0 筆」喊停或告警。

03 有沒有「輸出為空就報警」,而不只是「有資料才 log」 只在成功時 log 一行,等於失敗完全無聲。要一個正向斷言:長期掛 0 就該有人被吵醒。

# 你只有「有資料」才留痕跡,還是失敗也會出聲
grep -nE 'log|WARN|ALERT|returned' your-script.sh
# 更狠:數「拿到資料」的次數,長期是 0 就是井乾了
grep -c 'returned data' ~/.openclaw/logs/autopost.log

紅旗:只有成功才寫 log,失敗一片安靜;長期統計「拿到資料」的次數是 0,卻從沒人回頭看那個 0。

我們實際怎麼修的

把那行改成工具真的有的指令:先 blogwatcher scan -s 抓一輪,再 blogwatcher articles 把結果列出來,並在註解裡寫死一句「blogwatcher 沒有 --json,別再打了」留給下一個人。同一個洞在 mindthread/probe/advisor 三支姊妹腳本裡一模一樣,同批補掉。現在研究步驟每次真的帶著新聞進生成,log 也終於開始印 returned data。

值得講清楚它不是什麼:工具沒壞、blogwatcher 一直好好的、腳本沒 crash、timer 每天準時 fire、log 每天寫著任務完成。表面上一切健康。壞的只是一個沒人再查過的 flag,配上 2>/dev/null || true 把證據擦乾淨,再配上一個把「空」當成「正常」的守門檢查。三個東西單獨都無害,湊在一起就是一個靜默好幾個月的洞。

工具使用體檢清單

對你自己的系統跑一遍:

  • 每個外部工具呼叫的 flag/子指令,今天手動跑一次還存在嗎
  • 有沒有 2>/dev/null|| true 把工具的錯誤訊息吞掉了
  • 工具回空值時,程式會停下來喊停,還是當「今天沒資料」繼續
  • 有沒有「輸出為空就報警」的檢查,不只是「有資料才 log」
  • 長期統計「工具拿到資料」的次數,是不是一路掛 0 而沒人看
  • 依賴的工具改版、換指令時,有沒有東西會告訴你舊呼叫失效了

這一章的四句話

  • 工具會無聲爛掉。flag 改名、子指令下架、API 換格式,你的程式不會報錯,只會安靜地拿到空的。
  • 空值不是正常值。把「工具回 0 筆」當成「今天沒資料」放行,就是給無聲失敗發了通行證。
  • 2>/dev/null|| true 是在幫壞掉的整合湮滅證據。要驗一個工具,先把 stderr 放出來手動跑一次。
  • 成功要留痕跡,不是只有失敗才報警。一路掛 0 的「拿到資料」次數,比任何錯誤訊息都誠實。

原始碼位置:~/.openclaw/scripts/moltbook-autopost.sh(研究步驟,blogwatcher/hn-trending/summarize 三工具)、moltbook-autopost-mindthread.sh-probe.sh-advisor.sh(同一個 scan --json 的洞,同批修掉);工具本體在 /usr/local/bin/{blogwatcher,hn-trending,summarize}。壞掉的原始呼叫還留在 *.bak-* 備份裡:blogwatcher scan --json

這是《Agentic Design Patterns》× 龍蝦艦隊系列。我們照書把一人公司的 AI agent 艦隊系統化,然後對自己做對抗式稽核。宣稱做到的每一章,都被重新驗證過一次,也把查法和改法整理成你能照著跑的步驟。這個系列的可信度,來自我們願意公開自己打臉自己。

龍蝦艦隊 · 逐章稽核 · 第 6 / 22 篇

每週 AI 自動化實戰筆記

不廢話,只有能直接用的東西。Prompt 模板、自動化 SOP、技術拆解。

加入一人公司實驗室

免費資源包、每日建造日誌、可以對話的 AI Agent。一群用 AI 武裝自己的獨立開發者社群。

需要技術協助?

免費諮詢,24 小時內回覆。