本页目录

提示工程与结构化输出

采样参数被删之后,"调创造性/确定性"的旋钮换成了两个:prompt(写清意图)和 effort(给够算力)。而要让输出能被程序消费,靠的不是"请返回 JSON",是 schema 约束。

概述

Token 与采样 讲过一道分叉:Claude 的托管 API 从 Opus 4.7 起删掉了 temperature/top_p/top_k,传了直接 400。旧时代"调温度控创造性、温度 0 求确定"的手感没了。Anthropic 把控制权上移到两个更高层、更可控的旋钮:

  • prompting——要确定就把指令写死,要发散就在 prompt 里明确要求多样性;
  • effort——控制想多深、花多少 token(见 推理与 thinking)。

这一篇讲怎么用好这两个旋钮(上半:提示工程),以及当输出要喂给下游程序时,怎么用 结构化输出 把"自由文本"约束成"保证能解析的 JSON"(下半)。两件事常一起出现:prompt 定行为,schema 定形状。

上半:提示工程

模型一次看到的,是被拼起来的一段文本

上下文工程 已讲渲染顺序 tools → system → messages。提示工程就是决定这段文本里写什么、怎么排:

  • system:稳定的角色、规则、输出约定——冻结它,别插时间戳(保 缓存)。
  • user:本轮的具体任务 + 必要的动态上下文(检索片段、状态)。
  • few-shot 示例⁠:几个输入→输出范例,比一长串抽象规则更能"教会"格式与风格。放 system 与 user 之间。

四条经手就有感的原则

  • 写清"何时/边界",而非堆砌"必须"。 近期 Opus(4.7/4.8)指令遵循极强,旧时代用来"压服"模型的 CRITICAL: YOU MUST过度触发⁠。把"CRITICAL: 必须用搜索工具"软化成"当答案依赖对话里没有的信息时,先搜索再答"。
  • 指令放在注意力强的位置。 关键约束放靠前的 system 或靠后的 user,用 XML 标签 / 分隔符框住(<rules>...</rules>),别埋在中段(对抗 lost in the middle)。
  • 正例优于反例。 "像这样写:…"比"不要这样"更稳。要简洁,给一个简洁范例,比列十条"别啰嗦"管用。
  • 给意图,不只给指令。 说明"这是给谁、用来干嘛",模型能自己补全合理细节——长任务尤其明显。

迁移配方:temperature → prompt + effort

旧代码里的采样参数,按意图转译:

旧写法(意图)新写法
temperature=0(求确定)effort:"low" + 把指令写死、给定输出格式
temperature=高(求发散)prompt 里明确"给出 N 个不同方向";前端设计场景让模型"先给 4 个不同方向再实现"
temperature 控篇幅直接在 prompt 写长度/详略要求(模型会按任务复杂度自调,需要就钉死)

提示一句老误区:temperature=0 在旧模型上也从不保证逐字节复现(浮点累加顺序、批处理、MoE 路由都在抖,见 Token 与采样)。"确定性"是工程目标(写死 prompt + 低 effort + 接受微小漂移),不是某个参数的保证。

下半:结构化输出

要把模型输出喂给程序(存数据库、调下游 API、做断言),"请返回 JSON"靠不住——模型可能加前言、漏字段、格式飘。⁠结构化输出用 schema 在 API 层把输出约束成保证合法的形状。两个层面:

1. JSON 输出:约束整段响应

messages.create 上传 output_config.format(注意:旧的顶层 output_format 参数已废弃):

response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=16000,
    messages=[{"role": "user", "content": "Extract: John (john@co.com), Enterprise plan"}],
    output_config={"format": {
        "type": "json_schema",
        "schema": {
            "type": "object",
            "properties": {
                "name":  {"type": "string"},
                "email": {"type": "string"},
                "plan":  {"type": "string"},
            },
            "required": ["name", "email", "plan"],
            "additionalProperties": False,   # 必须
        },
    }},
)
# 第一个 text block 即为合法 JSON

SDK 还提供 client.messages.parse() + Pydantic/Zod,直接拿到校验过的对象,免手解析。

2. 严格工具调用:约束工具参数

让模型调工具时,参数也按 schema 严格校验——在工具定义上加 strict: true(放在工具上,不是 tool_choice 上),schema 需带 additionalProperties: falserequired:

tools=[{
    "name": "book_flight",
    "strict": True,
    "input_schema": {
        "type": "object",
        "properties": {
            "destination": {"type": "string"},
            "passengers":  {"type": "integer", "enum": [1,2,3,4]},
        },
        "required": ["destination", "passengers"],
        "additionalProperties": False,
    },
}]

这保证 tool_use.input 严格符合 schema——分类任务用带 enum 的工具/结构化输出,比让模型"输出一个标签词"再解析稳得多。

schema 的能力边界(要知道,否则静默踩坑)

结构化输出支持⁠:基本类型、enum/const/anyOf/$ref、字符串格式(date-time/email/uri/uuid…)、additionalProperties: false(每个 object 都得写)。⁠不支持⁠:递归 schema、数值约束(minimum/maximum)、字符串长度(minLength/maxLength)、复杂数组约束。Python/TS SDK 会自动剥掉不支持的约束、转到客户端校验。

两个实操点:⁠首个新 schema 有一次性编译开销⁠,之后 24 小时缓存命中;⁠结构化输出与 citations 互斥⁠(同开 400,见 RAG)。

结构化输出 × 评估:让校验变可编程

这是结构化输出最被低估的价值。评估与可观测 讲过打分"能用代码判定就别交给模型"。结构化输出让一大类校验从"LLM-as-judge"降级成"代码断言":返回是否符合 schema、枚举值是否合法、必填字段是否齐全——全部 assert,确定、零成本、无偏差。⁠先用 schema 把输出钉成可断言的形状,再谈要不要上 LLM 裁判。

最佳实践

  • 采样参数全删,意图转译成 prompt + effort。 temperature=0effort:"low"+写死指令;求发散→prompt 明确"给 N 个方向"。
  • 指令写"何时/边界",别堆"必须"。 新 Opus 指令遵循强,过激措辞会过度触发;关键约束放强位置 + XML 框住。
  • few-shot 正例 > 一堆抽象规则。 给范例教格式和风格,要简洁就给简洁范例。
  • 输出要喂程序就上 schema。 output_config.format 约束整段、strict:true 约束工具参数;别靠"请返回 JSON"。
  • 每个 object 写 additionalProperties:false + required 否则严格模式不生效。
  • 用 schema 把校验降成代码断言。assert 的别请裁判;结构化输出是 eval 可编程化的前提。
  • 记住 schema 边界与互斥。 不支持递归/数值/长度约束;与 citations 互斥,二选一。

权衡与失败模式

  • 新模型还传 temperature/top_p/top_k:400 → 删掉,转 prompt + effort。
  • 旧式 CRITICAL: YOU MUST 轰炸⁠:工具/技能过度触发 → 软化为"何时用"的条件句。
  • 靠"请返回 JSON":偶发前言/漏字段/格式飘 → output_config.format 强约束。
  • strict 放到了 tool_choice⁠:不生效 → 放在工具定义上,配 additionalProperties:false
  • schema 写了 minLength/minimum:静默被剥离,约束没生效 → 这类范围校验放客户端代码做。
  • 结构化输出同时开 citations:400 → 二选一;要溯源就走纯文本 + 引用,要可解析就走 schema。
  • 关思考时啰嗦⁠:thinking:disabled 下推理漏进正文 → 留 adaptive,或加"只输出最终答案"(见 推理与 thinking)。

参考

Keywords: prompt engineering, 提示工程, system prompt, few-shot, XML tags, 指令放置, temperature 迁移, effort, 结构化输出, structured outputs, output_config.format, json_schema, strict tool use, additionalProperties, required, messages.parse, Pydantic, Zod, enum, schema 编译缓存, citations 互斥, 可编程校验, 确定性