我们需要纯文本
Donald Knuth 在 TAOCP 的勘误页底部写了一段(核心部分)全大写的话:
BUT PLEASE DO NOT SEND EMAIL TO TAOCP EXCEPT TO REPORT ERRORS IN THE ART OF COMPUTER PROGRAMMING. And if you do report an error via email, please do not include attachments of any kind; your message should be readable on brand-X operating systems for all values of X. (Encrypted messages that I get from “gmail.com” are also gibberish and unreadable without great pain.) Send PLAIN ASCII TEXT ONLY. 1
「你的消息应当能在 brand-X 操作系统上被阅读,对所有的 X 成立。」这句话写于互联网蛮荒年代,但放在 2026 年,它比当初更刺眼。
因为我们今天的数字生活,正在以一种奇怪的方式远离这条原则。
格式是会过期的
八十年代的 WordStar 文档,今天几乎无法打开。九十年代的 Lotus 1-2-3 电子表格,同样如此。.wps 文件在金山自己的新版 WPS 里都不一定能正常渲染。格式是一种承诺,由某家公司在某个时间点做出的承诺。公司会倒闭,软件会停更,协议会变。
Knuth 的 TAOCP 第一卷出版于 1968 年。五十八年过去了,书中的算法描述依然可读,因为印刷是一种「无依赖」的输出。而这五十八年间死掉的文件格式,恐怕比活着的多。
纯文本没有这个问题。一个 UTF-8 编码的 .txt 文件,在 1991 年的 NeXT 工作站上能打开,在 2026 年的任何终端里也能打开。它不需要 Microsoft、Apple 或者任何一家公司继续存在。这是 Knuth 说的「for all values of X」。纯文本是对所有 X 成立的那个通解。
可 diff,可 grep,可管道
程序员对纯文本的偏爱有一个很实际的理由:它能被工具链处理。
一个 .docx 文件本质上是一个压缩的 XML 包,里面塞着样式定义、字体嵌入、修订历史、OLE 对象。你可以把它解压,但解压后看到的 XML 依然面目可憎,真正的内容淹没在数万行标签里。想对比两个版本的差异?祝你好运。Git 能记录它变了,但无法告诉你哪里变了。
纯文本则是 grep 的原生粮食。你可以用 diff 逐行比较,用 sed 批量替换,用 awk 做列提取,用 sort | uniq -c 统计词频。这些都是 Unix 诞生之初就存在的工具2,半个世纪了,依然是最锋利的刀。因为它们的假设极其简单:输入是一行一行的文本。满足这个假设,整条工具链就为你所用。
版本控制系统也建立在同一个假设之上。Git 之所以能精确到行地追踪变更、合并分支、回溯历史,前提是文件内容是文本。把一份合同存成 .docx 放进 Git,每次 commit 只能看到二进制 blob 变了。你知道箱子被动过,但不知道谁拿走了什么。
小,干净,天然安全
纯文本文件几乎不可能携带传统意义上的恶意代码。没有宏,没有脚本执行引擎,没有嵌入式对象。历史上那些著名的宏病毒(Melissa、ILOVEYOU)利用的都是 Word 的宏功能。PDF 的 JavaScript 引擎也曾是漏洞重灾区。这些攻击面在纯文本中根本不存在。
但纯文本有自己的安全盲区。LLM 时代带来了一类新风险:提示词注入(prompt injection)3。一段看似无害的纯文本,可以嵌入精心构造的指令,诱导 AI 模型执行非预期操作。钓鱼话术、社工文本同样以纯文本为载体。代码文件(本质也是纯文本)天然可以包含恶意逻辑。所以准确的说法是:纯文本消除了格式层的攻击面,但内容层的风险与格式无关,任何载体都需要防范。
体积也小得多。同样一万字的内容,.txt 大约 30KB,.docx 可能 300KB,如果嵌了图片和样式能到几 MB。在带宽受限的环境里(远程服务器、嵌入式设备、IoT 节点),纯文本是唯一合理的选择。Knuth 要求勘误邮件不带附件,原因之一大概也是这个:他的邮件客户端不需要解析你的富文本排版。
而且纯文本的容错能力极强。一个 .docx 文件如果损坏了几个字节,整个文档可能无法打开。一个 .txt 文件即使中间烂了一段,前后的内容仍然可读。结构越简单的东西,越难被彻底破坏。
表现力的问题
如果纯文本这么好,为什么大多数人还在用 Word?
因为纯文本确实没有格式:没有粗体、斜体、字号、颜色、表格、分栏、页眉页脚。日常办公需要这些东西。一封商务邮件需要得体的排版,一份报告需要图表嵌入,一本书需要目录与交叉引用。裸的 .txt 做不到。
这是事实。人类阅读需要漂亮的格式:排版精良的书页、层次分明的标题、带编号的公式和交叉引用。但关键问题是:这些漂亮的格式应该存储在哪里?
Word 的回答是:存在文件里,和内容混在一起。你在屏幕上看到什么样,文件里就存着什么样。所见即所得,WYSIWYG。这个思路直觉上很自然,代价却很大。内容和表现被焊死在同一个二进制容器里,拆不开。想换个模板?几乎要重做。想同时出 PDF 和网页版?不可能。想让程序自动处理内容?先祝你解析 .docx 的 XML 顺利。
Knuth 在 1978 年给出了另一个回答:\(\TeX\)。
\(\TeX\) 的思路恰好相反:源文件只存内容和结构标记,视觉呈现交给编译器在最后一步生成。你在 .tex 文件里写 \section{Introduction},编译器决定这个标题用什么字体、多大字号、上下留多少间距。你写 $$\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}$$,编译器把它渲染成数学家看了会满意的公式。源文件本身是纯文本。你用 vim 能编辑它,用 grep 能搜索它,用 Git 能追踪它的每一次变更。
这种「源码 → 编译 → 产物」的分层有一个深刻的好处:同一份源文件可以生成不同形态的输出。同一篇论文的 .tex 文件,换个文档类就能从期刊格式变成会议格式,加个参数就能从 A4 变成 Letter。内容没变,变的只是渲染规则。Word 做不到这件事,因为内容和格式从一开始就纠缠在一起了。
谈到漂亮本身。字距微调(kerning)、连字(ligature)、断行算法(line breaking),\(\TeX\) 在这些方面的水准至今无人超越。Knuth 为断行问题设计了一个动态规划算法,考虑整个段落的全局最优解,而 Word 只做逐行贪心。用 \(\TeX\) 排出来的页面,行距均匀、连字到位、公式间距精确到点(point)。这就是为什么几乎所有数学、物理、计算机科学领域的论文和书籍都用 \(\TeX\) 排版。视觉品质最高的输出,恰恰来自最朴素的纯文本输入。
Markdown 是同一思路的轻量版本。这篇博客本身就是一个 .markdown 文件,用 Jekyll 编译成 HTML。源文件里没有一行 CSS,没有一个 <div>,只有井号、星号和方括号。任何人用任何文本编辑器都能读懂它、修改它、合并它。Typst4 则是更年轻的尝试,语法比 \(\LaTeX\) 简洁,编译速度更快,输出质量接近,源码仍然是纯文本。
思路很清楚:人类需要漂亮的格式,但漂亮的格式应该被生成,而非被存储。 内容用纯文本写,格式交给编译器。源码是持久的资产,渲染结果是可复现的产物。
源码优先
这个原则可以推得更远。
矢量图形:SVG 本质是 XML 文本。你可以用代码生成它,用 Git 管理它,用 grep 在一千个 SVG 里搜某个颜色值。Illustrator 的 .ai 做不到。
乐谱:LilyPond 用纯文本描述音符(c'4 d' e'2),编译后生成的乐谱排版比大多数 GUI 软件更专业。改一个音符的时值,Git 精确显示哪一行变了。
幻灯片:reveal.js 和 \(\LaTeX\) Beamer 把演示文稿变成文本文件。从同一份 Markdown 可以同时生成网页版和 PDF 版。合并两个人对同一页幻灯片的修改,不会出现二进制冲突。
数据:CSV 是纯文本,能被 awk 处理,能被 sort 排序,不依赖 Excel,不会因为你的系统区域设置不同就把日期解析错。
3D 模型:OpenSCAD 完全用代码描述几何体(cube([10,20,30]); sphere(5);),参数化设计极其方便,模型的生成过程可版本控制、可自动化。
共同的模式是一样的:用纯文本描述意图,用工具链生成最终产物5。源码是你真正拥有的东西,PDF、PNG、HTML 只是某一时刻的快照。源码包含了创造的过程和逻辑,产物只是结果。
LLM 的母语
上面这些理由(持久、安全、可工具化)存在了几十年。但 2024 年之后,纯文本多了一个新的、可能是最重要的理由:它是大语言模型的原生格式。
LLM 的输入是 token 序列,输出也是 token 序列。Token 就是文本的碎片。整个训练语料(维基百科、GitHub、arXiv、Common Crawl)在被模型消化之前,第一步都是转成纯文本。PDF 要 parse,Word 要解压再抽取,HTML 要剥掉标签。每一步转换都有信息损耗。只有纯文本是零损耗直通的。
这意味着当你把内容交给 LLM 处理时,格式噪声会直接侵蚀你的上下文窗口。一个 .docx 文件转成文本后夹带的 XML 碎片、样式残留、元数据标签,都会变成无意义的 token,占据本该留给真正内容的空间。上下文窗口是有限资源。Claude 的窗口是 200K token,听起来很大,但一个中等规模的代码库加上对话历史就能填满。每一个浪费在格式噪声上的 token,都是从模型的「工作记忆」里偷走的。
再看 AI Agent 的工具链。Claude Code 用 grep 搜索代码库,用 diff 理解变更,用逐行编辑修改文件6。Cursor、Copilot、Cline,所有主流 coding agent 的底层操作都一样:读文本、搜文本、改文本。它们的武器库和 1970 年代 Unix 程序员的几乎重合。Agent 面对一个 .txt 或 .py 文件时如鱼得水;面对一个 .docx,它能做的事非常有限。
Anthropic 的 Agent Skill 框架也是纯文本。一个 SKILL.md 文件,YAML 头部加 Markdown 正文,描述 Agent 在特定领域应该怎么工作。系统提示词是纯文本。用户提示词是纯文本。模型输出的工具调用是 JSON,也是纯文本。Memory 文件是纯文本。整条链路上没有一个环节需要富文本。
这揭示了一个有趣的对称:Knuth 在 1984 年说,程序首先是写给人看的7。四十年后,程序,以及几乎所有的结构化内容,首先是写给人和 LLM 一起看的。纯文本恰好是两者的最大公约数。人能读,机器能处理,工具链能操作。没有任何其他格式能同时满足这三个条件。
换个角度想:如果你今天写的内容未来会被某个 AI 系统检索、引用、或者基于它做推理,那么纯文本就是你能送出去的最干净的信号。没有解析错误,没有格式歧义,没有编码陷阱。信号纯了,下游的一切都会更准确。
边界
说了这么多纯文本的好,该说说它不行的地方。
这篇文章的论点有一个隐含前提:我讨论的是源码层。也就是内容在被创建、存储、版本控制、协作编辑时应该采用什么格式。这个层面上,纯文本(含标记语言)有决定性优势。但源码层之外,还有交付层、合规层、协作层,这些层面的需求纯文本覆盖不了。
政务公文需要电子签章和法律效力。合同文本需要不可篡改的固定版面。企业文档需要权限管控、水印溯源、审计日志。这些需求指向 PDF/A、OFD 等封装格式,纯文本天然缺失这些能力。在这些场景里,「能打开」远远不够,「能证明没被改过」才是刚需。
对非技术用户来说,WYSIWYG 有独立的价值。一个行政人员用 Word 排公文,一个设计师用 InDesign 做画册,一个老师用 PowerPoint 做课件,他们的工作不会因为切换到 \(\LaTeX\) 而变得更好,只会变得更难。学习曲线是真实存在的成本,对大多数人来说这个成本太高了。
好在中间地带早已存在。Obsidian、Typora、Notion、HackMD 这类工具做的事情是:底层是纯文本(Markdown),表面是可视化编辑器。用户看到的是所见即所得的界面,存储的是纯文本文件。Google Docs 的底层虽然不是纯文本,但它的协作能力(多人实时编辑、评论、建议模式)解决了一类真实的工作流问题,纯文本工具至今没有同等体验的替代品8。
所以更准确的表述是:在你能选择的地方,选纯文本。 写代码、写文档、记笔记、存数据、管配置,这些场景下纯文本(含 Markdown、\(\LaTeX\)、YAML、CSV 等标记格式)是更好的默认选择。而在需要固定版面、法律效力、可视化协作的场景,用合适的工具,但尽量让源头保持纯文本,最终交付物由编译或导出生成。
回到 Knuth
Knuth 今年 88 岁,还在写 TAOCP 第四卷的后续分册。他用 \(\TeX\) 排版,用纯文本通信,用 PostScript 发布勘误,连网页都是 valid HTML 4.01 Transitional。他 1990 年就不再使用电子邮件9,理由是他需要不被打断地思考。偶尔需要通信时,他要求纯 ASCII 文本,不要附件,不要加密,不要任何多余的东西。
这不是偏执。这是一个把毕生精力投入到精确性和持久性中的人,对工具最朴素的要求:别在我的内容上面裹一层会腐烂的壳。
plain text is the new black. 这句话其实说反了。纯文本从来不是什么新潮流。它是最古老的数字格式,也将是最后一个还活着的数字格式。潮流来了又走,纯文本一直在那里。安静地、可靠地待着,等你需要时,随时可读。(可见的)时尚是一种循环,技术可能也是。
-
Unix 的
grep诞生于 1973 年,awk诞生于 1977 年,sed诞生于 1974 年。 ↩ -
关于 prompt injection 的系统性讨论可参见 Simon Willison 的系列文章。 ↩
-
Typst,2023 年发布的现代排版系统,源文件是纯文本,编译速度远快于 \(\LaTeX\),适合需要快速迭代的场景。 ↩
-
当然,位图、视频、音频等天然需要二进制压缩的格式除外。但即便如此,它们的元数据、处理脚本和构建流程仍然可以(也应该)是纯文本。 ↩
-
参见从 Claude Code 源码中学到的,Claude Code 的工具系统本质上就是一组操作纯文本的命令。 ↩
-
Donald Knuth, “Literate Programming”, The Computer Journal, 1984. ↩
-
公平地说,Git + 纯文本在异步协作上很强(分支、合并、代码审查),但在同步协作上(多人同时编辑同一段落、实时光标、内联评论)体验远逊于 Google Docs 类工具。/BTW,本人对Obsidian充满了明目张胆的偏爱。 ↩