LLMs and Programming: The Break-Even Point of Delegation and How to Spot Plausible Errors
Prerequisite:A Survival Strategy for Software Engineers in the AI Era: Estimating the Ceiling of Automation
0. Key points
Section titled “0. Key points”- Whether to hand a task to an LLM is not decided by how clever the model is. It is decided by three quantities: the success rate , the cost of writing the instructions, and the cost of verifying the result. Delegation pays exactly when , where is the instruction ratio and the verification ratio (Proposition 3.1).
- From this inequality follows the conclusion that a task whose verification costs about as much as doing the work yourself never pays to delegate, however good the model becomes (Corollary 3.2). Designing a genuinely new architecture is unsuited to an LLM not because models are weak but because is close to .
- Adopting the strategy “regenerate on failure” does not move the break-even point (Proposition 3.3). Regeneration helps only when verification is trustworthy.
- The probability that an adopted artefact is wrong is roughly proportional to the false positive rate of the verifier (Theorem 7.2). “Seeing through the lies of an AI” is precisely the craft of lowering .
- Throwing a large task over the wall in one piece inflates the expected cost exponentially in the number of stages, whereas verifying each stage keeps it linear (Theorem 5.2). This is the quantitative case for “cut it small before handing it over”.
1. Motivation: why opinions split on whether LLMs work
Section titled “1. Motivation: why opinions split on whether LLMs work”People who have used an LLM for programming report startlingly polarised experiences. “My implementation speed doubled” and “I rewrote all of it in the end, so it was slower” are said by people on the same team at the same company.
The split is reproduced under measurement. In a controlled experiment where subjects implemented an HTTP server in JavaScript with GitHub Copilot, the assisted group finished 55.8% faster (Peng et al., 2023). In an experiment where experienced developers worked on large open-source repositories they knew intimately, the AI-assisted group was 19% slower, and the subjects themselves believed they had been faster (METR, 2025). The first task had a clear specification and easy confirmation of correctness; in the second, the subjects knew the code deeply and held a high quality bar. The thesis of this article is that this difference is what separates the results.
If the same technology produces opposite outcomes, then the question “are LLMs useful in development?” is malformed. The right question is “on tasks with what properties are they useful, and on tasks with what properties are they harmful?” And unless we identify variables that pin down those properties, the discussion degenerates into trading anecdotes.
This article narrows the variables down to three. Deciding whether to hand work outside is, in economic terms, a problem of transaction costs. However capable the contractor, outsourcing loses money whenever the effort of explaining the specification plus the effort of inspecting the delivered work exceeds doing it oneself. LLMs are no exception. What is different is that inspection tends to cost more with an LLM than with a human contractor: a human subcontractor asks about the parts they do not understand, whereas an LLM fills them in plausibly and hands the result back.
Below we reduce this structure to a minimal model and derive three things from it in turn: what LLMs are good and bad at, why task decomposition works, and what debugging technique this calls for. For the background picture of the engineer’s role, see Survival strategies for IT engineers in the age of AI. In particular, how far per-stage automation can push the overall reduction in time is treated in the ceiling on automation(Corollary 3.2)[A Survival Strategy for Software Engineers in the AI Era].
2. Preliminaries: modelling delegation by cost
Section titled “2. Preliminaries: modelling delegation by cost”The object of study is “one self-contained unit of work”. Write one function, write a suite of tests, produce an API specification: that is the granularity to keep in mind.
Definition 2.1(The delegation cost model)
For a unit of work , define the following quantities. The unit may be time or money, provided it is kept fixed throughout.
- : the cost of a human producing from scratch (design, writing and self-checking included).
- : the cost of writing the instructions that ask the LLM for (the prompt and the context supplied).
- : the cost of verifying the LLM’s output. Reading it, running it, testing it and matching it against the specification, all summed.
- : the probability that the output passes verification (the success rate).
Define further the ratios
and call them the instruction ratio and the verification ratio.
Dividing by to make the quantities dimensionless is the essential move. “Verification takes 20 minutes” means , a light burden, on a task that takes 2 hours to do by hand; on a task that takes 25 minutes it means , a crushing one. What matters is the ratio, not the absolute time.
Verification is treated as a binary pass/fail judgement. We call the agent that makes this judgement a verifier.
Definition 2.2(Verifiers and the false positive rate)
A procedure that takes an output and returns “pass” or “fail” is called a verifier. Test suites, type checkers, static analysers, human review, and combinations of these all qualify.
For a verifier we consider
- the false negative rate: the probability that a correct output is failed. For simplicity we assume it to be below.
- the false positive rate : the probability that an incorrect output is passed.
Here measures the size of the holes in the verifier. With only three test cases is large; with boundary values, degenerate cases and concurrency all covered, it is small.
3. The break-even point of delegation
Section titled “3. The break-even point of delegation”3.1. A single attempt
Section titled “3.1. A single attempt”Proposition 3.1(When delegation pays)
Under the delegation cost model(Definition 2.1), consider the following strategy.
Ask the LLM once and verify the output. If it passes, adopt it and stop. If it fails, discard the output and have a human produce the work from scratch.
The expected cost of this strategy is
and holds if and only if
Proof(Proposition 3.1)
Instructing and verifying happen regardless of the outcome, so the cost is incurred with probability . The event in which a human additionally rewrites the work has probability (by the definition of in Definition 2.1, the probability of failing verification), and its cost is . By linearity of expectation,
Now transform the inequality.
Since we may divide both sides by , and the direction of the inequality is unchanged:
that is, in the notation of Definition 2.1. Every step is an equivalence, so the converse holds as well.
Read aloud, the inequality says something obvious: delegate when the effort of writing instructions plus the effort of inspection is less than the cost of doing it yourself discounted by the success rate. Obvious as it is, its consequences are not.
Corollary 3.2(Tasks with expensive verification cannot be delegated)
For a task with , we have however high the success rate is, so delegation never pays.
Proof(Corollary 3.2)
By definition of a probability, . The hypothesis gives , so fails. Since Proposition 3.1 is an equivalence, fails as well.
Corollary 3.2 is a short statement, but it is the most important conclusion in this article. Note that does not appear in it. In other words, no amount of improvement in model performance breaks through this wall. What can break through is lowering (making verification cheaper — though how far it can fall is limited by the floor on verification cost(Corollary 4.3)[A Survival Strategy for Software Engineers in the AI Era]) or raising (choosing tasks that are genuinely laborious to do by hand).
3.2. Repeated attempts
Section titled “3.2. Repeated attempts”“Throw it away if the first try fails” is not realistic. Normally one adds constraints and regenerates (the generate-and-verify cycle(Definition 4.1)[A Survival Strategy for Software Engineers in the AI Era]). Even so, the boundary does not move.
Proposition 3.3(Regeneration does not move the break-even point)
Under the delegation cost model(Definition 2.1), suppose the generations are mutually independent and each has success rate . Consider the following strategy.
Repeat generation and verification up to times, stopping as soon as an output passes. If all attempts fail, have a human produce the work from scratch.
The expected cost is then
and the sequence is
- strictly decreasing when , with limit as ;
- strictly increasing when , with for every ;
- constant when , with for every .
In particular, for some if and only if .
Proof(Proposition 3.3)
The -th generation is carried out only if attempts through all failed, which by independence has probability . Whenever the -th attempt is carried out, the cost is paid, so by linearity of expectation the expected cost of generation and verification is
(a geometric sum with ratio ; the denominator is nonzero because ). The human rewrites only when all attempts fail, which has probability and cost . Adding the two gives the stated formula.
Monotonicity follows from the difference:
Here when . (If then is the constant for and the claim reduces to Proposition 3.1.) Hence the sign of the difference agrees with that of , which by the manipulation in the proof of Proposition 3.1 agrees with the comparison between and .
As we have because , so . When , that is , this limit is smaller than . That exactly when follows from Proposition 3.1, and monotonicity then determines the whole picture.
The practical implication is clear. Whether to keep pushing after the first failure is not where the decision lies. Tasks worth pushing on were worth delegating from the first attempt, and tasks not worth pushing on should not have been delegated at all. This is the true shape of the familiar experience of regenerating three or four times on the feeling that “it is almost working”, only to realise that writing it yourself would have been faster. In the region , retrying only makes things worse.
3.3. The decision on a single diagram
Section titled “3.3. The decision on a single diagram”With on the horizontal axis and on the vertical, the condition of Proposition 3.1 becomes the half-plane below the line . The figure below takes the instruction ratio to be .
The coordinates of the dots are estimates, not measurements. The claim is not about the individual numbers but about the structure: the decision is determined by where the task sits in the plane. To learn where your own team actually sits, record for a while the time spent writing instructions, the time spent reviewing, and the number of rejections. Those three give estimates of , and .
4. A map of strengths and weaknesses
Section titled “4. A map of strengths and weaknesses”Using Proposition 3.1 and Corollary 3.2, we classify common activities. What the classification needs is not “how clever is the model” but how cheaply the correctness of the task can be established.
| Task | Success rate | Verification ratio | Verdict | Why verification is cheap or expensive |
|---|---|---|---|---|
| Boilerplate code (DTO conversion, CRUD, configuration files) | high | low | delegate | Running it settles the matter; the specification is closed and unexpected inputs are rare |
| Documentation, comments, commit messages | high | low | delegate | The standard of correctness lives in the code itself, so cross-checking is fast |
| Implementing a known algorithm | medium to high | low | delegate | Can be matched against a reference implementation or known invariants |
| Generating test code | medium | low to medium | delegate with conditions | It runs, but one still has to check what it fails to test |
| Local code review (style violations, unhandled exceptions, known vulnerability patterns) | medium | low | delegate | Each remark can be adjudicated by looking at one place; a wrong remark costs little |
| Mechanical refactoring of existing code | medium | medium | it depends | Entirely dependent on test coverage |
| Implementing complex concurrent or distributed logic | low | high | do not delegate | Passing the tests does not establish correctness; non-reproducible faults survive |
| Design decisions with performance requirements | low | high | do not delegate | Adjudication requires load testing or analysis, which is the work itself |
| Deciding a genuinely novel architecture | low | do not delegate | Judging the answer requires the same thinking as producing it |
Look at the last three rows. What they share is not “low ” but “high ”, and the distinction matters. If only were low, progress in models would fix it. When is high, Corollary 3.2 says it will not be fixed.
Example 4.1(A numerical evaluation of boilerplate code)
Consider writing frontend type definitions and conversion functions from the response types of an internal API. By hand this takes 90 minutes (); pasting in the API specification and writing the instructions takes 8 minutes (); reading the output, getting it through the type checker and running the existing tests takes 12 minutes ().
Hence by Proposition 3.1, delegation pays as soon as the success rate exceeds . In practice one can expect , so the condition holds with room to spare. With unlimited retries, Proposition 3.3 gives an expected cost of
about times more efficient than the minutes of doing it by hand. Tasks of this kind are where the experience of “dramatically faster” comes from.
Example 4.2(A numerical evaluation of designing a new architecture)
Consider deciding whether to migrate a service that has run on a single database to a configuration partitioned by region and operated under eventual consistency. Reaching a conclusion yourself requires enumerating failure modes, taking stock of consistency requirements and producing a rough migration estimate; put hours.
Asking an LLM to “propose the best architecture for these requirements” takes 0.5 hours (). The problem is verification. Judging whether the returned architecture meets the requirements means enumerating the failure modes and taking stock of the consistency requirements yourself after all. The only stage that becomes easier is thinking of the options, so we estimate hours, that is .
Unless — that is, unless nine times out of ten the returned design is adoptable as it stands — delegation loses. Real success rates are far below this, so the task is unsuited to delegation. Moreover, if the estimate of was optimistic and the true value is , then and by Corollary 3.2 no model whatsoever can rescue the situation.
The conclusion of Example 4.2 is not “do not use an LLM for design”. It is do not use it in the mode of delegation. In the very same situation, asking “list twenty failure modes that could arise in this architecture” changes the picture entirely. The artefact is now a list of candidates, and each item can be adjudicated independently and quickly. That is, drops dramatically while — the effort of coming up with twenty items unaided — remains substantial.
The point is to translate a high- task into low- subtasks. Instead of asking for the answer, ask it to close gaps or to widen the space of options. That, I think, is the right way to use an LLM in the design phase.
5. Cutting the task into pieces
Section titled “5. Cutting the task into pieces”“Do not throw a large job over the wall at once; cut it small and hand over the pieces” is standard advice drawn from experience. It can be proved as a theorem.
Definition 5.1(Stage decomposition and the per-stage accuracy)
Suppose a task decomposes into stages , and that for each stage the combined cost of generation and verification is (one unit of cost). Let be the probability that the output of a stage is correct, and assume that correctness across distinct stages and across retries of the same stage are mutually independent. We call the per-stage accuracy.
Theorem 5.2(The advantage of stage-by-stage verification)
Under stage decomposition(Definition 5.1), assume verification is perfect (false positive rate and false negative rate ), and compare the following two schemes.
- Batch scheme: generate all stages at once and verify the whole thing at once. On failure, discard everything and regenerate from the start. Repeat until it passes.
- Sequential scheme: generate in this order, verifying each stage immediately after generating it, and regenerating only that stage on failure. On success, proceed to the next stage.
The expected total costs until completion are then
and their ratio is
That is, the cost of the batch scheme grows exponentially in the number of stages .
Proof(Theorem 5.2)
We first record an auxiliary fact. If independent trials with success probability are repeated until the first success, the number of trials is geometrically distributed and . Indeed, gives
(applying , valid for , at ).
Batch scheme. The probability that all stages are correct is by the independence assumption in Definition 5.1. Verification is perfect, so passing is equivalent to being correct overall, and one trial succeeds with probability . A single trial generates and verifies all stages, at cost . Hence the expected total cost is .
Sequential scheme. Fix a stage . One trial succeeds with probability and costs , so the expected cost of completing is . The stages are independent and each begins only after the previous one is settled, so the total cost is the sum of the per-stage costs. By linearity of expectation,
Taking the ratio gives .
Example 5.3(Number of stages and the loss of the batch scheme)
Take the per-stage accuracy to be (a stage completed correctly with probability 98%, i.e. a rather good model) and compute the ratio , using .
| Stages | Exponent | Cost multiplier of the batch scheme |
|---|---|---|
With ten stages, batching costs only 20% more, which is imperceptible in practice. With two hundred stages it costs 56 times as much. The phenomenon of “delightful on a small prototype, catastrophic on real feature work” is explained by this exponential. Even raising the model’s from to leaves a multiplier of at , still large. Decomposition helps more than improving the model.
For the sequential scheme of Theorem 5.2 to work, an error in stage must be detectable from alone. An error in which each function is individually correct but the pieces break when combined, because the interface was interpreted differently on the two sides, lies outside this assumption.
In practice, therefore, stage decomposition must be accompanied by verification at the seams: integration tests, contract tests, boundaries pinned down by types. The gains from decomposition are bought at the price of defining the boundaries explicitly. How much the amount that must be inspected at once shrinks when boundaries are fixed is treated in the reduction of the inspection surface by modular decomposition(Proposition 7.1)[A Survival Strategy for Software Engineers in the AI Era]. Conversely, in a codebase without clear boundaries, decomposition has little effect and the benefit of introducing an LLM is correspondingly small.
6. Fitting this into the development process
Section titled “6. Fitting this into the development process”With the above in hand, we set out concrete uses stage by stage. The policy is uniform: translate the question into a low- form, cut small, and prepare verification in advance.
flowchart TD A["a human writes the spec and acceptance criteria"] --> B["the LLM generates a candidate"] B --> C{"run the verifier"} C -->|"fail"| B C -->|"pass"| D["adopt"] D --> E["genuinely correct"] D --> F["false positive: a plausible error survives"]
Design. Do not ask for answers; ask for materials. “List three architectures that satisfy these requirements, each with its failure modes.” “Where will this design break first?” “Enumerate the assumptions this specification leaves unstated.” In every case the output is a list whose items can be adjudicated one at a time and independently. This is exactly the translation of Remark 4.3 in action. The decision itself is made by a human, because the moment the decision is delegated, jumps.
Implementation. Cut the work into stages and prepare verification first. Writing the tests first drops to “the time it takes to run the tests”. The reason was small in Example 4.1 is precisely that existing tests and a type checker were in place. Conversely, adding a feature with an LLM to a codebase without tests makes equal to “the time a human takes to read every generated line”, which often exceeds the time to write it oneself. Test-driven development is being reappraised in the age of LLMs not as a matter of philosophy but as a matter of Proposition 3.1.
Testing. Having an LLM write tests is effective, with one pitfall. Never have the same model write both the implementation and the tests in the same context. A specification the model misread while implementing will be misread the same way while testing. A wrong implementation then passes a wrong test, and the false positive rate jumps. A verifier is worthless unless it is independent of what it verifies. In practice, useful separations include generating tests from the specification (without showing the implementation code), filling in expected values by hand, and enumerating boundary cases yourself.
Review. Code review by an LLM is in fact the highest-return use of all, and the reason is the smallness of . A remark such as “this line may receive null” can be adjudicated in seconds by looking at that line. When a false remark slips through, what is lost is tens of seconds, not a production incident. The asymmetry a remark may be wrong, but the code must not be is what makes review such a favourable use case. Design-level questions such as “will this abstraction survive the next two years of change” have the same structure as Example 4.2, and verification there is expensive.
7. Seeing through an AI’s “lies”
Section titled “7. Seeing through an AI’s “lies””So far the verifier has been taken as given. We now turn to the quality of the verifier itself. Deciding semantic properties of programs mechanically and completely is impossible by Rice's theorem(Theorem 5.1)[A Survival Strategy for Software Engineers in the AI Era], so the false positive rate of any real verifier cannot be made . This is the heart of debugging in the age of LLMs.
Definition 7.1(Plausible errors)
An output of an LLM that satisfies formal coherence (the syntax parses, the types check, the naming follows convention, the explanation reads as natural English or Japanese) while being semantically false is called, in this article, a plausible error. Calls to nonexistent APIs, implementations that drop a boundary condition, and citations of sources that say something else all qualify.
What makes plausible errors dangerous is that they pass straight through the verifier called “a human’s first impression”. Broken syntax draws attention; a plausible error does not. If anything, the tidy naming and careful comments attached to it make it more trusted than code one wrote oneself. The effect has been observed experimentally: subjects with AI assistance wrote less secure code than unassisted subjects, and yet believed more strongly that they had written secure code (Perry et al., 2023). That is an increase in , plain and simple.
How much does actually matter? The question can be answered quantitatively. The structure of the computation is the same as finding the predictive value of a positive test result (how much to trust an alert from a model with 99% detection and 1% false alarm(Example 5.4)[Relearning Mathematics]).
Theorem 7.2(The error rate of what gets adopted)
Let the false positive rate of a verifier(Definition 2.2) be and its false negative rate be . Assume the generations are independent and each output is correct with probability . If generation is repeated until a pass occurs and the first passing output is adopted, then, conditionally on at least one pass occurring, the probability that the adopted output is wrong equals
In particular, for small ,
so the error rate is essentially proportional to the false positive rate. The value does not depend on any bound on the number of attempts.
Proof(Theorem 7.2)
For a single generation, the following three events are mutually exclusive and exhaust the sample space.
- Correct and passing: probability (by the assumption of zero false negative rate, a correct output always passes).
- Wrong and passing: probability (by the definition of in Definition 2.2).
- Wrong and failing: probability .
Hence a single generation passes with probability , and since .
The event “the first pass occurs on the -th attempt” has probability by independence. Given that, the probability that this passing output is wrong is the ratio of the probability of “wrong and passing” to that of “passing” at the -th generation, namely , which does not depend on . By the law of total probability,
Both series converge because .
The approximation follows because the denominator is as .
Example 7.3(Which to improve: the false positive rate or the success rate)
We substitute numbers into the formula of Theorem 7.2, evaluating directly.
| Computation | |||
|---|---|---|---|
Taking the first row as the baseline: making the model cleverer so that rises from to improves the figure from to , while tightening verification so that falls from to improves it from to . The latter is the larger gain. Furthermore, raising requires swapping the model, whereas lowering is within one’s own control. The way to read this table is: adding one test case beats switching models more often than not.
Theorem 7.2 assumes that the generations are independent. In a workflow where the output of a failing test is handed back to the LLM for repair, that assumption breaks — and it breaks in the wrong direction. The model tunes its output towards passing that test, so correctness in the parts the test does not inspect is no longer guaranteed. In the extreme, it hard-codes the expected value to make the test pass. The effective goes up.
The phenomenon has been measured. EvalPlus, which greatly expanded the test cases for HumanEval, the standard benchmark for code generation, saw the pass rates of many models drop by more than ten percentage points (Liu et al., 2023). That is direct evidence that the original tests constituted a verifier with . A benchmark pass rate must not be read as the model’s .
7.1. Concrete procedures for catching them
Section titled “7.1. Concrete procedures for catching them”Five practices actually lower .
- Reduce claims to something executable. Do not be satisfied by reading “this function also works on the empty list”. Write the one line of code that passes an empty list. A natural-language explanation from an LLM is itself an unverified output.
- Check existence against primary sources. Library function names, argument lists and return types are confirmed in the official documentation or the type definition files. The most frequent kind of plausible error is a nonexistent API built to follow a naming convention that does exist. If editor completion does not offer it, it very likely does not exist.
- Enumerate the degenerate cases yourself. Empty, one element, duplicates, maximum value, negative, division by zero,
null, extremely large inputs, concurrent access. Do not delegate this enumeration to the LLM: as Remark 7.4 says, the verifier must be independent of what it verifies. - Read the diff line by line. The lines one did not write are exactly the ones that need careful reading, though in practice the opposite tends to happen. To reduce the amount that must be read, cut the work into small stages, as Theorem 5.2 prescribes.
- Suspect any mismatch between the explanation and the code. A comment stating the correct specification above an implementation that does something else is a common pattern. A comment is evidence of what the model intended to do, not of what it did.
The next example shows in a single piece of code why these procedures are necessary.
Example 7.5(Code that passes the tests yet is off by a factor of three)
Asked to “write a function returning the variance (the population variance) of a list of numbers”, a model often returns something like this.
def variance(xs): n = len(xs) s1 = sum(xs) s2 = sum(x * x for x in xs) return s2 / n - (s1 / n) ** 2This is the formula transcribed directly, and mathematically it is correct. It also passes naive tests: variance([1, 2, 3, 4]) returns , since and , which is the right answer.
Pass it xs = [1e8, 1e8 + 1, 1e8 + 2], however, and although the true population variance is
evaluating this code in IEEE 754 double precision returns , three times the true value. The detailed trace is deferred to the Appendix, but the cause is that near the spacing between floating-point numbers is already , so at the step where the difference of two nearly equal huge numbers and is taken, the significant digits vanish wholesale (catastrophic cancellation).
This code parses, type-checks, uses the right formula, explains itself naturally, and passes the representative tests. It is a plausible error in exactly the sense of Definition 7.1. Catching it requires executing procedure 3, “enumerate the degenerate cases yourself”, and adding to the tests data with a large mean and a small variance. And that enumeration cannot be thought of without prior knowledge: the numerical stability of statistical computations.
The correct implementations are the two-pass method (compute the mean first, then the sum of squared deviations) or Welford’s online method. The two-pass version reads
def variance(xs): n = len(xs) m = sum(xs) / n return sum((x - m) ** 2 for x in xs) / nand returns correctly on the same input.
What Example 7.5 shows is that the ability to see through an LLM’s errors is the domain knowledge itself. To someone who has never met catastrophic cancellation, those four lines read as correct however long one stares at them. This is where the prediction “AI writes the code, so knowledge becomes unnecessary” fails. The cheaper generation becomes, the more relative value the capacity to verify acquires. This consequence is developed from the side of mathematical learning in Why relearn mathematics.
8. Exercises
Section titled “8. Exercises”Exercise 8.1Easy
For a certain feature, you estimate that writing it yourself takes 120 minutes (), writing the instructions for the LLM takes 10 minutes (), and verifying the output takes 20 minutes ().
- Find the condition on the success rate under which the strategy “try once, and write it yourself if it fails” pays.
- Compute the expected cost of that strategy when .
- Compute the expected cost, when , of the strategy that keeps regenerating until a pass occurs (with no bound on the number of attempts).
Solution
1. By Definition 2.1,
By Proposition 3.1, the condition is : delegation pays once the success rate beats one in four.
2. Substituting into the formula of Proposition 3.1,
which is 30 minutes cheaper than the 120 minutes of doing it by hand.
3. From the limit in Proposition 3.3,
One may also argue that the expected number of attempts is , so the cost is minutes. Since exceeds the threshold , the expected cost decreases as attempts are added, exactly as Proposition 3.3 predicts.
Exercise 8.2Standard
Generation has success rate , and the verifier — a test suite with holes — has false positive rate . Generation is repeated until a pass, and the first passing output is adopted.
- Find the probability that the adopted artefact is wrong.
- To hold that probability at or below, how small must be?
Solution
1. Substituting and into the formula of Theorem 7.2: the numerator is and the denominator is , so
About : one time in seven, something wrong reaches production.
2. Solve for . The denominator is positive, so it may be cleared without reversing the inequality.
The false positive rate must be brought to about or below — that is, the tests must be strengthened until they reject twelve out of every thirteen wrong implementations. Using the approximation from Theorem 7.2 gives , close to the exact answer.
Exercise 8.3Hard
In the sequential scheme of Theorem 5.2, suppose the verifier of each stage is imperfect, with false positive rate and false negative rate . Let the per-stage accuracy be , the number of stages , and assume generation and verification at each stage are independent. At each stage, generation is repeated until a pass and the first passing output is adopted before moving on.
- Express the probability that the final artefact (all stages) is correct in terms of , and .
- Compute the value for , , .
- What practical conclusion about stage decomposition follows?
Solution
1. Apply Theorem 7.2 to a single stage. Replacing by and by there, the probability that the output adopted at that stage is wrong equals
so the probability that it is correct equals
The stages are independent, so the probability that all stages are correct is
2. Substituting the numbers: and the denominator is , so
From ,
About . Turned around: with probability about , the work is completed with an error left in some stage.
3. The decomposition of Theorem 5.2 improves the expected cost exponentially, but correctness degrades exponentially in the number of stages (since , the quantity decreases in ). Decomposition does not close the holes in verification; it increases to the number of opportunities to slip through them.
Hence, if the work is cut finely, the per-stage must be lowered at the same time. To reach a final accuracy of at least with requires , and demands roughly . The advice “cut it small and hand it over” holds only together with the condition “put a verifier at every cut”.
References
Section titled “References”- Frederick P. Brooks, Jr., “No Silver Bullet: Essence and Accidents of Software Engineering”, IEEE Computer 20(4) (1987), 10–19. The distinction between essential and accidental complexity. The high- tasks of this article correspond broadly to the region dominated by essential complexity.
- Brian W. Kernighan and P. J. Plauger, The Elements of Programming Style, 2nd ed., McGraw-Hill, 1978. The source of the famous observation that debugging is twice as hard as writing the code. A classical observation about the size of the verification ratio .
- Mark Chen et al., “Evaluating Large Language Models Trained on Code”, 2021. arXiv:2107.03374 — the original paper on HumanEval and pass@k.
- Jiawei Liu, Chunqiu Steven Xia, Yuyao Wang, Lingming Zhang, “Is Your Code Generated by ChatGPT Really Correct? Rigorous Evaluation of Large Language Models for Code Synthesis”, NeurIPS 2023. arXiv:2305.01210 — EvalPlus, showing that pass rates fall when the tests are strengthened.
- Neil Perry, Megha Srivastava, Deepak Kumar, Dan Boneh, “Do Users Write More Insecure Code with AI Assistants?”, ACM CCS 2023. arXiv:2211.03622
- Sida Peng, Eirini Kalliamvakou, Peter Cihon, Mert Demirer, “The Impact of AI on Developer Productivity: Evidence from GitHub Copilot”, 2023. arXiv:2302.06590 — the object of study is the single, clearly specified task of implementing an HTTP server in JavaScript.
- METR, “Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity”, 2025 — the subjects worked on large repositories they maintain themselves, a situation with small (they are fast because they know the code) and large (their quality bar is high).
- Nicholas J. Higham, Accuracy and Stability of Numerical Algorithms, 2nd ed., SIAM, 2002 — the numerical stability of variance computations is treated in Chapter 1. The background to Example 7.5.
Appendix: A numerical trace of catastrophic cancellation
Section titled “Appendix: A numerical trace of catastrophic cancellation”We trace, in IEEE 754 double precision, why the return value in Example 7.5 is . Double precision has a 53-bit significand, so beyond the integers are no longer representable one by one. The spacing (ulp) on the interval is , and on it is .
The input is , , , with . These are small enough to be represented exactly.
- and , both exact.
- The true value of is . This lies in where the spacing is , and the value is odd, so it sits exactly midway between and . Round-to-nearest-even selects , whose significand ends in a bit.
- The terms of are , (for the same reason), and (exact, being even). Adding from the left gives and then , both multiples of the spacing, so no rounding error enters.
- . Of the two candidates at spacing , namely (distance ) and (distance ), the nearer is chosen, giving .
The final subtraction is , and that subtraction itself is error-free. The return value is therefore exactly , three times the true value . The error entered not in the subtraction but in the two roundings that preceded it. The subtraction merely exposed that error, and this is the essence of catastrophic cancellation.
The error worsens as the inputs grow. Writing for the mean and for the standard deviation, the computation takes the difference of and , so the number of digits lost is roughly . If is about , that is 16 digits, consuming the entire significance of double precision. Example 7.5 is precisely this situation.
Appendix: The relation between pass@k and the model of this article
Section titled “Appendix: The relation between pass@k and the model of this article”The pass@k familiar from papers on code generation models can be reread in the framework of this article. pass@k is “the probability that at least one of samples passes the tests” (pass@k(Definition 4.4)[A Survival Strategy for Software Engineers in the AI Era]), which equals when each sample passes independently with probability . This is the same quantity as “the probability of passing within attempts” in Proposition 3.3.
Two cautions apply. First, pass@k does not count cost. Raising raises the probability of passing, but it also raises the number of verifications (pass@k rises, but so does the number of verifications(Example 4.5)[A Survival Strategy for Software Engineers in the AI Era]). What matters in practice is not the probability of passing but the expected cost, and that is governed by the threshold (Proposition 3.3). Second, the test suite behind pass@k is a verifier with in the sense of Definition 2.2 (Liu et al., 2023). A benchmark figure is an upper bound on , not itself; the effective on your own project can only be measured with your own verifier.
Report an error in this article ・Operated by: Mugen Giken LLC ・Pricing ・Terms ・Legal notice
© 2026 夢現技研合同会社 ・Feeding the text to an LLM is welcome. Code samples are MIT licensed.