<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 4sapi</title>
    <description>The latest articles on DEV Community by 4sapi (@4sapi).</description>
    <link>https://dev.to/4sapi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4208416%2F9939a1de-e380-41fc-8162-01ed67aacc88.png</url>
      <title>DEV Community: 4sapi</title>
      <link>https://dev.to/4sapi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/4sapi"/>
    <language>en</language>
    <item>
      <title>Your LLM Returned Valid JSON. Can Your App Trust It?</title>
      <dc:creator>4sapi</dc:creator>
      <pubDate>Tue, 27 Oct 2026 02:28:44 +0000</pubDate>
      <link>https://dev.to/4sapi/your-llm-returned-valid-json-can-your-app-trust-it-5h6i</link>
      <guid>https://dev.to/4sapi/your-llm-returned-valid-json-can-your-app-trust-it-5h6i</guid>
      <description>&lt;p&gt;Getting an LLM to return valid JSON feels like a milestone. The response parses, the fields exist, and the application can finally do something with the output.&lt;/p&gt;

&lt;p&gt;But there’s another question: are those fields actually correct?&lt;/p&gt;

&lt;p&gt;Consider a support assistant that turns a customer’s message into a structured request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"order_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ORD-1042"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"refund"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"damaged_item"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything looks reasonable. Yet the customer might have written: “My item arrived damaged. Can I get a replacement? I don’t want a refund.”&lt;/p&gt;

&lt;p&gt;The JSON is valid. The action is wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three checks worth separating
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Can the application parse it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the syntax check. Is the response valid JSON, or did it include extra text, broken quotes, or an incomplete object?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Does it match the expected structure?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the schema check. Are the required fields present? Are values the right types? Is &lt;code&gt;action&lt;/code&gt; one of the allowed options?&lt;/p&gt;

&lt;p&gt;A schema can reject an unknown action. It cannot, by itself, determine whether an allowed action matches the customer’s intent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Is the result supported and permitted?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is where application logic matters. Does the order belong to the authenticated customer? Did the customer request this action? Is the order eligible? Does the operation require confirmation?&lt;/p&gt;

&lt;p&gt;These checks need information beyond the shape of the model’s response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Separate interpretation from execution
&lt;/h3&gt;

&lt;p&gt;For a workflow like this, I’d treat the model’s output as a proposed interpretation. The backend would check the order, apply the relevant rules, and ask for clarification when the request is ambiguous.&lt;/p&gt;

&lt;p&gt;It also helps to give the model a way to express missing information. A required field with no “unknown” option creates pressure to fill in something, even when the source doesn’t support a confident answer.&lt;/p&gt;

&lt;p&gt;For example, an incomplete request could go into a &lt;code&gt;needs_clarification&lt;/code&gt; state instead of being forced into &lt;code&gt;refund&lt;/code&gt; or &lt;code&gt;replacement&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That state should have a real application path: ask a follow-up question, preserve the existing information, and wait before taking action.&lt;/p&gt;

&lt;h3&gt;
  
  
  A small test that reveals a lot
&lt;/h3&gt;

&lt;p&gt;Try evaluating the same workflow with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A clear request.&lt;/li&gt;
&lt;li&gt;A request that explicitly rejects an action.&lt;/li&gt;
&lt;li&gt;A message containing two different order numbers.&lt;/li&gt;
&lt;li&gt;A request with a missing identifier.&lt;/li&gt;
&lt;li&gt;A customer changing their mind halfway through the conversation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check both the extracted fields and what the application does next. A response can pass every formatting check and still lead to the wrong operation.&lt;/p&gt;

&lt;p&gt;Structured output makes model responses easier to process. Deciding when to trust those responses remains part of the application’s design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have you encountered an LLM response that passed validation but was still wrong in a way that mattered? How did you catch it?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
    </item>
  </channel>
</rss>
