Как проверить JSON от ИИ встроенным Python
Проверяем синтаксис JSON, повторяющиеся ключи и минимальный контракт встроенными средствами Python — до передачи файла рабочему скрипту.
- Система
- macOS 27.0
- Программы
- Python 3.9.6
Подробности проверки
- macOS 27.0 arm64
- zsh
- Python 3.9.6 (/Applications/Xcode.app/Contents/Developer/usr/bin/python3)
- только стандартная библиотека.
- Windows, Linux, другие версии Python и большие недоверенные файлы не проверены.
ИИ нередко возвращает настройки, список задач или параметры запроса в JSON. Файл может выглядеть аккуратно, но содержать лишнюю запятую, текст вокруг объекта, повторяющиеся ключи или правильный синтаксис с неправильной структурой. Если такой ответ сразу передать скрипту, ошибка обнаружится уже во время работы — иногда после частичной записи данных.
Ниже — проверка без платного API и сторонних пакетов. Нужен только Python 3.9 или новее. Сначала встроенный модуль json.tool проверит синтаксис и создаст удобную для чтения копию. Затем небольшой локальный скрипт отдельно проверит повторяющиеся ключи и минимальный контракт примера: верхний уровень должен быть объектом, title — непустой строкой, items — массивом.
Что именно проверяет эта инструкция
| Уровень | Что обнаруживает | Чего не гарантирует |
|---|---|---|
| Синтаксис | Незакрытые кавычки и скобки, лишние запятые, текст вне одного JSON-значения | Наличие нужных полей и пригодность данных для вашей программы |
| Повторяющиеся ключи | Два одинаковых имени внутри одного объекта | Правильный тип и смысл значения |
| Контракт | Нужные ключи и ожидаемые базовые типы из вашего задания | Полную бизнес-логику, безопасность и достоверность данных |
Перед началом определите контракт: какой тип ожидается на верхнем уровне, какие ключи обязательны и какого типа должны быть значения. В примере контракт намеренно небольшой. Для рабочего проекта замените title и items на реальные поля из документации вашей программы. Не добавляйте в фикстуры токены, персональные данные и производственные конфигурации.
Шаг 1. Сохраните только JSON
- Создайте новую отдельную папку для проверки и перейдите в неё в терминале.
- Скопируйте из ответа ИИ только содержимое JSON: без фразы «вот результат» и без тройных обратных кавычек.
- Сохраните файл под именем response.json в UTF-8. Исходный ответ оставьте отдельно, чтобы можно было сверить потерянные строки.
- Если файл содержит секреты или реальные пользовательские данные, замените их безопасной фикстурой той же структуры до запуска любых команд.
JSON требует двойных кавычек вокруг имён полей и строк. Комментарии, одинарные кавычки и запятая после последнего элемента не входят в обычный JSON. Не исправляйте сразу десятки строк вручную: сначала получите точное место первой синтаксической ошибки.
Шаг 2. Проверьте версию Python и синтаксис
python3 --version
python3 -m json.tool response.json >/dev/null
echo $?Первая команда должна вывести установленную версию Python. При корректном JSON вторая команда ничего не напечатает, а echo $? покажет 0. При ошибке json.tool завершится с ненулевым кодом и назовёт строку, столбец и позицию. Исправьте именно исходный response.json и повторяйте команду, пока она не вернёт 0.
Для выполнения проверки Python 3.9 или новее должен быть уже установлен и доступен по команде python3. Если оболочка сообщает command not found, сначала подготовьте среду с Python 3.9+ и затем вернитесь к этому шагу. Команда python вместо python3 допустима только после явной проверки, что она запускает Python 3.
Шаг 3. Создайте читаемую копию
python3 -m json.tool --no-ensure-ascii --indent 2 response.json response.pretty.jsonОжидаемый результат — новый response.pretty.json с отступом в два пробела и читаемыми кириллическими символами. Исходный response.json команда не меняет. Откройте обе версии и убедитесь, что форматирование не скрывает неожиданную вложенность: поле, которое вы считали списком, может оказаться строкой, а объект — массивом.

Для выполнения этого шага нужен Python 3.9 или новее: в Python 3.9 у json.tool появились параметры --no-ensure-ascii и --indent. Более старые версии Python по шагам этого гайда не проверены; не используйте для них приведённую команду без отдельной проверки.
Шаг 4. Не пропустите повторяющиеся ключи
Обычная загрузка через модуль json допускает повторяющиеся имена внутри объекта и сохраняет последнее значение. Поэтому визуально похожий фрагмент {"role":"user","role":"admin"} может тихо превратиться в role со значением admin. Для конфигурации и входных данных лучше останавливать обработку при первом повторе.
Создайте рядом с response.json файл check_json.py со следующим содержимым. Код использует только стандартную библиотеку. Функция object_pairs_hook получает пары каждого объекта в исходном порядке и позволяет обнаружить повтор до превращения пар в словарь. parse_constant отдельно отклоняет NaN и Infinity, которые принимает декодер Python, хотя они не входят в стандарт JSON.
import json
import sys
from pathlib import Path
REQUIRED_KEYS = {"title", "items"}
def reject_duplicate_keys(pairs):
result = {}
for key, value in pairs:
if key in result:
raise ValueError(f"повторяющийся ключ: {key}")
result[key] = value
return result
def reject_non_finite(value):
raise ValueError(f"недопустимое число: {value}")
path = Path(sys.argv[1])
try:
data = json.loads(
path.read_text(encoding="utf-8"),
object_pairs_hook=reject_duplicate_keys,
parse_constant=reject_non_finite,
)
except (OSError, UnicodeError, json.JSONDecodeError, ValueError) as error:
raise SystemExit(f"ОШИБКА: {error}")
if not isinstance(data, dict):
raise SystemExit("ОШИБКА: верхний уровень должен быть объектом")
missing = sorted(REQUIRED_KEYS - data.keys())
if missing:
raise SystemExit("ОШИБКА: нет обязательных ключей: " + ", ".join(missing))
if not isinstance(data["title"], str) or not data["title"].strip():
raise SystemExit("ОШИБКА: title должен быть непустой строкой")
if not isinstance(data["items"], list):
raise SystemExit("ОШИБКА: items должен быть массивом")
print(f"OK: объект прошёл проверку; элементов: {len(data['items'])}")Шаг 5. Подстройте контракт и запустите проверку
Строка REQUIRED_KEYS задаёт обязательные поля. Удалите демонстрационные имена и впишите реальные ключи вашего формата. Затем измените две проверки типов ниже: str соответствует строке, list — массиву, dict — объекту, bool — true или false. В Python bool считается подклассом int, поэтому число лучше проверять выражением type(value) is int, если логические значения недопустимы.
python3 check_json.py response.json
echo $?Для объекта из примера ожидается строка OK и код 0. Повторяющийся ключ, NaN, неправильный верхний уровень, отсутствие title или items и неверный базовый тип должны дать строку ОШИБКА и ненулевой код. Не удаляйте проверку только ради зелёного результата: сопоставьте ошибку с контрактом программы и исправьте данные либо сам контракт.

Шаг 6. Проверьте не только один удачный файл
- Сделайте минимальный корректный пример и подтвердите, что он возвращает OK.
- Добавьте лишнюю запятую и убедитесь, что json.tool останавливается с ненулевым кодом.
- Повторите один ключ внутри вложенного объекта и убедитесь, что check_json.py его отклоняет.
- Удалите каждый обязательный ключ по одному и проверьте понятное сообщение.
- Замените строку массивом и массив строкой, чтобы убедиться, что проверки типов работают.
- Только после этих отрицательных примеров передавайте копию данных следующему локальному шагу программы.
Сохраняйте команду, версию Python, код завершения и безопасные тестовые входы. Успех на одной фикстуре подтверждает только этот пример и этот контракт. Он не доказывает, что фактические значения правдивы, URL безопасны, пути разрешены или дальнейшая программа не выполняет опасных действий.
Как отменить изменения
Команды выше не меняют response.json. Для отмены удалите только созданные вами response.pretty.json, check_json.py и синтетические фикстуры из отдельной папки проверки. Перед удалением проверьте точный путь и не используйте рекурсивные команды с домашней папкой или переменными. Если вы изменяли исходный response.json при исправлении ошибок, восстановите его из сохранённой копии ответа ИИ или системы контроля версий.
Ограничения метода
- json.tool подтверждает разбор одного JSON-значения, но не знание предметной области и не соответствие внешней API-схеме.
- Демонстрационный check_json.py проверяет только несколько полей. Для сложного вложенного формата контракт нужно расширить по официальной документации потребителя данных.
- Проверка не делает безопасными команды, пути, HTML, SQL, URL или инструкции, которые хранятся внутри строк.
- Большой недоверенный файл может потребовать много памяти и процессорного времени. Не проверяйте таким способом неизвестные многогигабайтные данные.
- Формат JSON Lines состоит из отдельных JSON-значений по строкам и требует отдельного режима --json-lines; обычный единый JSON-файл из этого гайда устроен иначе.
Когда результат можно передавать дальше
Файл готов к следующему локальному шагу, когда json.tool возвращает 0, отформатированная копия прочитана, повторяющиеся ключи и нестандартные числовые значения отклоняются, обязательные поля и типы сверены с реальным контрактом, а отрицательные фикстуры действительно падают. Если контракт неизвестен, результат остаётся лишь синтаксически корректным JSON — это нужно так и записать.