> ## Documentation Index
> Fetch the complete documentation index at: https://meta.niceshare.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 海勒姆定律

> 海勒姆定律指出：使用者足夠多時，系統一切可觀察行為終將被人依賴。了解其起源、應對策略、經典案例與適用邊界。

<Info>
  **類別**: 定律<br />
  **類型**: 軟體相容與 API 演化定律<br />
  **來源**: Hyrum Wright（提出觀察）；Titus Winters 命名；《Software Engineering at Google》（2020）推廣<br />
  **別名**: 隱式介面定律；逐 bug 相容（bug-for-bug compatibility）
</Info>

<Note>
  **快速回答** — **海勒姆定律**（Hyrum's Law）指出：API 使用者足夠多時，人們會依賴一切可觀察行為，而不只依賴文件承諾。文件畫了一條線，真實用法會畫出更粗的線。實務上要把「看得見」本身當作合約風險，並為隱式依賴規劃變更。
</Note>

## 什麼是海勒姆定律？

**海勒姆定律**（Hyrum's Law）是一條觀察：使用者足夠多時，系統的每一種可觀察行為都會變成某人的依賴——無論官方合約是否寫明。

> 只要 API 使用者足夠多，你在合約裡承諾什麼並不重要：系統的一切可觀察行為，都會被某人依賴。

可以把選單當成合約，把後廚習慣當成實作：客人可能開始期待從未寫進選單的餐盤尺寸、等待時間與配菜。軟體裡，排序結果、錯誤文案、耗時，甚至 bug，都可能變成承重牆。規模一大，「私有」實作就不再私有：消費者集體把整塊表面釘死。

### 海勒姆定律的三層理解

* **入門**：使用者看得見的東西，總會有人拿來搭積木——管你寫沒寫進文件。
* **實務**：改函式庫或改 API 之前，先問呼叫方可能已經依賴了哪些「文件之外」的行為。
* **進階**：按使用熵來設計——減少意外可觀察面，用測試發現破壞，並在必須改隱式介面時預留遷移成本。

## 起源

**Hyrum Wright** 在 Google 做大規模函式庫與基礎設施變更時提煉出這一觀察：即便對核心 C++ 函式庫做「看不見」的微調，也會弄壞遠處那些依賴偶然行為的系統。他把極端形式稱為**隱式介面定律**——消費者足夠多時，實質上不存在私有實作，維護者往往需要**逐 bug 相容**。

同事 **Titus Winters** 將其命名為 **Hyrum's Law**，並在 Google 內部推廣。2020 年 O'Reilly 出版的《Software Engineering at Google》（Winters、Wright、Manshreck）把它當作長生命週期程式碼的核心約束：討論變更必須正視海勒姆定律，就像討論效率必須正視熵——可以緩解，無法消滅。

Wright 的公開站點（hyrumslaw\.com）固定了經典表述，並把它與 Joel Spolsky 的**洩漏抽象定律**（Law of Leaky Abstractions）相連：消費者終究會注意到、並依賴從抽象中漏出來的細節。

## 核心要點

海勒姆定律與其說是道德戒律，不如說是對大規模使用者如何凍結可見行為的預測。

<Steps>
  <Step title="可觀察壓過已文件化">
    合約寫的是允許什麼；用法寫的是依賴什麼。錯誤字串、回應欄位順序、快取耗時、預設格式，一旦被呼叫方寫進程式碼，就成為真實介面的一部分。
  </Step>

  <Step title="規模把偶然變成剛需">
    一個使用者依賴怪癖，是一份 bug 報告；上萬使用者依賴怪癖，就是一個遷移專案。流行度不發明新物理定律——它只放大「誰會注意到每個細節」。
  </Step>

  <Step title="相容常常意味著逐 bug 相容">
    修 bug 可能弄壞那些靠它繞道的呼叫方。團隊於是在保留 bug、雙路徑並行、或支付協同遷移之間選擇——這與[波斯特爾定律](/zh-hant/laws/postels-law)在寬容與嚴格之間的權衡相鄰。
  </Step>

  <Step title="測試能發現依賴，不能消除依賴">
    廣泛自動化測試能更早暴露隱式期望。它們並不消解依賴圖；只是讓破壞成本在發布前可見。
  </Step>
</Steps>

## 應用場景

只要某樣東西共享得足夠廣，「沒人會依賴那個」就往往是一廂情願——這時就用海勒姆定律。

<CardGroup cols={2}>
  <Card title="函式庫與 API 所有權">
    把有意保證寫清楚；對必須保留變更自由的偶然行為，盡量隱藏或隨機化（例如雜湊遍歷順序）。
  </Card>

  <Card title="產品與平台變更">
    把截圖版面、CSV 欄順序、webhook 酬載怪癖當作合作夥伴與重度使用者的事實 API——不只是工程師的事。
  </Card>

  <Card title="團隊流程與制度">
    未寫明的「我們一直這麼做」會像[康威定律](/zh-hant/laws/conways-law)塑造結構一樣承重——改儀式，就有靜默東西斷裂。
  </Card>

  <Card title="個人工具與學習">
    當你為試算表的偶然排序或應用的怪異匯出寫腳本時，給依賴貼標籤；廠商「修好」怪癖時要預期它會失效。
  </Card>
</CardGroup>

## 經典案例

Python 字典排序展示了海勒姆定律如何把實作細節變成語言承諾。在 **CPython 3.6**（2016）中，緊湊字典重設計讓插入順序得以保留，但這只是**實作細節**——有用且可見，卻不是對所有 Python 實作的語言保證。呼叫方仍開始在實務中假設該順序。

到 **2017 年 12 月 15 日**，經 python-dev 討論，Guido van Rossum 裁定：「Make it so. ‘Dict keeps insertion order’ is the ruling。」**Python 3.7**（**2018 年 6 月 27 日**發布）隨後把插入順序保留宣布為語言規範的正式部分，合規實作必須遵守。專案選擇**追認**已被廣泛觀察的行為，而不是故意打亂順序並弄壞已適應的生態。教訓很尖銳：足夠多使用者看得見某種行為後，「從未承諾」是弱辯護；要麼吸收成合約，要麼支付強制遷移。邊界同樣尖銳：追認只是一種策略——當偶然行為有害或鎖死更好設計時，並不總是正確選擇。

## 邊界與失效場景

海勒姆定律在**廣泛共享、長期存活的介面**上最強。只有兩個使用者的個人腳本可以自由改；有數百萬用戶端的平台 API 不行。

它不能當作**永遠不改進**的藉口。定律預測破壞風險，並不禁止變更。它要求你為排查、溝通與遷移定價——而不是永久凍結。

常見誤用是一邊罵使用者「誤用」API，一邊繼續發出高度可見卻未文件化的怪癖。可見卻不清晰，就是在邀請依賴。另一種誤用是把每個毛刺都奉為神聖：有些 bug 仍應透過帶版本的破壞與遷移路徑修復，尤其當它們製造安全或正確性債務時。

## 常見誤區

用清之前，先把預測、歸咎與設計策略分開。

<AccordionGroup>
  <Accordion title="海勒姆定律等於文件沒用">
    不對。清晰合約仍能減少意外耦合併引導誠實使用者。定律只是說：僅靠文件擋不住人們對仍可見之物的依賴。
  </Accordion>

  <Accordion title="它只適用於公有雲 API">
    不對。內部函式庫、CLI、設定格式，甚至家裡共享的試算表，只要足夠多人在上面搭東西，就服從同一模式。
  </Accordion>

  <Accordion title="唯一應對是永遠不改">
    不對。應對包括隱藏可觀察面、版本化、雙跑、對用戶端做混沌測試，以及有時把流行行為提升為顯式保證——正如 Python 對字典順序所做的。
  </Accordion>
</AccordionGroup>

## 相關概念

這些頁面有助於把海勒姆定律放在互操作、系統生長與意外耦合之中理解。

<CardGroup cols={3}>
  <Card title="波斯特爾定律" href="/zh-hant/laws/postels-law">寬容有助於互通——也可能把怪癖固化成日後的隱式合約。</Card>
  <Card title="康威定律" href="/zh-hant/laws/conways-law">組織結構塑造系統；非正式習慣同樣塑造人們依賴什麼。</Card>
  <Card title="蓋爾定律" href="/zh-hant/laws/galls-law">能工作的複雜系統從簡單系統長成——使用者也會抓住偶然表面。</Card>
  <Card title="古德哈特定律" href="/zh-hant/laws/goodharts-law">指標成目標就會扭曲；怪癖成依賴就會凍結。</Card>
  <Card title="意外後果法則" href="/zh-hant/laws/unintended-consequences">可見副作用會成為使用者真實結果集的一部分。</Card>
  <Card title="沃斯定律" href="/zh-hant/laws/wirths-law">軟體複雜度會吃掉硬體增益——複雜度也會繁殖可觀察面。</Card>
</CardGroup>

## 一句話總結

<Tip>
  把每一種可見行為都當作潛在合約——並按「已經有人依賴它」來設計、測試與遷移。
</Tip>
