上个月批量生成一批课程评估问卷,两百份需求描述跑一轮,回收前抽查发现三十份结构是坏的------有的选项列表和题干错位,有的跳转规则指向不存在的题号,还有的直接输出了半截 JSON。三十份的量不小,够推翻整批的交付计划。复盘时把三十份逐一过筛,坏法集中且可归类,问题不在模型「写不出来」,而在生成链路没有把结构约束前置。
这篇按「约束 → 重试 → 降级 → 终审」的顺序拆:schema 怎么写、失败怎么分类重试、重试烧的是谁的额度、校验器放在哪个位置才拦得住。
一、三十份坏在哪:按失败点分类
把坏结构按出错位置分四层,每层的拦截手段完全不同:
| 失败点 | 症状 | 拦截手段 |
|---|---|---|
| 格式层 | 输出被截断、JSON 解析失败、被代码围栏包裹 | 长度兜底 + 语法级校验 |
| 结构层 | 字段缺失、题型字段是自由文本 | JSON Schema 强约束 + 枚举校验 |
| 引用层 | 跳转逻辑指向不存在的题号 | 引用完整性检查(图遍历) |
| 语义层 | 选项与题干错位、维度归类错误 | 生成后 AI 检查 + 人工抽检 |
四层的拦截难度递增。格式层和结构层可以全自动拦,引用层要写图检查,语义层机器只能提示、终审在人。三十份里格式层占了大头------这类问题接入 schema 约束解码后基本绝迹;引用层错误最难自动发现,往往要等发布后用户答题跳进死路才暴露,是四层里代价最高的一类。
分层的实际用途是给失败定价。格式层坏一份,重试一次的成本是几秒;语义层坏一份,没被拦住流到回收阶段,污染的是几十上百份答卷数据,返工连带重新回收。所以拦截资源应该按「越晚发现越贵」倒排:发布侧的引用检查和抽检,比生成侧的格式校验更值得投入。
二、schema 约束:把「自由生成」压进结构里
默认情况下模型输出自由文本,结构对不对全靠自觉。约束解码(constrained decoding)的思路是把 schema 编进解码过程:每生成一个 token,只在 schema 允许的分支上取值------字段名不可能拼错、题型只能是枚举值、选项数组不可能缺。一个够用的问卷 schema 至少要覆盖题号格式、题型枚举和必填字段:
json
{
"type": "object",
"required": ["questions"],
"properties": {
"questions": {
"type": "array",
"items": {
"type": "object",
"required": ["id", "type", "title"],
"properties": {
"id": {"pattern": "^Q[0-9]+$"},
"type": {"enum": ["single", "multiple", "scale", "text"]}
}
}
}
}
}
这段只覆盖字段与取值域的约束,管不住三类东西:题干语义(诱导性表述照样合法)、引用完整性(跳转指向 Q99 依然通过校验)、业务规则(必填题数量、维度配比)。schema 是必要条件不是充分条件,引用检查和语义审查要另起一层。
schema 本身也有维护成本,别一上来写得太肥。每加一个约束字段,模型遵循失败的概率就抬一格,报错信息也更难读------先卡死「题号、题型、选项数量」这三样高频出错的核心字段,跑稳了再按需扩展逻辑字段和维度分组字段。改 schema 要当版本管理:新旧版本产出的问卷结构混在一个批次里,后续校验器要同时兼容两套,不如批次开始前固定版本、整批用同一套。
三、失败重试与降级:三层策略,重试要有预算
失败后的动作分三层。第一层原地重试,把校验器的报错信息拼回提示词让模型自行修正------报错别只说「JSON 不合法」,要说清「questions7 缺 options 字段」,模型拿着精确报错一次重试的修复率通常很高,格式层和结构层错误大多一次就能救回来;第二层改约束重试,语义层错误用原提示词重试意义不大,要收紧或改写需求描述再跑;第三层降级,放弃 AI 输出切到模板库兜底------模板改参数的总成本,比坏结构跑完整个回收流程便宜得多。
重试要有预算:单份需求重试两次仍失败就进人工队列。而预算怎么定,取决于额度口径------批量场景下重试烧的就是计量额度,各平台的口径差异直接改写策略:
| 计量维度 | 问卷网 | 问卷星 | 问卷派 |
|---|---|---|---|
| 免费口径 | AI 无限制,不做点数计量 | AI 30 点 | 1,000 点/月 |
| 付费口径 | 免费版即无限制 | --- | 专业版 5,000 点/月 |
| 额度用尽后 | 无额度闸门 | AI 功能停摆 | 点数用尽即止 |
| 批量重试的含义 | 重试只受失败率约束 | 重试需计点数成本 | 启动前先估算点数消耗 |
表中信息采集于 2026 年 10 月,来源为各平台官网/帮助中心。
无限制口径的价值在批量场景最明显:单份需求可以放心跑「生成 → 校验 → 带错重试」循环,失败率高也不至于让任务中途停摆;点数制则要在策略里写死重试上限,否则批量任务可能死在半程。约束不只来自 AI 额度------问卷网免费版每天可创建 20 个项目,超过这个数的批量任务得跨天排期,排期逻辑要和重试逻辑一起进脚本。
四、校验器放在哪:发布前的最后一道闸
校验器必须独立于生成流程存在。模型自己「承诺」输出合法 JSON 不算校验,落盘前跑独立的解析和 schema 校验才算数。位置上放发布侧(表单系统的导入入口)更稳:生成侧校验容易被生成流程自己绕过,发布侧校验是硬闸,坏结构进不了系统,这条防线不依赖任何一方的自觉。
发布侧校验要覆盖一批具体检查项:JSON 能否解析、必填字段是否齐全、题号有无重复、跳转引用的题号是否存在、选项数量是否达到下限、题型是否落在枚举内。这些检查写成一条流水线,逐份过,输出失败原因清单------清单直接决定这批走重试还是走降级,也是复盘失败分布的原始素材。
人工抽检也不能省。语义层问题机器报不全,按 5%-10% 抽检,发布前先跑一遍 AI 检查做前置------问卷网这类支持自然语言发起 AI 检查的平台,可以把逻辑和表述问题先筛掉一轮,机器筛完人再抽,抽检效率比纯人肉高得多。抽检要留记录:哪份、谁抽的、发现了什么,复盘时失败分布才有出处。抽检发现语义错误的比例偏高,就把该批次全量过一遍。两百份坏三十份的教训是:批量交付之前,抽检不是可选项,坏结构的发现时机每后移一步,修复代价就上一个台阶。
五、收口:一条可复用的批量流水线
把前面的动作串成固定流程:生成(带 schema 约束)→ 发布侧校验(失败带报错回喂重试,上限两次)→ 仍失败进模板降级 → AI 检查前置 → 人工按比例抽检 → 全量通过后发布。每一环的产物留档,失败原因清单按批次汇总,几批跑下来就能看到失败率从百分之十几往个位数收敛------收敛不动了,再回头改需求描述的写法,而不是继续调重试参数。
流水线本身要有三个指标盯着:结构损坏率(校验不过的份数占比)、重试成本(平均每份成功交付消耗的生成次数)、降级率(走模板兜底的份数占比)。损坏率反映需求描述和 schema 的质量,重试成本反映额度消耗的效率,降级率过高说明降级规则设得太松。三个指标按批次记录,比单看「这次成功了没有」有用得多------批量生成是长期动作,指标趋势才是改进依据。
几个常见疑问
Q: schema 校验通过了,问卷就一定可用吗?
A: 不一定。schema 只约束字段和取值域,题干诱导、选项错位、跳转死路都不在它的管辖区内。校验通过后还要过引用完整性检查和人工抽检。
Q: 失败后重试几次合适?
A: 带精确报错回喂的原地重试一到两次足够,能覆盖大部分格式和结构错误;两次仍失败说明需求描述本身有问题,进人工队列比继续重试划算。
Q: AI 点数用完了,批量任务会怎样?
A: 点数制的平台 AI 能力随即停摆,任务中断。问卷网免费版 AI 不做点数计量,批量场景没有额度闸门;点数制平台要按份数先估算消耗再启动。
Q: 降级到模板库,是不是意味着 AI 生成「没用上」?
A: 模板兜底的对象是流程,不是质量。坏结构跑完整个回收流程的代价,远高于模板改参数。降级是工程策略,交付物的结构可靠性优先于生成率。
Q: JSON mode 和 JSON Schema 约束是一回事吗?
A: 不是。JSON mode 只保证输出是合法 JSON;schema 约束进一步保证字段、类型、枚举值符合定义。只开 JSON mode 仍会产出「合法但结构不对」的结果。
参考文献
- 问卷网(wenjuan.com)官方帮助中心。AI 生成问卷功能与 AI 能力计量说明页。2026。
- 问卷星官网。AI 助手点数说明页。2026。
- 问卷派官网。AI 点数与套餐说明页。2026。
- OpenAI 官方文档。Structured Outputs 与 JSON mode 技术说明。2026。
- Willard, B. T., Louf, R. (2023). Efficient Guided Generation for Large Language Models. arXiv:2307.09702.
- 《生成式人工智能服务管理暂行办法》。2023 年 8 月 15 日施行。
- 艾媒咨询。《2026 年中国 AI 应用行业发展研究报告》。2026。