Apply to my task
arXiv:2510.15955 ★ 89 Oct 10, 2025

Processing JSON with LLMs: When Code Beats Words

Key result

The discovery: Even top LLMs are terrible at processing JSON directly – GPT-4o maxes out at 77% accuracy. Models get lost in the structure, confuse similar keys (name, room_name, full_name), and stumble over nesting. As the size grows to 80K tokens, Mistral-large drops by 91%. The method lets you extract data from complex API JSON responses with up to 95% accuracy – especially for filtering and aggregation. The trick: instead of "read the JSON and give me the answer" → "write a Python function that parses the JSON". The code runs – the result is exact. Add the JSON schema to the prompt – +12% accuracy. Even a trimmed structural sample works if the full response doesn't fit in the context.

01

TL;DR

How to handle JSON responses from APIs and tools — the research shows that LLMs do better when they generate Python code to parse the data instead of answering directly. Especially for harder tasks: filtering and aggregating data.

The main finding: Even top models are bad at processing structured data directly. GPT-4o tops out at 77% accuracy. When you ask a model to "look at this JSON and answer," it gets lost in the structure, picks the wrong keys, and drops data in nested levels. Accuracy falls as the response grows: GPT-4o loses 7%, Mistral-large 91% when going from 10K to 80K tokens. The answer's position matters too: models see the most recent data better (recency bias).

The core of the method: Instead of "read the JSON and answer" → "write a Python function that parses the JSON and returns the answer." The code runs and the result comes back. To boost it further: add the JSON schema to the prompt (+12% accuracy) and provide a sample of the structure even if the full response doesn't fit in the context.


Want this for your own case? Apply this study to your task: AI adapts its method to what you are working on and writes the prompt.

02

Method Blueprint

The study compared two main approaches:

APPROACH 1: Answer generation

Query → LLM reads the JSON → Outputs a text answer

APPROACH 2: Code generation ← works better

Query → LLM writes a Python function → Code runs → Result is returned

Ways to improve it:

  • Add the JSON schema to the prompt
  • Provide a trimmed version of the response if the full one doesn't fit
  • For complex tasks: add reasoning instructions (CoT)

Every approach works in a single call to the model.


03

Example in Practice

Task: You pulled Chicago apartment listings from a real-estate listings API as JSON (50+ objects, nested structure: neighborhood → building → unit → features). You need every two-bedroom under $750,000 with a balcony.

Prompt (basic approach — works poorly):

Here's a JSON with apartments. Find every two-bedroom under $750,000 with a balcony and list the addresses.

[JSON]

Prompt (improved — code generation):

Here is a JSON response from a real-estate listings API with apartments, plus the schema of that JSON.

Write a Python function that:
1. Takes the entire JSON as a dictionary
2. Filters apartments: rooms == 2, price <= 750000, has_balcony == true
3. Returns the list of addresses as a comma-separated string

Code requirements:
- Starts with "def "
- Checks that keys exist before accessing them
- Compares strings in lowercase
- Returns only the result (a string), with no extra text

JSON schema:
{
  "apartments": [
    {
      "address": "string",
      "price": "number",
      "rooms": "number",
      "has_balcony": "boolean",
      ...
    }
  ]
}

JSON:
[paste the data]

Python function:

Result: The model produces Python code with a def filter_apartments(data): function that handles the nesting correctly, checks the conditions and returns the list of addresses. You can run the code right away (in local Python or via the chat's code execution tool). Accuracy is 3-50% higher depending on the task's complexity.


04

Why It Works

The LLM's weakness: Models get lost in the structure when processing JSON directly. They confuse similar keys (name, room_name, name_without_policy), pull values from the wrong objects, and stumble over nesting. With long responses (50K+ characters) accuracy collapses. It's like eyeballing your way through a 100-sheet Excel workbook to find one row.

The LLM's strength: Models know code structure extremely well and can write precise instructions. Python for parsing JSON is home turf for them. Code is unambiguous: if item['price'] <= 750000 can't be read two ways. Plus code is more compact — a 20-line function instead of a sprawling 200-word text answer.

How the method exploits this: You move the task out of "understanding the structure" and into "writing code". Instead of "find it and tell me" → "write a function that finds it." The model generates the code, the code runs, and the result is exact. The JSON schema works as a map of the terrain — the model sees data types, nesting and relationships. A structural sample (even a trimmed one) shows real values, so the model understands the format ("USD 250" vs 250).

Control knobs:

  • JSON length → if it's >50K characters, use a trimmed version (one example of each object type)
  • Task type → for extracting a single value ("What is form type?") a direct answer is sometimes better; for filtering/aggregation, always use code
  • Schema → always add it if you have one — it gives +12% accuracy
  • CoT instructions → for aggregation (sums, averages) add "Think step-by-step" before code generation

05

Prompt Template

Here is a JSON response from {source} and its schema.

Write a Python function that:
1. Takes the entire JSON as a dictionary (parameter data)
2. {task description: filters/extracts/counts}
3. Returns the result as a string

Code requirements:
- Starts with "def "
- Checks that keys exist and values aren't None
- Compares strings in lowercase
- Cleans numeric strings (strips "$", spaces) before converting
- Returns only the result, with no extra text

JSON schema:
{schema}

JSON:
{data}

Python function:

Placeholder guide:

  • {source} — where the data comes from (a listings API, a CRM export, etc.)
  • {task description} — the specific operation ("find all X where Y", "compute the average Z")
  • {schema} — the JSON schema of the structure (generate one online or ask the model)
  • {data} — the JSON response itself (full or trimmed)

🚀 Quick start — paste into the chat:

Here is a template for processing JSON through code. Adapt it to my task: [your task].
Ask me questions to fill in the fields.

[paste the template above]

The LLM will ask where the JSON comes from, what you need to extract and whether there's a schema — because that information is critical for accurate parsing. It will take the function pattern from the template and adapt it to your data structure.


06

Limitations

⚠️ Task type: For simple extraction of a single value ("What is the price?") a direct answer is sometimes more accurate than code — 10 out of 15 models showed this. Code pays off for filtering and aggregation.

⚠️ Context size: With JSON >80K tokens, accuracy drops for every model. Even with code. Use trimming (one example of each object type).

⚠️ Code syntax: ~5-10% of errors come from incompatible syntax (wrong data type, traversal bugs). Top models (GPT-4o, Claude-4-Sonnet) produce runnable code 95%+ of the time.

⚠️ Semantic ambiguity: If the JSON has similar keys (name, room_name, full_name), the model may pick the wrong one. Specify the exact path in the task or clean up the JSON before feeding it in.


07

How They Tested It

The team collected 1,298 real question-answer pairs over API responses from RapidAPI (hotels, cars, flights, SEC filings, products). The JSON was long — from 24K to 74K characters. Questions were split into three types: extractive (find a value by key), filtering (return all records matching a condition), aggregation (compute a sum/average/minimum).

They tested 15 models (from Llama-3.1-8B to GPT-4o) with different prompts: answer generation vs. code, with and without a schema, with and without reasoning (CoT). Accuracy was measured with three metrics: exact match, contains (the result appears in the answer), and LLM as a judge (semantic match).

The results were surprising: Even GPT-4o reached only 77% with the best approach. Code beat direct answers in 13 of 15 models. The schema added +12% for code and +7% for direct answers. When JSON grew from 10K to 80K tokens, accuracy dropped by anywhere from 7% (GPT-4o) to 91% (Mistral-large). Recency bias (the answer's position in a list) had a 5-75% effect depending on the model.

The critical insight: When they stripped the JSON down to the bare minimum (oracle projection — keeping only the needed fields), accuracy jumped by 8-38 points. That means noise and structural complexity are accuracy's main enemy. Models can cope if you give them a clean, simplified version.


08

Original from the Paper

Context: The researchers used this prompt for code generation with the full schema and response.

You will be given a JSON object as data which is a response from a REST API containing information returned from the API call.
You will be given a JSON schema of the response from the REST API returned from the API call.
Your task is to extract and return information from the JSON object which follows the JSON schema and answers the user query: <<task_prefix>>

You need to write a Python function that:
- Starts the function with "def".
- Takes only the entire api response as input and doesn't have any other input.
- Identifies the structure of the input data, ensuring it checks for relevant keys and data types.
- When comparing strings, it should always convert both sides of the comparison to lowercase.
- Processes the provided data.
- Iterates through the data to extract relevant information.
- Cleans numeric strings by removing non-numeric characters before converting them to integers.
- Performs proper checks to ensure a key exists and is not None before querying its value.
- Returns only the requested data as a string and no other extra information or words.
- Do not add any extra keys or terms to the output.

Final Check:
- The function must be formatted in Python markdown for direct execution.
- No explanations, comments, or additional text should be included.
- Do not include any example usage data.

The JSON schema of the object given as data is as follows: <<json_schema>>

data = <<json_obj>>

Python Function:

09

Adaptations and Extrapolations

💡 Adaptation for tables in PDFs:

The same logic works for pulling data out of tables. Instead of JSON — an HTML or Markdown table extracted from a PDF.

Here is a table from a PDF report in Markdown format.

Write a Python function that:
1. Parses the table (you can use pandas)
2. Filters rows where {condition}
3. Returns the result as a list

Table:
{markdown_table}

Python function:

💡 Adaptation for nested dictionaries:

If the structure is really complex (the API returns 5 levels of nesting), ask the model to simplify it first, then process it:

Here is a complex JSON with 5 levels of nesting.

Step 1: Write a flatten_json() function that simplifies the structure down to 2 levels
Step 2: Write an extract_data() function that finds {what you need} in the simplified JSON

JSON:
{data}

🔧 Technique: Add debug output → see the logic

Add this to the prompt template:

- Add print() at every processing step for debugging

You'll get code with print(f"Found {len(items)} items") — so you can see how the model is reasoning. Handy for checking the logic.

🔧 Technique: Swap generic variable names for descriptive ones → fewer errors

Instead of:

for item in data:
    if item['key'] == value:

Ask for:

- Use descriptive variable names (apartment instead of item, price instead of value)

The model generates more readable code and gets confused less.


10

Resources

How Good Are LLMs at Processing Tool Outputs? https://github.com/LongFuncEval/toolJSONprocessing

Kiran Kate, Yara Rizk, Poulami Ghosh, Ashu Gulati, Tathagata Chakraborti, Zidane Wright, Mayank Agarwal — IBM Research, USA; Persistent Systems; Grab


Research digest

Key result

The discovery: Even top LLMs are terrible at processing JSON directly – GPT-4o maxes out at 77% accuracy. Models get lost in the structure, confuse similar keys (name, room_name, full_name), and stumble over nesting. As the size grows to 80K tokens, Mistral-large drops by 91%. The method lets you extract data from complex API JSON responses with up to 95% accuracy – especially for filtering and aggregation. The trick: instead of "read the JSON and give me the answer" → "write a Python function that parses the JSON". The code runs – the result is exact. Add the JSON schema to the prompt – +12% accuracy. Even a trimmed structural sample works if the full response doesn't fit in the context.

Principle

Don't ask the model to read the structure → ask it to write code that will. You move the task from "understanding the data" to "writing code". Instead of "find every two-bedroom under $750,000 with a balcony" (the model eyeballs the JSON) → "write a function def filter_apartments(data): that returns the filtered list". Code is unambiguous – `if item['price'] <= 750000` can't be read two ways. Python for parsing JSON is home turf for an LLM.

Why it works

Models get lost in the structure when reading directly. They take values from the wrong objects, mix up keys, and once nesting goes deeper than 3 levels accuracy hits the floor. It's like hunting for a row in a 100-sheet Excel workbook. But models know Python syntax for working with JSON inside out. Code is more compact – a 20-line function instead of a 200-word text answer, and it executes with zero ambiguity. The JSON schema works as a map of the terrain – the model sees data types, nesting and relationships. For complex tasks (filtering + aggregation) the improvement reaches 50% compared with a direct answer.

When to apply

Working with APIs and tools → specifically for filtering and aggregating JSON responses (selecting objects by conditions, computing averages, grouping), especially when the response is large (50K+ tokens) or deeply nested (3+ levels). NOT a fit for extracting a single simple value ("What is the price?") – there a direct answer is sometimes more accurate.

Mini recipe

1. Add the JSON schema to the prompt: Show the structure with data types – `{"apartments": [{"price": "number", "rooms": "number"}]}`. It's a map for the model. 2. Phrase the task as requirements for a function: "Write a Python function that: takes the JSON as a dictionary, filters by conditions X and Y, returns the result as a string". 3. Specify code requirements: Starts with `def`, checks that keys exist before accessing them, compares strings in lowercase, cleans numeric strings (strips "$", spaces). 4. If the JSON is large (50K+ tokens): Give a trimmed structural sample – one object of each type. The full JSON won't fit in the context – the sample shows real values. 5. Run the generated code: Execute the function in local Python or via the chat's code execution tool.

Examples

[BAD]: `Here's a JSON with apartments from a listings API. Find every two-bedroom under $750,000 with a balcony and list the addresses.` (The model eyeballs the JSON, confuses the has_balcony and balcony_type keys, and loses objects at the 3rd level of nesting) [GOOD]: `Here is a JSON response from a listings API with apartments, plus the schema of that JSON. Write a Python function that: 1) Takes the entire JSON as a dictionary, 2) Filters apartments where rooms == 2, price <= 750000, has_balcony == true, 3) Returns the list of addresses as a comma-separated string. Code requirements: starts with "def", checks that keys exist, compares strings in lowercase. JSON schema: {"apartments": [{"address": "string", "price": "number", "rooms": "number", "has_balcony": "boolean"}]}` (The model generates a `def filter_apartments(data):` function with precise logic – 95% accuracy vs 60% with direct reading)

In plain words

Here's the thing: for all their power, modern AI models still choke on plain tables and JSON files. When you feed a model a huge data dump from an API, it doesn't "see" the whole structure at once — it reads it sequentially, like text. So when there's a lot of data, the model hits cognitive overload: it mixes up nested fields, loses keys and starts flat-out hallucinating, grabbing numbers from neighboring objects. Having an LLM process data directly is a one-way ticket to errors, especially when something needs to be counted or filtered.

It's like asking an English major to find one specific typo in a thousand-page accounting report just by flipping through it. Technically they're reading, but by page one hundred their brain is mush and they start confusing debits with credits. Instead of making them suffer, it's easier to hand them a calculator and teach them a few simple formulas. In the AI world, that "calculator" is generating Python code that does all the grunt work for the model.

The research draws a clear line between two approaches: direct answers and programmatic processing. It turns out that when the model first writes a Python script to parse the JSON and then simply runs it, accuracy goes through the roof. Instead of guessing which field holds the apartment price, the model builds a clean filtering algorithm. It works like a charm: Python code doesn't botch indexes, unlike a model that might "forget" a closing bracket or mix up look-alike keys such as room_id and room_name.

It was tested on tough tasks like searching apartments by a pile of parameters, but the principle is universal. It applies to any interaction with external tools and APIs. If your task is harder than "summarize this paragraph," making the model analyze raw data directly is a total flop. Financial reports, server logs or a customer database — the pattern is the same: the model should act as the architect who writes the code, not the laborer sorting through rows by hand.

Bottom line: forget about feeding a model a giant wall of JSON and hoping for a sane result. If you want AI to genuinely help with analytics, use the Code-as-Intermediary method. Let the model write the code that processes the data instead of trying to be that code itself. Higher accuracy, fewer hallucinations, and you don't waste time double-checking every number behind a "smart" assistant that got it all mixed up again.

AI lab assistant

Apply this study to your task

Describe what you're working on. AI takes the method and the measured results from this paper and adapts them to your case, or writes a ready prompt built on them.

Based on Processing JSON with LLMs: When Code Beats Words arXiv:2510.15955

Sign in to apply this study New accounts get 50 free credits.