Türelmes JSONTolerant JSON
A munkások jó kódot írtak, csak rossz csomagolásban adták vissza – és a futás emiatt hibával állt le. Megtanítottuk az FRST-t kijavítani azt, amit biztosan ki lehet.
The workers wrote good code but wrapped it badly – and the run crashed because of it. We taught FRST to repair what can safely be repaired, and nothing more.
A probléma: jó kód, érvénytelen JSONThe problem: good code, invalid JSON
A munkások JSON-ban adják vissza a fájlokat, nagyjából így:
Workers return their files as JSON, roughly like this:
{"files": [{"path": "app.py", "content": "..."}]}
{"files": [{"path": "app.py", "content": "..."}]}
A content mezőben egy teljes forrásfájl utazik, és a modell időnként elfelejti rendesen escape-elni. Két hibát láttunk: nyers sortörést a sztringben, és escape nélküli idézőjelet a kódban. Szemléltetésként:
The content field carries a whole source file, and the model sometimes forgets to escape it properly. We saw two kinds of error: raw newlines inside the string, and unescaped quotes in the code. As an illustration:
{"files": [{"path": "db.py", "content": "DB = "notes.db"
conn = connect(DB)"}]}
{"files": [{"path": "db.py", "content": "DB = "notes.db"
conn = connect(DB)"}]}
Egy szigorú JSON-értelmező ezt elutasítja. Egy mérés egyik futása emiatt már az első kör után hibával leállt: mindkét munkás „értelmezhetetlen” választ adott – pedig a javításuk jó volt.
A strict JSON parser rejects this. In one measurement, a run stopped with an error after just one round for exactly this reason: both workers’ replies were “unparseable” – even though their fixes were correct.
Nem a munka volt rossz, hanem a csomagolás.
The work wasn’t wrong. The packaging was.
A megoldás, két lépésbenThe fix, in two steps
1. Nyers vezérlőkarakterek. A sztringeken belüli nyers sortörést, kocsivisszát és tabulátort escape-eljük. Ez egyértelmű: érvényes JSON-sztringben ezek nyersen nem fordulhatnak elő, tehát nincs mit mérlegelni.
1. Raw control characters. Raw newlines, carriage returns and tabs inside strings are escaped. This one is unambiguous: they can never appear raw in a valid JSON string, so there’s nothing to weigh up.
2. Escape nélküli idézőjel. Ez a nehezebb rész: egy " karakterről el kell dönteni, hogy lezárja-e a sztringet, vagy a kód része. A döntés a környezeten múlik:
2. Unescaped quotes. This is the harder part: for each " we have to decide whether it closes the string or belongs to the code. The decision depends on what surrounds it:
- kulcs után csak az az idézőjel zár, amelyet kettőspont követ;
- érték után a
}csak akkor számít lezárásnak, ha utána],,,}, kódblokk-jel vagy a szöveg vége jön; - a
,csak akkor, ha utána{vagy egy ismert kulcs következik: „file”, „find”, „replace”, „path”, „content”, „patches”, „files”.
- after a key, only a quote followed by a colon closes it;
- after a value, a
}counts as closing only if it is followed by],,,}, a code-fence marker or the end of the text; - a
,counts only if it is followed by{or a known key: “file”, “find”, “replace”, “path”, “content”, “patches”, “files”.
Kézenfekvő lenne egyszerűen újra megkérdezni a modellt. Csakhogy minden újrakérés egy újabb fizetős hívás, és semmi sem garantálja, hogy a második válasz ugyanolyan jó kódot tartalmaz, mint az első. Ha a tartalom rendben van, és csak az escape-elés hibás, olcsóbb és megbízhatóbb a csomagolást megjavítani, mint a munkát újra elvégeztetni.
The obvious alternative would be to simply ask the model again. But every re-request is another paid call, and nothing guarantees the second reply contains code as good as the first. When the content is fine and only the escaping is broken, fixing the packaging is cheaper and more reliable than having the work done over.
Miért ilyen szőrszálhasogató?Why so pedantic?
Mert az első, naiv javításunk nem volt az. Az egyszerűen azt nézte, jön-e az idézőjel után ,, : vagy ] – csakhogy ezek a karakterek a kódban is bőven előfordulnak. A naiv javítás így a kód közepén zárta le a sztringet. Ezért lett a mostani változat kulcs- és érték-érzékeny: más szabály érvényes egy kulcs és más egy érték végén.
Because our first, naive repair wasn’t. It simply checked whether a quote was followed by ,, : or ] – but those characters appear all over code. So the naive repair closed strings in the middle of the code. That’s why the current version is key- and value-aware: different rules apply at the end of a key and at the end of a value.
TesztelésTesting
A két valódi, korábban elbukott nyers választ tettük próbára. Mindkettő most hibátlanul feldolgozható, a javítás ugyanis csak a csomagoláshoz nyúl: a cél, hogy a munkás által írt kód változatlanul érkezzen meg.
We tested against the two real raw replies that had failed before. Both now parse cleanly, because the repair only touches the packaging: the point is that the code the worker wrote arrives unchanged.
| Változat | Kódban lévő , : ] | A 2 valódi elbukott válasz |
|---|---|---|
| Naiv javítás | rosszul zárt | – |
| Kulcs- és érték-érzékeny javítás | helyes | 2/2 feldolgozva |
| Version | , : ] inside code | The 2 real failed replies |
|---|---|---|
| Naive repair | closed wrongly | – |
| Key- and value-aware repair | correct | 2/2 parsed |
Ami még hátravanWhat’s still missing
Őszintén: nem minden menthető. Ha a modell „hangosan gondolkodik”, és a válasz végén egyáltalán nincs JSON, azt nincs mit megjavítani. Erre egy formátum-újrakérés az ötletünk – ez még nincs kész.
To be honest: not everything can be saved. If the model “thinks out loud” and there is no JSON at the end of the reply at all, there is nothing to repair. Our idea for that case is a format re-request – it isn’t built yet.
Tanulság. Ne büntesd a jó munkát a rossz csomagolásért – de csak annyit javíts, amennyit biztosan lehet.
Takeaway. Don’t punish good work for bad packaging – but only repair what you can repair with certainty.