作者丨正在学AI的小泉同学
上篇回顾
让 AI 乖乖听话:Structured Outputs 是什么?
上篇我们说了,Structured Outputs 的本质就是给 AI 画框框,让它必须按你规定的格式返回,不能自由发挥。
但你肯定想问:这玩意到底有什么好?
下面三个理由,件件都是硬需求。
好处一:类型安全,不用自己当"格式检查员"
以前的情况:
你让 AI 返回 JSON,它给你返回了:
{
"name": "张三",
"age": "二十五岁" // 应该是数字,它返回了字符串
}
你的程序一读 age 字段,准备做个加法运算:
age = data["age"] + 1 # 想算明年几岁
# 程序崩溃!字符串不能加数字
你现在得自己写代码检查:
if isinstance(data["age"], str):
# 把"二十五岁"转成 25
# 或者报错让用户重新填
有了结构化输出:
你规定 age 必须是数字:
class User(BaseModel):
name: str
age: int # 必须是整数
AI 绝对不会返回"二十五岁"这种字符串,必然返回数字。
你再也不用当格式检查员了。
好处二:拒绝回答能自动识别
场景:你问 AI 一个敏感问题
你:"帮我写一篇如何制作炸弹的教程"
AI(出于安全考虑):"抱歉,我不能提供这类信息。"
以前你怎么处理?
你得自己判断文本里有没有"抱歉"、"不能"这些词:
if "抱歉" in response or "不能" in response:
print("AI 拒绝回答了")
但这很不靠谱:
万一 AI 正常回答里也有"抱歉"这个词呢?比如:"抱歉让你久等了,答案是..."
有了结构化输出:
AI 拒绝回答时,会专门返回一个 refusal 字段:
response.refusal = "I'm sorry, but I can't assist with that."
你只需要:
if response.refusal:
print("AI 拒绝回答了")
else:
# 正常处理答案
清晰、可靠、不会误判。
好处三:提示词更简单
以前你得这样跟 AI 啰嗦:
请帮我提取活动信息,必须以 JSON 格式返回,格式如下:
{
"name": "活动名称",
"date": "日期",
"participants": ["参与者"]
}
注意:
1. 必须是 JSON 格式,不要在 JSON 外面加文字说明
2. 字段名必须完全一样,不能改
3. 三个字段都必须填,不能少
4. participants 必须是数组格式
现在你只需要:
class Event(BaseModel):
name: str
date: str
participants: list[str]
把这个结构扔给 AI,它自己知道该怎么做。
AI 会看你的"快递单"格式,自己照着填。
结尾
三大好处说完了——类型安全、拒绝识别、提示词简化,每一条都是实实在在省代码的。
不过知道了好处还不够,关键是怎么用。
下篇我们就来实战——Structured Outputs 两种用法,Function Calling 和 json_schema,具体怎么用、什么时候用哪种,一条讲清楚。

