你的 API 调用因 JSONDecodeError: Expecting property name enclosed in double quotes 而失败。时钟在滴答作响。数据来自 LLM,而在那个 2000 token 的响应里,某一个多余的尾随逗号毁掉了你整条流水线。
截至 2026 年 5 月,修复格式错误的 JSON 文件最快的方法是使用自动化库,比如 json_repair(Python)或 jsonrepair(npm)。这些工具专为瞬间修复 LLM 产生的语法错误而生。至于手动修复,常见的“元凶”是尾随逗号、单引号或未加引号的键——这是违反 RFC 8259 标准的三种最常见情形。
最快的修复方式:针对 LLM 输出的 json_repair
像 Python 的 json.loads() 这类标准解析器,在设计上就是严格的。一个错位的字符就会触发 JSONDecodeError,一切都随之停止。这在 2026 年是家常便饭,因为 LLM 经常把 JSON 包裹在对话文本里,把响应截断在句中,或者撒进一些破坏规范的注释。
json_repair 库是首选方案。据 GitHub 显示,截至 2026 年该项目已获得超过 4700 颗星。它的工作原理是“猜测”字符串的意图——补上缺失的括号、加上引号,并剥除 JSON 块周围多余的文字。

Python:改造前后
安装:pip install json-repair
损坏的输入:
import json_repair
bad_json = '{"user": "Alice", "status": tru'
decoded_object = json_repair.loads(bad_json)
幕后发生了什么:json_repair 判断出 tru 很可能是 true,补上了缺失的右大括号,并返回了一个合法的 Python 字典。全程零人工干预。
Salvage 模式:数据实在惨不忍睹时
对于更棘手的情况,json_repair(v0.59.5+)提供了 Salvage 模式。正如项目文档所述,这个模式专为被截断的 AI 响应或损坏的日志而构建。它可以把数组强制转换为对象,或者丢弃那些实在救不回来的条目,从而保证输出符合你的数据结构。
import json_repair
# Salvage mode for severely truncated data
result = json_repair.loads(
'{"items": [{"id": 1, "name": "Widget"}, {"id": 2, "na',
salvage_mode=True
)
# Result: {'items': [{'id': 1, 'name': 'Widget'}, {'id': 2}]}
# Dropped the incomplete 'na' but saved everything else
npm 替代方案
对于 Node.js 项目,jsonrepair CLI 能完成同样的工作:
# Fix a file in place
npx jsonrepair broken.json > fixed.json
# Fix a string in a script
const { jsonrepair } = require('jsonrepair');
const fixed = jsonrepair('{"name": "test",}');
手动调试:找出破坏规范的元凶
当自动化工具也搞不定时,你需要精确定位文件在何处违反了 RFC 8259。JSON 远不如 YAML 或 JavaScript 那样宽容。正如 JSONParser 诊断团队所解释的:“解析器在遇到第一个它无法理解的字符时就会失败,而这往往是几行之前某个问题的下游症状。”
三大 JSON 杀手
杀手 1:尾随逗号
据 DEV Community 的说法,尾随逗号是解析失败的头号原因。在 JavaScript 里它们没问题,但在 JSON 数组或对象的最后一项之后却是非法的。
// BROKEN - trailing comma after "active"
{
"name": "Alice",
"status": "active",
}
// FIXED - no comma before closing brace
{
"name": "Alice",
"status": "active"
}
杀手 2:单引号
JSON 要求键和字符串值都使用双引号(")。很多 Python 和 JavaScript 开发者会不小心用上单引号(')。正如 TidyCode 所指出的,这是必须修正的。
// BROKEN - single quotes
{'name': 'Alice'}
// FIXED - double quotes
{"name": "Alice"}
杀手 3:未加引号的键
在 JavaScript 中你可以写 { name: "Alice" }。但在 JSON 里,每个键都需要双引号。
// BROKEN - unquoted key
{name: "Alice"}
// FIXED - quoted key
{"name": "Alice"}

“Unexpected Token”错误
当验证器报出“Unexpected Token”时,意思是解析器遇到了 NaN、Infinity 或 undefined——这些都是 JSON 不支持的 JavaScript 常量。JSON 只允许 null、true、false 和数字。
// BROKEN - NaN is not valid JSON
{"score": NaN, "result": Infinity}
// FIXED - replace with null or valid values
{"score": null, "result": null}
严格解析 vs. 修复解析:何时用哪个
正确的方法取决于你的数据来自哪里。人工编辑的配置文件应当使用严格解析,以迫使作者修正错误;而来自 LLM 或 API 日志的机器生成数据,则需要基于修复的解析。
| 特性 | 严格(json.loads) |
修复(json_repair) |
|---|---|---|
| 尾随逗号 | 抛出 JSONDecodeError |
自动移除 |
| 单引号 | 失败 | 转换为双引号 |
| 被截断的数据 | 失败 | 补全未闭合的括号/引号 |
| 注释 | 失败 | 自动剥除 |
| 最佳用例 | 人工编辑的配置文件 | LLM 输出、API 日志 |
用 Pydantic 做结构引导的修复
你可以使用 Pydantic v2 或 JSON Schema 来引导修复过程。给 json_repair 提供一个 schema,工具不仅能修复语法——还能纠正类型(把字符串 "1" 转成数字 1)并用默认值填充缺失的必填字段。
from pydantic import BaseModel
import json_repair
class User(BaseModel):
id: int
name: str
active: bool = True
# Broken JSON with wrong types
raw = '{"id": "42", "name": "Alice"}'
repaired = json_repair.loads(raw)
# Validate against schema
user = User(**repaired)
# user.id is now int(42), user.active defaults to True
正如 Stefano Baccianella 在其 2025 年的项目说明中所提到的,这种方式针对的是语言模型常产出的那种“大体正确但技术上非法”的 JSON 而做了优化。
处理多 GB 文件而不崩溃
修复一个 10KB 的片段很容易。修复一个 2GB 的文件则需要一套不会吃光你内存的策略。把整个文件载入内存会导致内存溢出(OOM)错误。
策略 1:用 ijson 流式处理
对于海量数据集,使用 ijson 逐块处理数据。正如 Scrapfly 所述,ijson 会增量地处理数据。把它与一个在解析前逐行修复问题的清理脚本搭配使用。
import ijson
# Stream through a large JSON file
with open('huge_broken.json', 'r') as f:
for item in ijson.items(f, 'records.item'):
# Process each item individually
process(item)
策略 2:用 CLI 管道实现最高效率
处理大文件时最省内存的方法是使用 jsonrepair CLI,并把输出直接管道到一个新文件:
# Streams repair, never loads full file into memory
jsonrepair large_broken.json > fixed.json
这比把文件载入 Python 或浏览器要省内存得多。
结语
得益于 json_repair 这类对 AI 友好的库,修复格式错误的 JSON 已不再是体力活。你仍然需要了解 RFC 8259 的基本规则——不能有尾随逗号、不能有单引号、键必须加引号——但在 2026 年面对大规模数据时,自动化才是唯一现实的做法。
工作流程很简单:先尝试修复库。如果失败,再用验证器精确定位语法错误。这样即使输入的数据不那么完美,你的应用也能持续运行。
常见问题
JSON 官方是否支持注释或单引号?
不支持。RFC 8259 标准严格禁止注释。单引号同样非法——键和字符串只允许使用双引号。不过,json_repair 这类工具可以自动剥除注释并转换引号,使文件能被标准库解析。
如何处理超大且格式错误的 JSON 文件而不崩溃?
使用 ijson 这类流式解析器分块处理数据。避免把整个格式错误的字符串载入单个变量。为了最快速度,可使用 CLI 修复工具,把输出直接管道到磁盘上的新文件,无需把所有内容都留在内存中。
格式错误的 JSON 和无效的 JSON 有什么区别?
格式错误(malformed)的 JSON 违反语法规则——缺失括号、键未加引号、尾随逗号——使其无法解析。无效(invalid)的 JSON 遵守所有语法规则,但不符合某个具体的 JSON Schema(例如某个字段在 schema 里应为整数,实际却是字符串)。修复格式错误的 JSON 属于结构性修复;修复无效的 JSON 则关乎数据完整性。
我能把 json_repair 和 Pydantic 验证一起用吗?
可以。先用 json_repair.loads() 修复语法错误,再把修复后的字典传给你的 Pydantic 模型进行类型验证和 schema 校验。这种两步走的方法同时解决了结构性和语义性问题。
带有 JavaScript 风格注释的 JSON 怎么办?
标准 JSON 不支持注释,但 json_repair 可以自动剥除 // 和 /* */ 注释。如果你需要在配置文件里保留注释,可以考虑使用 JSONC(带注释的 JSON)格式,并搭配 json5(Python)这类兼容的解析器。




