获得一致且格式良好的输出对于生产应用和高效工作流程至关重要。本章介绍如何精确控制 AI 模型格式化响应的技术。

<Callout type="info" title="从散文到数据">
结构化输出将 AI 响应从自由格式文本转换为可操作、可解析的数据。
</Callout>

## 结构为何重要

<StructuredOutputDemo />

## 基础格式化技术

### 列表

列表非常适合分步指令、排名项目或相关要点的集合。它们易于浏览和解析。当顺序重要时使用**编号列表**（步骤、排名），对于无序集合使用**项目符号**。

<TryIt 
  compact
  title="列表格式化"
  prompt={`提供5个改善睡眠的建议。

格式：编号列表，每条带简短说明。
每个建议应加粗，后跟破折号和说明。`}
/>

<Callout type="tip" title="列表最佳实践">
明确指定你想要的项目数量、是否包含说明，以及项目是否应该加粗或具有特定结构。
</Callout>

### 表格

表格擅长在相同维度上比较多个项目。它们非常适合功能比较、数据摘要以及任何具有一致属性的信息。始终明确定义列标题。

<TryIt 
  compact
  title="表格格式化"
  prompt={`比较排名前4的 Python Web 框架。

格式化为 markdown 表格，包含以下列：
| 框架 | 最适合 | 学习曲线 | 性能 |`}
/>

<Callout type="tip" title="表格最佳实践">
指定列名、预期数据类型（文本、数字、评级）以及需要多少行。对于复杂比较，为了可读性限制在4-6列。
</Callout>

### 标题和章节

标题创建清晰的文档结构，使长响应易于浏览和组织。用于报告、分析或任何多部分响应。层级标题（##、###）展示章节之间的关系。

```
分析这份商业提案。

用以下章节结构化你的回复：
## 执行摘要
## 优势
## 劣势
## 建议
## 风险评估
```

<Callout type="tip" title="章节最佳实践">
按你期望的顺序列出章节。为保持一致性，指定每个章节应包含的内容（例如，"执行摘要：仅2-3句话"）。
</Callout>

### 大写指令强调

大写单词作为对模型的强信号，强调关键约束或要求。谨慎使用以获得最大效果——过度使用会削弱其效力。

**常见大写指令：**

<InfoGrid items={[
  { label: "NEVER", description: "绝对禁止：\"NEVER include personal opinions\"", color: "red" },
  { label: "ALWAYS", description: "强制要求：\"ALWAYS cite sources\"", color: "green" },
  { label: "IMPORTANT", description: "关键指令：\"IMPORTANT: Keep responses under 100 words\"", color: "amber" },
  { label: "DO NOT", description: "强烈禁止：\"DO NOT make up statistics\"", color: "red" },
  { label: "MUST", description: "必须执行：\"Output MUST be valid JSON\"", color: "blue" },
  { label: "ONLY", description: "限制条件：\"Return ONLY the code, no explanations\"", color: "purple" },
]} />

```
总结这篇文章。

IMPORTANT: 摘要保持在100字以内。
NEVER 添加原文中没有的信息。
ALWAYS 保持原文的语气和视角。
DO NOT 包含你自己的观点或分析。
```

<Callout type="warning" title="谨慎使用">
如果所有内容都大写或标记为关键，那什么都不突出了。将这些指令保留给真正重要的约束。
</Callout>

## JSON 输出

JSON（JavaScript 对象表示法）是结构化 AI 输出最流行的格式。它是机器可读的，被各种编程语言广泛支持，非常适合 API、数据库和自动化工作流程。可靠 JSON 的关键是提供清晰的模式。

### 基础 JSON 请求

从展示你想要的确切结构的模板开始。包含字段名、数据类型和示例值。这充当模型将遵循的契约。

<TryIt 
  title="JSON 提取"
  description="从非结构化文本中提取结构化数据。"
  prompt={`从这段文本中提取信息并以 JSON 格式返回：

{
    "company_name": "string",
    "founding_year": number,
    "headquarters": "string",
    "employees": number,
    "industry": "string"
}

文本："Apple Inc.，成立于1976年，总部位于加利福尼亚州库比蒂诺。这家科技巨头在全球雇用约164,000名员工。"`}
/>

### 复杂 JSON 结构

对于嵌套数据，使用层级 JSON，包含对象中的对象、对象数组和混合类型。清晰定义每个层级，并使用 TypeScript 风格的注解（`"positive" | "negative"`）来约束值。

```
分析这条产品评论并返回 JSON：

{
  "review_id": "string (generate unique)",
  "sentiment": {
    "overall": "positive" | "negative" | "mixed" | "neutral",
    "score": 0.0-1.0
  },
  "aspects": [
    {
      "aspect": "string (e.g., 'price', 'quality')",
      "sentiment": "positive" | "negative" | "neutral",
      "mentions": ["exact quotes from review"]
    }
  ],
  "purchase_intent": {
    "would_recommend": boolean,
    "confidence": 0.0-1.0
  },
  "key_phrases": ["string array of notable phrases"]
}

Return ONLY valid JSON, no additional text.

Review: "[review text]"
```

### 确保有效 JSON

模型有时会在 JSON 周围添加解释性文本或 markdown 格式。通过关于输出格式的明确指令来防止这种情况。你可以请求原始 JSON 或代码块中的 JSON——根据你的解析需求选择。

添加明确指令：

```
IMPORTANT:
- Return ONLY the JSON object, no markdown code blocks
- Ensure all strings are properly escaped
- Use null for missing values, not undefined
- Validate that the output is parseable JSON
```

或通过要求模型包装其输出来请求代码块：

````
以 JSON 代码块返回结果：
```json
{ ... }
```
````

## YAML 输出

YAML 比 JSON 更易于人类阅读，使用缩进而非括号。它是配置文件（Docker、Kubernetes、GitHub Actions）的标准，在输出将由人类阅读或用于 DevOps 场景时效果很好。YAML 对缩进敏感，因此要具体说明格式要求。

<TryIt 
  compact
  title="YAML 生成"
  prompt={`为 Node.js 项目生成 GitHub Actions 工作流。

以有效 YAML 返回：
- 包含：install、lint、test、build 阶段
- 使用 Node.js 18
- 缓存 npm 依赖
- 在推送到 main 和拉取请求时运行`}
/>

## XML 输出

XML 仍然是许多企业系统、SOAP API 和遗留集成所必需的。它比 JSON 更冗长，但提供属性、命名空间和用于复杂数据的 CDATA 部分等功能。指定元素名称、嵌套结构，以及何时使用属性与子元素。

```
将此数据转换为 XML 格式：

要求：
- 根元素：<catalog>
- 每个项目在 <book> 元素中
- 在适当的地方包含属性
- 对描述文本使用 CDATA

数据：[book data]
```

## 自定义格式

有时标准格式不能满足你的需求。你可以通过提供清晰的模板来定义任何自定义格式。自定义格式非常适合报告、日志或将由人类阅读的特定领域输出。

### 结构化分析格式

使用分隔符（===、---、[SECTION]）创建章节之间有清晰边界的可浏览文档。这种格式非常适合代码审查、审计和分析。

```
使用这种精确格式分析这段代码：

=== CODE ANALYSIS ===

[SUMMARY]
One paragraph overview

[ISSUES]
• CRITICAL: [issue] — [file:line]
• WARNING: [issue] — [file:line]  
• INFO: [issue] — [file:line]

[METRICS]
Complexity: [Low/Medium/High]
Maintainability: [score]/10
Test Coverage: [estimated %]

[RECOMMENDATIONS]
1. [Priority 1 recommendation]
2. [Priority 2 recommendation]

=== END ANALYSIS ===
```

### 填空格式

带空白（___）的模板引导模型填写特定字段，同时保持精确格式。这种方法非常适合表单、简报和需要一致性的标准化文档。

```
为给定产品完成此模板：

PRODUCT BRIEF
─────────────
Name: _______________
Tagline: _______________
Target User: _______________
Problem Solved: _______________
Key Features:
  1. _______________
  2. _______________
  3. _______________
Differentiator: _______________

Product: [product description]
```

## 类型化响应

类型化响应定义模型应识别和标记的类别或实体类型。这种技术对于命名实体识别（NER）、分类任务以及任何需要一致分类信息的提取都至关重要。用示例清晰定义你的类型。

<TryIt 
  compact
  title="实体提取"
  prompt={`从这段文本中提取实体。

实体类型：
- PERSON：人物全名
- ORG：组织/公司名称
- LOCATION：城市、国家、地址
- DATE：ISO 格式的日期（YYYY-MM-DD）
- MONEY：带货币的金额

将每个格式化为：[TYPE]: [value]

文本："Tim Cook 宣布 Apple 将在2024年12月前向奥斯汀新设施投资10亿美元。"`}
/>

## 多部分结构化响应

当你需要涵盖多个方面的综合输出时，定义具有清晰边界的不同部分。精确指定每个部分的内容——格式、长度和内容类型。这可以防止模型混合章节或遗漏部分。

```
研究这个主题并提供：

### PART 1: EXECUTIVE SUMMARY
[2-3 sentence overview]

### PART 2: KEY FINDINGS
[Exactly 5 bullet points]

### PART 3: DATA TABLE
| Metric | Value | Source |
|--------|-------|--------|
[Include 5 rows minimum]

### PART 4: RECOMMENDATIONS
[Numbered list of 3 actionable recommendations]

### PART 5: FURTHER READING
[3 suggested resources with brief descriptions]
```

## 条件格式化

条件格式化让你可以根据输入的特征定义不同的输出格式。这对于分类、分诊和路由系统非常强大，在这些系统中响应格式应根据模型检测到的内容而变化。使用清晰的 if/then 逻辑，并为每种情况提供明确的输出模板。

<TryIt 
  compact
  title="工单分类"
  prompt={`对这个支持工单进行分类。

如果 URGENT（系统宕机、安全问题、数据丢失）：
  返回：🔴 URGENT | [Category] | [Suggested Action]

如果 HIGH（影响多个用户、收入影响）：
  返回：🟠 HIGH | [Category] | [Suggested Action]

如果 MEDIUM（影响单个用户、存在变通方法）：
  返回：🟡 MEDIUM | [Category] | [Suggested Action]

如果 LOW（问题、功能请求）：
  返回：🟢 LOW | [Category] | [Suggested Action]

工单："我无法登录我的账户。我已经尝试重置密码两次但仍然收到错误。这阻止了我的整个团队访问仪表板。"`}
/>

## JSON 中的数组和列表

将多个项目提取到数组中需要仔细的模式定义。指定数组结构、每个项目应包含的内容，以及如何处理边缘情况（空数组、单个项目）。包含计数字段有助于验证完整性。

```
从这份会议记录中提取所有行动项目。

以 JSON 数组返回：
{
  "action_items": [
    {
      "task": "string describing the task",
      "assignee": "person name or 'Unassigned'",
      "deadline": "date if mentioned, else null",
      "priority": "high" | "medium" | "low",
      "context": "relevant quote from transcript"
    }
  ],
  "total_count": number
}

Transcript: "[meeting transcript]"
```

## 验证指令

自我验证提示模型在响应之前检查自己的输出。这可以捕获常见问题，如缺少章节、占位符文本或违反约束。模型将在内部迭代以修复问题，无需额外的 API 调用即可提高输出质量。

```
生成报告，然后：

VALIDATION CHECKLIST:
□ All required sections present
□ No placeholder text remaining
□ All statistics include sources
□ Word count within 500-700 words
□ Conclusion ties back to introduction

If any check fails, fix before responding.
```

## 处理可选字段

现实世界的数据经常有缺失值。明确指示模型如何处理可选字段——使用 `null` 比空字符串更简洁，更易于程序化处理。同时通过强调模型永远不应编造信息来防止"幻觉"缺失数据。

```
提取联系信息。对缺失字段使用 null。

{
  "name": "string (required)",
  "email": "string or null",
  "phone": "string or null", 
  "company": "string or null",
  "role": "string or null",
  "linkedin": "URL string or null"
}

IMPORTANT: 
- Never invent information not in the source
- Use null, not empty strings, for missing data
- Phone numbers in E.164 format if possible
```

## 总结

<Callout type="tip" title="关键技术">
明确格式、使用示例、指定类型、用 null 值处理边缘情况，并要求模型验证自己的输出。
</Callout>

<Quiz 
  question="结构化输出相对于非结构化文本的主要优势是什么？"
  options={[
    "它使用更少的 token",
    "AI 更容易生成",
    "可以程序化解析和验证",
    "它总是产生正确的信息"
  ]}
  correctIndex={2}
  explanation="像 JSON 这样的结构化输出可以被代码解析、跨查询比较、集成到工作流程中并验证完整性——这些对于自由格式文本来说是困难或不可能的。"
/>

结构化输出对于构建可靠的 AI 驱动应用程序至关重要。在下一章中，我们将探索用于复杂推理任务的思维链提示。
