8 種常見設定檔格式怎麼選:INI、XML、JSON、YAML、TOML 到 Markdown

整理 8 種常見設定檔格式的特點與取捨,包括 INI、XML、JSON、YAML、TOML、Apache 設定、Protocol Buffers,以及 AI Agent 時代重新受到關注的 Markdown。

只要你常寫程式、折騰伺服器、調遊戲參數,或者維護各種工具鏈,基本都逃不過設定檔。

很多時候,真正把程式搞炸的不是演算法,也不是框架,而是一行不起眼的設定:少了一個空格、多了一個逗號,或者某個值寫成了系統不想看到的樣子。把常見設定檔格式放在一起看,很自然就會回到幾個核心問題:

  • 哪些格式比較適合人來寫?
  • 哪些格式比較適合機器來讀?
  • 在 AI Agent 時代,設定檔這件事會不會發生變化?

這篇文章就是圍繞這個問題做的一次簡潔整理。

01 設定檔,本質上是在協調「人」和「機器」

有個說法我覺得很準確:設定檔其實就是人和程式之間簽下的一份「行為契約」。

它的價值很明顯。你不需要重寫業務程式碼,也不用重新編譯,只改幾行文字,就能改變網站行為、應用邏輯、部署方式,甚至遊戲畫質和隱藏選項。

問題在於,這份契約天生就有矛盾。

從人的角度,我們想要的是:

  • 好看、好寫、層級清楚
  • 最好支援註解,方便自己和別人之後回頭看
  • 能少寫就少寫,最好還能重用和模組化
  • 寫錯時不要一碰就炸

但從機器的角度,它根本不在乎優不優雅,只在乎兩件事:

  • 解析要快
  • 規則要嚴,型別要清楚,最好沒有歧義

這就是為什麼設定檔格式總是在「人類友善」和「機器友善」之間拉扯。越適合人閱讀的格式,機器往往解析更麻煩;越適合機器高效處理的格式,人寫起來通常越容易崩潰。

02 INI:簡單直接,但能力有限

先從 INI 說起。

它的優點非常直接:

  • 結構簡單
  • 分區加鍵值對,幾乎一眼就能看懂
  • 支援註解
  • 很適合一些輕量設定場景,例如遊戲參數微調、基礎環境設定

如果你改過老遊戲設定,或手動調過某些工具參數,基本都見過它。

INI 的問題也很明顯。它的結構太扁平,原生不適合表達複雜巢狀和陣列。再加上它通常缺少嚴格的型別系統,很多值本質上就是一串文字,最後怎麼解釋,還是得靠程式自己處理。

所以 INI 比較像一台老式但順手的工具車,做輕活很好用,專案一複雜就容易顯得力不從心。

一個很典型的 INI 設定會長這樣:

1
2
3
4
5
6
[server]
host=127.0.0.1
port=8080

[feature]
enable_cache=true

03 XML:嚴謹、穩定,但寫起來很累

第二位是 XML

如果你維護過老 Java 專案,或者看過一大堆成對閉合標籤的設定檔,對它應該不陌生。

XML 的優點包括:

  • 層級結構明確
  • 支援註解
  • 規則嚴整
  • 可以搭配 schema 做強校驗

這意味著機器在正式讀取前,就能先知道欄位型別、出現次數和結構約束,安全感很高。

但它對人的折磨也很經典:

  • 標籤冗長
  • 視覺噪音很大
  • 檔案容易膨脹
  • 稍微漏掉一個閉合標籤,就可能整頁報錯

所以 XML 非常像一份蓋章齊全的正式合約。機器喜歡,人維護 often 很累。現在很多新專案已經不再優先選它,但在一些老系統和嚴規則場景裡,它仍然沒有完全退場。

同樣的設定如果寫成 XML,大概會像這樣:

1
2
3
4
5
6
7
8
9
<config>
  <server>
    <host>127.0.0.1</host>
    <port>8080</port>
  </server>
  <feature>
    <enable_cache>true</enable_cache>
  </feature>
</config>

04 JSON:資料交換霸主,但不適合手寫複雜設定

說到現代開發,JSON 幾乎繞不過去。

JSON 來說,一個很典型的判斷是:作為資料交換格式,它非常強;但作為人工維護的設定檔,它有點彆扭。

它的優勢包括:

  • 物件和陣列結構清楚
  • 網路傳輸友善
  • 解析器成熟
  • 很適合 Web API 和前後端通信

尤其跟 XML 放在一起看時,JSON 的輕量優勢會很明顯。同樣的資料結構,JSON 通常更短,也更適合在網路中傳來傳去。

但它有個致命缺點:標準 JSON 不支援註解。

另外,它的語法也比較嚴格:

  • key 必須加雙引號
  • 最後一項後面不能多逗號
  • 少一個符號就可能直接報錯

所以 JSON 很適合 API、服務之間的資料交換,卻不一定適合需要人手動維護、寫說明、頻繁修改的設定檔。

例如:

1
2
3
4
5
6
7
8
9
{
  "server": {
    "host": "127.0.0.1",
    "port": 8080
  },
  "feature": {
    "enable_cache": true
  }
}

05 YAML:可讀性很強,但縮排和隱式型別會坑你

如果你碰過 Docker、CI/CD、Kubernetes、自動化部署,那基本一定和 YAML 打過交道。

它最吸引人的地方,就是看起來很「乾淨」:

  • 少了很多大括號和引號
  • 用縮排表達層級
  • 支援註解
  • 還能做錨點重用

所以從人的第一眼體驗來看,YAML 通常比 JSON 友善得多。

但問題也正出在這裡。它把很多複雜性藏起來了,實際使用時經常會出現兩類經典事故:

  • 縮排地獄
  • 隱式型別轉換

縮排問題很好理解,空格多一個少一個,設定就可能直接壞掉。更麻煩的是隱式型別轉換,例如某些看起來像普通字串的值,可能會被自動解釋成布林值或其他型別。

這也是為什麼很多人一邊誇 YAML 好看,一邊又被它折騰得很慘。它在人的閱讀體驗上確實很好,但機器解析它時並不輕鬆,而且不同解析庫之間還可能有細微差異。

同樣的設定寫成 YAML,通常會更清爽:

1
2
3
4
5
6
server:
  host: 127.0.0.1
  port: 8080

feature:
  enable_cache: true

06 TOML:在可讀性和確定性之間找平衡

TOML 經常被放在「當代均衡答案」的位置上。

TOML 的好處在於,它有點像把 INI 的直觀和 JSON 的型別明確結合在一起:

  • 支援註解
  • 結構清楚
  • 強型別更明確
  • 日期時間等常見型別支援更自然
  • 不容易出現 YAML 那種隱式轉換坑

尤其在現代工具鏈裡,TOML 已經越來越常見,例如 Python 的 pyproject.toml

當然它也不是沒有缺點。對於很深層的巢狀結構,TOML 會顯得有點囉嗦,路徑式書寫多了會煩。但如果場景是中小型專案設定、工具設定、套件管理設定,TOML 的整體體驗通常比較穩。

如果你想找一種「註解有、語義清、機器也不難受」的格式,TOML 的確值得優先考慮。

一個常見的 TOML 寫法會像這樣:

1
2
3
4
5
6
[server]
host = "127.0.0.1"
port = 8080

[feature]
enable_cache = true

07 .conf 和 Apache 設定:不是通用格式,而是領域語法

有一點很值得提醒:很多人看到 .conf,會誤以為它是一種統一格式,其實不是。

.conf 只是 “configuration” 的副檔名,裡面到底怎麼寫,完全取決於具體系統自己的規則。也就是說,.conf 比較像一個大類,而不是一套標準語法。

Apache 設定舉例,它的寫法很有代表性:

  • 一部分像單行指令
  • 一部分又像有作用域的標籤結構
  • 很適合 Web 伺服器這種特定領域

優點是對運維場景很順手,表達權限、路由、虛擬主機這類規則都很自然;缺點是它幾乎只服務於自己的生態,不具備太強的通用性。

所以這類設定更像「領域專用語言」,在特定系統裡很好用,但不適合拿來當成通用設定格式來看。

例如一個極簡的 Apache 風格設定,看起來會更像一組指令:

1
2
3
4
5
6
Listen 80

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot "/var/www/html"
</VirtualHost>

08 Protocol Buffers:工業級強型別方案,但門檻高

Protocol Buffers 其實已經不是傳統意義上的「隨手寫個設定檔」了,而更像一套正式的資料定義與序列化方案。

它的優勢很強:

  • 強型別
  • schema 明確
  • 向前向後相容性好
  • 二進位傳輸體積小
  • 機器處理效率高

但代價也很明顯:

  • 需要先寫 .proto
  • 需要工具鏈和編譯步驟
  • 對小專案來說門檻偏高

所以它不適合「我只是配個小工具」這種輕量場景,但如果你是在做大型系統、RPC、分散式服務,或長期演進的資料協議,它往往會比很多輕量設定格式更可靠。

它的寫法更接近「先定義結構,再生成程式碼」:

1
2
3
4
5
6
7
syntax = "proto3";

message ServerConfig {
  string host = 1;
  int32 port = 2;
  bool enable_cache = 3;
}

09 在 AI Agent 時代,Markdown 可能重新變成「設定方式」

最有意思的部分,是把 Markdown 也放進了「設定檔」的討論裡。

從傳統程式的視角來看,這聽起來有點奇怪,因為 Markdown 本來更像文檔格式。但如果把對象換成大語言模型或 AI Agent,這個判斷其實是成立的。

為什麼?

因為傳統程式依賴的是嚴格語法和固定欄位,而大模型更擅長理解語義、結構和上下文。對它們來說:

  • 標題就是層級
  • 列表就是步驟
  • 粗體就是強調
  • 自然語言本身就能承載規則

也就是說,當設定對象從「死板的解析器」變成「能讀懂語義的 Agent」,Markdown 這類對人友善的結構化文字,反而可能成為一種更自然的設定形式。

這也是一個很關鍵的判斷:在傳統軟體時代,很多設定格式是為了讓人去適應機器;而在 AI 時代,機器開始反過來適應人的表達。

例如給 Agent 寫任務設定,完全可以直接寫成:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 任务目标

为新用户写一封欢迎邮件。

## 要求

- 语气友好
- 不超过 150 字
- 提到产品的 3 个核心功能

## 禁止事项

- 不要承诺不存在的功能
- 不要使用夸张营销语气

10 到底該怎麼選

如果把這些觀點壓縮一下,我覺得大致可以分成這幾類:

  • 想要極簡、輕量、扁平設定:INI
  • 想要強結構、強校驗、舊系統相容:XML
  • 想要網路傳輸和介面交換:JSON
  • 想要高可讀性、雲原生與部署設定:YAML
  • 想要更穩的現代通用設定體驗:TOML
  • 想要特定系統內部規則:.conf / Apache 一類 DSL
  • 想要工業級協議與長期演進能力:Protocol Buffers
  • 面向 AI Agent 的自然表達與任務編排:Markdown

所以「最好的設定檔格式」其實並不存在。它取決於你是寫給誰看的:

  • 給人維護
  • 給機器高速解析
  • 給服務彼此通信
  • 或者給 AI Agent 理解與執行

簡單總結

設定檔的發展史,本質上就是人和機器不斷重新分配理解成本的過程。

過去是人遷就機器,所以我們要記住各種括號、縮排、引號和嚴格規則。現在隨著大語言模型和 Agent 系統越來越成熟,機器開始更能理解自然表達,於是「設定」這件事本身也在發生變化。

也許未來很多場景裡,設定檔不再是某種固定語法,而會更像一段結構化的意圖說明。而在那之前,JSONYAMLTOMLINIXML 這些格式仍然會長期共存,各自佔據最適合自己的位置。

记录并分享
使用 Hugo 建立
主題 StackJimmy 設計