<?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>GitHub Weekly: Agent Skills Sweep Top 3, “De-AI” Design Leads</title>
      <dc:creator>4sapi</dc:creator>
      <pubDate>Mon, 02 Nov 2026 07:17:23 +0000</pubDate>
      <link>https://dev.to/4sapi/github-weekly-agent-skills-sweep-top-3-de-ai-design-leads-4n91</link>
      <guid>https://dev.to/4sapi/github-weekly-agent-skills-sweep-top-3-de-ai-design-leads-4n91</guid>
      <description>&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;GitHub Trending's weekly ranking, read on November 2, 2026, lists 16 projects. Thirteen of them are Skills, plugins or companion tools built for coding agents such as Claude Code, Codex and Cursor. All three top entries are Skills. Impeccable gained about 12,000 stars this week as a design-vocabulary and "AI-flavor" detection rule set. Hallmark from Together AI added about 11,600 stars with a "pages should not look AI-generated" stance. Cloudflare's open-source security-audit-skill added about 10,000 stars, turning the seed of its internal vulnerability-hunting system into a six-stage security-audit Skill. The week's main line is clear: the community is no longer comparing only which model is stronger. It is comparing who can give agents better craftsmanship: aesthetics, security auditing, SEO, and cross-session memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Weekly Signal: Skills over Raw Model Power
&lt;/h2&gt;

&lt;p&gt;The GitHub weekly hotlist is the GitHub Trending ranking sorted by stars added in the current week. The edition read on November 2, 2026 contains 16 projects. Of those, 13 serve the coding-agent ecosystem.&lt;/p&gt;

&lt;p&gt;The distribution itself is the story. Skill-based extensions now outnumber raw model releases in community attention. Most of these Skills install with a single npx skills add command, but at runtime they consume the model quota of the agent's own configuration. Some single runs can burn hundreds of thousands of tokens. The popularity of Skills is therefore also a statement about where the ecosystem believes the leverage sits: not in the model alone, but in the working method loaded on top of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The Top Twelve by Weekly Stars
&lt;/h2&gt;

&lt;p&gt;Sorted by stars added this week, the top twelve are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pbakaus/impeccable: +12,017&lt;/li&gt;
&lt;li&gt;nutlope/hallmark: +11,566&lt;/li&gt;
&lt;li&gt;cloudflare/security-audit-skill: +10,069&lt;/li&gt;
&lt;li&gt;pingdotgg/3code: +6,926&lt;/li&gt;
&lt;li&gt;aftan-m/ECC: +6,299&lt;/li&gt;
&lt;li&gt;obra/superpowers: +5,896&lt;/li&gt;
&lt;li&gt;thedotstack/claude-mem: +5,852&lt;/li&gt;
&lt;li&gt;JetBrains/thinkrail: +5,760&lt;/li&gt;
&lt;li&gt;TauricResearch/TradingAgents: +5,432&lt;/li&gt;
&lt;li&gt;Leonxlnx/taste-skill: +5,336&lt;/li&gt;
&lt;li&gt;AndrejDaniel/claude-seo: +5,034&lt;/li&gt;
&lt;li&gt;multica-ai/andre-karpathy-skills: +4,459&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The set spans five categories: design de-AI, security auditing, agent working methods, memory and IDE, and vertical domains. The design category dominates the top. Impeccable and Hallmark together account for the two largest weekly gains, and taste-skill adds a third design entry further down the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The Weekly List at a Glance
&lt;/h2&gt;

&lt;p&gt;By weekly stars, the 16 projects fall into five categories. The leading entries show both weekly gains and total star counts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Design "de-AI": pbakaus/impeccable +12,017 (total 99,417); Nutlope/hallmark +11,566 (44,950); Leonxlnx/taste-skill +5,336 (107,848); jakubkrehel/skills +1,607 (10,106)&lt;/li&gt;
&lt;li&gt;Security auditing: cloudflare/security-audit-skill +10,069 (56,442)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. The Three Head Projects Take Different Approaches
&lt;/h2&gt;

&lt;p&gt;The top three design Skills each solve the same problem differently.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1 Impeccable: A Design Vocabulary
&lt;/h3&gt;

&lt;p&gt;Impeccable (Apache-2.0) is a set of "design words". It provides 24 commands such as bolder, quieter, polish, critique and audit, letting the user direct one kind of change with a single word. It also ships 62 deterministic rules for detecting AI flavor. Those rules do not call a model and do not require an API key. Impeccable is better at modifying existing pages. The latest version, cli-v4.8.0, was released on October 26.&lt;/p&gt;

&lt;p&gt;The model-free rules are the notable part. A design tool that detects "AI-ness" without invoking a model means the detection is reproducible and cheap to run at scale. There is no hidden prompt, no vendor dependency, and no per-check token cost. That design choice is what makes the 62 rules a reusable asset rather than a wrapper around another model.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2 Hallmark: A Generator with Hard Bottom Lines
&lt;/h3&gt;

&lt;p&gt;Hallmark (MIT, from Together AI) is a generator with hard constraints. It bundles 50 theme material sets plus 755 openly licensed photos. After building, it runs a soplint check across 8 widths. Contrast, focus states, mobile layout and fabricated facts are treated as bottom lines. If a page does not meet them, it is not delivered.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.3 taste-skill: Direction First, Then Build
&lt;/h3&gt;

&lt;p&gt;taste-skill (MIT) is based on a study of 247 hand-picked websites. It establishes a direction first, then looks for "an idea that belongs only to this client", and finally screenshots itself and fixes the first three problems, with at most three iterations. The README is explicit that one build takes roughly 30 to 45 minutes and consumes hundreds of thousands of tokens.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.4 The Shared Discipline
&lt;/h3&gt;

&lt;p&gt;The common thread across all three is discipline rather than model capability. They all require real material and refuse to fabricate numbers. They all check the finished product in a real browser, rather than letting the model claim it "looks good".&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Cloudflare's Security-Audit Skill: Six Stages of Vulnerability Hunting
&lt;/h2&gt;

&lt;p&gt;cloudflare/security-audit-skill is the original seed of Cloudflare's vulnerability-hunting system. The README states that the system later expanded into a multi-stage system covering the whole company, described in the Cloudflare blog post "Build your own vulnerability harness". This Skill is the single-repository starting point of that system.&lt;/p&gt;

&lt;p&gt;Its core design is that every stage is re-checked by a fresh, independent agent:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reconnaissance: map the architecture, trust boundaries and input surface, and write architecture.md and a coverage ledger.&lt;/li&gt;
&lt;li&gt;Coverage-guided hunting: dispatch mutually isolated hunter agents according to the ledger, and let a "coverage review" find places that were missed.&lt;/li&gt;
&lt;li&gt;Candidate validation: hand each suspected vulnerability to a new agent whose task is to disprove it.&lt;/li&gt;
&lt;li&gt;Structured output: split results into confirmed, pending and rejected, and validate against a JSON Schema.&lt;/li&gt;
&lt;li&gt;Record review: dispatch another new agent to verify the source code referenced by the final conclusion.&lt;/li&gt;
&lt;li&gt;Report: generate the report from the reviewed records.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Runs are cumulative. A second run works against the previous ledger to fill gaps. The Skill ships 11 hunting prompts classified by attack surface, covering web protocols, supply chains, cloud deployment and LLM prompt injection. It can be installed with one line: npx skills add ... --skill security-audit.&lt;/p&gt;

&lt;p&gt;The "every stage gets a fresh agent" rule is the architectural point. The finder and the verifier are deliberately separated. A new agent that inherits none of the finder's context is less likely to confirm a plausible-looking hypothesis just because it was framed convincingly. Falsification is an explicit assignment, not an afterthought. This mirrors the separation of duties that security teams impose on human reviewers, and it is enforced by process rather than by trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Other Projects Worth Watching
&lt;/h2&gt;

&lt;p&gt;Beyond the top three, several projects carry strong signals.&lt;/p&gt;

&lt;p&gt;JetBrains ThinkRail is an incubation project, created only in July, that gained 5,760 stars this week. It wraps the open-source coding agent pi into a lightweight IDE. Each task gets a git worktree workspace, so multiple agents run in parallel without interfering. Project intent is written into a set of SPEC.md files and preserved across sessions.&lt;/p&gt;

&lt;p&gt;claude-mem has crossed 109,000 total stars and stays on the list. It compresses each agent tool call into an observation record and injects those records by index into the next session.&lt;/p&gt;

&lt;p&gt;claude-seo contains 26 sub-Skills and 19 dedicated agents. A full SEO audit takes about 10 to 15 minutes. One dedicated check evaluates how likely a page is to be cited by AI search products such as Google AI Overviews, ChatGPT and Perplexity.&lt;/p&gt;

&lt;p&gt;andrej-karpathy-skills contains only a single CLAUDE.md file, yet holds 228,000 total stars. A well-written behavior specification is itself in high demand.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Hands-On: Install This Week's Skills with One Command
&lt;/h2&gt;

&lt;p&gt;Most Skills on this week's list support Vercel's npx skills command-line tool, which works across Claude Code, Codex, Cursor and OpenCode. Node 18 or higher is required.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Design Impeccable (run in the project root; after install, reload tools and run /impeccable init):
npx impeccable install&lt;/li&gt;
&lt;li&gt;Design Hallmark (-g means global install):
npx skills add npm:@hallmark -g&lt;/li&gt;
&lt;li&gt;Design taste-skill (requires Node 22+ and a local Chrome):
npx skills add &lt;a href="https://github.com/Leonxlnx/taste-skill" rel="noopener noreferrer"&gt;https://github.com/Leonxlnx/taste-skill&lt;/a&gt; --skill "design-taste-frontend"&lt;/li&gt;
&lt;li&gt;Security audit Cloudflare security-audit-skill:
npx skills add &lt;a href="https://github.com/cloudflare/security-audit-skill" rel="noopener noreferrer"&gt;https://github.com/cloudflare/security-audit-skill&lt;/a&gt; --skill security-audit --global&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Interactive commands after install:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/impeccable critique the pricing cards&lt;/li&gt;
&lt;li&gt;/hallmark audit ./index.html&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The security-audit Skill does not need a special command. In the repository to be audited, start the agent and say "run a security audit on this repository".&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Where the Tokens Go: Runtime Cost Is Real
&lt;/h2&gt;

&lt;p&gt;These Skills run on the model already configured for the agent. Security audits and multi-round design iterations spawn multiple sub-agents, so token consumption jumps sharply. A heavy run can reach tens of thousands of tokens.&lt;/p&gt;

&lt;p&gt;The billing model matters here. Skills are not free computation; they are instruction sets that multiply the agent's model usage. A single design iteration reported at hundreds of thousands of tokens means the cost of "de-AI design" is dominated by model spend, not by the Skill file itself.&lt;/p&gt;

&lt;p&gt;When such workloads need to point at different model backends, or when several Skills and agents share one budget, a consistent routing and metering layer becomes necessary. An API gateway such as 4sapi lets a team set a custom base URL with an OpenAI-compatible endpoint, so agents and Skills call the same interface regardless of which provider sits behind it, while usage and spend are tracked in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Two Things to Check Before Installing
&lt;/h2&gt;

&lt;p&gt;Skills execute scripts with your permissions. Impeccable's live mode runs the validation script specified in package.json; the README warns to inspect it before use in an unfamiliar repository. Hallmark's browser check needs puppeteer-core and Chrome. For a Skill of unknown origin, read SKILL.md and the scripts directory first.&lt;/p&gt;

&lt;p&gt;Do not stack same-kind Skills. The three design Skills have conflicting rules, and enabling them together can leave the agent torn between contradictory guidance. Pick one, run it on a few pages, compare the effect, and then decide.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Frequently Asked Questions
&lt;/h2&gt;

&lt;p&gt;Q: Where is the GitHub hotlist, and what is the difference between weekly and monthly rankings?&lt;br&gt;
A: The weekly ranking sorts by stars added this week and better reflects sustained attention. This article uses the weekly ranking.&lt;/p&gt;

&lt;p&gt;Q: What is the difference between a Skill and an Agent service?&lt;br&gt;
A: A Skill is a small functional module that does not need its own process. Its core is a single SKILL.md, which provides tools to the agent through a protocol. For work like design and auditing that does not need extra capability, a Skill is lighter. An Agent service is used when the task must connect to an external system independently.&lt;/p&gt;

&lt;p&gt;Q: Why do these Skills cost so many tokens?&lt;br&gt;
A: The Skill itself is text. The cost comes from the model runs it triggers. Design iteration that screenshots and fixes three problems, or a security audit that dispatches fresh agents per stage, multiplies inference calls. A heavy workflow can reach hundreds of thousands of tokens in one build, so the practical budget is set by the model pricing, not by the Skill install.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Summary
&lt;/h2&gt;

&lt;p&gt;In the first week of November 2026, the GitHub weekly ranking put coding-agent Skills in the top three spots, and 13 of the 16 listed projects serve the agent ecosystem. "De-AI" design is the hottest direction. Impeccable, Hallmark and taste-skill represent three different ideas: a design vocabulary, a hard-bottom-line generator, and a "decide direction before building" flow. Cloudflare turned the seed of its internal vulnerability-hunting system into a six-stage audit Skill, which is the project most worth attention from engineering teams this week.&lt;/p&gt;

&lt;p&gt;The ranking has a deeper implication. The spread of Skills is a shift in where value is created in the agent stack. Model quality still matters, but the marginal leverage is moving to the working methods, checklists and safety flows that surround the model. A design Skill that refuses to fabricate numbers, an audit Skill that re-checks every claim with a fresh agent, and a memory Skill that compresses tool calls into indexed observations are all examples of the same idea: the product is not the model, it is the disciplined process around the model.&lt;/p&gt;

&lt;p&gt;Star counts were read on November 2, 2026. The hotlist changes daily, and install commands should follow the latest instructions in each repository README.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The Ultimate Tech Stack for Building an AI Agent in 2026</title>
      <dc:creator>4sapi</dc:creator>
      <pubDate>Fri, 30 Oct 2026 08:34:45 +0000</pubDate>
      <link>https://dev.to/4sapi/the-ultimate-tech-stack-for-building-an-ai-agent-in-2026-4blc</link>
      <guid>https://dev.to/4sapi/the-ultimate-tech-stack-for-building-an-ai-agent-in-2026-4blc</guid>
      <description>&lt;p&gt;Building an AI Agent is like cooking. You can have the best ingredients (LLMs), but if your kitchen (tech stack) is a mess, the final dish will be bad.&lt;/p&gt;

&lt;p&gt;I've been iterating on AI Agents for months. Today, I'm sharing my "ultimate stack"—the tools I use for development, testing, deployment, and monitoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Brain: LLM APIs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;For Complex Reasoning&lt;/strong&gt;: OpenAI's &lt;code&gt;gpt-4o&lt;/code&gt; or Anthropic's &lt;code&gt;claude-3.5-sonnet&lt;/code&gt;. (Don't use 3.5-turbo for agents, it fails on tool calling).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;For Fast &amp;amp; Cheap Tasks&lt;/strong&gt;: &lt;code&gt;Llama 3 8B&lt;/code&gt; via Groq. The token generation speed is insane and perfect for simple routing tasks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. The Framework: LangGraph
&lt;/h2&gt;

&lt;p&gt;As I mentioned in a previous article, I prefer LangGraph over standard LangChain. The state-machine model gives me the deterministic control I need so my agents don't spiral into infinite loops.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The Memory: Supabase + pgvector
&lt;/h2&gt;

&lt;p&gt;Instead of setting up a whole new vector database, I use Supabase. It provides a Postgres database with vector extensions built-in. It handles both my user authentication and my RAG memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The Observability: Langfuse
&lt;/h2&gt;

&lt;p&gt;You cannot debug an Agent using &lt;code&gt;print()&lt;/code&gt; statements. Langfuse is an open-source tool that traces every LLM call, tool call, and prompt. It shows you exactly where the Agent failed and how many tokens you burned.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. The API Router: OpenRouter / LiteLLM
&lt;/h2&gt;

&lt;p&gt;If you are like me and constantly switch between GPT, Claude, and open-source models, don't write new code for each API. Use OpenRouter. One API key, hundreds of models. (Bonus: It handles rate limits gracefully).&lt;/p&gt;

&lt;h2&gt;
  
  
  6. The Evaluation: Ragas
&lt;/h2&gt;

&lt;p&gt;How do you know if your Agent is getting better or worse? &lt;code&gt;Ragas&lt;/code&gt; is an evaluation framework that tests your RAG pipelines and agents on metrics like "faithfulness" and "answer relevance".&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The Stack Summarized:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;User Input -&amp;gt; Next.js -&amp;gt; LangGraph (Orchestrator) -&amp;gt; Groq/OpenAI -&amp;gt; Supabase (Memory) -&amp;gt; Langfuse (Monitoring)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What does your stack look like? Am I missing any game-changing tools? Let me know below!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LangChain vs. CrewAI vs. AutoGen: Which AI Agent Framework Actually Works for Production?</title>
      <dc:creator>4sapi</dc:creator>
      <pubDate>Thu, 29 Oct 2026 09:43:02 +0000</pubDate>
      <link>https://dev.to/4sapi/langchain-vs-crewai-vs-autogen-which-ai-agent-framework-actually-works-for-production-3gc9</link>
      <guid>https://dev.to/4sapi/langchain-vs-crewai-vs-autogen-which-ai-agent-framework-actually-works-for-production-3gc9</guid>
      <description>&lt;p&gt;The AI Agent ecosystem is exploding. Every week there's a new framework claiming to be the "ultimate solution" for building autonomous agents. &lt;/p&gt;

&lt;p&gt;As a developer, it's overwhelming. To cut through the noise, I spent the last two weeks building the exact same multi-agent workflow (a research assistant that searches the web, summarizes data, and writes a report) using the three most popular frameworks: &lt;strong&gt;LangChain, CrewAI, and AutoGen&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is my honest, unsponsored breakdown of what actually works and what falls apart when you try to push them to production.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Test Case
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Goal&lt;/strong&gt;: Create a 3-agent workflow (Researcher -&amp;gt; Analyst -&amp;gt; Writer).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Tools needed&lt;/strong&gt;: Web Search (Tavily), File Reader (Pandas).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Constraint&lt;/strong&gt;: Must run locally using Llama 3 8B first, then fallback to GPT-4o.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. LangChain (LangGraph)
&lt;/h2&gt;

&lt;p&gt;LangChain has transitioned heavily into LangGraph for agents. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Good&lt;/strong&gt;: Complete control. You can define the exact state graph, loops, and conditional edges. If you want to build a complex, deterministic workflow, LangGraph is king.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Bad&lt;/strong&gt;: Steep learning curve. The documentation moves fast, and you'll often find yourself diving into the source code to understand why a node isn't firing.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Verdict&lt;/strong&gt;: Best for complex, production-grade applications where you need to control every state transition.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. CrewAI
&lt;/h2&gt;

&lt;p&gt;CrewAI takes a role-playing approach (Manager, Researcher, Writer).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Good&lt;/strong&gt;: The fastest to get started. You define roles, goals, and backstories in pure Python, and it works out of the box. It's incredibly intuitive.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Bad&lt;/strong&gt;: Abstraction leakage. When agents fail to communicate, it's very hard to debug because the underlying prompts are dynamically generated and hidden from you.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Verdict&lt;/strong&gt;: Great for rapid prototyping and simple sequential tasks. Harder to scale for highly complex, non-linear workflows.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. AutoGen (Microsoft)
&lt;/h2&gt;

&lt;p&gt;AutoGen focuses on conversational multi-agent systems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Good&lt;/strong&gt;: Brilliant for tasks requiring continuous back-and-forth reasoning. The concept of &lt;code&gt;GroupChat&lt;/code&gt; is powerful for simulating team dynamics.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Bad&lt;/strong&gt;: Prone to infinite loops. You have to strictly enforce termination conditions (like &lt;code&gt;max_consecutive_auto_reply&lt;/code&gt;) or you'll burn through your API credits in minutes.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Verdict&lt;/strong&gt;: Best for research and reasoning-heavy tasks, but requires careful guardrails.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Verdict
&lt;/h2&gt;

&lt;p&gt;If I had to ship a product tomorrow, I would build my base logic with &lt;strong&gt;LangGraph&lt;/strong&gt; for its reliability, but use &lt;strong&gt;CrewAI&lt;/strong&gt; for quick internal proof-of-concept tests. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about you?&lt;/strong&gt; Have you tried building with these frameworks? Which one do you trust for production? Let me know in the comments!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
    </item>
    <item>
      <title>Building Reliable AI Agents: How I Fixed JSON Hallucinations in Tool Calling</title>
      <dc:creator>4sapi</dc:creator>
      <pubDate>Wed, 28 Oct 2026 10:12:24 +0000</pubDate>
      <link>https://dev.to/4sapi/building-reliable-ai-agents-how-i-fixed-json-hallucinations-in-tool-calling-1g7c</link>
      <guid>https://dev.to/4sapi/building-reliable-ai-agents-how-i-fixed-json-hallucinations-in-tool-calling-1g7c</guid>
      <description>&lt;p&gt;If you've built an AI Agent that uses external tools, you know the pain. You define a strict JSON schema for your tool, send the prompt, and the LLM returns something like this:&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="err"&gt;Here&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;requested:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
json&lt;br&gt;
{&lt;br&gt;
  "action": "search",&lt;br&gt;
  "query": "OpenAI API limits"&lt;br&gt;
}&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I hope this helps!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
markdown&lt;/p&gt;

&lt;p&gt;And your Python &lt;code&gt;json.loads()&lt;/code&gt; function just crashed. &lt;/p&gt;

&lt;p&gt;LLMs are text predictors, not schema validators. When you ask them to output JSON, they love to add Markdown syntax, conversational filler, or even hallucinate extra parameters. &lt;/p&gt;

&lt;p&gt;In this post, I’ll share the 3-layer approach I used to bring the Tool Calling accuracy of my Agent from ~70% to near 99%.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Test: OpenAI vs. Claude vs. Llama 3
&lt;/h2&gt;

&lt;p&gt;I ran a simple stress test with 50 complex nested parameters using raw prompts. Here's the failure rate of raw JSON output:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GPT-4o&lt;/strong&gt;: 12% failure (mostly added Markdown backticks)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Claude 3.5 Sonnet&lt;/strong&gt;: 15% failure (tended to add conversational text)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Llama 3 70B (via Groq)&lt;/strong&gt;: 45% failure (hallucinated keys, missing quotes)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To fix this, relying on a simple prompt like &lt;em&gt;"Please output in JSON"&lt;/em&gt; is no longer enough. We need a structured engineering approach.&lt;/p&gt;
&lt;h2&gt;
  
  
  Layer 1: The System Prompt &amp;amp; Schema Validation
&lt;/h2&gt;

&lt;p&gt;First, stop parsing with standard &lt;code&gt;json.loads()&lt;/code&gt;. Use a library that can repair broken JSON or enforce schemas, like &lt;code&gt;json_repair&lt;/code&gt; and &lt;code&gt;pydantic&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Always pair your model with a strict Pydantic model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Literal&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AgentAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Literal&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;web_search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;database_query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The name of the tool to use&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;The exact arguments for the tool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# This ensures we strictly validate the output before feeding it to the next node.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Layer 2: Native Function Calling (Stop Parsing Text)
&lt;/h2&gt;

&lt;p&gt;If you are still prompting models to "output JSON", you are doing it wrong. Use the native tool calling APIs provided by OpenAI, Anthropic, or Google.&lt;/p&gt;

&lt;p&gt;Here is how it works with the OpenAI Python SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;

&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;function&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;function&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_weather&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Get current weather&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;parameters&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;object&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;properties&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;string&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;string&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;enum&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;c&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}]&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s the weather in Tokyo?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tool_choice&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;auto&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; 
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# The API guarantees valid JSON structure in response.choices[0].message.tool_calls
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: Even with native tool calling, models occasionally generate invalid enum values. Always catch the exception and pass it back to the model in a retry loop.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: The Retry &amp;amp; "Self-Correction" Loop
&lt;/h2&gt;

&lt;p&gt;When parsing fails, don't crash. Feed the error back to the LLM. This is the most powerful pattern in Agent engineering.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_tool_with_retry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm_response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_retries&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Attempt to parse and validate
&lt;/span&gt;            &lt;span class="n"&gt;parsed_action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AgentAction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model_validate_json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm_response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;run_tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parsed_action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parsed_action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;error_msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Your previous output caused an error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. Please fix the JSON format and try again.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="c1"&gt;# Send the error back to the model
&lt;/span&gt;            &lt;span class="n"&gt;llm_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_new_completion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error_msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Agent failed to generate valid tool calls after multiple attempts.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;By combining &lt;strong&gt;strict Pydantic validation&lt;/strong&gt;, &lt;strong&gt;native Tool Calling&lt;/strong&gt;, and a &lt;strong&gt;feedback retry loop&lt;/strong&gt;, the Agent's execution reliability jumped from a frustrating 70% to virtually 99%. The key is to never trust the LLM blindly.&lt;/p&gt;

&lt;p&gt;Building a reliable AI Agent requires treating the LLM not as a magic brain, but as an unreliable API that needs strict input/output sanitization.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have you encountered JSON parsing errors in your Agent workflows? How do you handle model hallucinations when calling external tools? Let me know in the comments!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;P.S. I'm currently documenting real-world performance and stress tests of various AI Agents on my personal blog. If you're building with LLMs, I'd love to connect and hear what metrics you care about most.&lt;/em&gt;&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ai</category>
      <category>devops</category>
    </item>
    <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>
