Ну, технически верно, но это указывает на ошибку в коде. Фоллбэк работает, поэтому ошибка не возникает, но лучше исправить источник, а не переносить сообщение на уровень INFO, чтобы скрыть проблему, верно?
JSON позволяет использовать символы перевода строки как пробельные символы, но не допускает escape-последовательности вне строк; однако функция экранирования экранирует их. Чтобы исправить это, вы можете изменить код так, чтобы экранировались только ASCII-символы от 0x0 до 0x1f включительно, согласно спецификации JSON. (Я не знаю, как это написать на Ruby, поэтому PR не предоставляю.)
Модели с 4 миллиардами параметров будут испытывать трудности с соблюдением требований. Хотя они становятся лучше, это определённо более старые решения.
Если вы всё же выбираете модель на 4 миллиарда параметров, я бы порекомендовал что-то более свежее… попробуйте Qwen 3.5-4B или Gemma 4 E4B.
Я полагаю, что llama.cpp принудительно применяет схему, выбирая только токены, соответствующие ей. Я также перехватил ответ с помощью tcpdump и проверил, что возвращаемый ответ является валидным JSON.
Однако он содержал пробелы и переносы строк вне строк (т.е. это был JSON с форматированием), и эти переносы строк были экранированы Discourse, что сделало его невалидным (я проверил это в консоли Rails).