准备 Claude Certified Architect 前置能力的人,通常会在 API 调用上卡一下。不是模型回答质量不行,而是输入输出格式没设计好。Part 9 把 XML 单独拿出来讲,我一开始也觉得奇怪:Claude API 本质是文本接口,XML 又不像 JSON 那样是默认数据格式,为什么要专门学?实际跑过几个项目后才发现,XML 在这类 API 场景里的价值不是传输,而是结构。它非常适合用来给 Claude 传递带层级关系的提示词模板,让模型严格按节点返回结果,也为后续的日志解析、配置复用和自动化编排打基础。这篇就按我自己的实测顺序,把 Claude API 中的 XML 输入构造、返回解析、报错排查和适用边界完整拆一遍。
1. 先搞清楚:Claude API 里为什么要单独讲 XML
1.1 XML 不是 API 的必选格式,而是提示词结构
很多人听到“Claude API 与 XML”时,第一反应是“API 不是用 JSON 请求吗?”。这个理解没有错。Claude API 的请求和响应在传输层确实是 JSON 格式,但问题是:你发给模型的内容本身,是放在 JSON 的某个字符串字段里的。也就是说,API 接口长什么样和模型接收到的文本长什么样,是两回事。
XML 在这里发挥的作用,是提示词的组织语言。比如你要让 Claude 从一篇长文本里提取订单信息,自然语言写法通常是:
“请从下面的文本中提取订单号、商品列表、总金额,分别放到对应字段里。”
这种写法模型能听懂,但任务一多、字段一多,就很容易漏。使用 XML 标签后,指令和数据之间的边界就会清晰很多:
<request> <task>从订单文本中提取结构化信息</task> <data> 用户张三购买了两台显示器,单价为1999元,订单号是20240615A。 </data> <output> 根节点为 order,包含 order_id、items、total 三个子节点。 </output> </request>对 Claude 来说,<task>、<data>、<output>就像三个抽屉,模型能更快判断哪些内容是任务说明,哪些是待处理数据,哪些是输出要求。很多同学反馈“提示词已经写得很细了,模型还是会乱”,我建议优先检查一下结构,而不是继续堆字。
在 API 场景里,用 XML 还有一个隐性好处:日志可读。请求和响应都会经过日志系统,如果是纯自然语言,你需要从大量文本里定位某一段;如果外层有 XML 标签,不管是人看还是脚本过滤,都会轻松不少。
1.2 输出端用 XML 做结构化,比 JSON 更稳的场景
Claude 这类大模型在输出 JSON 时,偶尔会出现多余的反引号、注释,或者把字段名拼错。XML 同样有风险,但只要你把根节点和闭合标签写清楚,解析时的容错空间会更大。因为 XML 的结构是成对标签,即使模型漏了一个字段,你也能通过缺哪个闭标签快速定位,而不是像 JSON 一样因为一个逗号就整体解析失败。
我并不是说 XML 全面优于 JSON。JSON 在程序里转字典、转对象太方便了,绝大多数接口都应该优先返回 JSON。但下面几类场景,我个人会更倾向 XML:
- 需要把一段文本拆成多层级结构,且层级关系很重要时。
- 需要给节点加属性,比如
<item id="001" currency="CNY">这种带元信息的数据。 - 输出内容要直接对接旧系统、配置文件或流程引擎,而这些系统本身就用 XML。
- 希望日志里保留可读的区块,方便人工复查时快速定位。
Claude API 对文本内容没有强制要求用 XML。你可以按自己的习惯来,但如果你正在做批量文档抽取或者自动化流程,XML 的标签边界确实能减少很多“模型漏了一个字段”的情况。
2. 环境准备:先把 Claude Code 和 API 请求链路跑通
2.1 安装 Claude Code 时最容易踩的命令识别问题
网络上有不少人在安装 Claude Code 后,执行claude命令时遇到“无法将‘claude’项识别为 cmdlet、函数、脚本文件或可运行程序的名称”之类的报错,或者在 Windows 下提示“不是内部或外部命令”。这个问题的原因通常不是工具没装好,而是命令没有被系统找到。
排查顺序建议是这样:
- 先确认安装是否完成。如果使用包管理器安装,安装输出最后一般会有“successfully installed”字样。安装过程中如果出现权限、网络中断,需要重新安装。
- 检查执行命令的终端是否重启。Windows 下新配置的系统环境变量不会自动同步到已经打开的终端,关掉重开通常能解决一大部分问题。
- 查看命令实际所在位置。Windows 可以用
where claude,macOS 或 Linux 可以用which claude。能输出路径,说明命令存在,问题在 PATH 配置。 - 如果是在 VSCode 里使用,记得在 VSCode 的集成终端里重新加载窗口,或者直接在系统终端测试一次。
- 确认 Node.js 环境正常。很多类似工具依赖 Node.js,版本太旧可能导致命令安装一半就失败。
我还见过一种情况:用户同时装了多个版本,旧版本在 PATH 里排在前面,导致新命令没生效。这个问题很隐蔽,因为表面看起来只是“命令不对”,实际上是路径优先级的问题。检查 PATH 时可以把所有相关目录都列出来,不只看第一个。
2.2 API 调用前必须确认的三个基础配置
环境跑通之后,真正调用 Claude API 前,我会先确认三件事。
第一,API Key 是否存在且有效。不要把 Key 写死在代码里,建议放到环境变量或.env文件中。示例:
ANTHROPIC_API_KEY=your-api-key代码里只负责读取,避免密钥被提交到版本库。
第二,模型名称是否可用。不同模型名称对应的上下文长度、计费和能力都不同。你不一定需要记住全部模型名,但要确认你调用的模型名在当前账号、当前 API 版本下是存在的。如果模型名写错,通常会收到类似“The supported api model names are ...”的提示。遇到这种提示,不要怀疑网络,先检查模型名拼写和可用列表。
第三,上下文长度和max_tokens是否匹配。模型对单次请求的总 token 数有限制。即使你只发送很短的内容,如果系统提示词、历史消息、XML 模板、输出要求加在一起超过限制,也会报错。这是后面常遇到的 400 错误的原因之一。
环境配置阶段不要急着写复杂业务,先用一个最小请求确认输入、输出、日志都正常,再往后加 XML 结构。
3. 用 Claude API 发送包含 XML 的请求
3.1 构造 XML 输入:根节点、子节点、属性怎么设计
XML 输入设计得好不好,直接影响 Claude 的理解和输出质量。我一般遵循几个原则。
根节点只保留一个。一个请求里最好只有一个根节点,比如<request>,不要同时出现多个独立根节点。模型在解析时会更明确,输出也更容易对齐。
任务指令和业务数据分开。<task>里放你要让模型做什么,<data>里放原始内容,<output>里放输出要求。混在一起时,模型经常分不清哪些字段需要提取,哪些是给它的指令。
标签命名要见名知意。像<a>、<b>这种短标签虽然省 token,但在复杂任务里很容易让模型误解。使用order_id、product_name这样的命名更稳妥。
属性适合放“分类信息”或“元信息”。比如:
<item category="electronics"> <name>显示器</name> <quantity>2</quantity> <price>1999</price> </item>属性不要滥用。如果一个字段后续会被当作普通文本来处理,就放到节点文本里;如果它只是用于标记类型或归类的信息,再考虑属性。
还有一个容易忽略的点:XML 里的特殊字符。如果你的业务数据中包含<、>、&,直接放进 XML 会导致结构解析出现问题。稳妥做法是用<、>、&转义,或者把整段内容放到 CDATA 区块中。在 Claude API 场景下,最安全的方式是在拼提示词时先对业务数据进行转义,不要让特殊字符破坏标签结构。
3.2 在提示词里告诉 Claude 解析规则和返回格式
模型不是解析器,它不会自动知道你要什么 XML。你必须在提示词里把输出规则说清楚。我通常会加这样一段:
“请只返回 XML,不要使用 markdown 代码块,不要添加注释,不要输出额外解释。根节点必须为 order。”
这段要求很重要。如果你不说明“不要使用 markdown 代码块”,很多模型会自动把返回内容包在```xml里。虽然这只是三个反引号,但脚本解析时还得额外处理一层,很容易踩坑。
另外,建议在模板中列出期望的节点结构,甚至给出一个空节点模板:
<order> <order_id></order_id> <items></items> <total></total> </order>模型看到这种结构后,通常会按字段顺序补全内容。比只写“提取订单信息”要稳定得多。
如果你需要描述“输出字段名为 order”,不要在提示词里直接写order这个容易和自我闭合标签混淆的东西。可以写“根节点为 order”,或者用转义写法。否则模型可能把字段名当成实际标签的一部分,返回结果会出现多余嵌套。
3.3 一个最小可运行的 Python 示例
下面是一个调用 Claude API 的最小示例,里面用到 XML 作为提示词结构。以官方 Python SDK 为例,具体方法名以你安装的版本为准:
import anthropic client = anthropic.Anthropic( api_key="your-api-key" ) xml_prompt = """ <request> <task>从下面的订单文本中提取结构化信息</task> <data> 用户张三购买了两台显示器,单价为1999元,订单号是20240615A。 </data> <output> 请返回 XML,根节点为 order,包含 order_id、items、total 三个子节点。 不要使用 markdown 代码块,不要添加额外解释。 </output> </request> """ resp = client.messages.create( model="claude-3-5-sonnet-latest", max_tokens=1024, messages=[ {"role": "user", "content": xml_prompt} ] ) print(resp.content[0].text)说明几个点。模型名这里写的是示例,实际要以你账号可用的模型为准,不确定的话去查 API 文档或错误提示。max_tokens是允许输出的最大 token 数,不是总上下文,所以不要把它设置成超过模型上限。你先用这个小样例跑通,确认能拿到文本输出,再替换成真实业务数据。
如果返回结果不是预期 XML,先看两样东西:一是 API 返回的原始文本,二是提示词里的 XML 有没有被转义或被模型误解。很多问题都不是代码没过,而是 prompt 里的结构表达不准确。
4. 返回结果里的 XML:解析和验证
4.1 正确处理 XML 输出,不要直接当普通文本拼接
Claude 返回的内容本质上还是字符串。即使你在提示词里要求“不要 markdown 代码块”,也不能完全保证每次输出都干净。所以拿到输出后,第一步是清理,第二步才是解析。
常见的清理操作是定位根节点。比如要求根节点是<order>,那么可以这样做:
raw = resp.content[0].text start = raw.find("<order>") end = raw.rfind("</order>") + len("</order>") xml_text = raw[start:end]这段代码不是万能的,但它能处理大部分“前面有解释文字,后面有补充说明”的情况。如果返回内容里有 XML 声明<?xml version="1.0" encoding="UTF-8"?>,那find("<order>")依然能找到根节点,不影响截取。如果根节点带命名空间,比如<order xmlns="...">,你的字符串匹配逻辑就要改成按结尾标签判断,或者统一用解析库处理。
不要直接把原始返回文本拼到日志或数据库里。一方面,模型可能输出反引号、注释;另一方面,原始文本可能包含多余的上下文,不利于下游使用。
4.2 验证 XML 合法性和内容一致性的方法
清理完之后,建议用 Python 标准库xml.etree.ElementTree验证 XML 是否合法。示例:
import xml.etree.ElementTree as ET try: root = ET.fromstring(xml_text) except ET.ParseError as e: print("XML 解析失败:", e)只要 XML 不合法,这个步骤一定会抛出异常。解析失败时先看错误信息里的行列号,再回头检查闭合标签和特殊字符。
合法性通过后,还要验证内容一致性。比如订单号字段是否为空,金额是否为数字,商品列表是否为空。模型可能生成一个结构合法但字段内容缺失的 XML,这时候程序不会报错,但业务会出问题。建议提取节点后做基础校验:
order_id = root.findtext("order_id") total = root.findtext("total") if not order_id: print("缺少 order_id")如果字段很多,可以把校验规则写成一个函数,逐个节点检查。最好在批量任务开始前先用五到十条样例验证一遍,确认所有关键字段都能被正确填充,再放大规模。
4.3 很多“XML解析错误”其实是浏览器样式信息和编码问题
有些人把 Claude 返回的 XML 存成.xml文件后用浏览器打开,会看到类似 “This XML file does not appear to have any style information associated with it” 的提示。这句话的意思是:浏览器没有找到 XSL 样式表,所以直接按纯文本展示了 XML 内容。这并不代表 XML 文件损坏,也不代表 Claude 输出有问题,只是一种正常提示。
真正要注意的是编码问题。如果 XML 包含中文,文件头需要声明 UTF-8,保存时也要用 UTF-8 编码。Windows 下偶尔默认保存成 GBK 或 ANSI,打开时就会出现中文乱码或解析异常。用 Python 读写文件时,建议显式指定编码:
with open("output.xml", "w", encoding="utf-8") as f: f.write(xml_text)另外,如果模型输出里包含 这样的实体而你的解析器不认识,也会报错。标准 XML 只内置少量实体,其他实体需要先在 DTD 中声明。遇到这种情况,最好在写提示词时就要求模型不要输出特殊实体,或者在后处理时把常见实体替换掉。
5. 常见报错排查:从 529 到 400 再到本地命令问题
5.1 API Error 529:服务端过载,应该等多久、重试几次
529 是一个比较常见的 API 错误,提示信息大致是“overloaded. This is a server-side issue, usually temporary”。意思是服务端当前负载过高,问题不在你的代码,不在 API Key,也不在 XML 格式。
这种错误通常是临时的。我一般会采用指数退避重试:第一次等 1 秒,第二次等 2 秒,第三次等 4 秒,最多重试 5 次左右。如果持续报 529,说明并发请求可能太集中,可以降低并发数,或者错峰提交。
不要把 529 当成 bug 去反复调试。先看时间窗口内是否有大量请求发出;如果是批量任务,给每批请求之间留一点间隔;如果只是单条请求,等几秒再试。
5.2 API Error 400:最大上下文长度超限怎么办
网络热词里有一条很典型:api error: 400 this model's maximum context length is 1048576 tokens。这类报错表示你发送的 prompt 加上输出预留的总 token 数超过了模型支持的上下文长度。
很多人以为是单条消息太长,其实上下文长度包含了好几部分:
- 系统提示词
- 多轮对话里全部历史消息
- 当前请求里的 XML 模板和业务数据
- 输出预留的
max_tokens - 可能存在的工具定义或结构化输出限制
解决办法不是只调一个参数,而是按顺序处理:
- 先压缩历史消息,只保留必要上下文。
- 再检查 XML 数据,去掉不用的节点,或者把大文本拆分。
- 降低
max_tokens,但要注意别把输出空间压得太小,导致内容被截断。 - 换个支持更长上下文的模型,以实际可用的模型为准。
如果任务本身需要很长的数据,不要一次全塞进去。可以先把文档切块,分别让 Claude 提取局部信息,再汇总。XML 在这时候不是帮倒忙,它反而能让你每个切块都有固定结构,方便后续合并。
5.3 Claude 命令无法识别:PATH 与安装方式检查
前文提到过 Windows 下claude命令无法识别的问题。实际排查时,我建议按这个顺序看:
- 在相同终端里直接执行
claude --version,如果还是报“不是内部或外部命令”,说明命令不在 PATH。 - 执行
where claude,看能否找到命令路径。找不到就说明安装位置没有被系统索引。 - 检查安装工具是否正常。如果是通过 Node 生态安装的,执行
node -v,确认 Node 可用。 - 确认安装命令确实执行成功。有些安装输出会在最后提示“运行以下命令设置 PATH”,很多人都忽略了。
- 重启终端,或者重启 VSCode 窗口,再试一次。
这类问题最大难点是环境差异。你的系统、终端、包管理器、权限都不一样,直接套别人的命令不一定适用。最稳妥的方式是安装后立即查看安装日志里的提示,按提示补 PATH。
6. 实战边界:XML 方案什么时候适用,什么时候该换回 JSON
6.1 适合 XML 的典型任务
如果你正在准备 Claude Certified Architect 相关的项目实践,可以重点看这几类任务:
第一类是文档抽取。合同、简历、发票、简历这类文本层级明显,用 XML 模板比自然语言描述更清晰。你可以让 Claude 按预设节点返回,再用 XML 解析器入库。
第二类是配置模板生成。把一段配置要求写成 XML,让 Claude 按节点填充。后续程序可以直接读取 XML 配置,不需要额外做格式转换。
第三类是日志标注和指令编排。一个任务里可能包含多个步骤,用 XML 把步骤和数据分开,模型在响应时就不容易把步骤说明当成数据处理。
这类任务之所以适合 XML,是因为它们都需要“边界”和“层级”。XML 的标签恰好能提供这两样东西。
6.2 不适合 XML 的场合
XML 不是万能药。很多场景用 JSON 反而更省事。
如果你的下游系统只接受 JSON,那就不要为了用 XML 而用 XML。Claude API 完全能直接输出 JSON,只要你在提示词里明确字段和格式即可。
如果业务数据是大量数组,比如一个订单里有 100 个商品,XML 会变得非常冗长。JSON 数组在这种场景下更简洁,转 Python 对象也更容易。
如果团队对接口要求严格类型校验,比如字段必须是数字、布尔值,JSON Schema 的生态更成熟。XML 虽然也有 XSD,但很多开发团队不熟悉,维护成本会高一些。
还有一类安全场景要注意:如果 XML 来源不可信,解析时不要启用外部实体。历史上有过通过外部实体读取本地文件的安全问题。在 Claude API 场景里,解析模型返回的 XML 通常风险较低,但如果你把 XML 数据再传给其他系统,就要严格关闭外部实体支持。
6.3 给认证学习和项目落地的一句话建议
我个人的建议是:先把单条 XML 请求跑稳,再设计批量流程。不要一上来就想着“所有任务都用 XML”。你先选一个结构简单、字段固定的任务,比如从一条订单文本里提取三个字段,跑通之后再扩展到更复杂的层级。
同时,把 XML 模板当作代码来管理。模板改动会影响所有下游解析逻辑,所以最好有版本记录。批量任务开始前,先用小样本验证字段完整性、XML 合法性和运行耗时。日志里要能清楚看到每次请求的原始输出,这样出了问题才能定位是模型回答的问题,还是提示词结构的问题,还是解析代码的问题。
整套流程踩过几次之后你会发现,很多报错并不是 Claude 能力不够,而是环境、格式、上下文和重试策略没处理好。把 XML 这块准备扎实,后面做复杂自动化流程会省很多事。