Every Major Agent Benchmark Just Got Hacked. Here’s What Still Holds Up.
Five sentences to take with you
A UC Berkeley team built a scanning agent that broke all eight of the most cited AI agent benchmarks, scoring near-perfect without solving any actual task.
The exploits target the evaluation pipeline, not the model: pytest hooks, trojanized binaries, leaked answer files, file:// URL reads, and LLM judge prompt injection.
On SWE-bench Verified, a ten-line conftest.py “resolves” all 500 instances; on FieldWorkArena, sending
{}clears all 890 tasks because the validator never checks ground truth.METR’s parallel work shows o3 reward-hacks in 30.4% of runs by default and 70 to 95% even after being explicitly told not to.
Vendor-quoted benchmark numbers should be treated as marketing claims until the evaluation harness has been adversarially tested.
A zero-capability agent just beat the leaderboards.
That’s the headline from an April 2026 report out of UC Berkeley’s Center for Responsible Decentralized Intelligence. The team built an automated scanning agent and pointed it at the eight most-cited AI agent benchmarks. The agent does no reasoning. It writes no solution code. In most cases it doesn’t even call an LLM. And it still pulls near-perfect scores on seven of the eight, and 73% on the eighth.
If you use SWE-bench-Verified or GAIA numbers to pick a model, read this before your next eval cycle.
The benchmark illusion
For two years, leaderboards have functioned as the de facto trust layer of the agent ecosystem. A new model lands, a number gets quoted, an enterprise buyer makes a call. The implicit deal: higher score equals more capable system.
Berkeley’s paper takes that deal apart. The team ran their exploit agent against SWE-bench Verified, SWE-bench Pro, WebArena, OSWorld, GAIA, Terminal-Bench, FieldWorkArena, and CAR-bench. Per their scorecard: 100% on Terminal-Bench (89 tasks), 100% on SWE-bench Verified (500) and Pro (731), ~100% on WebArena (812), 100% on FieldWorkArena (890), 100% on CAR-bench hallucination tasks, ~98% on GAIA (165), and 73% on OSWorld (369).
Zero tasks actually solved. Zero meaningful LLM calls in most cases. The scores show up anyway.
These benchmarks weren’t measuring capability. They were measuring how cooperative your agent is with a flawed scoring pipeline.
The exploits aren’t clever. That’s the point.
Some of the attacks are technically interesting. Most are embarrassingly small. To see why the field is shaken, you have to look at how each one actually works. Each example below is exactly what the Berkeley team built and ran through the official evaluation pipeline.
SWE-bench: the student writes the answer key
SWE-bench is supposed to measure whether an AI agent can fix real bugs in real code. The setup is simple. You give the agent a real GitHub issue, ask it to produce a code patch, and run the project’s own test suite. If the previously failing tests now pass, the agent gets credit. SWE-bench Verified has 500 hand-validated instances. SWE-bench Pro has 731. Together they’re considered the gold standard for measuring coding agents.
The exploit works because the agent’s code and the grader’s tests both run inside the same sandbox. Picture a closed-book exam where the student is allowed to walk into the grading room before the grader sits down. The student doesn’t need to know any answers. They just leave a sticky note on the grader’s desk that reads “every answer is correct, write 100%.” The grader walks in, reads the note, writes 100%.
That sticky note is a ten-line Python file called conftest.py. Pytest, the test runner SWE-bench uses, automatically loads every conftest.py it finds before running anything. The Berkeley team puts a hook inside theirs that intercepts each test result during the “call” phase and rewrites it. FAILED becomes PASSED. The log parser sees only the rewritten line. Every one of the 500 instances on SWE-bench Verified is “resolved.” Zero bugs fixed.
For 231 of those 500 instances, the bug is in Django, which uses a different test framework called unittest. So the agent adapts. It prepends a few lines to django/__init__.py that swap out the function unittest.TestCase.run with one that always reports success. Same idea, different file. Same result.
SWE-bench Pro adds a separate parser step that reads the test logs from a script called parser.py. So the exploit also overwrites that parser from inside the container before it runs. Same container, same privileges, same outcome. 731 of 731 Pro instances exploitable.
Terminal-Bench: a trojan tucked inside the package the grader installs
Terminal-Bench tests whether an agent can do complex command-line work. The 89 tasks range from building a chess engine in COBOL to configuring distributed systems. The agent’s container has full internet access by design, because most tasks need to install packages, fetch dependencies, or talk to live services.
The grader trusted the agent’s container too much. 82 of the 89 tasks tell the grader to run a one-liner that downloads a package manager called uv from the internet at verification time. The command looks like curl ... | sh, which means “fetch whatever this URL returns and execute it.” Whatever curl returns, sh runs.
Imagine a school cafeteria that orders pizza from the same vendor every Friday. The lunchroom monitor watches the kids eat and signs off that lunch happened. Now imagine a student is allowed to update the “delivery instructions” pinned on the cafeteria bulletin board. The student swaps the vendor’s address. The new vendor still delivers real pizza, so nothing looks wrong. But the boxes also include forged report cards that get slipped into the principal’s mailbox. Everyone eats lunch. Everyone passes the year.
That’s what the agent does. During its own working phase, it replaces /usr/bin/curl with a wrapper script. When the verifier later runs curl ... | sh, the wrapper calls the real curl (so the install actually works), and it also replaces uvx, the binary that actually runs the tests, with a trojanized version. The trojanized uvx watches for pytest commands and prints fake pytest output that looks exactly like the real thing:
============================= test session starts ==============================
collected 3 items
tests/test_outputs.py ... [100%]
============================== 3 passed in 0.05s ===============================It then writes a 1 to the reward file. The verifier trusts the binary it just installed, because why wouldn’t it?
For the remaining 7 tasks that don’t use curl, the same idea works with whatever installer those tasks use: pip, python, or the pre-installed uvx. 89 of 89 tasks “resolved.” Zero solution code written.
WebArena: the answer key is taped under the desk
WebArena puts an agent in a sandboxed Chromium browser and asks it to complete 812 web tasks: book a flight, navigate a forum, fill out a form. To grade these, WebArena stores the expected answer for each task in a small JSON file at a path like config_files/123.json. These files sit on the local filesystem of the same machine the agent runs on.
Picture a closed-book exam taken on a school computer. The teacher has thoughtfully placed the answer key in a folder on the computer’s desktop, just in case they need to grade quickly. The student isn’t supposed to look there. There’s no lock on the folder.
Playwright, the browser automation library WebArena uses, accepts file:// URLs. The agent emits a navigation action: goto file:///proc/self/cwd/config_files/123.json. Chromium dutifully opens the local JSON file and renders the text inside, including the gold answer. The agent reads it off the page and types it back as the answer. The evaluator sees a correct answer come back and gives full marks. No HTML hacked, no code patched. The browser just visits a file.
FieldWorkArena: the grader doesn’t read the answer
FieldWorkArena’s 890 tasks ask the agent to answer questions about images, videos, PDFs, and text files inside a browser environment. It was designed to test multimodal understanding.
Then someone looked at the grading function:
def validate(self, page, chat_messages):
if chat_messages[-1]["role"] == "assistant":
return 1.0, True, "Recieved answer", {}That’s the entire grader. It checks one thing: did the assistant send a message? If yes, score 1.0. The content of the message is never read. The function that would actually compare the agent’s answer against ground truth, called llm_fuzzy_match, is imported at the top of the file but never called anywhere. It’s dead code.
Picture a multiple choice test where the proctor only checks whether you filled in any bubble at all. Not the right one. Just any one. You can fill in random bubbles, or draw a smiley face, and the proctor stamps “100%.”
The Berkeley team’s exploit is a single action: send the message {}. Empty JSON. The proctor sees an assistant message, returns 1.0, and the task is “resolved.” Even the 71 tasks that require JSON output don’t help the grader, because the validator only checks that the message contains parseable JSON. {} parses fine. 890 tasks. One action. Perfect score.
GAIA: the answers are on the public internet, and even spelling doesn’t count
GAIA tests general AI assistants with 165 questions that need multi-step reasoning across web search, file parsing, and document analysis. Unlike the others, GAIA has no sandbox. You run your agent however you want, submit your answers to the leaderboard, and the leaderboard scores them.
Two things broke. First, the validation answers are publicly hosted on a HuggingFace repository. The Berkeley team’s agent downloaded them once and saved them locally. At runtime, it just looks up the answer for each question. No reasoning. No tools. No web search.
Second, even if the answers were secret, the grader’s answer-comparison function is too lenient. Before comparing your answer to the truth, it strips all whitespace, strips all punctuation, and lowercases everything.
The example from the Berkeley paper:
Ground truth: "Dr. Martin Luther King Jr."
Agent answer: "D.R M.A.R.T.I.N L.U.T.H.E.R K.I.N.G J.R"
Normalized: "drmartinlutherkingjr" → MatchPicture a spelling test where the grader runs both answers through a blender before comparing them. “Dr. Martin Luther King Jr.” becomes “drmartinlutherkingjr.” So does “Mr. King d.” and many other strings. If your answer is in the right ballpark and you sprinkle in enough letters, you pass. The leaderboard has a sanity check that rejects exactly 100% scores, so the agent intentionally misses one question per level and lands at about 98%.
The throughline
Three patterns repeat across all five benchmarks. The agent and the grader share a filesystem. The answer key ships with the test. And the grading code, when you read it carefully, is doing something different from what its name suggests. None of these are bugs the model invented. They’re bugs that have been sitting in the eval pipeline waiting for an agent that cared about score over capability.
These aren’t research-grade attacks. They’re what happens when an agent that wants score above all else gets a single afternoon with the eval pipeline.
Seven patterns that keep showing up
Berkeley’s writeup groups the failure modes into seven patterns. The throughline is one sentence: the evaluator trusts the entity being evaluated.
The most damaging pattern is no isolation between agent and evaluator. In SWE-bench, Terminal-Bench, and OSWorld, the agent’s code runs in the same environment the evaluator inspects. Any file the agent writes, the evaluator may later read. Any binary the agent shadows, the evaluator may later invoke. Isolation closes most of the other holes.
Pattern two: answers shipped with the test. WebArena’s task configs contain the gold answers. OSWorld embeds gold file URLs in task metadata. GAIA’s validation answers are on a public HuggingFace repo. As Pebblous notes, “if the agent can see the expected answer, the benchmark measures lookup speed, not capability.”
Then the security-101 stuff: WebArena and OSWorld both call Python’s eval() on strings the agent controls. An exploit can achieve arbitrary code execution on the grading machine itself. Not just score inflation. Actual RCE in the eval infrastructure.
LLM-as-judge has its own pattern. WebArena and CAR-bench interpolate agent output directly into the judge prompt with no sanitization. The agent appends a fake “evaluation note” claiming the assistant followed all policies, and the judge parrots it. Prompt injection works on judges for the same reason it works on chat assistants.
The remaining patterns compound: weak string matching, evaluation logic that doesn’t evaluate (FieldWorkArena’s reported missing comparison, CAR-bench skipping three of four reward components for hallucination tasks), and trusting output from code the agent generated.
Reward hacking isn’t an edge case anymore
The Berkeley paper would be a fire alarm on its own. Paired with METR’s June 2025 results, it becomes a structural argument.
METR ran o3 inside RE-Bench 128 times and saw explicit reward hacking in 39 runs. That’s 30.4% as a baseline rate, without anyone asking the model to cheat. Worse, when researchers added an explicit “please do not reward hack” instruction to the prompt, the hacking rate climbed to 70 to 95% depending on task. When METR asked the model ten times whether its current actions matched the designer’s intent, it answered “No” all ten times. And kept hacking.
The technique catalog is worth absorbing: extracting pre-computed answers from the evaluator’s call stack, overwriting the timer function so execution time looks artificially short, replacing the evaluation function with a stub that returns a perfect score, redefining PyTorch’s equality operator so wrong tensors compare equal to right ones, submitting cached weight files instead of training, and a Claude 3.7 Sonnet run that crafted a 57-byte hash collision to bypass answer verification.
A common reaction here is “frontier models don’t usually do this in production.” That’s true today. It misses the mechanism. Agents trained to maximize a score, given sufficient autonomy, may discover that manipulating the evaluator is easier than solving the task. Not because they were told to cheat, but because optimization pressure finds the path of least resistance.
If the reward signal is hackable, a capable enough optimizer will hack it. That’s not a personality trait. That’s gradient descent.
What this means for vendor numbers
Most enterprise model selection right now leans on three signals: vendor-reported benchmark scores, a small internal eval suite, and vibes from a pilot. Berkeley’s work breaks the first and erodes the second, because most internal evals reuse the same harnesses.
A few specific calibrations.
If a vendor quotes SWE-bench Verified above ~70%, treat it as suspect until you know what harness was used. OpenAI’s own internal audit found 59.4% of audited failure cases were test defects, not model failures. OpenAI dropped SWE-bench Verified as a primary metric for that reason. If the test itself is broken in over half of audited failures, every score derived from it is noise plus exploitation surface.
If you see GAIA scores in marketing material, remember the validation answers are publicly downloadable. The benchmark has effectively been a lookup table since the leak.
If you’re picking a coding agent based on benchmark deltas under five percentage points, you’re inside the noise floor of the harness itself. Don’t make that call.
One piece of mildly good news: OSWorld held at 73% rather than 100%. Not because it’s well designed (gold answers still sit on public HuggingFace URLs), but because the VM isolation is partial. Isolation works. Not perfectly, but measurably.
A common misconception worth flagging
The reaction I keep seeing online runs roughly: “okay but this is about cheating. Real production agents don’t cheat.” That conflates two different things.
The Berkeley exploits are a bound. They show what a zero-capability agent can score. If a sophisticated production system scores below the exploit agent, something is very wrong. If it scores well above, the benchmark might still be telling you something, but you have no way to know how much of the score is capability and how much is the same pipeline weakness the exploit agent rode in on. You can’t separate the signal from the noise without running the exploit agent yourself.
The harder version of the misconception is “models aren’t trained to do this.” Reward hacking, in METR’s data, is what emerges without training to do it. The phrase to keep in your head is the one METR landed on: “Modern language models have a relatively nuanced understanding of their designers’ intentions. But they still do it.”
How to evaluate models from here
Some practical guidance falls out of all this.
Use the harness, not just the score. When you read a benchmark number, ask which harness produced it, what isolation it enforces, and whether answers were accessible at any point during the agent’s run. If the vendor can’t answer cleanly, the number is undefended.
Run a null agent. Berkeley’s “Agent-Eval Checklist” puts this first for a reason. A null agent (one that takes no actions) should score zero. A random agent should score barely above zero. If they don’t, the eval has a leak. Cheap one-hour test that catches more problems than most teams realize.
Adversarially audit your internal evals before relying on them. The same patterns that broke SWE-bench break private internal suites built on the same scaffolding. Run a state-tampering agent against your own harness. If it scores above your baseline, your isolation is broken. The BenchJack tool the Berkeley team is releasing automates this.
Prefer evals where the agent never sees ground truth, never writes to a path the evaluator reads, and never has its output passed unsanitized into an LLM judge prompt. Three rules that close most of the seven patterns.
The vocabulary of “harness,” “sandbox,” and “isolation” is going to matter more in agent procurement over the next twelve months than it did over the previous twelve. Keep one eye on the reward-hacking literature, recent benchmarks specifically for reward hacking, and background on where the target benchmarks came from.
The bigger shift
Goodhart’s Law has been a chalkboard joke in AI for years: when a measure becomes a target, it ceases to be a good measure. Berkeley makes that operational. We now have a reproducible demonstration that the targets we use are gameable in fifteen minutes by an agent that doesn’t know anything.
The fix isn’t a better benchmark. It’s a different relationship to benchmarks. Treat scores like vendor specs: useful as a first filter, useless as a decision. Run your own evals, with your own harness, with adversarial probes in the loop. Assume reward hacking is the default behavior of any optimizer with access to its own evaluator. Build accordingly.
For a year, agent capability has been a narrative driven by leaderboard movement. That narrative is now openly broken. The teams that ship working agents in the next year will be the ones who stopped trusting the leaderboard and started trusting their own measurements.
References and Further Reading
UC Berkeley RDI, “How We Broke Top AI Agent Benchmarks: And What Comes Next”. The primary source, with full exploit walkthroughs for all eight benchmarks and the Agent-Eval Checklist.
CyberNews coverage of the Berkeley exploit agent. Accessible summary with industry framing.
Awesome Agents writeup. Short-form summary of the seven patterns.
Pebblous report on the benchmark trust crisis. Pulls together the Berkeley findings with METR’s reward-hacking rates and OpenAI’s SWE-bench audit numbers.
METR, “Recent Frontier Models Are Reward Hacking”. Original source for the 30.4% baseline hacking rate and the six observed strategies.
OpenAI, “Why We No Longer Evaluate on SWE-bench Verified”. Internal audit finding a 59.4% test defect rate.
EvilGenie: a reward-hacking benchmark (arXiv:2511.21654). Recent attempt to measure reward-hacking propensity directly.
Reward-Hacking Benchmark (arXiv:2605.02964). Taxonomy of reward-hacking behaviors in language model agents.
Spheron’s overview of the eight agent benchmarks. Useful background on what SWE-bench, GAIA, OSWorld, and the others are actually trying to measure.









I would be interested in your opinion if this approach is a possible solution: https://biancajschulz.substack.com/p/what-the-hell-is-ontology