首頁技術文章 › AI PLC 基準測試

我們把 AI 寫 PLC 的準確率量出來了

易歐特科技 · 平台技術 · 20 題基準測試的方法、數字與失敗分析

「AI 自動生成 PLC 程式,效率提升 10 倍。」——每一家都這樣寫。沒有一家給數字。

原因很簡單:給了數字就要負責。而且一旦你認真去量,量出來的數字通常不好看。

這篇是我們的量測結果,包含不好看的那幾項。也包含兩段我不太願意寫、但必須寫的過程:我們的量尺本身壞了,而我差一點就照著那個壞掉的數字去調整整個引擎;以及後來我們花了一整輪基準測試,證明了一件對自己不利的事。

為什麼要自己做基準測試

在這之前,我們每改一次提示詞、每加一條規則,只能憑感覺說「好像變好了」。

那不是工程,那是賭博。

而且在 PLC 這個領域,「好像」是不夠的。你不會想在客戶的曝氣池上、在別人的產線上,發現我們的「好像」是錯的。

學術界有 benchmark(Agents4PLC 用了 23 題、LLM4PLC 有自己的題庫),但那些題目跟台灣的現場長得不一樣。沒有人在 benchmark 裡放「養殖池溶氧感測器斷線時,水車該開還是該關」這種題目——而那正是我們客戶每天面對的東西。

20 題,全部來自真實案場

題目分成五組,全部是易歐特實際做過的案型:

組別題目
基本功(5 題)馬達啟停自保持、正反轉互鎖、液位兩點控制、輸送帶計數分揀、紅綠燈時序
廢水處理(4 題)曝氣池溶氧控制、pH 加藥、三台提升泵交替運轉、污泥排放定時程序
淨水 / 純水(3 題)多介質過濾器自動反洗、RO 產水導電度監控、原水槽與產水槽連動
溫室環控(3 題)降溫序列與天窗連動、定時灌溉、CO2 施肥控制
水產養殖(3 題)溶氧控制、自動投餌、電子圍籬
跨品牌(2 題)同樣的需求換成西門子 S7-1200、台達 DVP

每一題都跑完整的驗證管線——跟客戶按下「產生」時走的是同一條路,一步都沒有簡化。

這一點是整套基準測試最重要的設計原則。

如果我們為了跑得快而簡化了任何一步,量出來的數字就是假的。而假的數字比沒有數字更危險——它會讓你對錯誤的方向充滿信心。

四個維度,以及為什麼不比對「標準答案」

最直覺的做法是準備標準答案來比對。但 PLC 沒有唯一正確寫法。十個工程師會寫出十種都對的程式:有人用 SET/RST,有人用 OR 自保持;有人拆成三個 Rung,有人寫成一個 CASE 狀態機。拿標準答案去比,只會量出「像不像我」,不是「對不對」。

所以我們比對的是「該有的性質」:

維度怎麼量
① 編譯通過送進 matiec(真的 IEC 61131-3 編譯器)實際編譯。編不過就把錯誤訊息餵回去請 AI 修,最多三輪。
② 行為測試編成執行檔,在虛擬 PLC 上驅動 I/O、模擬時間、驗證輸出。「編得過」不等於「做的事是對的」。
③ 品牌白名單拿該品牌的指令白名單,逐行比對每一個助記碼。有沒有把西門子的 MOVE 寫進三菱程式。
④ 結構正確性這一題「該成立的規則」有沒有被違反。馬達啟停題如果「缺少自保持」觸發了,那就是錯了——不管它寫得多漂亮。

然後定義一個最嚴格、也最誠實的數字:「整體全對」= 三項全部通過才算。

第一次跑出來的結果

指標結果
編譯通過率85%
品牌指令乾淨95%
結構正確性50%
整體全對40%

結構正確性只有一半。最常被違反的是「缺少自保持」——20 題裡有 6 題觸發。

我當下的反應是:那就去加強提示詞、多給自保持的範例、把規則寫得更兇。

然後我停下來,去看了實際的程式碼

量尺壞了。

「缺少自保持」這條規則,把所有沒有把自己 OR 回來的 M 繼電器全部列為可疑。

問題是:一支稍微大一點的程式裡,大部分的 M 根本不該自保持。它們是每次掃描重算的旗標——「訊號有效」「警報成立」「條件符合」「在自動模式」。這些東西本來就該跟著條件走,自保持反而是錯的。

結果:這條規則在任何複雜一點的程式上幾乎必定觸發。它量的不是 AI 的錯誤率,是它自己的誤報率

如果我沒有停下來看程式碼,接下來會發生什麼事?

我會針對「自保持」瘋狂加強提示詞。AI 會學乖,開始把每一個 M 都 OR 回來——包括那些根本不該自保持的旗標。於是「警報成立」這個旗標一旦亮起就永遠不會熄滅,「訊號有效」的判斷會卡在某個狀態下不再更新。

我會用一個壞掉的量尺,把一個原本正常的引擎,調成一個真的有問題的引擎。而分數還會變得很漂亮。

這就是為什麼我說假數字比沒有數字更危險。

修好量尺

把規則改成只抓真正的「啟動鈕樣式」:這個 M 所在的那一段,是由 X 接點(實體按鈕)起始的,而且整段裡沒有把自己 OR 回來 → 放開按鈕就會消失 = 寸動。由感測器比較、其他 M 運算出來的旗標,不在此列。

然後用三個案例驗證這條規則本身:

A. 真的缺自保持(按鈕直接驅動 M0,沒 OR 自己)  → 必須抓到  ✅
B. 正確的自保持寫法                              → 不可誤報  ✅
C. 由其他 M 運算出來的旗標                       → 不可誤報  ✅

還有第二個量測錯誤,更隱蔽

基準測試跳過了「自動訂正」。

我們的產品在把程式交給客戶之前,會自動訂正機械性問題(雙線圈、計時器編號重複、指令借錯牌),並且重新編譯驗證過。

但基準測試量的是訂正之前的原始輸出。

量錯了對象,再漂亮的數字也沒有意義。客戶拿到的不是那份東西。

兩個都修好之後,重跑一次。

真實的數字

指標修正前修正後
編譯通過率85%95%
品牌指令乾淨95%100%
結構正確性50%70%
整體全對40%65%

提升來自三件事:把提示詞從瀏覽器搬進核心(以前核心連「自己怎麼問」都不掌握)、寫入八條現場鐵則、加上實案範例庫(錯誤寫法 vs 正確寫法的對照),以及編譯回修從 1 輪加到 3 輪。

但先講清楚這些數字的精度

20 題的解析度,是「一題 5 個百分點」。

我們後來又跑了三輪。四輪下來:

· 編譯通過率:80~95%
· 品牌指令乾淨:100%(四輪都是)
· 結構正確性:65~70%
· 整體全對:55~65%

這就是小樣本基準的極限,而我不打算假裝它有它沒有的精度。 所以我們對外公布的是區間,不是單點——挑最漂亮的那一次貼出來,是在騙人。

然後我們花了一整輪,證明了一件對自己不利的事

行為測試的覆蓋率一開始只有 55%——有將近一半的程式,我們其實跑不起來。查下去才發現原因跟計時器毫無關係:

是大小寫。

matiec 會把識別字全部轉成大寫(X000_StartX000_START),但 AI 設計測試案例時用的是原本的大小寫。 測試骨架產出 inst.X000_Start.value,gcc 找不到這個成員 → 編譯失敗 → 整組行為測試被丟掉

我之所以查了很久,是因為診斷訊息本身有 bug:它會試兩種型別名稱,但只留下「最後一次」的錯誤——也就是那個注定失敗的備用嘗試。真正的錯誤被自己的診斷蓋掉了。

還有第二個,更難堪:

我們的測試台把常閉接點的初始狀態搞反了。

停止鈕、過載是常閉接點——正常時是 ON。但測試台把所有變數初始化成 0,等於「過載跳脫中 + 停止鈕被按住」。

於是一支失效安全做得完全正確的程式,馬達永遠啟動不了,三個測試全部失敗。

我們一邊要求 AI 用常閉接點,一邊用一個假設常開的測試台去考它。 這比 AI 寫錯還糟——它讓正確的答案看起來是錯的。而如果我沒查清楚就去「修」那支程式,我會親手把斷線安全改掉。

兩個都修好之後,覆蓋率從 55% 拉到 80%。行為測試第一次變成一個有意義的數字。

然後我們讓 AI 自己修

做法是:測試沒過 → 讓 AI 當裁判,判斷是「程式錯」還是「測試錯」 → 如果是程式錯,讓它提出修正 → 修正必須通過三道守門員(不可弄壞安全邏輯、必須還編得過、重跑測試必須真的變好),任一道沒過就整個回退。

結果:

審判結果次數
判定「AI 程式真的寫錯」10
判定「AI 出的考題寫錯」5
→ 判定程式錯,而且真的修好了2
→ 判定程式錯,但修正被守門員擋下8

關鍵在於:那 8 次回退,是被哪一道守門員擋的?

守門員次數意義
修了也沒變好7模型能力的天花板
回了說明文字不是程式1格式問題
編譯不過0
想弱化安全邏輯0
這是最壞的一種答案。

如果回退是因為「編譯不過」,那是工程問題——我加一輪編譯器回修就能救。
如果是因為「它想弱化安全來讓測試通過」,那是守門員立功,我該慶祝。

但它是「修了也沒變好」。7 次都是。

意思是:AI 診斷得出問題,提出的修正語法正確、編譯得過、也沒動安全邏輯——然後跑測試,沒有變好

我們甚至懷疑是不是它的輸出被截斷(修正一支 400 行的程式需要很多 token),於是把輸出上限加倍再跑一輪。一點幫助都沒有。

結論

AI review 幫得上找出可疑點,但 finding 本身也會誤報、必須經規則層與測試結果校正;它更不能可靠地「修好」程式。

這不是提示詞的問題,不是模型不夠大的問題,也不是多跑幾輪能解決的。這是今天這一代模型的能力邊界。

所以我們不會再往這個方向加輪數。那是拿客戶的點數去買一個已經被證明無效的東西。

行為測試回修迴圈最後的實際產出是 2/10,把行為測試通過率從 17.7% 拉到 22.9%。有用,但很有限。

而這個發現本身,比多榨出來的那幾個百分點值錢得多——因為它精確地說明了為什麼四層驗證必須存在,以及為什麼「必須由合格工程師審查」不是一句免責聲明。

那是我們自己量出來的事實。

為什麼「範例」比「換更大的模型」有效?

AI 寫 PLC 的錯誤,九成不是「不會寫程式」,而是「沒在現場待過」

它不知道停止鈕要用常閉、不知道 4 小時不能寫成 K144000(16 位元定時器上限 K32767)、不知道溶氧感測器斷線時要把水車「打開」而不是關掉。

這不是能力問題,是經驗問題。而經驗是可以用範例傳遞的。

那錯掉的 35%,錯在哪

這是這篇文章最重要的一段。

最難看的一題:錯的是我們,不是 AI

2026-07-13 更正。這一節原本的內容是錯的,而且錯得很嚴重。我們沒有刪掉它,我們把它改寫成真相。

原本我們在這裡舉了一個「AI 犯的安全錯誤」當例子。後來發現:AI 寫的是對的,是我們的規則寫反了。

當時我們展示了一段 AI 產出的程式,說它錯了:

LD  X002        (* 過載保護,實體常閉接線 *)
OR  M1
OUT M1          (* 過載故障鎖定 *)

我們的規則說:「停止、急停、過載一律用 ANI / LDI 讀取,這才是斷線安全。」
我們的 linter 照著這條規則,把上面這段標成紅色錯誤。

那條規則是反的。

把訊號走一遍就知道了

常閉接線的過載保護,沒跳脫的時候電路是導通的 → PLC 輸入 X002 = ON(1)
跳脫、或線斷掉 → X002 = OFF(0)

所以「允許運轉」的條件必須在 X002 = 1 時成立 → 這正是常開接點(AND X002)。

如果照我們原本的規則寫 ANI X002:X002 平常就是 1,條件恆為 false → 馬達永遠啟動不了。

口訣:實體常閉 → 程式常開。接線與程式的接點型式是相反的。

真正危險的不是「啟動不了」

設備啟動不了,是個很吵的錯誤——試車第一天就會被發現。

危險的是下一步:現場為了讓設備能動,最直覺的做法就是把停止鈕改接成常開。

從那一刻起,線斷掉 = 訊號恆為 OFF = 程式判定「沒人按停止」= 停不下來。失效安全消失了,而且沒有人會發現,因為設備「看起來完全正常」。

一個接點寫反,毀掉的是整套安全設計。而我們把這個錯誤寫進了提示詞、寫進了 few-shot 範例庫(還打了 ✅)、寫進了 linter,以及四篇公開的技術文章裡。模型不是笨——它是照著我們教的寫。

這件事怎麼被抓到的

不是靠人看程式碼。是靠行為測試

我們的測試平台會把安全輸入初始化成 ON(常閉接線的正常狀態——這一塊我們一開始就寫對了)。於是規則叫 AI 寫 ANI,測試把輸入設成 1,馬達永遠不動,測試必定失敗。

兩個相反的假設在系統裡並存了很久,而測試分數一直在替我們付這個帳。我們卻把失敗歸因成「AI 修不好問題」。

所以本頁 2026-07-13 之前公布的準確率數據,全部作廢。

行為測試通過率、整體正確率,有多少是模型的問題、有多少是我們自己造成的,舊數據分不出來。

修完之後重跑,分數反而更低

我們以為修好規則、重跑一輪,數字就會回來。結果是:結構正確 55%、整體全對 40%——比作廢的舊數據還難看。

照理說應該高興才對:這才是「誠實的低分」。但有一個地方不對勁。

失分裡有 7 次是「缺少自保持」。而其中 5 次,行為測試是滿分。

一支被編成執行檔、在虛擬 PLC 上實際跑過「按下啟動 → 放開按鈕 → 馬達仍在運轉」並且通過的程式,不可能缺少自保持。

不是程式錯了。是量尺在亂叫。

查下去,量尺有三個洞:

一、把「猜測」當成「事實」在扣分。
那條規則的完整標題是「狀態繼電器可能缺少自保持」,說明裡還寫著「若本來就是寸動,可忽略此提醒」。它是一條啟發式的警告(warn),不是確定性的錯誤(err)——但計分程式一視同仁,照扣不誤。

它對這種寫法誤報:

LD  X010    (* 手動/自動 選擇開關 —— 維持型,撥過去就一直保持 *)
OUT M10     (* 自動模式旗標 *)

選擇開關不是瞬時按鈕,它本來就不需要自保持。但規則看到「X 接點驅動 M 線圈、沒有 OR 回來」就開叫。

二、一個我們自己剛剛親手弄壞的檢查項。
修正安全規則時,我們把它的標題從「安全訊號用了常開接點」改成「…反相接點」。但忘了同步基準測試裡的檢查清單。於是整套基準最重要的那個安全檢查,變成一個永遠不會觸發的死檢查——而分數看起來完全正常。

一把不會叫的量尺,比沒有量尺更危險。

沒有量尺,你知道自己不知道。
量尺壞了還在報數字,你會以為自己知道。

三、一個 JSON 解析失敗被算成「品牌指令混用」。
有一題的輸出爆掉了,解析不出來。檢查器對著一堆殘骸判定「這支程式混用了他牌指令」。那不是模型的錯,那是我們在對著空氣打分數。

三個修正

1. warn 只有在行為測試也失敗時才採信。
行為測試是真的把程式編譯成執行檔、灌進虛擬 PLC 跑過的。當一條猜測性的規則和一個真的跑起來的測試打架,該輸的是規則。

2. 加上量尺自檢(auditRuler)。
每次載入時自動比對:基準測試裡的每一個檢查項,是不是真的對得上某一條存在的規則。對不上就在啟動 log 裡大聲叫。這次是規則改名讓檢查項無聲死掉——下次不會再無聲。

3. 檢查器學會辨認維持型開關。
從 IO 表判斷「選擇 / 切換 / 模式 / 手動自動」這類開關,不再對它們要求自保持。這個誤報原本也會出現在客戶面前。

量尺修好之後的真實數字

指標舊(已作廢)壞量尺那輪修正後
通過真實編譯器80~95%80%85%
品牌指令混用0%5%0%
結構正確65~70%55%80%
整體全對55~65%40%65%
解析失敗1 題0 題

失分的 4 題,每一項都說得出是什麼:1 題真的把安全訊號寫成反相接點(那個復活的安全檢查抓到了一個真的錯誤)、1 題雙線圈、2 題真的缺自保持——而且這 2 題的行為測試也同時失敗,兩邊互相佐證。另有 3 題編譯不過。

值得說的是:「AI 找得出問題,但修不好問題」這個結論,在量尺修好之後依然成立。

審判迴圈判定「程式真的寫錯」5 次,4 次回退全部是「修了也沒變好」。
有趣的是它也判定「測試寫錯」5 次——次數一樣多。連我們的測試都不見得是對的。

那我們還是不自動修安全問題

這次的事件反而讓這個原則更站得住腳。

如果我們當初「自動幫客戶修好」這一項,今天就是幾百支程式被自動改成錯的。

停止鈕該怎麼接、程式該用哪種接點,取決於你現場的實體接線。我們不知道,所以我們不猜——我們只把它標出來給你看

一個「被自動修好」的安全問題,比一個「被明確標示」的安全問題危險十倍。因為前者會讓工程師停止思考。他看到綠色勾勾就簽名了。

這一次,停止思考的是我們。標示出來的那道防線,是我們自己也需要的。

所以我們的分工是:

問題類型我們怎麼做
機械性(雙線圈、計時器編號重複、指令借錯牌)自動訂正,並重新編譯驗證。改壞了自動回退。
安全性(接點型式、互鎖、時基、急停)絕不自動修。找出來、講清楚、告訴你為什麼,決定權在你手上。

我們自己的兩個洞

既然要誠實,就一起講完。

洞一:行為測試覆蓋 80%,還有 20% 跑不起來

「把程式真的跑起來」這一層,是我們跟同業最大的差異。修好大小寫與常閉初值那兩個 bug 之後,覆蓋率從 55% 拉到 80%

但仍有 20% 的程式,測試骨架建不出來——這代表這些程式我們沒有「真的跑起來驗證過」,它們只通過了編譯、規範檢查與規則檢查。這是我們自己工具的限制,不是 AI 的問題,而我們還在修。

洞二:西門子的 SCL 編譯通過率較低

matiec 檢查的是標準的 IEC 61131-3 ST。西門子的 SCL 有自己的擴充語法(REGION、雙引號識別字、%I0.0 位址格式),編不過不必然代表 TIA Portal 不接受。

所以我們對西門子的判定是保守的:「通過」講得肯定,「沒過」講得保守。不要嚇到客戶,也不要騙他。

這套基準測試的意義

它讓「準確率」從一句話術,變成一個可以被證明、可以被改進、也可以被推翻的數字。

之後我們每改一次核心——加一條規則、換一個提示詞、調一個參數——就跑一次這 20 題。變好還是變差,跑完就知道。不用再猜,也不用再賭。

跑一輪要花我們大約 US$3 的模型費用。這筆錢不跟客戶收。它買的不是程式碼,是「我們知道自己多準」

最後,一句必須講的話。

通過這 20 題不代表 AI 會寫 PLC。它代表的是:在這 20 種我們見過的情況下,它沒有犯我們知道的錯。

這是有意義的,但不要拿它當安全保證。

任何 AI 產出的 PLC 程式,上線前都必須由合格工程師審查並實機驗證。安全功能(急停、互鎖)必須以硬體安全迴路實現,不能只靠程式邏輯。

這不是免責聲明。這是我們做這行的規矩。

自己試一次,看看它會標出什麼

用中文說出你的控制需求,立即產生階梯圖與 ST。每一份都會跑過編譯器、PLCopen 規範、行為測試與現場規則——包括那些我們刻意不替你修、只標示出來的安全問題。

免費試用 AI PLC 工具 →

免費會員每月 15 點 · 不需信用卡 · 產生失敗不扣點

這種事,交給真的在做工程的人

易歐特科技不只是賣工具。廢水處理、淨水純水、溫室環控、水產養殖、雲端監控——10 年以上、100+ 完成案例。從盤面設計、程式撰寫到現場試車,可以整案委託。

提出工程需求 →

免費評估 · 7 個工作天內報價

延伸閱讀:我們怎麼驗證 AI 產生的 PLC 程式:四層管線 · 自保持電路與斷線安全 · 4-20mA:為什麼是 4 不是 0