CCDV-F 备考手册 · Claude Certified Developer – Foundations
Chapter 10 · Domain 6(本章 skill 权重合计 7.2%)

Prompt Engineering 与输出处理
指令怎么写、放哪儿,结果怎么收、怎么不信它

本章管一次调用的两个端口:入口——指令写成什么样、放在哪个组件里(TS 6.2);出口——结果怎么变成你代码里可以信任的数据(TS 6.3)。两端由同一条纪律串起来:你写进去的是意图,拿回来的是待校验的数据。中间那段「上下文里该放什么、怎么裁」不在本章,在 ch11。

本章的事实纪律 — prompt engineering 极易写成经验之谈,所以本章每条做法都挂官方出处:clarity 的判据、XML tag 的作用、格式控制的三条、few-shot 的三个要求、structured outputs 的字段形状与限制、减少 hallucination 的基础与进阶手法,全部有 vb: 登记。没有官方措辞支撑的工程做法(例如第七节的代码片段结构)会显式标注为「工程实践」,不冒充产品行为。

一、指令住在哪:system、user,还是对话中途

TS 6.2 把 system vs. user placement 与「prompt/instruction 在组件间的放置」并列写进同一条 skill。这不是排版问题,是三个不同的生效时点。

指令的性质放哪儿依据
从会话第一轮就要生效的全局指令、角色设定顶层 system 字段官方:想加 system prompt 就用顶层 system 参数;messages 的第一条不能是带内容的 system message
本轮的任务、数据、可变输入user turnmessages 是 user / assistant 交替的回合序列
对话进行到一半才需要生效的新指令mid-conversation system message可在一个 user turn 之后放 "role": "system" 的消息,它与顶层 system 同等权威

role 该放哪儿是有官方答案的:在 system prompt 里设定一个 role,能把 Claude 的行为与语气聚焦到你的用例上,哪怕只有一句话也有差别。所以「你是一位资深财务分析师」这种句子属于 system,不属于每一轮的 user turn——放进 user turn 你要么每轮重复一遍(浪费预算),要么只说一次然后被后面几十轮稀释。

放置也有成本这一面 — mid-conversation system message 追加在消息历史末尾,因此不会让它之前的 cached prefix 失效;而改动顶层 system 会让 system 层及其之后的 messages 层一起失效。同一条指令放在两个位置,正确性一样、账单不一样。完整推演在 ch02 第六节。

input sanitization:外来的字节要有自己的槽位

TS 6.2 还点了 input sanitization。在 prompt 构造这一层,它的落点很具体:用户提交的文本、抓来的网页、工单正文,都要包进一个明确标注的 tag 里,而不是拼接进你的指令句子。官方对 XML tag 的说明正是这个用途——XML tag 帮助 Claude无歧义地解析复杂 prompt,尤其当 prompt 混合了指令、上下文、示例与可变输入时;把每一类内容包进自己的 tag(例如 <instructions>、<context>、<input>)能减少误读。

这是 ch01 P2「外来的是数据」在 prompt 构造层的形态。但要说清楚边界:包 tag 降低的是「模型把数据当指令读」的概率,它不是一道闸门。真正的注入防护——把敏感动作收到 guardrails 与 hooks 后面——是 TS 7.1 的地界,见 ch14。本章只负责「别把不可信内容和你的规则并排摆在一起」。

二、把话说清楚:官方给的可操作做法

官方对 instruction clarity 的说法与它给的检验法都值得背下来:Claude 对清晰、明确的指令反应好;想要「超出基本要求」的行为就明确提出来,不要指望模型从含糊的 prompt 里推断。类比是「把 Claude 想成一个聪明但缺乏你们规范与工作流上下文的新员工」;检验法是那条 golden rule——把你的 prompt 拿给一个几乎没有该任务背景的同事看,如果他会困惑,Claude 也会。两条具体动作:对期望的输出格式与约束要具体;顺序或完整性重要时,用编号列表把指令写成顺序步骤。

加上「为什么」。官方说给指令附上背景或动机——比如解释为什么这种行为很重要——能帮 Claude 更好理解你的目标;而且 Claude 足够聪明,能从这个解释里泛化。文档给的例子很能说明问题:与其写 NEVER use ellipses,不如写「你的回应会被 TTS 引擎朗读,所以不要用省略号,因为 TTS 不知道怎么念它」。前者是一条孤立禁令,后者让模型能推广到你没列举的相邻情形。

控制输出格式的三条。① 告诉 Claude 该做什么,而不是不该做什么——与其「不要用 markdown」,不如「你的回应应由流畅的散文段落构成」;② 使用 XML 格式指示符;③ 让 prompt 的排版风格匹配你想要的输出风格——官方明说 prompt 里的排版风格可能影响回应风格,例如把 prompt 里的 markdown 去掉可以减少输出里的 markdown 量。第三条最反直觉,也最容易在题目里出现:你的 prompt 本身就是一个 few-shot 示例。

few-shot:示例是最可靠的格式控制手段

官方的定位是:示例是引导 Claude 输出格式、语气与结构最可靠的手段之一。三个要求——relevant(贴近真实用例)、diverse(覆盖边界情形,别让它学到你没想让它学的模式)、structured(用 <example> 包裹,多个示例外层用 <examples>);数量建议 3–5 个。zero-shot / single-shot / multi-shot 这条谱系与 token 代价的关系在 ch06 第九节。

三、iterative refinement:prompt 是要被迭代的构件

TS 6.2 把 iterative refinement 与 prompt adjustment 并列点名。这里要分清两个同名的东西。

题目里要分清这两者。「上线后错误率高,怎么办」如果答案是「让模型再自我检查一遍」,那是运行期迭代——它有官方背书,但它产出的仍然是模型输出,仍然要过第五节那道校验(这一点第七节会再说一次)。如果题干给的是「我们改了三版 prompt,每次都靠人工看几个例子」,那缺的是开发期的评测集与版本轴,不是再加一轮自检。

四、structured output patterns:三条路,以及少了的那一条

TS 6.3 的第一项是 structured output patterns。官方目前提供的路径有三条,选哪条取决于你要约束的是「它说什么」还是「它怎么调你的函数」。

路一:直接要求(prompting)

把期望结构写清楚,配 XML 格式指示符。官方在讲 prefill 迁移时给了一句对这条路的定性:先试试直接要求模型遵循你的输出结构,新模型在被明确要求时能可靠匹配复杂 schema,配上重试尤其如此。代价是它没有保证,需要重试与校验兜底。

路二:structured outputs(约束「它说什么」)

官方定义:structured outputs 把 Claude 的回应约束成遵循某个 schema,从而保证下游能拿到合法可解析的输出;它通过 constrained decoding 保证 schema 合规——总是合法(不再有 JSON.parse() 错误)、类型安全(字段类型与必填字段有保证)、可靠(不需要为 schema 违规重试)。

请求形状要认得:字段是 output_config.format,type 取 json_schema、schema 放你的 JSON Schema;原先的 output_format 参数已经移到 output_config.format,而且不再需要 beta header。响应侧:Claude 的响应是匹配你 schema 的合法 JSON,放在响应的 text content block 里——注意它不是一个新的 block 类型,你的取文本逻辑不用改。

限制要记,因为它们正是干扰项的产地:支持标准 JSON Schema,但不支持递归 schema、enum 里的复杂类型、外部 $ref、数值约束(minimum / maximum / multipleOf)、字符串长度约束(minLength / maxLength);数组的 minItems 只支持 0 与 1。

这条限制的工程含义 — minimum / maxLength 这类约束不能靠 schema 强制,意味着「金额必须为正」「SKU 不超过 32 字符」这类业务规则必须留在你自己的校验层。structured outputs 保证的是形状,不是取值——这正好是第五节存在的理由。

路三:strict tool use(约束「它怎么调你的函数」)

官方把两者的分工写得很干净:JSON outputs 控制 Claude 的回应格式(它说什么);strict tool use(strict: true)校验工具参数(它怎么调你的函数)。两者可以独立使用,也可以在同一个请求里合用——合用时 Claude 既能用保证合法的参数调工具,又能返回结构化的 JSON 回应,官方说这在「既需要可靠工具调用、又需要结构化最终输出」的 agentic 工作流里有用。工具定义本身(input_schema 与 description 的写法)在 ch12。

少了的那一条:prefill 不再是选项

这一条是本章最需要更新记忆的地方。从 Claude 4.6 各模型与 Claude Mythos Preview 起,最后一条 assistant turn 上的 prefill(给出一段部分 assistant 消息让 Claude 续写)不再被支持,带 prefill 的请求返回 400。更早的模型仍然支持;在对话的其他位置添加 assistant 消息不受影响。官方给的理由是模型的智能与指令遵循已经进步到多数 prefill 用例不再需要它。

迁移路径官方也写明了:想强制输出结构,Structured Outputs 就是为此设计的;分类任务用带 enum 字段的 tool 或 structured outputs;想去掉「Here is…」这类开场白,用 system prompt 直接指示、或让模型输出在 XML tag 内、或用 structured outputs/tool calling,偶有漏网就在后处理里剥掉。

你要约束的选它保证什么
回应文本的结构output_config.format形状合法,不保证取值正确
工具入参的结构tool 的 strict: true工具名与入参通过 schema 校验
两者都要同一请求里合用官方支持的组合
只是想让它别说废话指令 + XML tag + 后处理倾向,非保证

五、defensive parsing:出口处的四道关

TS 6.3 点了 response validation 与 defensive parsing。这一节是本章唯一给代码的地方,因为它考的正是「你的集成层长什么样」。

先把原则说死:模型输出一旦进入你的进程,它就是一段来自外部的数据。这是 ch01 P7。下面这段是把它拆成四道关的一个可运行骨架——结构是本书的工程实践,不是产品行为;每一道关背后的产品事实各自挂了出处。

import json, jsonschema

REPLY_SCHEMA = {
    "type": "object",
    "required": ["invoice_id", "total_cents", "line_items"],
    "properties": {
        "invoice_id":  {"type": "string"},
        "total_cents": {"type": "integer"},
        "line_items": {"type": "array", "items": {
            "type": "object",
            "required": ["sku", "qty", "unit_cents"],
            "properties": {"sku":        {"type": "string"},
                           "qty":        {"type": "integer"},
                           "unit_cents": {"type": "integer"}}}},
    },
}

def handle(resp):
    # 关 1 · 先读 stop_reason,再读 content
    #        取值 max_tokens 表示输出被截断——一段"看起来完整"的 JSON 也可能是半截
    if resp.stop_reason == "max_tokens":
        return Degraded("truncated", raw=resp)

    # 关 2 · 解析。模型输出是外部数据,json.loads 一定要包在 try 里
    text = "".join(b.text for b in resp.content if b.type == "text")
    try:
        data = json.loads(text)
    except json.JSONDecodeError as err:
        return Degraded("unparseable", raw=text, err=str(err))

    # 关 3 · 校验形状。字段缺失/类型不对走降级分支,而不是让 KeyError 冒到调用方
    try:
        jsonschema.validate(data, REPLY_SCHEMA)
    except jsonschema.ValidationError as err:
        return Degraded("schema", path=list(err.absolute_path), err=err.message)

    # 关 4 · 交叉校验。形状合法 != 数值自洽,这一关 schema 替你做不了
    computed = sum(li["qty"] * li["unit_cents"] for li in data["line_items"])
    if computed != data["total_cents"]:
        return Degraded("inconsistent", computed=computed, claimed=data["total_cents"])

    return Ok(data)

四道关各自对应一个真实的失败模式:

关挡住的失败依据
1 · stop_reason输出被截断,JSON 是半截取值 max_tokens 表示触到了请求的 max_tokens 或模型上限;4.5 及更新模型上还有 model_context_window_exceeded
2 · parse不是合法 JSON没开 structured outputs 时这是可能的;开了则官方保证「不再有 JSON.parse() 错误」
3 · schema字段缺失、类型不对同上;structured outputs 保证必填字段与类型
4 · 交叉校验形状合法但取值错schema 里连 minimum 都不支持,业务不变量只能你自己算

开了 structured outputs 之后,关 2 与关 3 还要不要留?要。理由有两层:其一,关 1 与关 4 不在 structured outputs 的保证范围内,而它们恰好是最贵的两类错误(半截数据入库、金额对不上);其二,schema 不支持数值与长度约束,业务不变量本来就得自己校。能删的是重试逻辑,不是校验逻辑。

降级路径怎么写 — 四道关都返回一个带原因码的 Degraded,而不是抛同一个异常。原因码决定下一步:truncated 可以提高 max_tokens 重试;unparseable 值得重试一次并记录原文;schema 通常是 prompt 或 schema 的问题,重试无益,该进人工队列;inconsistent 最危险——它形状合法、能入库、错得安静,必须硬失败。「所有失败都重试」与「所有失败都报警」都是错的,分类才是。(本段为工程实践,无 vb: 出处。)

六、skepticism toward confident output

blueprint 用的原话是「对自信输出保持怀疑」。官方文档里有一整页在讲它的机制面。

定性:连最先进的语言模型(包括 Claude)有时也会生成事实错误或与给定上下文不一致的文本,这个现象叫 hallucination,它会损害 AI 方案的可靠性。注意这句话里没有「模型会告诉你它不确定」这一层——语气的笃定程度与内容的正确程度不是同一件事,这正是 blueprint 那句 skepticism 的落点。

官方给的基础手法三条:

进阶四条:chain-of-thought verification(开 thinking 并设 display: "summarized",答案看起来不对时审阅 thinking block 里的推理摘要,暴露有缺陷的逻辑)、best-of-N verification(同一 prompt 跑多次比对输出,输出之间的不一致可能指示 hallucination)、iterative refinement(第三节讲过)、external knowledge restriction(明确要求只用所提供文档里的信息,不用通用知识)。

第一条的官方写法改过:本书 2026-08 登记时它还是「让 Claude 先逐步解释推理再给最终答案」,旧资料也多这么写。现在别这么做:官方要求读 thinking block 而不是在回应正文里索要推理,在 Claude Fable 5.1、Opus 5.5、Opus 5、Sonnet 5.5 与 Fable 5 上,试图让模型把内部推理写进正文的请求可能直接被拒,stop_details.category 为 "reasoning_extraction"。

而全章最该记住的收口是官方自己加的那条免责:这些技巧显著减少 hallucination,但并不能彻底消除它们;关键信息永远要校验,高风险决策尤其如此。

把它和第五节接起来:prompt 侧的所有手法都在降低概率,出口处的校验才是那道确定性的关。「让模型自己再检查一遍」不等于校验——那份检查结果仍然是模型输出,仍然要过同一道关。这是 ch01 P7 边界那一段的完整依据。

本章刻意没写的:具体模型的 prompting 差异页(Fable 5.1 / Opus 5.5 / Sonnet 5 等各型号的调参建议)、agentic 场景下的 overeagerness 与 long-horizon state tracking 提示词模板、以及 Console 的 prompt generator / improver 工具。前两类属模型选型与 agent 设计的面(ch07、ch08),第三类是产品工具而非 blueprint 点名的能力。另外,「让 Claude 在动破坏性操作前先确认」这类提示词在官方 prompting 页确实存在,但它作为安全控制的定性属 TS 7.1/7.3,见 ch14——本章不把提示词当闸门讲。

本章题组

QUESTION 01 · TS 6.3 · WHAT A SCHEMA CANNOT HOLD
An invoice extractor uses output_config.format with a json_schema requiring total_cents (integer) and line_items (array of {sku, qty, unit_cents}). Parsing never fails. But finance reports that 1 in 400 invoices posts with a total_cents that does not equal the sum of its line items, and one had qty: -3. The team's handler does json.loads then writes straight to the ledger. What should they change?
正确 Astructured outputs 保证的是形状:constrained decoding 给的是「总是合法、类型安全、不需为 schema 违规重试」。取值层面的业务不变量它管不了,而且官方明说 schema 不支持数值约束(minimum / maximum / multipleOf)。所以交叉校验只能落在你自己的校验层——这正是本章第五节的「关 4」。
D1 凭空捏造违反 P5B:给一个真实机制安上了它明确声明不具备的能力。官方限制清单里 minimum、maximum、multipleOf 逐个被点名为不支持。这一项之所以像真的,是因为这些关键字在普通 JSON Schema 里确实存在。
D7 过度工程违反 P10C:best-of-N 是官方点名的手法,但它的用途是用输出间的不一致来提示 hallucination,代价是三倍调用。这里的两个缺陷都能用一行算术和一个符号判断在本地零成本抓住;而且三次跑出同一个错误加总时,投票会一致通过。
D6 半对半错违反 P5D:前半句的机制是真的,后半句的定性是错的。官方的分工是 JSON outputs 控制回应格式、strict tool use 校验工具参数——两者都是 schema 层面的校验。换成 strict tool 只是把同一份 schema 挪了个位置,业务不变量依旧无人校验。
QUESTION 02 · TS 6.2 · A PREFILL THAT STOPPED WORKING
A classification service has run for two years on an older Claude model. It appends a final assistant message containing {"label": " so the reply always continues into JSON. During a migration to claude-opus-5, every request now fails with a 400 before generation. The migration ticket says "response format must stay machine-parseable." What is the correct migration?
正确 D400 的来源官方写得很直接:从 Claude 4.6 各模型起,最后一条 assistant turn 上的 prefill 不再被支持,带 prefill 的请求返回 400。迁移路径也是官方给的:Structured Outputs 就是为约束 schema 而设计的,分类任务用带 enum 字段的 tool 或 structured outputs。题干正是一个分类服务。
D6 半对半错违反 P5A:「在对话其他位置添加 assistant 消息不受影响」确实是官方原句。但把半截 JSON 挪到倒数第二条,就不再是 prefill 了——它变成了历史里的一条普通消息,约束输出结构的作用随之消失。真机制、错用法。
D1 凭空捏造违反 P5B:output-format-legacy 这个 header 是本书自制的干扰项,没有官方出处。它像真的,是因为 Anthropic 确实用 beta header 门控新特性——但官方对 prefill 的表述是「不再被支持」,给的是迁移路径而不是兼容开关。
D6 半对半错违反 P7C:这条确实是官方为「去掉开场白」给的迁移办法之一,方向不算错。但题干的要求是 machine-parseable,而指令加后处理给的是倾向;在同一段迁移建议里,官方把「约束成给定 schema」明确指给了 Structured Outputs。用软手段解决一个已经有硬手段的问题。
QUESTION 03 · TS 6.2 · WHERE THE INSTRUCTION GOES
A support copilot sends a 900-token persona and tone guide as the first message of messages with "role": "system", and the API rejects it. A developer's fix is to prepend the same 900 tokens to every user turn instead. Sessions run 30+ turns; the team also relies on a cached prefix for the tool definitions and knowledge base. What should they do?
正确 B三条依据叠在一起。被拒的原因:messages 的第一条不能是带内容的 system message,从头生效的指令要用顶层 system 字段。该放哪儿:官方明说在 system prompt 里设定 role 能聚焦 Claude 的行为与语气。为什么不是每轮重复:顶层 system 每个请求发一次,而不是每一轮各发一份。
D6 半对半错违反 P9A:缓存确实能把重复前缀的计费压下来。但持久 900 token 塞进每一轮 user turn,它们仍然逐轮占用 context window——缓存改变的是计费方式,不是它们算不算数。而且这些块落在 messages 层、每轮内容都变,缓存前缀按 tools → system → messages 逐层失效。
D5 错层承载违反 P4C:伪造一轮「收到」把角色设定塞进对话历史,是把 system 该承担的职责搬到 messages 层。它在 30 轮之后会被后续内容稀释,而顶层 system 是每个请求都完整送达的。
D6 半对半错违反 P4D:「离问题越近越好」听起来很有道理,但它没有官方依据,而「role 放 system prompt」有。拆开还留下最坏的一半——tone 规则仍然逐轮重发,token 成本与稀释问题一个没解决。
QUESTION 04 · TS 6.3 · A CONFIDENT WRONG ANSWER
A compliance assistant answers questions over a 60k-token policy pack. Spot checks find that ~4% of answers cite clauses that do not exist in the pack, and those answers read as the most assertive ones in the sample ("Section 7.3 explicitly requires…"). The team proposes adding "be accurate and do not make things up" to the system prompt. What is the better plan?
正确 C三条都是官方点名的基础手法:明确允许 Claude 说「我不知道」(官方说这一条就能大幅减少虚假信息);长文档先逐字抽取原句做事实锚定;用 citation 做校验,找不到支撑原句就必须撤回该断言。末句对应官方的收口——这些技巧显著减少但不能彻底消除 hallucination,关键信息永远要校验。
D3 措辞冒充控制违反 P7A:让模型自报一个 confidence 分数,再拿这个分数当分诊信号——那个分数本身也是模型输出,同样要过校验。题干给的证据恰恰相反:错的那些答案读起来是最笃定的。blueprint 那句 skepticism toward confident output 说的就是这件事。
D4 换模型当解法违反 P1B:effort 调的是 Claude 在整个回应上投入多少工作量,它不是「事实准确性」的旋钮,官方也没有把它列进减少 hallucination 的手法。而且它是软引导而非保证,4% 的编造率不会因为想得更久就消失。
D6 半对半错违反 P1D:按需检索本身是合理架构(也确实能省 context),但它没有作用在题干指认的变量上——问题不是「文本没进上下文」,是模型在已经拿到全文的情况下仍然编造条款号。把 60k 换成按需取回,编造的对象只会从「不存在的条款」变成「没取回来的条款」。
QUESTION 05 · TS 6.3 · TRUNCATION LOOKS LIKE SUCCESS
A batch summarizer requests JSON with max_tokens: 1024. Its handler does json.loads(text) inside a try block and, on JSONDecodeError, retries the same request up to three times before giving up. Ops sees a steady 2% of documents burning all four attempts, always the longest documents, and the logged raw text always ends mid-string. Retries never help. What is the fix?
正确 B题干的三个信号——最长的文档、原文总在字符串中间断开、重试无效——全部指向输出被截断。stop_reason 取值 max_tokens 的官方释义正是「触到了请求的 max_tokens 或模型上限」。这就是本章第五节「关 1 在关 2 之前」的理由:一段解析失败的文本,先要知道它是格式错还是被切断。
D6 半对半错违反 P6A:structured outputs 的保证是真的——constrained decoding 给「总是合法、不再有 JSON.parse() 错误」。但它约束的是生成出来的内容符合 schema,解决不了「输出在 1024 token 处被硬切」这个源头;额度不够时该修的是额度。这一项覆盖的是另一类失败。
D7 过度工程违反 P10C:为一个只需改一个数字的问题引入一条修复链路,而且修复本身还是一次模型调用——它产出的仍然是待校验的模型输出(P7),还可能把截断处的内容补造出来,把「明显失败」变成「安静的错误」。
D2 无关杠杆违反 P6D:题干已经把源头指认清楚了——失败与文档长度相关、与时间无关,而且原文总在同一种位置断开。重试作用于瞬时失败;把三次加到八次,只是把同一个确定性截断记录八遍。
QUESTION 06 · TS 6.2 · MIXING INSTRUCTIONS AND DATA
A triage bot builds its request by string-concatenating a rules paragraph, the ticket body, and a closing instruction into one user message. Since a customer began pasting long formatted logs into tickets, the bot sometimes summarizes the log instead of triaging, and once followed a line in the ticket that read "ignore previous formatting rules." What is the right first change to the prompt construction?
正确 C官方对 XML tag 的说明正对着这个场景:XML tag 帮 Claude 无歧义地解析复杂 prompt,尤其当 prompt 混合了指令、上下文、示例与可变输入时;把每一类内容包进自己的 tag 能减少误读。后半句同样重要——包 tag 降低的是「把数据读成指令」的概率,它不是闸门;敏感动作的强制拦截是另一层(P3,见 ch14)。
D6 半对半错违反 P2A:把规则搬进 system 是对的一半——从头生效的指令本来就该在那儿。但「原始工单正文直接作为整条 user 消息、不需要任何标记」把另一半丢了:不可信内容仍然没有被标注成数据,模型无从判断这段字节是任务还是素材。
D3 措辞冒充控制违反 P3B:用一句话声明「以下内容不可信」,与官方样题 Q2 里被排除的那个选项是同一型——在 prompt 里礼貌请求 is not an enforceable control。而且这句声明本身也只是紧挨着不可信内容的又一段文本。
D2 无关杠杆违反 P1D:剥格式作用在「输入长什么样」上,而题干指认的变量是「指令与数据没有分界」。何况工单里的日志格式往往正是分诊需要的证据,剥掉它等于为了防误读而先毁掉素材。
QUESTION 07 · TS 6.2 · WHY THE RULE KEEPS LEAKING
A product-description generator's system prompt says Do not use markdown. Output still contains bold and bullets in roughly a third of responses. The prompt itself is a heavily formatted markdown document with headers, bold key terms, and bulleted rules. The team wants adherence up without moving to a schema. What should they try first?
正确 D官方给的格式控制三条里有两条正对这道题:告诉 Claude 该做什么而不是不该做什么(与其「不要用 markdown」,不如「你的回应应由流畅的散文段落构成」);以及让 prompt 风格匹配想要的输出风格——prompt 里的排版风格可能影响回应风格,把 prompt 里的 markdown 去掉可以减少输出里的 markdown 量。题干把那份重度 markdown 的 prompt 明写出来,就是在给这条信号。
D3 措辞冒充控制违反 P3A:把同一句禁令说两遍再加「这很关键」,仍然停留在措辞层,而且它保留了官方点名要避免的那种写法(说不该做什么)。「边界位置最被注意」也不是官方依据。
D6 半对半错违反 P1B:加示例是官方点名最可靠的格式控制手段之一,数量也合规。但它保留了两个病因中的两个——否定式的禁令没改,重度 markdown 的 prompt 本体没动。示例是在和 prompt 自身的排版信号打架,方向对、力度被抵消。
D2 无关杠杆违反 P5C:temperature 控制的是采样随机性,不是格式遵循度;「调高一点让它别被锚定」是给一个真实参数安上它没有的职责。更实际的是它在 Claude 4.7 及之后的模型上已 deprecated,设成非默认值直接返回 400。
QUESTION 08 · TS 6.3 · WHICH CONSTRAINT, WHERE
An agentic expense reviewer must (1) call an internal approve_expense(expense_id, amount_cents, reason) tool with well-formed arguments, and (2) return a final report object the dashboard renders. Today both go wrong occasionally: malformed tool arguments cause 422s from the internal service, and the final report sometimes comes back as prose. Which configuration matches the requirement?
正确 A官方把这两件事划得很清楚:JSON outputs 控制 Claude 的回应格式(它说什么),strict tool use 校验工具参数(它怎么调你的函数);两者可以独立使用,也可以在同一个请求里合用——合用时 Claude 既能用保证合法的参数调工具、又能返回结构化的 JSON 回应,官方说这正适合「既需要可靠工具调用、又需要结构化最终输出」的 agentic 工作流。题干的两个症状一一对应。
D1 凭空捏造违反 P5B:把 tool call 塞进响应 schema 的 tool_calls 数组,是本书自制的干扰项,没有官方出处。工具调用走的是 tool_use content block 与 tool_result 的往返,不是响应 JSON 里的一个字段;而 output_config.format 的产物是放在 text content block 里的 JSON。
D6 半对半错违反 P4C:strict: true 确实保证工具入参过 schema,这半句对。但把最终报告塞成工具的一个额外参数,是把「给用户的输出」错层承载在「给内部服务的调用」上——dashboard 要渲染的东西会跟着一次审批动作一起被发去内部服务。
D6 半对半错违反 P5D:后半句把 JSON outputs 的作用域说大了——它管的是回应格式,不覆盖工具入参,这正是官方要分成两个特性的原因。靠 description 文字描述参数形状也只是影响倾向;description 的官方职责是说明工具做什么、何时用、如何表现。