第 61 章:输出的精确控制

个人公众号

卷五协议验证日期:2026-05-17,基于 Anthropic Output Configuration 和 Structured Output 规范

前面六章都在讲输入。这一章讲输出——如何控制 Claude 回答的深度、格式和确定性。


路线图

1
2
3
4
5
6
7
graph LR
CH60["← 第 60 章<br/>聪明的缓存"] --> CH61["📖 第 61 章<br/>输出的精确控制"]
CH61 --> CH62["第 62 章<br/>配置的多重宇宙"]

style CH60 fill:#e8f5e9,stroke:#333
style CH61 fill:#FF8F00,color:#fff,stroke:#333
style CH62 fill:#e1f5fe,stroke:#333

三大输出控制维度

维度参数效果
努力程度output_config.effort控制思考深度和 token 消耗
输出结构output_config.format强制 JSON Schema 格式
随机性temperature, top_p, top_k控制创造性和确定性

effort — 控制思考深度

1
2
3
4
5
6
7
8
9
10
11
12
13
// → src/my-agent/output-config.ts
interface OutputConfig {
effort?: "low" | "medium" | "high" | "xhigh" | "max";
format?: StructuredFormat;
}

const configs: Record<string, OutputConfig> = {
quick: { effort: "low" }, // 快速回答,token 最少
balanced: { effort: "medium" }, // 性价比
thorough: { effort: "high" }, // 默认,高质量
extended: { effort: "xhigh" }, // 长期任务(Opus 4.7 专有)
maximum: { effort: "max" }, // 最强能力,token 最多
};

各 effort 级别的行为和适用场景

effort行为典型场景
low精简回答,减少工具调用分类、简单问答、高吞吐
medium平衡速度和质量常规编程、Agent 任务
high全面分析(默认)复杂推理、代码审查
xhigh扩展探索(Opus 4.7)长时 Agent 任务(30分钟+)
max最强能力,不限 token前沿问题、需要极致质量

各模型推荐设置

1
2
3
4
5
6
7
8
9
10
11
12
// → src/my-agent/output-config.ts
const MODEL_EFFORT_DEFAULTS: Record<string, OutputConfig> = {
"claude-opus-4-7": {
effort: "xhigh", // 编码和 Agent 推荐的起步值
},
"claude-sonnet-4-6": {
effort: "medium", // 推荐默认值(Sonnet 4.6 的 high 较慢)
},
"claude-haiku-4-5": {
effort: "low", // Haiku 在低 effort 下最快
},
};

effort 与 thinking 的关系

1
2
3
4
5
6
7
8
9
10
Opus 4.7: effort + adaptive thinking
high/xhigh/max → 基本总是思考
low/medium → 简单问题可能跳过思考

Opus 4.6/Sonnet 4.6: effort + adaptive thinking
high/max → 基本总是思考
low/medium → 简单问题可能跳过思考

Opus 4.5: effort + manual thinking (budget_tokens)
effort 和 budget_tokens 互补控制

Structured Output — 强制 JSON

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// → src/my-agent/structured-output.ts
import type { OutputConfig } from "./types";

// 定义输出 Schema
const extractSchema: OutputConfig = {
format: {
type: "json_schema",
schema: {
type: "object",
properties: {
name: { type: "string", description: "人名" },
age: { type: "integer", description: "年龄" },
skills: {
type: "array",
items: { type: "string" },
description: "技能列表",
},
},
required: ["name", "age", "skills"],
additionalProperties: false,
},
},
};

// 使用
const response = await client.createMessage({
model: "claude-sonnet-4-6",
max_tokens: 1024,
output_config: extractSchema,
messages: [{
role: "user",
content: "张三,28岁,会 Python、TypeScript 和 Rust",
}],
});

// response.content[0].text 一定是合法的 JSON
const person = JSON.parse(response.content[0].text);
// { name: "张三", age: 28, skills: ["Python", "TypeScript", "Rust"] }

Schema 约束

  • 支持 JSON Schema Draft 2020-12
  • 必须是 { "type": "object", ... } 顶层
  • 不支持 oneOfanyOf 等复杂组合(子 schema 可用)
  • 模型保证输出符合 schema

错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// → src/my-agent/structured-output.ts
async function extractStructured<T>(
client: ApiClient,
prompt: string,
schema: OutputConfig,
maxRetries = 3
): Promise<T> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await client.createMessage({
model: "claude-sonnet-4-6",
max_tokens: 2048,
output_config: schema,
messages: [{ role: "user", content: prompt }],
});

try {
const text = response.content.find(b => b.type === "text")?.text ?? "";
return JSON.parse(text) as T;
} catch {
// JSON 解析失败(极少发生,但防范)
if (attempt === maxRetries - 1) throw new Error("Structured output failed");
}
}
throw new Error("Unreachable");
}

采样参数 — 控制随机性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// → src/my-agent/sampling.ts
interface SamplingParams {
temperature?: number; // 0.0-1.0,默认 1.0
top_p?: number; // 核采样阈值
top_k?: number; // Top-K 采样
stop_sequences?: string[]; // 遇到即停
}

// 确定性输出(代码生成、数据提取)
const deterministic: SamplingParams = {
temperature: 0,
};

// 创造性输出(写作、头脑风暴)
const creative: SamplingParams = {
temperature: 0.9,
top_p: 0.95,
};

// 严格格式化输出
const precise: SamplingParams = {
temperature: 0.1,
stop_sequences: ["```", "\n\n\n"],
};

实现 OutputController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// → src/my-agent/output-controller.ts
export class OutputController {
private config: Required<OutputConfig> & SamplingParams;

constructor(options: {
effort?: OutputConfig["effort"];
schema?: object;
temperature?: number;
topP?: number;
}) {
this.config = {
effort: options.effort ?? "high",
temperature: options.temperature ?? 1.0,
top_p: options.topP,
top_k: undefined,
stop_sequences: undefined,
};
}

applyTo(params: MessageCreateParams): MessageCreateParams {
return {
...params,
output_config: {
effort: this.config.effort,
...(this.config.schema ? {
format: { type: "json_schema", schema: this.config.schema },
} : {}),
},
temperature: this.config.temperature,
top_p: this.config.top_p,
top_k: this.config.top_k,
stop_sequences: this.config.stop_sequences,
};
}

// 预设模式
static codeGeneration(): OutputController {
return new OutputController({ effort: "high", temperature: 0 });
}

static extraction(): OutputController {
return new OutputController({ effort: "low", temperature: 0 });
}

static creative(): OutputController {
return new OutputController({ effort: "high", temperature: 0.9 });
}
}

试试看

任务 1:同一段代码审查,分别用 effort: "low"effort: "medium"effort: "high" 发送。比较回答的详细程度和 token 消耗。

任务 2:从一段自由文本中提取结构化数据(人名、年龄、技能),实现自动重试。

任务 3:对比 temperature: 0temperature: 0.5temperature: 1.0 下同一个创意写作任务(如”写一首关于编程的俳句”)的输出多样性。


常见错误

现象原因解法
Schema 格式错误不是合法的 JSON Schema用 JSON Schema validator 预检
effort 不生效模型不支持该 effort 级别检查模型 capability
structured output 不精确Schema 过于宽松additionalProperties: false
Opus 4.7 用 high 觉得不够该用 xhigh编码/Agent 推荐起步 xhigh

检查点

  • 理解了 effort 五个级别及其与 thinking 的关系
  • 能用 output_config.format 强制结构化输出
  • 理解了 temperature/top_p/top_k 的采样语义
  • 实现了 OutputController(预设模式切换)
  • 能根据任务类型选择合适的输出控制策略

← 上一章:第 60 章 聪明的缓存 | 下一章:第 62 章 配置的多重宇宙 →