TL;DR — 30 秒看懂 YAML
- YAML 是用缩进(空格)表示数据层级的序列化格式,和 JSON 处理相同的数据模型:字符串、数字、布尔值、null、数组、对象。
- 去掉了花括号、逗号和引号,读起来更清爽,所以配置文件中几乎清一色都是 YAML。
- Kubernetes、GitHub Actions、Docker Compose、Ansible 全都用 YAML 写。
- 比 JSON 多了注释(
#)、多行字符串(|、>)和锚点(&)/ 别名(*)。 - 想校验 YAML 或转成 JSON,直接粘贴到 YAML to JSON 工具,浏览器内完成,报错时显示行号。
YAML 是什么
YAML(YAML Ain't Markup Language)是一种面向人可读写的文本序列化格式,广泛用于配置文件和基础设施即代码(IaC)定义。
这个名字最早是 "Yet Another Markup Language"(又一种标记语言)的缩写,后来为了强调它和 HTML/XML 不同——不是标记文档结构而是表达数据——改成了递归缩写 "YAML Ain't Markup Language"。
YAML 由 Clark Evans 等人于 2001 年提出,当前主流版本是 YAML 1.2,定义为 JSON 的超集。也就是说,任何合法的 JSON 文档同时也是合法的 YAML 文档。
最核心的特征是:用缩进而不是花括号来表示层级关系。
把同一份数据分别用 YAML 和 JSON 写出来,对比一下就很直观:
name: Alice
age: 30
isStudent: false
{
"name": "Alice",
"age": 30,
"isStudent": false
}
YAML 省去了花括号、键两侧的引号和行尾逗号,只用缩进和换行来表达结构。对于需要人频繁手动编辑的配置文件来说,这种可读性非常实用。
基本语法
键值对
用冒号加空格(: )分隔键和值。冒号后面必须有空格。大多数情况下值不需要加引号。
name: 张三
age: 30
city: 北京
以下情况必须加引号:
- 值可能被解析为其他类型(
version: "1.0"、country: "NO"、zip: "07030") - 值中包含冒号(
:)、井号(#)、方括号([)、花括号({)等特殊字符(message: "Error: file not found")
缩进与层级
YAML 用空格缩进表示父子关系。
- 只允许空格:Tab 字符在语法上是严格禁止的。
- 保持一致:通常推荐 2 个空格作为一级缩进。
user:
name: 张三
address:
city: 北京市
district: 朝阳区
数组
用短横线加空格(- )表示列表项。
fruits:
- 苹果
- 香蕉
- 橘子
也支持类似 JSON 的方括号行内写法:
fruits: [苹果, 香蕉, 橘子]
注释
# 后面的内容直到行尾都是注释。JSON 没有注释语法,这是 YAML 在配置文件中最实用的特性之一。如果想给 JSON 加注释,替代方案见 JSON 可以注释吗?。
# 数据库连接配置
database:
host: localhost # 生产环境请改为域名
port: 5432
多行注释
YAML 没有 /* ... */ 这样的块注释语法。多行注释需要每行都加 #。
# 此块配置主数据库连接。
# 如果指向副本,写入会失败,请注意。
database:
host: db-primary.example.com
VS Code、IntelliJ、Vim 等主流编辑器都支持选中多行后按 Cmd+/(macOS)或 Ctrl+/(Windows/Linux)一键批量添加或移除 #。
注释掉配置以临时禁用
因为 # 可以出现在任何位置,所以可以用它来临时禁用某项配置而不删除它。
timeout: 30
# timeout: 60 # 旧值,留作参考
注意:# 要被视为注释,前面必须是空格或行首。如果写成 key: a#b(没有空格),# 会被当作字符串的一部分。
多行字符串
写长文本或脚本时,YAML 提供两种块文本标记:
字面块(|):保留换行
description: |
第一行。
第二行。
换行原样保留。
折叠块(>):换行变空格
description: >
这段话在编辑器中
为了可读性分成了多行,
但解析后是一整行长字符串。
数据类型与隐式类型推断
YAML 解析器会根据值的形态自动推断数据类型:
- 字符串:不加引号或用引号包裹
- 数字:
42、3.14、0xFF(十六进制)等自动识别 - 布尔值:
true、false;YAML 1.1 的解析器还会把yes、no、on、off当作布尔值 - null:
null、~、或冒号后留空
integer_val: 100
float_val: 3.14
boolean_val: true
null_val: ~
empty_val:
锚点与别名(值复用)
为了减少配置中的重复,YAML 支持锚点(&)、别名(*)和合并键(<<)。
# 定义公共默认配置(锚点)
default_config: &default_settings
timeout: 30
retries: 3
# 生产环境:继承默认值并覆盖 timeout
production:
<<: *default_settings
timeout: 60
# 开发环境:继承默认值并开启调试
development:
<<: *default_settings
debug: true
<<: *default_settings 会把锚点的所有键值复制过来,然后可以单独覆盖个别键。管理大型配置文件时非常省心。
实际使用场景
Kubernetes
Pod、Deployment、Service、ConfigMap 等所有资源定义都用 YAML。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
GitHub Actions
.github/workflows/*.yml 文件全是 YAML。缩进结构让 Job 和 Step 的层级一目了然。
name: CI Pipeline
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 安装依赖并运行测试
run: |
npm install
npm test
Docker Compose
docker-compose.yml 同样采用 YAML 格式,一次定义多个容器服务。
services:
web:
image: nginx:latest
ports:
- "8080:80"
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: mysecretpassword
其他工具
- Spring Boot:
application.yml分层配置 - Ansible:基础设施自动化 Playbook
- OpenAPI / Swagger:REST API 规范定义
- 静态站点生成器:Jekyll、Hugo、Astro 的 Markdown frontmatter 元数据
frontmatter 里的 YAML 如何转 JSON,实操见 Markdown frontmatter 是什么?。
常见陷阱
用了 Tab 导致语法错误
这是最常见的 YAML 报错。编辑器里看起来缩进没问题,但解析器遇到 Tab 直接报错。建议在编辑器设置中开启"Tab 键插入空格"。
挪威问题——country: NO
YAML 1.1 的解析器(如 Python 的 PyYAML)会把不带引号的 NO、no、YES、yes、ON、off 自动解析为布尔值。挪威的国家代码 NO 变成 false 就是这个原因。务必加引号:
# 错误写法(可能被解析为 false)
country: NO
# 正确写法(保持为字符串)
country: "NO"
冒号后漏了空格
key:value 不会被识别为键值对,会被当作一整个字符串。必须写成 key: value。
缩进深度不一致
同一块内混用 2 格和 4 格缩进,或者某一行多缩进或少缩进了一个空格,解析器会报出难以定位的错误。缩进、锚点、多行字符串等各语法的写法规则系统整理见 YAML 语法指南。
YAML 与 JSON 互转
YAML 和 JSON 的数据模型几乎一致,可以互相转换:
- YAML 转 JSON:把人类友好的 YAML 配置转成 API 或程序需要的严格 JSON 格式
- JSON 转 YAML:把 API 返回的 JSON 或已有 JSON 配置转成可读性更好的 YAML,方便写 Kubernetes 清单或 Docker Compose 文件
在 YAML to JSON 工具 中粘贴 YAML 即可实时校验语法并转换为 JSON,出错时会标注问题行号和原因。两个方向的转换规则详解见 YAML 转 JSON 指南 与 JSON 转 YAML 指南。


FormatArc 的所有数据转换都在浏览器本地完成,数据不会上传到服务器,涉及敏感信息的配置文件也可以放心校验。
常见问题
YAML 是什么意思?
"YAML Ain't Markup Language" 的缩写。最初是 "Yet Another Markup Language"(又一种标记语言),后来改为递归缩写以强调它是数据表达格式而非标记语言。
YAML 是编程语言吗?
不是。YAML 是纯数据序列化格式,没有条件判断、循环、函数等控制结构,只用于数据交换和配置文件的编写。
.yml 和 .yaml 有区别吗?
没有。所有 YAML 解析器对两种扩展名的处理方式完全相同。官方规范推荐 .yaml,但 .yml 因为短一个字符也被广泛使用。
为什么 Kubernetes 和 GitHub Actions 用 YAML 而不是 JSON?
因为人眼读起来更直观。没有花括号和逗号的视觉噪音,加上可以写注释说明为什么设这个值,手动编辑配置时体验好很多。
YAML 和 JSON 的主要区别是什么?
数据模型相同,但 YAML 用缩进表示结构,支持注释、多行字符串和锚点。JSON 语法更严格、解析速度更快,适合机器之间的 API 通信。两者的系统对比见 YAML 和 JSON 区别。
为什么 country: NO 变成了 false?
YAML 1.1 规范把 NO、no、YES、yes、ON、off 定义为布尔值的别名。用引号包起来写成 country: "NO" 就能保持为字符串。
总结
- YAML 是用缩进表达层级的可读性优先的数据格式
- 支持注释、多行文本、锚点等 JSON 没有的特性
- 是 Kubernetes、GitHub Actions、Docker Compose 等 DevOps 工具的标准格式
- 注意:Tab 禁用、冒号后必须空格、
NO等词会被隐式转为布尔值 - 需要校验或转换时,用浏览器内的 YAML to JSON 工具 即可