为什么 Claude 特别吃 XML 标签?这是我摸了半年的答案
去年十月我接了个活儿:从一批医疗器械注册文件里抽取 14 个字段。文件结构乱、术语杂、有中文有英文。我一开始用 markdown 写的 prompt,测完一批,准确率 74%。
改天心血来潮,把同一个 prompt 的分区从 ## 文档内容 改成 <document>...</document>、## 抽取要求 改成 <instructions>...</instructions>,其它一个字没动。再跑一遍,准确率 91%。
17 个百分点。我当时就懵了,以为是哪里串了变量。反复对了三次,确实就是标签的差别。
从那以后我就开始系统地玩这套东西,到现在差不多大半年。这篇写一下我摸出来的规律。
这事的历史根源
先说个不那么技术的背景。Claude 的训练数据里,XML 出现的频率和使用方式跟 GPT 那边不太一样。Anthropic 官方在多份文档里直接推荐用 XML 标签组织 prompt——这不是一个说说而已的”最佳实践”,而是他们从训练阶段就在铺这条路。
具体表现是:Claude 对成对出现的 <tag>...</tag> 有非常强的”边界感知”。它会把标签内的内容视为一个语义独立的单元,而不是和周围文字融成一片。
反观 markdown 标题,## 某某某 只是一个软分界——视觉上清楚,但模型在注意力机制里并没有对它做特别处理。于是你的”文档内容”和”抽取要求”在它眼里可能是一碗汤里的两块肉,有时候分得清有时候分不清。
这个差别在任务复杂度低的时候不明显。越是长上下文、多段文本、多任务混排的场景,XML 的优势越明显。我那个 14 字段抽取就是典型长文档 + 多目标。
我实测过的几组对比
除了开头那个医疗文档,我后来又做了几组对照实验,数据大致是这样:
- 短对话(单轮、上下文 <500 字):markdown 和 XML 几乎没差,都在 95%+,在误差范围内。
- 中等文档抽取(2k-5k 字 + 3-5 个字段):XML 普遍高 5-10 个点。
- 长文档 + 多段指令(10k+ 字 + 多任务混排):XML 优势 15-20 个点,甚至有任务从不可用变成可用。
- RAG 场景(多段检索结果 + 用户问题):XML 把”检索内容”和”用户问题”隔开的效果明显,减少了幻觉引用。
所以不是什么情况都非得用 XML。短任务你爱用啥用啥。我现在的习惯是:只要 prompt 里有两段以上语义不同的内容块,就上 XML。一段的就 plain text 算了,别瞎包。
关于这个话题 XML 和 Markdown 的深度对比那篇有更细的版本对照,我不展开重复。
标签怎么起名是个学问
刚开始玩的时候我也犯过错。为了好看,标签名起得很文艺,<gorgeous_article>、<user_question_that_requires_thoughtful_answer>——这种不但没加分还减分。
摸到的规律是:标签名要语义化、短、尽量用通用词。
通用词是指 <document>、<context>、<instructions>、<example>、<input>、<output>、<question>、<answer>、<thinking> 这类。Claude 的训练数据里见得多,它一看到就知道”哦这是文档内容”。
自创词也不是不能用,但得让标签名本身传达清楚角色。<medical_report> 可以,<the_big_text_blob> 就很差。
还有一点,标签名本身就是一种提示。我做法律项目时试过把 <text> 改成 <contract>,没改其它任何东西,合同里的风险识别率微微上升了一点。模型会根据标签名调整对内部内容的”期待”。
嵌套别上头
见过有人把 XML 嵌套玩出六层的。<task><context><documents><document><metadata><author>... 这种。
这么写 Claude 不会报错,但会累。我实测过嵌套超过三层之后,模型对内层标签的”尊重程度”开始下降。三层以内是甜蜜区。
我现在的原则:扁平优先,能不嵌套就不嵌套。需要层级的时候也不超过三层。
比较健康的一种结构:
1 | <context> |
三层封顶,每层职责清楚。需要更细的分组,用属性(像上面那个 id="1")比继续嵌套好。
闭合标签不要偷懒
我见过一些人写到后面懒了,只写 <document> 开标签不写闭合。这个我测过,不严重但确实会有损耗——大概降 2-3 个百分点,尤其是在多段内容的场景。
Claude 对成对标签的处理是优化过的。你不闭合,它会自己猜边界,猜得多数时候对,有时候不对。不对的那几次就是你损失的精度。
同理,<tag/> 这种自闭合标签在纯 prompt 场景里我建议少用,没啥必要,还可能引起歧义。
什么时候 XML 反而拖累
XML 不是万能药。有些场景它反而碍事:
一、纯创作任务。你让它写一首诗、编一个故事,前面包一堆 <poem_topic>、<style_preference>、<length> 标签,会让模型进入”分析模式”,输出反而板正。这种场景 plain text 自然语言就够了。
二、极短 prompt。system 里就一句”你是个客服助手”,包个 <role>你是个客服助手</role> 没意义,反而显得刻意。
三、需要模型自由展开的头脑风暴。标签会隐性收紧模型的发散范围。要创意的时候给它松绑。
Tool use 的响应里也有 XML 痕迹
顺便提一下。你用 Claude 的 tool use(function calling)时会发现,模型在推理阶段倾向用类 XML 的结构组织它的”思路”,最后才调用工具。这不是巧合——它的 thinking 模式就是在 <thinking>...</thinking> 标签里展开的。
这也反过来印证了 Claude 训练时 XML 的权重。你要让它”想一下再答”,用 <thinking> 标签比用”让我们一步步来”这种自然语言触发词要稳得多。相关细节我在思考还是直接给答案那篇里有说。
说到 tool use,它和 MCP 的区别和选型在这篇里有讲,感兴趣可以顺手看看。
我现在的默认模板
给一个我个人在中等复杂度任务上的骨架:
1 | <context> |
四个块、全闭合、不嵌套。90% 的项目这个骨架够用了。
最后说一句心里话。XML 这东西在 prompt 工程里被神化过也被踩过,我摸了大半年,结论还是那句:它不是魔法,是一个让你的意图传达得更准的工具。你意图本身就乱,再包多少标签都救不回来。但你想法清楚的时候,XML 能帮你把想法”原封不动”地送到模型面前,而不是在路上被稀释掉。
延伸阅读
想看更全的对照实验数据,看 XML vs Markdown 的深度对比。想理解 system 里怎么和 XML 配合,去 System Prompt 放什么那篇。想把这套结构化输入和 tool use 结合起来,别错过 MCP vs Function Calling。
- 标题: 为什么 Claude 特别吃 XML 标签?这是我摸了半年的答案
- 作者: Claude 中文知识站
- 创建于 : 2026-04-18 13:45:00
- 更新于 : 2026-04-19 16:10:00
- 链接: https://claude.cocoloop.cn/posts/prompt-xml-tags-claude-special/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。