第4课

Structured Outputs:让 AI 返回标准 JSON

让 AI 按固定格式交答案,程序才能一读就懂。

本课项目:AI作文评分器

学习重点:JSON Schema、字段、类型、必填项。工具重点:Structured Outputs。

OpenAI AI编程第4课封面
AI 工具地图

OpenAI 项目工具栈

页面里加入 OpenAI、Node.js、Python 和 JSON 图标,帮助学生把 AI 能力、后端调用、脚本实验和结构化输出放在同一条学习路线里理解。

学习路线

阶段入口与周课入口

先用阶段卡片看清大方向,再用周课卡片进入具体项目。每节课都保留理论、例子、Node.js、Python、练习和自测,学生可以直接按卡片推进。

OpenAI 项目地图

阶段入口

第01阶段:AI应用基础与 OpenAI 入门

先看懂 AI 应用的工作流程,再完成第一次 API 调用,最后学会写清楚提示词。

进入学习

第02阶段:让 AI 输出程序能读懂的结果

AI 不只要会说话,还要按固定格式交答案,这样程序才能稳定处理。

进入学习

第03阶段:Function Calling:让 AI 调用函数

AI 负责理解语言,函数负责精确计算;两者配合,结果更可靠。

进入学习

第04阶段:多模态应用:文字 + 图片

把图片也交给 AI 看,再让它用清楚的文字或 JSON 结果回答。

进入学习

第05阶段:内置工具:Web Search 与 File Search

需要最新消息时查网页;需要班级资料时查文件。先找资料,再回答。

进入学习

第06阶段:前后端 AI 应用开发

把 AI 能力做成网页:前端收集输入,后端保护密钥,页面展示结果。

进入学习

第07阶段:AI Agent、安全与成本

Agent 会按步骤完成任务,但你要给它工具、边界、检查规则和预算意识。

进入学习

第08阶段:毕业项目发布会

把前面学过的提示词、JSON、函数、检索、网页和安全设计合在一个作品里。

进入学习

周课入口

第4课:Structured Outputs:让 AI 返回标准 JSON

让 AI 按固定格式交答案,程序才能一读就懂。

进入学习

第5课:AI分类器:把信息放进正确类别

分类器会读懂一段文字,并给出类别、难度、原因和下一步动作。

进入学习

4.1 今天你要完成什么

JSON 像一张固定表格。字段名固定,类型固定,程序就能稳定读取。

本课闯关:完成“AI作文评分器”,并用 3 组输入测试它。

4.2 核心理论

理论不是背概念,而是帮你判断项目为什么这样设计。下面这些规则会在代码里反复出现。

4.3 课堂讲解

这一课的项目是“AI作文评分器”,重点是“JSON Schema、字段、类型、必填项”。你可以把它当成一个小实验:先给它一个清楚输入,再观察代码里哪些地方用到了 Structured Outputs。课堂里我们不会一上来就追求复杂功能,而是先把最小版本做出来。最小版本跑通以后,你再改输入、改提示词、改输出格式,变化就会看得很清楚。

这几课的重点是让答案变得可检查。自然语言像聊天,JSON 像表格。聊天适合给人看,表格适合给程序读。

本课有一条很实用的学习线索:先问“用户到底给了什么”,再问“程序希望拿到什么”。比如你可以试这些输入:写一篇关于公园观察的短作文;作文只有一句话:我今天很开心;作文跑题:我想介绍游戏装备。这些输入故意有简单的,也有容易出问题的。正常输入能帮你确认功能;短输入、空输入、奇怪输入能帮你发现系统边界。

写代码时建议你分三轮。第一轮只跑通官方调用,不加自己的想法;第二轮把输入换成自己的例子,看看结果是否还合理;第三轮才开始改结构,比如增加字段、加错误提示、做网页交互。这个顺序有点慢,但很稳。真正浪费时间的不是慢,而是一下子改太多,最后不知道错在哪里。

最常见的问题是字段不稳定。今天叫 score,明天叫 points,程序就会读不懂。所以字段名、类型、必填项要提前写死。

理论部分要和代码一起看。比如“输入契约”不是一个漂亮词,它在代码里就是长度检查、必填字段、表单校验;“输出契约”也不是空话,它在代码里就是 JSON Schema、固定字段或页面渲染规则。你每写一行检查代码,都是在告诉系统:什么结果可以接受,什么结果需要退回去重新处理。

课堂里可以把同桌当成第一个用户。你把项目跑给同桌看,让对方换一个输入,观察系统会不会乱。很多问题都是别人随手一试才出现的,比如输入太短、问题太模糊、连续点击按钮、图片看不清。能处理这些小麻烦,作品就会从“我电脑上能跑”变成“别人也能用”。

最后做复盘时,不要只写“我学会了调用 API”。可以写得更具体:我学会了怎样限制输入,怎样让输出固定,怎样判断结果不可靠,怎样把报错变成用户看得懂的提示。这样的复盘有用,因为下一课你真的会再次用到它。

课堂讨论题

4.4 先看例子

先把例子看懂,再动手写代码。你不需要一次记住所有概念,先能说清楚“输入是什么、输出是什么、程序要检查什么”。

自然语言不稳定

这篇作文不错,我给 82 分。优点是内容完整,缺点是细节少。

JSON 输出稳定

{
  "score": 82,
  "strengths": ["内容完整"],
  "weaknesses": ["细节不够"],
  "next_steps": ["加入一个具体场景"]
}

Schema 片段

{
  "type": "object",
  "properties": {
    "score": { "type": "integer", "minimum": 0, "maximum": 100 }
  },
  "required": ["score"],
  "additionalProperties": false
}

你可以替换成这些输入

4.5 完整代码实现

下面同时给出 Node.js 和 Python 两套完整最小实现。先任选一种原样跑通,再改输入、改提示词、改输出格式。

Node.js 运行方式

  1. 新建文件 lesson-04.mjs,把下面完整代码放进去。
  2. 在终端运行:npm init -y
  3. 安装依赖:npm install openai
  4. 设置环境变量 OPENAI_API_KEY。Windows PowerShell 示例:$env:OPENAI_API_KEY="你的密钥"
  5. 运行:node lesson-04.mjs
  6. 把最后一行的示例输入换成你自己的测试内容。

Node.js 完整代码

import OpenAI from "openai";

const client = new OpenAI();
const MODEL = process.env.OPENAI_MODEL || "gpt-5.5";

const essaySchema = {
  type: "object",
  properties: {
    score: { type: "integer", minimum: 0, maximum: 100 },
    strengths: {
      type: "array",
      items: { type: "string" },
      minItems: 1,
      maxItems: 3,
    },
    weaknesses: {
      type: "array",
      items: { type: "string" },
      minItems: 1,
      maxItems: 3,
    },
    next_steps: {
      type: "array",
      items: { type: "string" },
      minItems: 1,
      maxItems: 3,
    },
  },
  required: ["score", "strengths", "weaknesses", "next_steps"],
  additionalProperties: false,
};

async function scoreEssay(essay) {
  const response = await client.responses.create({
    model: MODEL,
    input: [
      {
        role: "system",
        content: "你是一位小学作文老师。评分要温和、具体、可改进。",
      },
      {
        role: "user",
        content: `请批改这篇作文,并给出 JSON 结果:\n${essay}`,
      },
    ],
    text: {
      format: {
        type: "json_schema",
        name: "essay_score",
        strict: true,
        schema: essaySchema,
      },
    },
  });

  return JSON.parse(response.output_text);
}

const essay = "今天我去公园观察昆虫。我看到蚂蚁排队搬食物,还画下了它们的路线。我觉得它们很会合作。";
const result = await scoreEssay(essay);

console.log(JSON.stringify(result, null, 2));

Python 运行方式

  1. 新建文件 lesson-04.py,把下面完整代码放进去。
  2. 建议新建虚拟环境后再安装依赖。
  3. 安装依赖:pip install openai
  4. 设置环境变量 OPENAI_API_KEY。Windows PowerShell 示例:$env:OPENAI_API_KEY="你的密钥"
  5. 运行:python lesson-04.py
  6. 把 main 里的示例输入换成你自己的测试内容。

Python 完整代码

from openai import OpenAI
import json
import os

client = OpenAI()
MODEL = os.getenv("OPENAI_MODEL", "gpt-5.5")

essay_schema = {
    "type": "object",
    "properties": {
        "score": {"type": "integer", "minimum": 0, "maximum": 100},
        "strengths": {
            "type": "array",
            "items": {"type": "string"},
            "minItems": 1,
            "maxItems": 3,
        },
        "weaknesses": {
            "type": "array",
            "items": {"type": "string"},
            "minItems": 1,
            "maxItems": 3,
        },
        "next_steps": {
            "type": "array",
            "items": {"type": "string"},
            "minItems": 1,
            "maxItems": 3,
        },
    },
    "required": ["score", "strengths", "weaknesses", "next_steps"],
    "additionalProperties": False,
}


def score_essay(essay):
    response = client.responses.create(
        model=MODEL,
        input=[
            {
                "role": "system",
                "content": "你是一位小学作文老师。评分要温和、具体、可改进。",
            },
            {
                "role": "user",
                "content": f"请批改这篇作文,并给出 JSON 结果:\n{essay}",
            },
        ],
        text={
            "format": {
                "type": "json_schema",
                "name": "essay_score",
                "strict": True,
                "schema": essay_schema,
            }
        },
    )
    return json.loads(response.output_text)


essay = "今天我去公园观察昆虫。我看到蚂蚁排队搬食物,还画下了它们的路线。我觉得它们很会合作。"
result = score_essay(essay)
print(json.dumps(result, ensure_ascii=False, indent=2))

4.6 跟着做

  1. 写出评分器需要返回哪些字段。
  2. 给每个字段规定类型:数字、字符串、数组。
  3. 写 required,确保重要字段不会丢。
  4. 写 additionalProperties: false,避免多出奇怪字段。
  5. 用正常、很短、跑题三种作文测试。

4.7 常见错误

排查顺序:先看输入,再看提示词,再看输出格式,最后看程序逻辑。

4.8 课后练习

  1. 把作文评分器改成读书笔记评分器。
  2. 新增 level 字段,值只能是 A、B、C。
  3. 提交 3 组输入和 JSON 输出。

4.9 自测清单