Discourse AI: la risposta in output strutturato non era JSON valido

Ho eseguito l’aggiornamento ieri[1] e ora ci sono molti errori nei log:

Discourse AI: structured output response was not valid JSON, falling back to best-effort parsing (311 bytes) 

Ho ispezionato la risposta HTTP e non presentava problemi. Poi ho provato il testo con rails console:

...
discourse(prod)> p = JsonCompleter.new
=>
#<JsonCompleter:0x00007f48763b0270
...
discourse(prod)> p.parse text
=>
{"spam" => false,
 "reason" =>
  "..."}
discourse(prod)> p.parse DiscourseAi::Utils::BestEffortJsonParser.escape_control_characters(text)
(discourse):14:in '<main>': unexpected token "\\" (JsonCompleter::ParseError)

si è scoperto che Discourse ha effettuato l’escaping dei caratteri di newline prima dell’analisi[2], causando l’errore.


  1. ↩︎

  2. code, introdotto da pr#41716 ↩︎

Quello è un avviso, non un errore.

Detto questo, sto abbassando il livello a INFO, perché la gente continua a preoccuparsi per queste cose :face_exhaling:

Beh, tecnicamente vero, ma indica un bug nel codice. Il fallback funziona, quindi non viene generato alcun errore, ma è meglio correggere la fonte invece di spostarlo al livello INFO per nascondere il problema, non è così?

JSON consente caratteri di avanzamento riga come spaziatura, ma non consente sequenze di escape al di fuori delle stringhe; la funzione di escape, tuttavia, le escape. Per correggerlo, puoi modificare l’escape solo dei caratteri ASCII da 0x0 a 0x1f inclusi, secondo la specifica JSON. (Non so come scriverlo in Ruby, quindi nessuna PR.)

Per illustrare, il seguente è un JSON valido:

{
  "key": "value"
}

Il seguente è una versione con caratteri di escape, che è non valida e causa il problema:

{\u000a  "key": "value"\u000a}

Quale LLM stai utilizzando?

llama-server -hf mradermacher/Qwen3-4B-Instruct-2507-GGUF:Q4_K_M

Un modello da 4B farà fatica a rispettare i requisiti; stanno migliorando, ma questo è sicuramente un po’ datato.

Se stai optando per un modello da 4B, ti consiglierei qualcosa di più recente… prova Qwen 3.5-4B o Gemma 4 E4B.

Credo che llama.cpp imponga lo schema selezionando solo token che vi conformano. Ho anche catturato una risposta con tcpdump e verificato che la risposta restituita sia JSON valido.

Conteniva spazi e interruzioni di riga all’esterno delle stringhe (ovvero era un JSON formattato), e queste interruzioni di riga sono state escape da Discourse, rendendolo non valido (l’ho verificato nella console Rails).

Sto usando la funzione di rilevamento dello spam, tra l’altro.

Giusto, sto lavorando a una soluzione.

La correzione è disponibile qui: