← 所有文章2026.10.03 · AI 工程

可靠的 AI 工作流:允許不知道、知道何時停下,並保留人的決定

從 BIM 與工程量工作流抽出一套可移植架構:Human > Agent > Rule、合法留白、確定性計算、停止條件、證據鏈與規則沉澱。

範圍說明:這篇從一套 BIM、圖面解讀與工程量工作流中,抽出可以套用到其他高風險 AI 系統的設計原則。重點不是某個模型或產品,而是如何分配決策權、允許系統誠實留白,並讓每項結論都能追溯與重跑。

結論先行

可靠的 AI 工作流,不是想辦法讓 agent 永遠回答,而是把下面幾件事設計清楚:

  • 哪些事情只能由確定性程式處理?
  • 哪些事情可以交給 agent 判讀?
  • 哪些決定一定要由人採用與核准?
  • 資料不足時,系統能不能回答 pending 或 null?
  • Agent 應該在什麼條件下停止?
  • 最終結論能不能一路追到來源、版本與人工修正?

在 BIM、工程量、金融、醫療與合規等領域,錯誤通常不是「答案不夠漂亮」,而是錯誤數字真的會進入報價、採購、施工或責任判定。因此最值得保留的不是 prompt,而是下面這套權限與證據架構:

Human > Agent > Rule

Rule 提供可重現的預設判定;Agent 處理規則無法完整描述的證據;Human 對工程口徑、例外、採用與交付負責。重新執行 workflow 時,較低權限的結果不能把較高權限的決定洗掉。

先分清楚三種能力

AI workflow 最常見的設計錯誤,是把所有工作都包成 agent task。其實一個可靠系統應先分成 Code、Agent 與 Human。

執行者 適合負責 不應負責
Code 幾何轉換、單位換算、schema 驗證、hash、版本、工程量計算、diff 解讀模糊圖面、決定工程口徑
Agent 圖框、圖層、表格與文字理解;整理證據;產生候選值;選擇下一項檢查 未經證據直接交付最終工程量;覆蓋人工核准
Human 定義口徑、處理例外、採用候選值、核准與交付 重複執行可由程式穩定完成的機械計算

這不是依技術潮流分工,而是依錯誤性質分工。

  • 確定性問題應盡量交給 code。相同輸入應得到相同輸出,也能用 unit test 與 regression 固定。
  • 需要語意判讀的問題交給 agent,但輸出只是一項帶證據的 candidate。
  • 具有責任、風險或業務口徑的問題由 human 決定。

Agent 不直接產生不可質疑的最終答案,錯誤的 blast radius 就比較容易控制。

flowchart LR
  S[圖面 / BIM / 表格] --> C[Code<br/>解析 · 座標 · schema · hash]
  C --> A[Agent<br/>判讀 · 整理證據 · 候選值]
  A --> V[Code<br/>驗證 · 計算 · regression]
  V --> H[Human<br/>採用 · 修正 · 核准]
  H --> D[可交付結果]

Human > Agent > Rule 是權限順序,不是執行順序

三層結果可能同時存在。例如:

  • Rule 根據圖層名稱推定某物件屬於結構牆。
  • Agent 從圖例與鄰近標註判斷它可能是非結構隔間。
  • 工程師根據設計變更單確認它應按照結構牆計算。

如果只保存最後一個 value,下一次 rerun 很容易再次套用 rule 或 agent 結果,把人工決定覆蓋掉。正確做法是保留候選值與決策來源,並在合併時套用固定優先序:

type Authority = 'rule' | 'agent' | 'human';

const priority: Record<Authority, number> = {
  rule: 1,
  agent: 2,
  human: 3,
};

資料本身也必須攜帶 provenance:

{
  "field": "wallType",
  "value": "structural",
  "status": "accepted",
  "authority": "human",
  "sourceDrawing": "A-203",
  "location": "Grid B4-B7",
  "reason": "Confirmed by design change notice DCN-17",
  "runId": "run_2026_10_04_0031",
  "decidedBy": "reviewer-12",
  "decidedAt": "2026-10-04T09:30:00Z"
}

這裡需要區分兩種權力:

  • Human 有最終的採用權。
  • Code 仍保有不可繞過的契約驗證。

人工可以決定採用哪個工程口徑,但不能讓格式錯誤、單位不存在或違反 schema 的資料悄悄進入計算。若真的要突破既有約束,也應建立有理由、有簽核、有版本的 explicit override,而不是偷偷跳過 validator。

pending 與 null 是正式結果

很多 AI 系統把空值視為失敗,於是模型被隱性鼓勵填滿所有欄位。對高風險工作,這正好把不確定性變成看似精確的錯誤答案。

更好的狀態模型應明確區分:

狀態 意義 下一步
candidate 有初步判讀與證據,尚未採用 驗證或人工 review
accepted 已由相應權限採用 進入下游計算
rejected 候選值已被否決 保留理由,不再自動採用
pending 資料可能存在,但目前證據不足 補圖、補表或人工確認
null 在目前範圍明確不存在或不適用 不進行推測與計算
conflict 多個可信來源互相矛盾 停止並交由較高權限處理

評分機制也要配合。若猜對得一分、留白得零分、猜錯卻只扣一點,模型仍可能偏向亂猜。高風險欄位應讓 false positive 的代價顯著高於 abstention。

簡化後可以寫成:

正確且有證據:+1
pending / 無法判定:0
錯誤採用:-5
無來源或偽造證據:直接失敗

目的不是讓 agent 變得保守,而是讓 confidence 與實際證據一致。系統知道自己不知道,通常比輸出一個難以察覺的錯誤值更有價值。

Candidate 和 final result 必須分開

Agent 的任務是縮小人工判斷範圍,不是把候選答案偽裝成最終答案。

一個欄位可以同時保留多個來源:

{
  "field": "floorHeightMm",
  "candidates": [
    {
      "value": 3200,
      "authority": "rule",
      "evidence": "Default floor schedule rule R-12"
    },
    {
      "value": 3350,
      "authority": "agent",
      "confidence": 0.78,
      "evidence": "Section S-04, elevation annotation near Grid C"
    }
  ],
  "resolved": null,
  "status": "conflict"
}

這種表示方式比只存 3350 多一些資料,但它保留了真正重要的資訊:系統為什麼不能直接往下算。

只要 downstream calculation 明確要求 status === "accepted",未解決的 candidate 就不會不小心進入工程量。

Skill 必須包含停止條件

多數 agent SOP 只描述 happy path:打開檔案、抽取表格、判讀欄位、輸出 JSON。真正可靠的 skill 還必須回答另外五個問題:

  1. 什麼條件下可以開始?
  2. 允許讀取與修改哪些資料?
  3. 什麼叫完成?
  4. 哪些情況必須停止?
  5. 完成或停止後,由誰接手?

可以把 skill 當成一份小型契約:

name: classify-drawing-elements
inputs:
  - normalized_drawing
  - layer_manifest
allowed_actions:
  - inspect_text
  - inspect_geometry_preview
  - propose_candidates
completion:
  - every candidate has source and location
  - output passes candidate schema
stop_when:
  - drawing version is missing
  - two authoritative sources conflict
  - required scale cannot be established
  - confidence is below the field threshold
forbidden:
  - overwrite human decisions
  - emit final quantities
handoff:
  success: quantity-validator
  blocked: human-review-queue

「停止」不是 agent 失敗,而是 workflow 正確地守住權限邊界。沒有 stop condition 的 agent,通常只剩兩個選擇:無限嘗試,或猜一個答案交差。

證據不是附註,而是輸出的一部分

每個 candidate 至少應回答:

  • 來自哪張圖、哪一版?
  • 位於哪個圖框、表格、座標或構件?
  • 使用哪條規則或哪段推導?
  • Confidence 如何產生?
  • 哪個 model、prompt、skill 與程式版本建立它?
  • 後來是否被人工修改?修改前後是什麼?

一次 run 也需要 manifest:

{
  "runId": "run_2026_10_04_0031",
  "inputHash": "sha256:...",
  "drawingVersion": "REV-C",
  "model": "model-name-and-version",
  "skillVersion": "classify-elements@1.4.2",
  "ruleSet": "bim-rules@2026.10.1",
  "startedAt": "2026-10-04T09:12:03Z",
  "completedAt": "2026-10-04T09:29:41Z"
}

人工修正不應直接覆寫舊資料,而要形成 audit event:

{
  "field": "wallType",
  "before": "partition",
  "after": "structural",
  "reason": "Design change notice DCN-17",
  "actor": "reviewer-12",
  "timestamp": "2026-10-04T09:30:00Z"
}

有了這條證據鏈,團隊才能重現結果、定位 regression、比較模型版本,也能回答「為什麼當時會採用這個數字」。

把人工經驗沉澱成規則,但不要立刻自動化

這套工作流另一個重要能力,是把重複的人工作業逐步轉成 rule。正確流程不是看到一次 correction 就新增一條規則,而是:

flowchart LR
  H[人工修正] --> L[保留 before / after / reason]
  L --> P[找出重複模式]
  P --> R[提出 candidate rule]
  R --> B[回放歷史案例]
  B --> D{改善且沒有新 regression?}
  D -->|否| K[保留為人工知識]
  D -->|是| A[Human approve + version]
  A --> E[上線並監控例外]

一條規則要進入正式 rule set,至少需要:

  • 多個案例支持,而不是單次例外;
  • 清楚的適用範圍;
  • 正例、反例與邊界案例;
  • 對歷史資料做 replay;
  • Human 核准;
  • 版本、rollback 與失效條件。

同時要把知識放進最有約束力的層級:

經驗類型 最適合沉澱的位置
固定數學或幾何關係 Code / test
格式與必填契約 Schema
可明確表達的分類條件 Rule engine
需要上下文的判讀方式 Agent skill
工程口徑與特殊例外 Human decision record

不是所有 correction 都應該變成 prompt,也不是所有經驗都值得變成 skill。

Rerun 應該重算,不應該失憶

可重跑是可靠 workflow 的必要條件,但 rerun 不能等於清空所有決策重新猜一次。

合理的 rerun 應遵守:

  1. 新輸入使用 hash 與版本識別。
  2. Code 重新執行 deterministic extraction 與 calculation。
  3. Agent 可以提出新的 candidate。
  4. 既有 human decision 預設保留。
  5. 若新證據與人工決定衝突,建立 conflict,而不是覆蓋。
  6. 只有 human 明確撤銷或新版本使決定失效時,才重新開放採用。
flowchart TD
  N[新一輪執行] --> X[重新解析與計算]
  X --> A[新的 Agent candidates]
  A --> M{已有 Human decision?}
  M -->|否| R[依 authority resolve]
  M -->|是,且一致| P[保留 Human decision]
  M -->|是,但衝突| C[標記 conflict<br/>等待人工處理]

這是 Human > Agent > Rule 真正有價值的地方:它不只是畫在架構圖上的責任分工,而是資料合併時可以執行的規則。

一份實用的健康檢查

在把 AI 加入高風險流程之前,我會先檢查:

  • 最終值和 candidate 是否分開?
  • pending、null、conflict 是否為合法狀態?
  • 人工決定會不會被 rerun 覆蓋?
  • Agent 是否只能在明確範圍內判讀?
  • 數學、幾何與工程量是否由 deterministic code 計算?
  • 每個候選值是否有來源、位置、推導與 confidence?
  • 每次 run 是否記錄 input hash、model、skill 與 rule version?
  • Skill 是否包含 stop condition、forbidden action 與 handoff?
  • 人工修正是否保留 before、after 與 reason?
  • 新 rule 是否經過歷史 replay、人工核准與版本化?
  • 下游系統是否只接受已核准狀態?

我的整理

這套設計最精華的地方,是它沒有把 AI 當成比較聰明的函式,也沒有把人只放在最後按下 Approve。

它承認三件事:

  1. 有些問題可以確定計算,不應交給模型猜。
  2. 有些問題需要語意判讀,但判讀只能是帶證據的候選值。
  3. 有些決定涉及工程口徑與責任,必須由人採用,而且不能被下一次 rerun 沖掉。

好的 AI 工作流不追求消滅 null,而是讓未知保持可見;不追求 agent 永遠完成,而是讓它知道何時停止;不把人工修正當成一次性 patch,而是保留證據,再謹慎地沉澱成可驗證規則。

這比「換一個更強的模型」更接近真正的工程進步。