Apply to my task
arXiv:2510.07315 ★ 90 Oct 8, 2025

VeriCode: Verifiable Instructions for Evaluating LLM-Generated Code

Key result

Add 5 code style requirements (line length, docstrings, pathlib instead of os.path) and functionality drops by 6%, even though the requirements have NOTHING to do with whether the code works. Even top models satisfy all 5 instructions at once only 47% of the time. VeriCode, a taxonomy of 30 automatically checkable instructions (style, logic, documentation, error handling), lets you measure not just whether code works but whether it follows the requirements. Each instruction is checked via linters and AST analysis and returns pass or fail. The researchers extended the classic BigCodeBench and LiveCodeBench benchmarks with these instructions, creating Vibe Checker — an environment that evaluates both dimensions.

01

TL;DR

VeriCode is a taxonomy of 30 verifiable coding instructions (style, logic, documentation, error handling, libraries). Each instruction is checked automatically via linters and AST analysis and returns pass or fail. The researchers extended the classic BigCodeBench and LiveCodeBench benchmarks with these instructions, creating Vibe Checker — a test environment that evaluates both functionality and instruction following.

LLMs struggle to juggle several instructions at once. When you add 5 non-functional instructions (for example, "max 79 characters per line" + "use pathlib instead of os.path" + "Google-style docstrings"), functionality drops by 6% on average, even though the instructions had nothing to do with whether the code works. Even top models satisfy all 5 instructions only 47% of the time on real-world tasks and 41% on algorithmic ones. Models show position bias: instructions in the middle of the list are followed worse than those at the beginning or end.

The method works in two modes: single-turn (all instructions at once in one prompt) preserves functionality better but follows instructions worse; multi-turn (instructions added gradually) meets the requirements better but breaks working code more often. The main takeaway: human preferences in coding tasks correlate best with a mix of functionality and instruction following (the optimum is 40-70% weight on IF), not with working code alone.

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

VeriCode includes 5 categories of instructions:

Coding Style & Conventions (9):

  • Line length, indentation, variable naming, import order

Logic & Code Patterns (9):

  • Number of branches, nesting depth, function complexity, use of specific patterns

Documentation & Commenting (6):

  • Docstring style (Google/NumPy/PEP 257), comments, parameter descriptions

Error Handling & Management (4):

  • Exception handling, canonical error classes, specific except blocks

Library & API Constraints (2):

  • Using specific libraries (pathlib instead of os.path), replacing deprecated APIs

Each instruction includes:

  • A category
  • A natural-language description for single/multi-turn modes
  • Configurable parameters (for example, line_length: 79 or 88)
  • Verifier code (returns True/False)
03

Example in Action

Task: Write a Slack bot that sends notifications about new orders from the CRM. The code needs to be readable for the team — junior devs will be finishing it.

Prompt:

Build a Slack bot in Python that sends notifications about new orders.

Code requirements:
1. Maximum 88 characters per line
2. Use pathlib instead of os/os.path for file handling
3. Document functions with Google-style docstrings
4. Use specific exceptions instead of a generic Exception
5. Maximum 3 branches (if/elif/else) per function

The bot should:
- Read the token from a .env file
- Load order data from a JSON file
- Post a formatted message to the channel

Result:

The model will produce code that technically works, but with a probability of ~47% it will violate at least one of the five requirements. Instruction number 3 (in the middle of the list) will suffer most often because of position bias. Functionality may also degrade by 6-9% — for example, the bot might not handle some file edge cases that it would have handled without the extra instructions.

If you give the same instructions gradually (first a basic bot, then "add the line-length limit," then "add pathlib," and so on), the code will meet the requirements better (~55% success instead of 47%), but functionality will take a bigger hit (a drop of up to 9% instead of 6%).

04

Why It Works

LLMs generate code while automatically balancing many goals: working code, readability, style, performance. When you add explicit instructions, the model redistributes its attention — part of its "compute budget" goes to meeting the new requirements at the expense of core functionality.

Position bias comes from the transformer architecture: the attention mechanism pays more attention to the beginning and end of the context. Instructions in the middle of the list "get lost" even in short prompts (a few hundred tokens). Single-turn shows primacy bias (the first instruction is followed best), multi-turn shows recency bias (the last one is).

Multi-turn vs single-turn: In single-turn, the model sees the whole picture at once and prioritizes keeping the code working. In multi-turn, each iteration focuses on a local task (add a new requirement), which boosts instruction compliance but more often breaks what used to work — the classic edit distance problem.

The correlation with human preferences shows that users intuitively judge code on both axes — whether it works and its style/patterns. For real-world tasks (BigCodeBench), instruction following is even more important than functionality (a weight of 0.7 vs 0.3); for algorithmic tasks (LiveCodeBench) it's the other way around.

Control Levers

Number of instructions: 1-2 instructions — safe, 3-4 — noticeable regression, 5+ — high risk. For complex tasks, split them across several prompts instead of one prompt with 5+ requirements.

Order of instructions: Put the most important ones at the beginning or end and the secondary ones in the middle. If you're using multi-turn, add critical requirements last (recency bias).

Interaction mode: Single-turn for production code where functionality is critical. Multi-turn for prototypes or when style/patterns matter more than working code.

Instruction parameters: VeriCode supports parameter tuning — you can vary line_length (79/88/120), max_branches (2/3/4), docstring_convention (Google/NumPy/PEP257). Stricter values → higher chance of a violation.

05

Prompt Template

For 1-2 instructions (the safe zone):

Write {task description}.

Code requirements:
1. {instruction_1}
2. {instruction_2}

Task: {details}

For 3+ instructions (watch the functionality):

Option A — Single-turn (preserve functionality):

Write {task description}.

Code requirements (important ones at the edges):
1. {critical_instruction_1}
2. {secondary_instruction}
3. {secondary_instruction}
4. {critical_instruction_2}

Task: {details}

Option B — Multi-turn (maximize instruction following):

// Round 1:
Write {task description}.
Task: {details}

// Round 2:
Add a requirement: {instruction_1}

// Round 3:
Add a requirement: {instruction_2}

// And so on, with critical requirements last

Specific VeriCode instructions (examples):

Style:

  • No line longer than {79/88/120} characters
  • Use Google/NumPy/PEP257-style docstrings
  • Sort imports: standard library → third-party → local

Logic:

  • Maximum {2/3/4} branches (if/elif/else) per function
  • Nesting depth no more than {2/3} levels
  • Cyclomatic complexity ≤ {5/10/15}

Libraries:

  • Use pathlib instead of os.path/os/glob/open
  • Replace all aliased exceptions (IOError, WindowsError) with the canonical OSError

Error handling:

  • Use specific except clauses instead of a generic Exception
  • Don't use bare except (except for SystemExit/KeyboardInterrupt)
06

Limitations

⚠️ Functional regression: Adding 5 non-functional instructions lowers functionality by 6% on average for real-world tasks and by up to 10% for algorithmic ones. The more instructions, the higher the risk.

⚠️ Low success rate: Even top models satisfy all 5 instructions at once only 40-47% of the time. With 3+ instructions, most models fall below 50%.

⚠️ Position bias: Instructions in the middle of the list (positions 2-3 out of 5) are followed 5-10% worse than those at the beginning or end. The effect shows up even in short prompts.

⚠️ Multi-turn trade-off: Adding instructions gradually raises compliance by 3-8% but amplifies functional regression by 3-5% compared with single-turn.

⚠️ Task specifics: The method was built for Python. Other languages need their own linters and verifiers. Algorithmic tasks suffer more than real-world ones (10% vs 6% regression).

07

How They Tested It

The researchers took 800+ rules from the popular Python linter Ruff, filtered them in three stages and ended up with 30 core instructions. First they removed duplicate and overly narrow rules, then tested on Gemini 2.5 Flash: anything followed 90%+ of the time without losing functionality was thrown out. They kept only the ones where even top models stumble. Each instruction got a deterministic verifier — either linter-based or via AST analysis.

Next they extended two classic benchmarks: BigCodeBench (1,140 real-world tasks) and LiveCodeBench (1,055 algorithmic ones). For each task, an LLM selector (Claude 4 Opus) picked a subset of the 30 instructions — only relevant ones that didn't conflict with each other. That produced over 10,000 checks at the level of individual instructions.

They tested 31 models from 10 families in two modes: single-turn (all instructions at once) and multi-turn (gradually). They measured two metrics: pass@1 for functionality and instruction-level/task-level success for meeting the requirements. A task counted as a success only if ALL instructions were satisfied — hence the exponential drop as the number of requirements grows.

Why these conclusions: Multi-turn showed a systematic pattern — better IF, worse functionality. That's no accident but an architectural property: in multi-turn, the model focuses on a local task at each iteration (add a new requirement) without seeing the full picture as it does in single-turn. Position bias reproduced on both benchmarks with different shapes: a U-shape on real-world tasks (lost-in-the-middle), a linear trend on algorithmic ones, but everywhere — the middle does worse than the edges.

The link to human preference: They correlated the results with 800K+ votes from the LMArena coding subset. The correlation peaks with a mix of metrics (40-70% weight on IF), not with pure functionality or pure IF. And for real-world tasks IF matters more (optimum at 70%), while for algorithmic ones functionality does (optimum at 30%). This explains why Copilot Arena rankings correlate weakly with classic benchmarks: those benchmarks measure only half of what users value.

08

Resources

Vibe Checker: Aligning Code Evaluation with Human Preference
Ming Zhong, Xiang Zhou, Ting-Yun Chang and team (Google DeepMind, UIUC, USC)
arXiv:2025.XXXXX (pre-print)

The VeriCode taxonomy and verifiers will be released publicly.
Ruff linter: https://docs.astral.sh/ruff/rules
BigCodeBench: https://openreview.net/forum?id=YrycTjllL0
LiveCodeBench: https://openreview.net/forum?id=chfJJYC3iL
LMArena coding leaderboard: https://lmarena.ai/leaderboard/text/coding


Research digest

Key result

Add 5 code style requirements (line length, docstrings, pathlib instead of os.path) and functionality drops by 6%, even though the requirements have NOTHING to do with whether the code works. Even top models satisfy all 5 instructions at once only 47% of the time. VeriCode, a taxonomy of 30 automatically checkable instructions (style, logic, documentation, error handling), lets you measure not just whether code works but whether it follows the requirements. Each instruction is checked via linters and AST analysis and returns pass or fail. The researchers extended the classic BigCodeBench and LiveCodeBench benchmarks with these instructions, creating Vibe Checker — an environment that evaluates both dimensions.

Principle

LLMs suffer from position bias — instructions in the middle of the list are followed 5-10% worse than those at the beginning or end. This holds even in short prompts of a few hundred tokens. Two modes of operation: One prompt (single-turn): all requirements at once → the model sees the full picture → prioritizes functionality → less regression (6%) but worse instruction following (47% success). Gradually (multi-turn): you add requirements one at a time → each iteration focuses on a local task → better instruction following (55%) but more often breaks what used to work (9% regression).

Why it works

The model automatically balances between goals: working code, readability, style, performance. Add explicit instructions and the model redistributes its attention "compute budget". Part of its resources goes to the new requirements at the expense of core functionality. Position bias comes from the transformer architecture: the attention mechanism pays more attention to the beginning and end of the context. Instructions in the middle "get lost." In a single prompt you see primacy bias (the first instruction is followed best); with gradual additions, recency bias (the last one is). The study showed that human preferences correlate with a mix of functionality and instruction following (40-70% weight), not with working code alone. For real-world tasks, style matters even more than functionality.

When to apply

Generating production code → specifically when you need to follow company standards (line length, documentation style, specific libraries), especially in team development where junior devs will read the code. Evaluating models → for benchmarks where code quality matters, not just whether it runs. NOT a fit: for quick prototypes or one-off scripts where functionality is critical and style is secondary.

Mini recipe

1. Rank your instructions by criticality: split them into those critical for functionality (error handling, logic) and secondary ones (style, formatting) 2. Pick the mode for the task: One prompt — if functionality matters more than style (production code, complex algorithms). Gradually — if style matters more or the code is simple (utilities, scripts for the team) 3. Order instructions with the bias in mind: The most important ones at the beginning or end of the list. Secondary ones in the middle. When adding gradually, add critical requirements last 4. Limit the count: 1-2 instructions is safe, 3-4 means noticeable regression, 5+ is high risk. For 5+ requirements, split them across several prompts 5. Verify automatically: use linters (flake8, pylint) and AST analysis instead of manual checks

Examples

[BAD]: `Write a Slack bot. Requirements: max 88 characters per line, pathlib instead of os.path, Google-style docstrings, specific exceptions, max 3 branches per function` — 5 requirements in one heap, and the critical ones (error handling) get lost in the middle [GOOD]: `Write a Slack bot. Code requirements (by priority): 1. Use specific exceptions instead of a generic Exception (CRITICAL for debugging) 2. Max 88 characters per line 3. Use pathlib instead of os.path 4. Max 3 branches per function (CRITICAL for readability) 5. Google-style docstrings` — critical instructions at the beginning and end, secondary ones in the middle. Or split it into 2 prompts: first a basic bot with requirements 1 and 4, then a refactor for requirements 2, 3 and 5

In plain words

The problem is that modern models write code that works but looks like a pile of junk. You ask the model to add error handling or to skip the heavyweight libraries, and it either ignores your requests or hands you a chunk of broken code. This happens because the model has a limited compute budget: when you load it up with style requirements, it starts slipping on the logic. Vibe Checker is an attempt to finally measure this balance and see how well a model holds up in real conditions rather than in a sterile test.

It's like hiring a builder who can lay bricks but keeps forgetting the blueprints and leaves mountains of debris behind. Technically the house is standing, but you can't live in it, and fixing it costs more than building from scratch. We used to check only "is the house standing"; now Vibe Checker also checks whether the worker wore a hard hat, cleaned up after himself and didn't use duct tape where cement was needed. If the code runs but breaks five of your style rules, that's a failure, not a solution.

To stop guessing, the researchers rolled out VeriCode — a strict list of 30 rules checked automatically through linters and rigorous code analysis. It's all practical: from error handling and documentation to bans on specific libraries. No more subjective verdicts along the lines of "well, it looks kind of nice." The system returns a clear pass or fail for each instruction. If you asked for junior-friendly code and the model spat out unreadable one-line magic, it gets slapped down, even if the algorithm is correct.

The approach was tested on tough benchmarks like BigCodeBench, and the principle is universal. Whether you're writing a Slack bot for your CRM or a complex analytics system, the rules of the game are the same. Vibe Checker proves that following instructions is a separate skill that often runs counter to raw performance. Now we see the real picture: which models know how to listen to the client and which just crank out quick-and-dirty scripts, ignoring the context and the team's standards.

Bottom line: the era of "code that just works" is over, and the era of controlled generation has begun. Stop celebrating the fact that the model produced anything at all — demand that it follows standards. Vibe Checker gives you a tool to rub the model's nose in its mistakes and make it write code the whole team won't have to rewrite. Those who learn to balance logic and style will survive this zoo; the rest will drown in technical debt created by their own AI assistants.

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 VeriCode: Verifiable Instructions for Evaluating LLM-Generated Code arXiv:2510.07315

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