← All Problems

8. Validate a Model's Structured (JSON-like) Output

Confirmed Hard Anthropic-Style Coding Rounds
Grounding: Confirmed: a 2024 Blind thread ("Anthropic coding interview Round 2") explicitly lists parsing as one of the general Python topics covered in Anthropic's non-ML coding round. This problem is a stack-based parsing/validation exercise in that spirit; the structured tool-call framing itself is a synthesized scenario, not a reported question. (Source: teamblind.com/post/Anthropic-coding-interview-Round-2-wWDSfxXX)

Problem

A model is prompted to emit a structured tool call as JSON-like text, but generated text can come back malformed: a truncated response, a bracket closed with the wrong type, or a string left unterminated.

Before the runtime tries to parse the output into an actual tool call, it needs a fast structural check: are all the brackets/braces/parens balanced and correctly nested, treating the contents of double-quoted strings as opaque, so a brace typed inside a string doesn't count as real structure?

Source: src/8_validate_structured_output.py

def is_valid_json_like(output: str) -> bool:
    ...

Examples:
>>> is_valid_json_like('{"tool": "search", "args": ["query", "value"]}')
True

>>> is_valid_json_like('{"tool": "search", "args": ["query")]}')
False

Step-by-Step Approach

  1. Recognize this as the classic "valid parentheses" stack problem, extended with a string-literal mode that must suppress bracket-matching while inside quotes.
  2. Scan the text character by character, tracking two extra pieces of state beyond the stack: whether you're currently inside a string (in_string) and whether the next character is escaped (escape).
  3. While in_string is true, only watch for a backslash (set escape for one character) or an unescaped closing quote (exit string mode) — every other character, including brackets, is ignored.
  4. While not in a string, an opening quote enters string mode; an opening bracket pushes onto the stack; a closing bracket must match the type on top of the stack (pop it) or the input is invalid immediately.
  5. After the full scan, the input is valid only if the stack is empty (nothing left unclosed) and in_string is false (no unterminated string).

The key insight is that a string literal is a self-contained sub-mode of the scanner — once you correctly gate all bracket-matching logic behind "are we inside a string right now," the rest is the same stack-based algorithm as plain bracket matching.

Reference solution

_PAIRS = {")": "(", "]": "[", "}": "{"}
_OPENS = set(_PAIRS.values())
_CLOSES = set(_PAIRS.keys())


def is_valid_json_like(output: str) -> bool:
    # standard "valid parentheses" stack, extended with a string-literal
    # mode so brackets typed inside a "..." string are ignored. O(n).
    stack: list[str] = []
    in_string = False
    escape = False
    for ch in output:
        if in_string:
            if escape:
                escape = False
            elif ch == "\\":
                escape = True
            elif ch == '"':
                in_string = False
            continue
        if ch == '"':
            in_string = True
            continue
        if ch in _OPENS:
            stack.append(ch)
        elif ch in _CLOSES:
            if not stack or stack[-1] != _PAIRS[ch]:
                return False
            stack.pop()
    # everything must be closed, and no string left dangling open
    return not stack and not in_string

Key Functions & Tricks

  • stack.append(ch) / stack.pop() — tracks currently-open brackets in nesting order
  • _PAIRS[ch] — maps a closing bracket to the opening bracket it must match
  • in_string flag — suppresses all bracket-matching logic while scanning inside a string literal
  • escape flag — makes an escaped quote (\") not terminate the current string
  • not stack and not in_string — final validity check: nothing left open, no dangling string

How to Recognize This Pattern

The signal is "validate balanced/nested delimiters in text," the classic stack-based bracket-matching family — the twist to watch for is any sub-region (string literals, comments) where the normal matching rules must be suppressed. A single boolean mode flag checked at the top of the loop is usually enough to handle that cleanly. Common variations add multiple string-quote styles (single and double quotes), nested comments, or require you to report the *position* of the first invalid character rather than just true/false. A common pitfall is forgetting the escape-character case inside strings, so an escaped quote (\") is mistaken for the string's actual terminator and the scanner falls out of string mode early, corrupting all matching after that point.