说实话,Windows 下用 codex 写带中文的文档,第一次看到满屏???和“锟斤拷”的时候,血压是真的压不住。明明代码逻辑没问题,生成的 Markdown 打开一看全乱,命令行里更是惨不忍睹。这个事不是个例,几乎每个在 Windows 上跑 CLI 类 AI 工具的开发者都会撞上。我一直认为这不是 codex 的锅,真正的问题出在 Windows 那套祖传编码体系上:简体中文系统默认代码页是 GBK,而 codex 这类工具产出的文本基本是 UTF-8,两边字符集不在一个频道上,乱码就成了必然。
这篇博文要分享的,是我自己整理并验证过的一个 codex skill,专门用来在 Windows 下拦截和修复文档书写过程中的中文乱码问题。它不是玄学补丁,而是把编码检测、转码规则、输出规范做成了 skill,让 codex 在写任何含中文的文档前先过一遍流程。适合所有在 Windows 下使用 codex 或同类 AI 命令行工具写文档、写脚本、写配置的人。你不需要是编码专家,照着装、照着用就行,底层原理我也会讲清楚。
1. 先定性:乱码的根子在 Windows 的编码生态,不在 codex
1.1 两个字符集,一场持续几十年的战争
中文 Windows 从 DOS 时代延续下来,简体中文系统的默认代码页是 936,也就是我们常说的 GBK。GBK 用两个字节表示一个汉字,在设计上兼容了区位码和 ASCII。而 codex 以及绝大多数现代开发工具用的都是 UTF-8,它是 Unicode 体系下的变长编码,英文占一个字节,中文通常占三个字节。
这两套编码最关键的区别不是“字节数不同”,而是同一个汉字的字节序列完全不同。比如“中文”这两个字,GBK 下是D6 D0 CE C4,UTF-8 下是E4 B8 AD E6 96 87。当 UTF-8 的字节流被当成 GBK 去解码时,系统会把每两个字节强行拼成一个“汉字”,结果就是锟斤拷、烫烫烫这类经典乱码。反过来,GBK 字节流被当成 UTF-8 解码,通常直接报错或者出现一堆问号。理解了这一点,再看所有乱码问题就清晰了:乱码的本质永远是解码方式与编码方式不匹配。
我用一个生活化的类比总结:GBK 是中文世界的“本地话”,UTF-8 是世界通用的“普通话”。Windows 里的 cmd、老版本记事本、各种国产软件默认只讲本地话;codex 从出生就只讲普通话。两边各说各的,能不乱吗。
1.2 乱码发生的链路:终端、文件、工具一个都不能少
在 Windows 下,codex 输出文字要经过三层,每一层都可能出问题,这也是为什么很多人修了半天发现“终端好了文件又乱”“文件好了,换个软件打开又乱”。
第一层是终端层。控制台代码页决定了 codex 打印到屏幕上的字符怎么被解析。Windows 默认代码页 936,而 codex 往标准输出里写的是 UTF-8 字节流,终端按 GBK 解码,屏幕上自然全是乱码。这层出了问题,现象是“在终端里看到乱码,但文件内容可能是正常的”。
第二层是文件层。codex 在写文件时,用什么编码写入、有没有带 BOM,直接决定这个文件在别的软件里能不能被正确识别。UTF-8 分为带 BOM 和不带 BOM 两种,BOM 是文件开头的三个魔法字节EF BB BF,用来告诉读取者“我是 UTF-8”。但很多 Windows 老程序不认识 BOM,会把 BOM 当成内容的一部分读进去,造成第一行出现奇怪的字符。
第三层是工具层。你用什么软件打开文件,就决定了文件以何种编码被展示。同一个 UTF-8 无 BOM 文件,新版记事本能猜对并正常显示,老版本记事本大概率按 GBK 读,VSCode 又可能自动识别成 UTF-8。工具识别错了,内容没坏,但看起来就是乱码。
这三层链路一旦串起来出问题,排查就特别费劲。网上那些高频搜索词,比如“vscode终端中文乱码”“cmd 运行中文程序输出乱码”“批处理脚本 echo 中文闪退”“devc++ 编译输出中文乱码”“qt 输出中文乱码 vs2019”“matlab 中文注释乱码”“Windows 高版本系统 notepad 记事本中文乱码”,本质全都可以归纳到这条链路上。我们这篇聚焦 codex 场景,但把链路理解透了,那些问题也能顺手解决大半。
1.3 不只是 codex:Windows 下所有中文乱码都是同一个坑
很多人在 codex 里遇到乱码后,第一反应是“这工具不行”,其实是冤枉它了。随便搜一下就能看到,vscode 终端乱码、printf 中文乱码、devc++ 输出乱码、matlab 注释乱码,这些跟 codex 八竿子打不着的场景,问题根源高度一致。
以 printf 中文乱码为例,你写了个 C 程序,源码保存成 UTF-8,编译时编译器按本地代码页处理字符串字面量,运行环境又是 GBK 的 cmd 窗口,输出不乱才怪。vscode 终端乱码也一样,终端用的 code page 还是 936,shell 输出的 UTF-8 字符显示出来就是乱的。它们和 codex 乱码唯一的共同点就是:生产端和消费端的编码不一致。
这也是为什么我最终决定做一个 skill 而不是记一堆零散笔记。因为只解决 codex 的单点问题没有意义,得让 codex 在 Windows 上从源头养成正确的编码习惯,才能保证它生成的所有文档、脚本、配置文件都能顺利交付到其它工具链里。
2. skill 是什么,以及为什么用它来治乱码
2.1 skill 不是 agent,它的定位是“专业能力包”
最近“skill”这个词在 AI 工具圈热度很高,各种 skill 层出不穷,比如数学建模 skill、workbuddy skill、仓颉 skill。很多人会把 skill 和 agent 搞混,我先说下两者的关系。
agent 是能自主拆解任务、调用工具、执行动作的主体,你可以把它想成一个“全能实习生”。而 skill 是给这个实习生用的“岗位操作手册”或者“专业能力包”,它规定了在特定任务下应该遵循的流程、规范和注意事项。同一个 agent 可以挂载很多个 skill,同一个 skill 也可以被不同的 agent 复用。
拿 codex 来举例。codex 本身就是一个 agent,它能理解你的自然语言指令、编辑文件、执行命令。当你给它挂上“Windows 乱码修复 skill”后,它在执行写文档任务时,就会自动参考 skill 里的编码规则,而不是靠模型临时发挥。模型未必记得住 Windows 下 GBK 和 UTF-8 的那些细节,但 skill 里白纸黑字写清楚了,它只需要照着做。
2.2 用 skill 治乱码的好处:从“每次手动修”到“每次自动防”
如果你只是偶尔一次乱码,手动执行一下chcp 65001切代码页就够了。但 codex 写文档是日常操作,每次都要记得切换、每次都要盯着输出检查,太反人类了。
skill 的核心价值在于把规范和决策树固化到 codex 的工作流里。只要触发条件命中,codex 就会自动执行 skill 里的流程:先检查当前系统编码状态,再根据输出目标选择合适编码,文件生成后做二次验证,遇到已有乱码文件会先备份再转码。整个过程不需要你干预,从“事后修”变成了“事前防”。
而且 skill 是可维护的。你在使用过程中发现了新的编码坑,直接编辑 SKILL.md,加一条规则就行。这比在系统里改一堆环境变量、写一堆批处理要干净得多,也方便在不同机器之间同步。
2.3 codex skill 的大致工作机制
codex 通常在用户主目录下有一个.codex配置目录,Windows 下一般是C:\Users\你的用户名\.codex\。skill 就放在这个目录下的skills子目录里,每个 skill 是一个独立文件夹,核心文件是SKILL.md。
当 codex 在对话中识别到某个 skill 被启用或与当前任务相关时,它会把SKILL.md的内容加载进上下文,作为执行指令的一部分。SKILL.md可以写触发条件、执行流程、规范规则,还可以引用辅助脚本。codex 会按这些步骤来执行,而不是自由发挥。
需要提醒的是,不同版本的 codex 对 skill 的触发方式和配置项细节可能有差异。我在下面的实操中会给出一个通用的目录结构和配置方式,你按照自己安装的版本微调即可。重点是理解思路,不要死记路径。
3. 实战:写一个专治 Windows 中文乱码的 skill
3.1 目录结构与核心文件
我设计的这个 skill 叫fix-windows-encoding,目录结构如下:
~/.codex/skills/fix-windows-encoding/ ├── SKILL.md ├── scripts/ │ ├── check_encoding.py │ └── fix_mixed_encoding.pySKILL.md是 skill 的核心指令文件,负责告诉 codex“在什么场景下启用、按什么规则输出、遇到乱码如何修复”。scripts目录下放两个 Python 脚本,一个用于编码环境检查和单文件编码识别,另一个用于批量转码和备份。Python 在 Windows 下基本是标配,如果你机器里实在没有 Python,也可以用 PowerShell 替代,但 Python 的编码探测能力更干净利落。
3.2 SKILL.md 的核心指令编写
以下是一个可以拿来就用的 SKILL.md 模板,它基于 codex 常见的 SKILL 机制编写,具体字段可能需要根据你的 codex 版本做微调:
--- name: fix-windows-encoding description: 在 Windows 环境下编写文档、脚本、日志、配置文件时,自动处理和预防中文乱码问题。适用于 codex 生成或修改 markdown、txt、bat、ps1、json、log 等文件。 trigger: 当任务涉及创建、修改或修复包含中文的文档、脚本、配置文件,或用户明确提到乱码、编码、GBK、UTF-8 等问题时,自动启用本 skill。 version: 1.0.0 --- # 执行流程 1. 编码环境检测 - 记录当前控制台代码页(chcp 输出结果) - 检查目标文件当前编码状态,优先用 scripts/check_encoding.py 识别 2. 输出编码规范 - markdown、txt、log、json、yaml、env 文件:默认使用 UTF-8 无 BOM - bat / cmd 批处理脚本:使用 GBK 或 UTF-8 无 BOM,严禁带 BOM - PowerShell 脚本:使用 UTF-8 无 BOM - 如果目标交付对象明确只支持 ANSI/GBK,则转 GBK 并在交付说明中注明 3. 乱码修复流程 - 修复前先备份原文件为 .bak - 用 scripts/check_encoding.py 探测原文件编码 - 根据探测结果,用 scripts/fix_mixed_encoding.py 转码为指定编码 - 转码完成后再次用 check_encoding.py 验证 4. 强制规则 - 不修改系统级区域设置 - 不要求用户开启 Beta 版 UTF-8 全局支持 - 生成文件时主动在最终交付说明里注明该文件的编码格式这份 SKILL.md 的核心思想是“先检测、再决策、后操作”。codex 读到这里时,会先跑检测脚本,再根据文件类型决定编码,最后才动手写内容。这样一来,codex 就不会再拍脑袋乱写编码了。
3.3 编码巡检脚本:让 codex 先诊断再动手
check_encoding.py的作用有两个:一是查看当前系统的编码环境,二是识别单个文件的编码类型。脚本内容如下:
import os import sys import locale import subprocess from pathlib import Path def detect_encoding(filepath: str) -> str: raw = Path(filepath).read_bytes() if raw.startswith(b"\xef\xbb\xbf"): return "utf-8-sig(UTF-8 带 BOM)" if raw.startswith(b"\xff\xfe"): return "utf-16-le(UTF-16 小端)" try: raw.decode("utf-8") return "utf-8(无 BOM)" except UnicodeDecodeError: pass try: raw.decode("gbk") return "gbk/ansi" except UnicodeDecodeError: return "unknown(无法识别)" if __name__ == "__main__": print("Python 默认编码:", sys.getdefaultencoding()) print("locale 首选编码:", locale.getpreferredencoding(False)) console_enc = os.device_encoding(0) or "未知" print("控制台编码:", console_enc) chcp_result = subprocess.run( ["chcp"], capture_output=True, text=True, encoding="gbk", errors="replace" ) print("chcp 输出:", chcp_result.stdout.strip()) if len(sys.argv) > 1: for path in sys.argv[1:]: if Path(path).exists(): print(f"{path} -> {detect_encoding(path)}") else: print(f"{path} -> 文件不存在")有几个细节我解释一下。chcp在 Windows 下的输出是 GBK 编码的,所以用encoding="gbk", errors="replace"读取,避免子进程返回乱码导致误判。locale.getpreferredencoding(False)拿的是系统区域设置下的首选编码,简体中文系统通常是cp936。os.device_encoding(0)返回当前标准输入设备的编码,在终端里运行时如果是 65001,说明代码页已经切到 UTF-8 了。
这个脚本还有一个隐藏价值:codex 执行命令时会读取它的输出,如果你不告诉它“chcp 输出要用 GBK 解码”,它很可能自己就被乱码干扰了判断。脚本提前处理好了这个坑,codex 拿到的就是干净、可解析的信息。
3.4 乱码文件批量修复脚本:先备份再转码
fix_mixed_encoding.py负责真正动手修复已有乱码文件。它的设计原则很朴素:不知道原编码就探测,探测不出来就跳过,改之前必须先备份。
import sys from pathlib import Path def smart_convert(filepath: str, target: str = "utf-8") -> None: p = Path(filepath) raw = p.read_bytes() if raw.startswith(b"\xef\xbb\xbf"): src = "utf-8-sig" elif raw.startswith(b"\xff\xfe"): src = "utf-16-le" else: try: raw.decode("utf-8") src = "utf-8" except UnicodeDecodeError: try: raw.decode("gbk") src = "gbk" except UnicodeDecodeError: print(f"跳过:{filepath},无法可靠识别编码") return text = raw.decode(src) if target == "utf-8": new_data = text.encode("utf-8") elif target == "gbk": new_data = text.encode("gbk") else: raise ValueError(f"不支持的目标编码: {target}") backup = p.with_suffix(p.suffix + ".bak") p.rename(backup) p.write_bytes(new_data) print(f"已转换 {filepath}: {src} -> {target},原文件备份为 {backup.name}") if __name__ == "__main__": if len(sys.argv) < 2: print("用法: python fix_mixed_encoding.py <文件或目录> [目标编码]") sys.exit(1) target = sys.argv[2] if len(sys.argv) > 2 else "utf-8" path = Path(sys.argv[1]) if path.is_file(): files = [path] else: files = list(path.rglob("*.txt")) + list(path.rglob("*.md")) + list(path.rglob("*.log")) + list(path.rglob("*.json")) for f in files: smart_convert(str(f), target)这里有个容易忽略的点:p.rename(backup)执行的是“原文件改名成备份”,然后再用原名写入新文件。这样做的意图非常明确——宁可多留一份.bak,也不要把唯一副本转坏了。
另外,转码方向的选择要谨慎。如果文件本来是 UTF-8 无 BOM,内容里却还有大量 GBK 字样,说明这个文件被多次错误转换过,已经发生了“信息折叠”,这种情况下机械转码救不回来,需要回到最早期的版本重新处理。skill 里的规则也提醒了 codex:遇到不确定的文件,不要硬转,先备份后交给用户确认。
3.5 安装与启用:三步把 skill 挂到 codex 上
安装过程不复杂,三步搞定。
第一步,创建 skill 目录。在 Windows 的 PowerShell 或 cmd 里执行:
mkdir %USERPROFILE%\.codex\skills\fix-windows-encoding\scripts第二步,把编写好的SKILL.md放到fix-windows-encoding目录下,把两个 Python 脚本放到scripts子目录。文件结构跟上面展示的一致即可。
第三步,在 codex 会话中启用。最简单的方式是直接告诉 codex:“本次会话启用 fix-windows-encoding skill,遵照 SKILL.md 处理所有文件输出。” codex 会自动加载对应 skill。
如果你希望每次会话都自动启用,可以在 codex 的config.toml里加上类似下面的配置,具体字段名以你自己安装的版本实际支持为准:
# ~/.codex/config.toml [skills] enabled = ["fix-windows-encoding"]配置完成后,建议做一个快速验证:让 codex 写一个包含中文的 markdown 文件,然后自己用 Python 或 VSCode 打开检查编码。能正常显示,说明 skill 已经在干活了。
4. 高级配置:从“会修”到“不生乱”
4.1 为什么默认挑 UTF-8 无 BOM,而不是有 BOM 的 UTF-8
很多 Windows 老用户习惯了“带 BOM 的 UTF-8”,因为记事本能通过 BOM 快速识别文件编码。但在跨平台场景下,BOM 带来的麻烦远大于它带来的便利。
首先是兼容性问题。Linux 和 macOS 下的很多工具不认 BOM,会把EF BB BF当作真实字符读进去,导致文件第一行多出一个不可见字符,轻则格式错乱,重则脚本解析报错。Git 也经常跟 BOM 过不去,导致 diff 显示异常。其次是复制粘贴时 BOM 容易残留,比如从一个 UTF-8 带 BOM 文件里复制一段代码贴到另一个无 BOM 文件里,第一行前面悄悄多了一个零宽字符,排查起来非常隐蔽。
所以现代开发实践的主流是 UTF-8 无 BOM。新版 Windows 记事本(Windows 10 1903 以后)已经默认用 UTF-8 无 BOM 读写,VSCode 也默认如此。唯一要注意的是个别老旧软件仍然“见 BOM 才认 UTF-8”,遇到这种情况再用 4.2 的决策表单独处理,不要为了少数场景牺牲全局默认。
4.2 按目标场景定编码的决策表
在 SKILL.md 里,我给了 codex 一张编码决策表,让它在不同交付场景下能自主选择:
| 输出目标 | 推荐编码 | 原因 |
|---|---|---|
| Markdown / txt / log / json / yaml | UTF-8 无 BOM | 跨平台最友好,Git 无冲突,现代编辑器默认 |
| 批处理 .bat / .cmd | GBK 或 UTF-8 无 BOM | 带 BOM 的 UTF-8 会导致 cmd 解析异常,中文 echo 可能闪退 |
| PowerShell .ps1 | UTF-8 无 BOM | PowerShell 7+ 默认一致,PS 5.1 也兼容 |
| 配置文件 .env / config.ini | UTF-8 无 BOM | 避免特殊字符被误读 |
| 面向老软件、老设备的接口文件 | GBK | 目标系统只支持 ANSI 时必须顺应对方 |
| C/C++ 源码文件 | UTF-8 无 BOM,注释前检查编译器选项 | 防止源码编码与编译器预期不一致 |
这张表不是死的,它在传递一个核心思路:编码不是越“高级”越好,而是越“合适”越好。codex 有了这张表,就不会在写批处理时自作主张搞出 UTF-8 带 BOM 的坑文件。
4.3 再固化两个兜底规则
除了编码选择,我在 SKILL.md 里还写了三条兜底规则,它们来自我踩过的真实教训。
第一条,所有 bat/cmd 脚本一律禁止使用 UTF-8 带 BOM。cmd 的老式解析器对 BOM 的处理极其脆弱,一个带 BOM 的 bat 脚本哪怕内容完全正确,也可能在中文字符后面出现命令截断、闪退、乱码。要么 GBK,要么 UTF-8 无 BOM,二选一,没有第三个选项。
第二条,codex 生成包含中文文件名的文件时,尽量使用 ASCII 或拼音命名。Windows 文件系统本身支持 Unicode 文件名,但跨系统传输、压缩、打包时中文文件名很容易变成乱码。这个约束让交付物在 Linux、macOS、Windows 之间流转时更省心。
第三条,每次交付含中文的文件时,codex 必须在说明里注明编码格式。这一步非常反直觉,但很管用。收文件的人如果知道“这是 UTF-8 无 BOM”,就不会用 GBK 去打开,沟通成本直线下降。
5. 排查清单与踩坑实录
5.1 直接可用的乱码速查表
先把最实用的速查表放出来,遇到乱码时对照着做,能解决大部分问题:
| 乱码现象 | 可能原因 | 快速处理 |
|---|---|---|
| codex 在终端输出全是问号或乱码 | 终端代码页仍是 936,codex 输出 UTF-8 | 重开终端,执行chcp 65001,或在 Windows Terminal 里运行 |
| 生成的 .md 文件用记事本打开正常,VSCode 乱码 | VSCode 自动猜测编码失败 | 右下角点击编码,手动选 UTF-8 或 GBK |
| 生成的 .md 文件 VSCode 正常,记事本乱码 | 文件是 UTF-8 无 BOM,老记事本按 GBK 读 | 升级到新版记事本,或改用带 BOM 的 UTF-8 |
| bat 脚本含中文就闪退或乱码 | bat 文件带 BOM,或 cmd 代码页与文件编码不匹配 | 保存为 GBK 或 UTF-8 无 BOM,并在脚本开头加chcp 65001 >nul |
| PowerShell 脚本执行后中文乱码 | PS 5.1 默认输出编码与脚本文件编码不一致 | 脚本保存为 UTF-8 无 BOM,输出时用Out-File -Encoding utf8 |
| 文件中出现“锟斤拷” | UTF-8 字节被按 GBK 解码,再次按 GBK 编码后形成折叠 | 找回原始 UTF-8 文件,或用转码脚本反向处理,前提是信息未损坏 |
| 文件中出现“烫烫烫” | 未初始化内存的调试占位符,常见于 C/C++ | 不是编码问题,是代码问题,检查内存分配和字符串初始化 |
这张表我让 codex 也看一遍,它以后排查问题时思路会更清晰。表中的最后两行,尤其是“锟斤拷”,是很多人的知识盲区。它不是某种特殊字符,而是“UTF-8 解码失败按 GBK 硬解又被编码回去”后的产物,属于典型的二次编码事故。
5.2 几个我踩过的真坑
光有速查表不够,我把实战中真正踩过的坑细讲一下,这些细节常规文档里不会写。
第一个坑,chcp 65001只对执行命令之后启动的新进程生效,对当前已经打开的终端窗口无效。很多人执行完chcp 65001,发现终端还是乱,就开始怀疑人生。正确操作是:切换代码页后,重开一个终端窗口,或者直接改用 Windows Terminal——它对 Unicode 的支持比传统 conhost 好太多,字体渲染也更稳。我现在基本不用老的 cmd 窗口跑 codex,全部交给 Windows Terminal。
第二个坑,PowerShell 5.1 和 PowerShell 7+ 的默认输出编码完全不一样。PowerShell 5.1 里的Out-File默认是 UTF-16 LE,Set-Content默认是 ANSI(也就是 GBK),而 PowerShell 7+ 默认是 UTF-8 无 BOM。如果你的系统里同时存在这两个版本的 PowerShell,codex 执行命令时生成的文件可能编码各异。我的 skill 之所以强制指定转码脚本,就是为了摆脱 PowerShell 默认行为的不确定性,让编码完全可控。
第三个坑,手动开启系统的 Beta 版 UTF-8 支持(在区域设置里勾选“使用 Unicode UTF-8 提供全球语言支持”)确实能从根本上解决代码页冲突,但代价很大。开启后,部分老软件会直接显示乱码甚至无法运行,一些依赖 ANSI 编码的协议栈也会出问题。我试过一段时间,最后因为几个工业软件全崩只能回退。所以 skill 里我明确写了一条:不修改系统级区域设置,不要求用户开启 Beta 版 UTF-8。这是最稳妥的路线。
第四个坑,VSCode 打开乱码文件时,别急着改全局配置,右下角点一下编码按钮,选择“通过编码重新打开”,再试“UTF-8”或“GBK”即可。很多时候两秒钟就恢复,改配置文件反而容易被全局设置误伤其它文件。
5.3 验证修复效果:别信肉眼,信字节
乱码修没修好,不能靠肉眼扫一眼就说“行了”,因为一部分乱码字符可能恰好被错误解码成看起来正常的汉字序列。最靠谱的方式是看文件头字节和实际解码结果。
如果你装了 Python,直接调用我们 skill 里的巡检脚本:
python ~/.codex/skills/fix-windows-encoding/scripts/check_encoding.py test.md脚本会输出当前环境编码和该文件的识别结果。如果你想手动验证文件头,可以用 PowerShell 的format-hex命令看前几个字节:
format-hex test.md | Select-Object -First 5如果你看到文件开头是EF BB BF,说明是 UTF-8 带 BOM;直接看到中文字符的 UTF-8 字节序列,就是无 BOM;如果识别出来是 GBK 的D6 D0 CE C4之类的双字节序列,说明文件实际是 GBK。关键判断逻辑就是:文件内容到底想用什么编码与外界对话,和终端/编辑器以为它是什么编码,这两者是否一致。一致就是正常,不一致就是乱码。
我在实际使用中的体会是,不管 skill 写得多细,最后都要落到两个系统级兜底:能切 UTF-8 的场景坚决切,不确定时就先备份再转码。codex 本身只是一个工具,它对编码毫无“常识”可言,全靠 skill 喂给它的规则。所以这个 skill 的维护价值很高,每次遇到新编码坑,往 SKILL.md 里补一条规则,后面就再也不会踩第二次。
最后再分享一个小细节:codex 如果读到了带 BOM 的 UTF-8 文档,它给出的修改结果很容易带上 BOM 残留,导致文件第一行隐性出错。我在 skill 里规定所有输出必须是 UTF-8 无 BOM,这个小规则帮我省掉了至少十次莫名其妙的“文件第一行解析失败”。你如果也做同样的配置,大概率也会觉得这一条特别值。