跳到內容

八大原則

八個概念,區分出「只能運作一次」與「持續運作」的建置。它們都不需要新奇的技術。多數是關於一段邏輯該放在哪裡、由誰來變更的決定。

1. 溯源性

這代表什麼。 答案中的每一個數字,都能追溯到它的出處;若資料中沒有答案,回覆會明確說明。一個沒有來源佐證的數字,並不是「有來源數字的簡化版」——它是完全不同性質的東西,而這個差異在有人依據它採取行動之前,是看不出來的。

做得好的樣子。

  • 答案中的每一個數字,都附上其所依據的紀錄,以及資料更新至哪一天。
  • 每一句引述都會與其聲稱出處的文件核對,且答案會說明它出現在該文件的哪個位置。
  • 當資料中沒有答案時,回覆會明確說明,不會捏造數字來填補空缺。
  • 每一種答案都有固定的格式——哪些數字、來自哪些來源、依什麼順序排列。固定的格式能在書面規則本身無法做到的地方,擋下捏造的數字。

會怎麼出錯。

  • 言之鑿鑿的摘要。 由 AI 產出、讀起來很順的數字,背後卻什麼依據也沒有。它能通過審查,正是因為讀起來很順。
  • 裝飾用的來源標註。 來源清單只列出文件名稱,卻沒有指出具體的列或段落,導致沒有人能不重做一遍就核對該數字。
  • 被悄悄淡化的發現。 一個曾被標記的問題,在後續處理中被悄悄降級,卻沒有人注意到它已經變了。
  • 只是存在的引述。 檢查「引述句是否出現在來源中」,只能證明這句話存在,不能證明它支持所引用的結論。

該問的問題。

  1. 挑一個近期答案中的數字。你能不問建置這個系統的人,就追溯到它的出處紀錄嗎?
  2. 答案是否附有資料的更新日期?
  3. 取一句引述。系統能證明它出現在來源中,並說出位置嗎?
  4. 當資料無法回答問題時,使用者實際上會看到什麼?
  5. 每一句引述,是否真的支持它所附加的結論,還是只是剛好出現在來源裡?

2. 確定性

這代表什麼。 由 AI 判斷該套用哪一條規則,但規則本身是一份使用者可以閱讀、可以修改的資料。運算永遠以同一種方式執行。任何有實際影響的結果,都不會在 AI 自身的推理過程中被算出來;同一個問題問兩次,會得到相同的答案。

做得好的樣子。

  • 運算永遠經過同一個專屬的計算步驟,且每一項輸入都會顯示出來。
  • 規則以使用者可以編輯的資料列或欄位存在,因此調整門檻值不需要開發人員或新版本發布。
  • 系統尚未支援的規則,會明確拒絕執行,而不是被悄悄略過或用猜的。

會怎麼出錯。

  • 寫進提示詞裡的規則手冊。 限制、標準或門檻值被寫進 AI 的指示中,沒有人能編輯、引用或稽核它們。
  • 可以跳過的計算步驟。 沒有任何機制強制 AI 使用專屬的計算步驟,於是在負荷較大時,它會自行算出結果——通常是對的,直到某次不對了,而且不會有任何提示。
  • 混在一起的規則。 系統自動套用的數字,與 AI 應當照原文引用的文字,被儲存在同一處,導致分不清哪個是哪個。
  • 用否定句寫的規則。 用「不可以發生什麼」的方式寫成的規則,無論是人還是模型,都容易讀反。把每一條規則寫成你想看到的條件,並把「兩者擇一」的要求維持為一條規則,而不是拆成兩條。

該問的問題。

  1. 輸出中的每一個數字,具體是在哪裡被計算出來的?
  2. 業務人員能不能在不找開發人員的情況下,自行調整門檻值或限制?
  3. 把同一個問題問兩次,兩次答案是否完全一致?
  4. 當系統遇到一條它還沒被教過的規則時,目前會發生什麼事?

3. 模組化

這代表什麼。 一個建置是由多個元件組裝而成,每個元件都有明確的職責與明確的介接方式,而不是一大團客製邏輯糾結在一起。只有當兩個各自獨立、指名可查的用途,都確實照原樣在使用同一個元件時,它才算「共用」——而不是因為它看起來像可以重複使用。

做得好的樣子。

  • 每個元件只做一件事,有明確定義的輸入與輸出,並且可以單獨測試。
  • 被稱為共用的元件,確實有兩個真實的使用者,照原樣在使用它,其中至少一個用途並非它最初被建置的目的。
  • 若兩個版本的差異在於內部細節被改動過,那它們老實說就是兩個不同的元件,而不是一個元件假裝通用。

會怎麼出錯。

  • 名義上共用。 一個被標為可重複使用的元件,實際上只有一個真實使用者,於是下一個團隊繼承了一個從未成立的承諾。
  • 另立門戶的副本。 因為需要再多做一點調整,有人把整個元件複製了一份,而不是把它參數化。結果變成有兩份東西要維護,卻共用同一個名字。
  • 沒有使用者的元件。 因為看起來「大概用得到」而被建置出來,卻要永遠維護下去,實際使用次數頂多一次。

該問的問題。

  1. 挑一個被標為共用的元件。指名它的兩個真實、各自獨立的使用者。
  2. 是否有任何「變體」,其差異其實來自核心邏輯被改動,而不是來自設定?
  3. 一個元件能不能在不使用真實帳號、不連接網路的情況下,單獨測試?
  4. 建置中是否存在沒有真實、指名使用者的東西?它為什麼存在?

4. 領域無關的核心

這代表什麼。 建置核心的可重複使用邏輯——代理人的核心指示、共用技能——不帶有任何客戶名稱、特定業務流程,或屬於單一公司的細節。所有屬於特定公司的內容,都以設定的形式提供,與核心並列,而不是寫死在核心裡。

做得好的樣子。

  • 核心讀起來像是在描述一個角色或一項工作,而不是把某一家公司的流程寫成一段文字。
  • 每一項屬於特定公司的細節,都透過設定提供,核心本身不包含任何超出該設定所宣告範圍的內容。
  • 只要更換設定,同一個核心就能服務不同的公司或不同的產業,不需要改動核心本身。

會怎麼出錯。

  • 寫死的業務內容。 提示詞或邏輯本體中帶有某一家公司的產品清單、專有名詞或流程,一旦該公司的資料變動,內容立刻過時。
  • 通用元件裡的公司名稱。 一個以某筆交易或某位客戶命名的元件,下一個團隊若不重新命名、重新改寫就無法重複使用。
  • 不誠實的設定。 設定中宣告了卻從未被核心實際使用的項目,或是核心使用了卻從未在設定中宣告的項目——導致沒有人能說清楚核心究竟依賴了什麼。
  • 寫死的位址。 工作流中寫入了某台機器的網路位址,將建置綁死在單一網路上,一旦搬遷安裝環境,就得逐一找出並修改每個用到它的步驟。請以安裝環境自己的內部名稱來指稱服務,並向負責維運的人員確認。

該問的問題。

  1. 在核心邏輯中搜尋公司名稱、帳號識別碼,或屬於特定客戶的用語。找到了什麼?
  2. 只更換設定,這個核心能不能服務不同的公司或產業?
  3. 設定中的每一項是否都確實被核心使用?核心是否完全不使用任何未宣告的項目?
  4. 是否有任何工作流中包含機器的網路位址?

5. 人為治理

這代表什麼。 關卡是針對特定項目所記錄下來的決定——誰做的決定、決定了什麼、什麼時候決定的——而且預設為「失敗時關閉」:沒有記錄到決定,就不會有任何輸出發出去。使用者預設在自己原本工作的地方做決定——一封附有「核准」與「拒絕」按鈕的電子郵件,每個按鈕都會開啟一個確認頁面;但決定是否被記錄下來,則不是可以選擇的事。

做得好的樣子。

  • 關卡會根據底層資料自行算出答案,而不是直接相信 AI 在同一輪對話中剛說的話。
  • 決定會被記錄下來,包括誰做的決定、決定了什麼、什麼時候——由系統本身擷取,而不是只出現在對話紀錄裡。
  • 使用者在自己原本工作的地方做決定,文件就在眼前:一封按鈕會開啟確認頁面的電子郵件。單單打開連結,不會決定任何事;只有頁面上的「確認」才會。
  • 任何有實際影響的事項都不會被自動核准。缺少決定會擋下輸出,而不是預設放行。
  • 提出請求只是暫停流程,不是結束流程。一旦決定確立,同一個執行程序會自行繼續下去——完成工作,或通知提出請求的人——不需要有人再回來問一次。

會怎麼出錯。

  • 背後空無一物的關卡。 一個要靠使用者手動更新的狀態欄位,卻沒有任何機制在監看它或依據其變動採取行動。看起來像有把關,實際上什麼也沒把。
  • 填在儲存格裡的決定。 使用者被要求在數據表裡選一個值來核准。那個值藏在一個他們沒有理由打開的表格裡,要儲存後才會生效,也讓人感覺不像是在做決定。
  • 一打開就做出決定的連結。 一個只要被造訪就會記錄決定的按鈕,會被第一個打開它的郵件掃描程式或預覽功能替人做出決定。
  • 對話式的「好」。 使用者對 AI 輸入「好」,卻沒有任何持久的紀錄留下,於是這個決定只存在於一份不會再有人讀的對話紀錄裡。
  • 輕信的關卡。 核准步驟直接採用 AI 提出的數字,而不是自行獨立算出,於是一個錯誤的數字能夠核准自己。
  • 自我核准的代理人。 代理人能透過它用來做其他事情的同一個工具,自行寫入決定——狀態、核准與否、決定者。用來記錄決定的欄位,應該在紀錄建立時就取得初始值,並拒絕代理人之後的任何寫入。
  • 把「尚無結果」讀成「通過」。 一項尚未執行、或執行失敗的檢查,會讓紀錄看起來和真正通過的一模一樣。為每一筆紀錄——包括明確通過的——都標註結果,並讓所有後續步驟等待這個結果,沒有結果就拒絕繼續。
  • 問了就卡住的請示。 決定被記錄下來了,之後卻沒有任何動作。提出請求的人得自己注意並主動追蹤後續。

該問的問題。

  1. 出示最近一次決定的紀錄。誰、決定了什麼、什麼時候?
  2. 如果核准者無法出面,還會有任何東西被放行嗎?
  3. 關卡是自行算出答案,還是相信別人交給它的數字?
  4. 審核者原本在哪裡工作、他們看到什麼?那條路徑是否曾以那個人的身分從頭到尾走過一遍?單單打開連結,會不會決定任何事?
  5. 如果同一個決定送達兩次,會發生什麼事?
  6. 代理人能不能寫入記錄決定的欄位?
  7. 當檢查還沒為紀錄標註結果時,後續步驟會怎麼做?
  8. 分別核准它、拒絕它,以及讓其中一項保持未回應。在每一種情況下,流程是否都會自行繼續——完成工作,或回報結果——不需要有人問第二次?

關於使用者如何從一封電子郵件做出決定、確認頁面做了什麼,以及為什麼單靠一句聊天回覆並不算是決定,請參見人工核准。

6. 原生優先

這代表什麼。 如果平台本身已經提供了做某件事的方式——搬移資料、發送訊息、等待某人處理、連接到另一個系統——就使用那個方式,而不是自己寫客製程式碼來做。如果你能把某項能力指名為平台的功能,用客製程式碼重新打造它,只會把這項能力藏起來、隨時間變得不易維護,而且通常最後會需要一組內建方式原本完全不需要的憑證。

做得好的樣子。

  • 建置可以透過平台自身的元件,一步一步讀懂,連非開發人員也能理解。
  • 與其他系統的連線,儲存在平台自身的連線儲存區中,範圍受限且可重複使用,絕不會內嵌在建置的邏輯裡。
  • 在確實需要客製程式碼的地方,它只針對拿到的輸入進行運算,不會自行呼叫其他任何東西。
  • 任何例外都會被寫下來:考慮過哪項平台能力、為什麼沒有使用它,以及什麼條件下能夠停用這段客製程式碼。

會怎麼出錯。

  • 手工打造的捷徑。 客製程式碼做了平台早已提供的事,通常是因為沒有人事先確認過。它通常會需要一組內建方式原本不需要的憑證,而且建置一旦搬到別的地方就會壞掉。
  • 包裝過的腳本。 一大段客製邏輯,表面上加了一層薄薄的 AI。它能得出正確答案,卻完全無法證明這個設計是否禁得起考驗。
  • 不動聲色的憑證。 一組登入資訊或金鑰被嵌在建置的某個角落,沒有人記錄下來,結果也從來沒有人回頭把它移除。

該問的問題。

  1. 打開這個建置。非開發人員能不能說出每個步驟在做什麼?
  2. 在建置中搜尋任何看起來像憑證或存取金鑰的東西。找到了什麼?
  3. 針對每一段客製程式碼:曾經考慮過哪項平台能力?為什麼它不夠用?
  4. 把建置搬到不同的帳號或環境。什麼東西會壞掉?

更多內容請見原生優先。

7. 可維運性

這代表什麼。 讓建置持續運作,是建置工作本身的一部分,而不是事後才補上的想法:要有辦法把它重設回已知狀態、要有一組固定的測試案例可以用來評分、建置的每一種運作模式都真的被實際執行過,還要有第二道獨立的檢查,來確認第一道檢查的成果。

做得好的樣子。

  • 建置的每個部分都有測試,可以在不使用真實帳號或憑證的情況下執行,而且這些測試會在任何東西發布之前自動執行。
  • 一組固定的測試案例,每次都用同樣的方式評分;無法執行的案例會被回報為「已跳過」,絕不會被悄悄算成通過。
  • 第二道獨立的檢查會審視主要流程,並標出不一致之處,而不會自己悄悄把它修好。
  • 建置可以在平台內部被重設回起始狀態,而不是靠某個人從自己的筆電手動還原。
  • 工具傳回的錯誤訊息保持簡短,而且每一段對話的篇幅,都依執行它的模型的上下文長度來設計。

會怎麼出錯。

  • 沒被親眼看過的綠燈。 一份「測試通過」的報告,是貼上去的,而不是真的被人看著跑過一遍。
  • 各自的評分方式。 每個建置都自創一套比對結果與預期的方式,導致任何兩次回報的分數都代表不同的意思。
  • 無法重設的示範。 一個只能成功運作一次的建置,之後每次要再展示,都得靠開發者本人手動把它重新組回去。
  • 未經稽核的通過。 一個結果就這樣被相信了,因為從來沒有其他人查核過它。
  • 把狀態當成結果。 一個步驟的狀態只能告訴你這個步驟跑過了;它原本該產出的紀錄,才能告訴你工作真的完成了。要查的是紀錄。
  • 被盲目信任的標準答案。 測試的標準答案是人寫的,可能有錯。當某個結果與標準答案不一致時,也要檢查標準答案本身,並同時依照原始版本與修正後的版本回報結果。

該問的問題。

  1. 你是否親自執行了測試,並且親眼看著它通過?
  2. 固定的測試集放在哪裡?上一次評分是什麼時候?
  3. 重設這個建置。它是否會回到完全相同的狀態?
  4. 是什麼在獨立檢查主要流程?上一次發現不一致是什麼時候?
  5. 沒有參與建置的人,能不能只靠套件與文件就把它安裝並執行起來?
  6. 對每一個步驟而言,哪一筆紀錄能證明它的工作確實發生過?

8. 安全與主權

這代表什麼。 在這類平台上,一組憑證是通往大量資源的鑰匙,而不是一組只對應單一小東西的密碼。要以這種心態對待它:範圍設定得越窄越好、存放在設定中、絕不內嵌在建置自身的邏輯裡、絕不提交進共用文件,也絕不作為工作上下文的一部分交給 AI 程式碼工具。

做得好的樣子。

  • 建置透過平台自身的連線來存取其他系統,因此其邏輯完全不含任何憑證,可以安全地被分享或搬遷。
  • 任何刻意保留的例外,都會直接寫在建置本身上,說明它是什麼,以及在什麼情況下就不再需要它。
  • 自動化檢查會在任何東西發布之前攔下其餘的問題:形似憑證的文字、內部機器名稱或檔案路徑、個人聯絡資訊,一概不放行。
  • 敏感欄位的遮蔽,是由平台本身對底層資料強制執行的,而不是邏輯中一個可能被跳過或遺忘的步驟。存放未遮蔽原始識別碼的儲存區,永遠不會連接到任何 AI。
  • 哪些 AI 模型能讀取資料,是依每個安裝環境、每個組織各自設定的。在讓個人資料進入系統之前,要向負責該安裝環境的人員確認:它所使用的每一個模型——無論用於對話、讀取文件或搜尋——都在部署範圍之內執行。

會怎麼出錯。

  • 圖方便的捷徑。 為了回答一個棘手的問題,暫時把存放原始敏感資料的儲存區,直接連到 AI 上。「兩者分離」原本就是整個保障的關鍵,卻就這樣悄悄失效了。
  • 藏在匯出檔裡的憑證。 一份共用套件之所以能運作,是因為裡面帶著一組有效憑證,卻被交給了團隊以外的人。
  • 無法分辨的憑證。 流程中沒有任何標示,能把用完即丟的測試憑證與正式使用中的憑證區分開來,導致建置可能誤用錯誤的一組。請為測試憑證與正式憑證分別標示,並在分享或執行建置之前,先確認它持有的是哪一種。
  • 未經檢查的匯出檔。 分享匯出檔之前沒有先打開檢查過。每一份匯出檔在離開團隊之前都要先打開,確認裡面不含任何憑證、客戶資料或個人資訊。
  • 傳進 webhook 裡的憑證。 執行歷史會保留每次執行的輸入內容,以便日後查核——這正是憑證絕不該出現在 webhook 呼叫中的原因。應傳送識別碼,讓工作流使用已儲存的連線。

該問的問題。

  1. 在即將分享出去的所有內容中,搜尋任何看起來像憑證的東西。找到了什麼?
  2. AI 程式碼工具能存取的憑證,是不是範圍受限、用完即丟的那一種?
  3. 敏感欄位的遮蔽,是由平台強制執行的,還是靠某個可能被跳過的步驟?
  4. 誰能看到未遮蔽的原始資料?實際上是什麼機制,阻止了 AI 被連接到它?
  5. 你上一次分享出去的套件,裡面實際上裝了什麼?
  6. 哪些 AI 模型會讀取這個建置的資料?其中是否有任何一個在部署範圍之外?