AI创新网络AI INNOVATION NETWORK
LEARN / PRACTICE

AI 输出 JSON 后怎样进入工作流:本地校验器的 16 个样例实测

本站已实测 · 核验日期 2026-10-21

Node.js v24.19.0;16 个人工构造样例;仅实测本地接收端,未调用模型或自动发布

把 AI 输出交给后续流程之前,先明确接收端允许什么格式、什么字段和什么来源。本文用一个内容卡示例,搭建只读文件、检查结构、输出规范 JSON 的本地校验环节。

实测范围先说明

本次实测对象是本地 JSON 接收端脚本:v24.19.0、16 个人工构造样例。没有调用 AI 模型,没有测模型成功率,也没有把内容自动发布到网站。读者可使用自己的公开资料和模型输出复现接收端检查。

第一步:写出输出契约

本例只接收 title、summary、source_urls 三个字段。标题最多 80 个 Unicode 码点,摘要最多 240 个;来源为 1 至 5 个不重复的 HTTPS URL,域名限定为示例里使用的三个文档站。URL 无账号密码或自定义端口。

{
  "title": "JSON 解析与接收端检查",
  "summary": "先确认 JSON 语法,再检查字段和来源,最后由人核对结论。",
  "source_urls": [
    "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse"
  ]
}

第二步:让模型依据给定资料输出

下面是可调整的任务说明。只填入可公开的资料,来源链接由你预先选定;资料不足时应保留缺口。

请仅依据我提供的资料整理一张内容卡。
只输出一个 JSON 对象,不加 Markdown 代码围栏。
字段只能是 title、summary、source_urls。
title 和 summary 使用单行文字,分别不超过 80、240 个字符。
source_urls 只允许引用我给出的链接,不要补造链接。
如果资料不足,请在 summary 中明确说明资料不足。
资料与允许引用的链接:
[在这里粘贴公开资料和已核对的链接]

第三步:先用本站工具箱检查语法

将输出作为纯文本保存为 result.json。也可以先打开本站 JSON 工具检查和格式化。JSON 能成功解析,只说明语法层面可处理;缺字段、错误类型或不合适的来源仍需要独立检查。

第四步:运行本地字段与来源检查

保存下面的代码为 validate-ai-json.cjs,使用 Node.js 运行。脚本不联网、不执行文本中的指令,只读取指定文件并校验;允许域名是本示例的编辑策略,应按实际资料来源调整。

'use strict';
const fs = require('node:fs');
const allowedHosts = new Set(['developer.mozilla.org', 'docs.docker.com', 'json-schema.org']);
function checkCard(value) {
  if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('顶层必须是对象');
  const expected = ['source_urls', 'summary', 'title'];
  const keys = Object.keys(value).sort();
  if (JSON.stringify(keys) !== JSON.stringify(expected)) throw new Error('字段必须恰好是 title、summary、source_urls');
  for (const [key, max] of [['title', 80], ['summary', 240]]) {
    const text = value[key];
    if (typeof text !== 'string' || !text.trim() || [...text].length > max || /[\u0000-\u001f]/u.test(text)) {
      throw new Error(key + ' 必须是非空单行文字,长度上限为 ' + max);
    }
  }
  if (!Array.isArray(value.source_urls) || value.source_urls.length < 1 || value.source_urls.length > 5) {
    throw new Error('source_urls 必须包含 1 到 5 个来源');
  }
  const urls = value.source_urls.map(text => {
    if (typeof text !== 'string' || text !== text.trim()) throw new Error('来源必须是 URL 字符串');
    const url = new URL(text);
    if (url.protocol !== 'https:' || url.username || url.password || url.port || !allowedHosts.has(url.hostname)) {
      throw new Error('来源必须使用允许域名的 HTTPS URL,且无账号、密码或自定义端口');
    }
    return url.href;
  });
  if (new Set(urls).size !== urls.length) throw new Error('来源不能重复');
  return {title: value.title.trim(), summary: value.summary.trim(), source_urls: urls};
}
if (require.main === module) {
  try {
    const file = process.argv[2];
    if (!file) throw new Error('用法:node validate-ai-json.cjs result.json');
    if (fs.statSync(file).size > 65536) throw new Error('文件超过 64 KiB');
    const text = fs.readFileSync(file, 'utf8');
    if (Buffer.byteLength(text, 'utf8') > 65536) throw new Error('文件超过 64 KiB');
    process.stdout.write(JSON.stringify(checkCard(JSON.parse(text)), null, 2) + '\n');
  } catch (error) {
    process.stderr.write('校验失败:' + error.message + '\n');
    process.exitCode = 1;
  }
}
module.exports = {checkCard};
node validate-ai-json.cjs result.json

通过时,标准输出是整理后的 JSON,退出码为 0;不通过时,错误写到标准错误,退出码为 1。接入流程时只有退出码为 0 的结果进入下一步;失败项保留原输入和错误记录,修正后重新检查。不要用执行脚本的方式解释模型输出。

16 个样例的预期与实测结果

项目 应确认的内容
valid 接受;实测与预期一致
malformed 拒绝;实测与预期一致
markdown 拒绝;实测与预期一致
top_array 拒绝;实测与预期一致
missing 拒绝;实测与预期一致
extra 拒绝;实测与预期一致
wrong_type 拒绝;实测与预期一致
blank 拒绝;实测与预期一致
too_long 拒绝;实测与预期一致
empty_sources 拒绝;实测与预期一致
http 拒绝;实测与预期一致
unknown_host 拒绝;实测与预期一致
credentials 拒绝;实测与预期一致
duplicate 拒绝;实测与预期一致
control_char 拒绝;实测与预期一致
oversize 拒绝;实测与预期一致

通过校验后还需要人工检查什么

  • 逐个打开来源,确认页面存在且内容支持摘要;域名白名单不能证明具体页面和结论正确。
  • 核对引用的版本、时间、使用前提,以及是否遗漏限制。
  • 把文本作为数据处理;进入网页时按输出位置做转义,不能直接拼成 HTML 或可执行脚本。
  • 这个示例没有检测 JSON 重复键,也没有评估事实准确率;复杂契约可以在此基础上使用 JSON Schema 等工具进一步约束。

接收端检查通过后,先生成待人工审核的草稿。把“输入契约 → 语法检查 → 字段检查 → 来源核对 → 人工确认”保存成自己的验收记录,再逐步连接更大的工作流。

来源与延伸阅读

更新记录

2026-10-21:新增输出契约、纯本地校验代码、16 个样例结果与人工复核边界。

继续探索

同一方向的资料与实践。

查看全部 →