回到部落格

2026-04-29

【LLM應用】第三關:運維評估——批次運行過程中不知道AI做錯了怎麼辦?

【LLM應用】第三關:運維評估——批次運行過程中不知道AI做錯了怎麼辦?

【LLM 應用】第三關:運維評估——批次運行過程中不知道 AI 做錯了怎麼辦?

你有沒有遇過這種狀況:丟了一批資料進去跑,等它慢慢處理,等了二十分鐘,打開結果一看——

格式全錯、內容答非所問,或是前幾筆還好,後面越來越離譜。

整批重跑,再等一次。

這種事發生個兩三次之後,你就會開始想:有沒有辦法在跑的過程中就知道它在亂來,而不是等全部跑完才發現?

第三關要解的,就是這件事。

還沒看過前幾篇的話,可以從 [第一篇:做 LLM 應用,你在第幾關?] 開始,比較有脈絡。


最怕的是跑完才發現要重來

批次處理最怕的不是跑慢,是跑完了才發現整批都要重來。

時間浪費了,API 費用也花了,結果產出一堆沒辦法用的東西。更麻煩的是,你不知道是從哪一筆開始出問題的,只能整批重跑,然後繼續等。

第三關要做的事,就是在這個流程裡加幾道機制,讓每一筆在跑的時候就自己驗、跑完整批之後有辦法自動知道好不好、出了問題有紀錄可以查——而不是靠你親眼打開每一筆去看。

這一關有三個工具。


第一個工具:讓每一筆自己驗、自己修

想像你有一個很負責的助理,你交辦任務給他。

普通助理是做完就拿給你,有沒有問題你自己看。比較負責的助理會先自己看一遍,發現不對就自己修,修到覺得 OK 了才拿給你。

Agent 狀態機做的就是這件事——你定義好「什麼樣的輸出算過關」,它就會在每一筆交出來之前,自己先驗、自己調、自己重跑,直到符合你的標準。真的搞不定的才標記起來,讓你人工處理,不會悄悄混進去。

# 示意寫法,重點是邏輯,不是可以直接執行的程式碼

graph = StateGraph()
graph.add_node("generate", llm_generate)    # 生成這筆輸出
graph.add_node("validate", check_output)    # 自己驗,過不過關
graph.add_node("fix", adjust_and_retry)     # 不過關就自己調

# 驗不過 → 自動去調 → 調完再驗 → 過了才算完成這筆
graph.add_edge("validate", "fix", condition=lambda x: not x.is_valid)
graph.add_edge("fix", "validate")

你拿到的是每一筆都通過驗證的結果,不是「模型這次心情好不好」的結果。

核心工具是 LangGraph,概念不難,有興趣可以去翻翻文件。


第二個工具:改了 prompt,怎麼知道這批比上批好?

這個問題很實際——你調了一個 prompt,重新跑了一批,感覺好像比較好,但說不清楚哪裡好、好多少。

靠感覺很難進步,因為你沒有基準。

LLM-as-Judge 做的事是:你設定一次評分標準,讓另一個 LLM 扮演評審,對每一筆輸出自動打分。跑完整批之後,你有一個分數,可以跟上次的分數比。

# 示意寫法
scores = []
for item in batch:
    output = llm.call(item.input)
    score = judge_llm.evaluate(output, rubric)  # 另一個 LLM 來打分
    scores.append(score)

avg = sum(scores) / len(scores)
print(f"這批平均分:{avg},上批是 {previous_avg},{'進步了' if avg > previous_avg else '退步了,去看看改了什麼'}")

概念上跟寫單元測試一樣,只是評分的不是你,是另一個 AI。有了這個,改 prompt 就不再是靠感覺,是有數字在說話。

工具可以看看 PromptfooRagas,都有在做這件事。


第三個工具:記下每一筆的狀況

批次跑完之後,你通常想知道的事情是:

這一百筆裡面,幾筆成功、幾筆有問題、哪幾筆需要人工補、總共花了多少錢、跑了多久。

但如果沒有記錄,你只知道「跑完了」,其他一概不知。

# 示意:每一筆跑完記下來的東西
record = {
    "item_id": "doc_042",
    "status": "failed",           # 這筆有問題
    "retry_count": 3,             # 試了三次都不行
    "output": "...",              # 跑出來的結果是什麼
    "tokens_used": 842,           # 花了多少 token
    "cost_usd": 0.0023,          # 花了多少錢
    "failure_reason": "格式不符"  # 為什麼沒過
}

有了這份記錄,跑完整批你就能知道哪幾筆要人工處理、這批總花費是多少、如果要重跑只需要重跑失敗的那幾筆,不用整批來過。


走完三關,回頭看一眼

這個系列到這裡告一段落了。

第一關,你把積木接起來,讓東西能跑。第二關,你加了一些機制,讓格式不再亂跑、費用不再花得莫名其妙、簡單任務不再殺雞用牛刀。第三關,你讓工具開始能自己顧自己——每一筆自己驗自己修、改了 prompt 有數字告訴你好不好、跑完有記錄知道哪裡出了問題。

三關走完,基本上已經脫離「丟個 prompt 撞撞運氣」的階段了。

最後說一次:不要過度工程化。第一關還沒穩,不用急著做 LLM-as-Judge;工具還沒真的在用,不用先把所有東西都記錄起來。有痛點,再補,這才是這張地圖的正確用法。

若喜歡這樣的文章,還請給我幾個掌聲,您的支持是我寫下去的原動力!

我是一個半路出家卻把 coding 當作興趣,且不斷鑽研技巧的開發者,希望有朝一日能成為全然獨當一面的技術大神。

祝大家天天有 coding,天天有成長!