Majority vote (default)
All steps
Parts of this pattern
- Code Input / output
- The code snippet to audit for an exploitable vulnerability.
- Voter 1 LLM call
- First independent voter: audits the snippet, reasons step by step and ends with VERDICT: vulnerable or safe.
- Voter 2 LLM call
- Second independent voter: gets the same snippet and reasons on its own, so its answer can differ.
- Voter 3 LLM call
- Third independent voter: also audits the same snippet separately and may disagree with the others.
- Tally Aggregator
- Plain code, not a model: counts verdicts and returns the majority, or 'needs human review' without one.
- Verdict Input / output
- The winning verdict, or 'needs human review' when no answer gets a majority.
- Code → Voter 1
- The same snippet goes to voter 1 in the audit prompt, sampled at temperature 0.8.
Decide whether the code below contains an exploitable vulnerability. <code>query = 'SELECT * FROM users WHERE id=' + uid</code>
- Code → Voter 2
- An identical copy goes to voter 2, also at temperature 0.8; voters share nothing.
Decide whether the code below contains an exploitable vulnerability. <code>query = 'SELECT * FROM users WHERE id=' + uid</code>
- Code → Voter 3
- An identical copy goes to voter 3 at temperature 0.8; only sampling makes its answer differ.
Decide whether the code below contains an exploitable vulnerability. <code>query = 'SELECT * FROM users WHERE id=' + uid</code>
- Voter 1 → Tally
- Voter 1's reasoning and final verdict line go to the tally.
The uid value is concatenated into the SQL string with no escaping, so it is injectable. VERDICT: vulnerable
- Voter 2 → Tally
- Voter 2's reasoning and final verdict line go to the tally.
String concatenation into a query lets an attacker alter it. VERDICT: vulnerable
- Voter 3 → Tally
- Voter 3's reasoning and final verdict line go to the tally; this one dissents.
No exploit shown without knowing how uid is built. VERDICT: safe
- Tally → Verdict
- The majority verdict leaves the tally as the final answer.
vulnerable
LLM picks
For free-form answers that never match exactly, an LLM reads all N candidates and picks the one most consistent with the rest.
All steps
Parts of this pattern
- Code Input / output
- The code snippet that needs a written security finding, not just a yes or no.
- Sample 1 LLM call
- First independent sample: writes a full one-paragraph finding for the snippet.
- Sample 2 LLM call
- Second independent sample of the same prompt; its wording differs even when its conclusion agrees.
- Sample 3 LLM call
- Third independent sample; a real run often uses five or more.
- Selector LLM call
- An LLM that reads every candidate and picks the one most consistent with the rest, answering with its number only.
- Finding Input / output
- The selected candidate, returned word for word as it was sampled.
- Code → Sample 1
- The snippet goes to the first sample in the finding prompt.
You are a security reviewer. Write a one-paragraph finding... <code>query = 'SELECT * FROM users WHERE id=' + uid</code>
- Code → Sample 2
- An identical copy goes to the second sample at the same time.
You are a security reviewer. Write a one-paragraph finding... <code>query = 'SELECT * FROM users WHERE id=' + uid</code>
- Code → Sample 3
- An identical copy goes to the third sample at the same time.
You are a security reviewer. Write a one-paragraph finding... <code>query = 'SELECT * FROM users WHERE id=' + uid</code>
- Sample 1 → Selector
- Candidate 1, a full paragraph, goes to the selector.
SQL injection: uid is concatenated into the query, so '1 OR 1=1' returns every user. Use a parameterized query.
- Sample 2 → Selector
- Candidate 2 goes to the selector.
The query is built by string concatenation with uid, allowing SQL injection (e.g. uid = "1; DROP TABLE users"). Bind uid as a parameter instead.
- Sample 3 → Selector
- Candidate 3 goes to the selector; this one reaches a different conclusion.
Nothing is exploitable here unless uid comes from user input, which the snippet does not show.
- Selector → Findingpick
- The selector names one candidate, and that candidate is returned unchanged.
Response 2
Model ensemble
Different models answer the same question; a ranker compares their answers in pairs and a fuser merges the best ones into one.
All steps
Parts of this pattern
- Question Input / output
- The question to answer, such as 'How should we store user passwords?'.
- Model A LLM call
- The first of several different models, each answering the same question independently.
- Model B LLM call
- A second, different model; its strengths and blind spots differ from model A's.
- Model C LLM call
- A third, different model, run in parallel with the others.
- Ranker Evaluator
- Compares the answers two at a time, in both orders, and scores each by its wins.
- Fuser LLM call
- Merges the top-ranked answers into one, keeping what they get right and dropping what they get wrong.
- Answer Input / output
- The single fused answer.
- Question → Model A
- The question goes to model A.
How should we store user passwords?
- Question → Model B
- The same question goes to model B at the same time.
How should we store user passwords?
- Question → Model C
- The same question goes to model C at the same time.
How should we store user passwords?
- Model A → Ranker
- Model A's answer goes to the ranker.
Hash them with bcrypt at cost 12 and a per-user salt; never store plain text.
- Model B → Ranker
- Model B's answer goes to the ranker.
Use Argon2id with a unique salt per user and tune memory cost to about 64 MB; rehash on login when parameters change.
- Model C → Ranker
- Model C's answer goes to the ranker.
Encrypt them with AES-256 and keep the key in a vault.
- Ranker → Fusertop 2
- The two highest-scoring answers go to the fuser, best first.
Scores: B 2 wins, A 1 win, C 0 wins. Fusing B then A.
- Fuser → Answer
- The fused answer is returned.
Hash passwords with Argon2id (or bcrypt at cost 12 if Argon2 is unavailable), with a unique salt per user; rehash on login when parameters change. Never encrypt or store plain text.
← → neighboursesc atlas
Parallelization: Voting
Also known as Self-consistency · Ensembling · Majority vote
Run the same task N times, or with N different prompts, and take the majority or consensus answer.
Majority vote: Introduced by Wang et al. (2022) · Google Research & Brain Team
Self-consistency (ICLR 2023): sample several reasoning paths and take the most common final answer. Anthropic popularized the "voting" framing in 2024.
LLM picks: Introduced by Chen et al. (2023) · Google
Universal self-consistency: the model itself selects the most consistent response, which extends voting to open-ended outputs such as summaries and code.
Model ensemble: Introduced by Jiang et al. (2023) · AI2, USC and others
LLM-Blender (ACL 2023): a pairwise ranker (PairRanker) picks the top candidates and a generative fuser (GenFuser) merges them. The paper trains a small ranker and fuser; here both are prompted LLMs.
Measured over one run
Majority vote
- Nodes
- 6. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 3. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 0. Messages sent to a tool node in the first scenario.
- Steps
- 4. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 1. Distinct example runs you can switch between on the diagram.
- Loop
- no. Whether the flow cycles back on itself until a condition is met.
- Parallel
- yes. Whether two or more messages are in flight at the same time.
- Branch
- no. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- low. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- high. Relative token spend per request.
- Latency
- low. Relative wall-clock time per request.
LLM picks
- Nodes
- 6. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 4. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 0. Messages sent to a tool node in the first scenario.
- Steps
- 4. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 1. Distinct example runs you can switch between on the diagram.
- Loop
- no. Whether the flow cycles back on itself until a condition is met.
- Parallel
- yes. Whether two or more messages are in flight at the same time.
- Branch
- no. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- low. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- high. Relative token spend per request.
- Latency
- low. Relative wall-clock time per request.
Model ensemble
- Nodes
- 7. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 5. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 0. Messages sent to a tool node in the first scenario.
- Steps
- 4. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 1. Distinct example runs you can switch between on the diagram.
- Loop
- no. Whether the flow cycles back on itself until a condition is met.
- Parallel
- yes. Whether two or more messages are in flight at the same time.
- Branch
- no. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- low. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- high. Relative token spend per request.
- Latency
- low. Relative wall-clock time per request.
Counted from the first scenario's timeline when the site is built.
Problem
A single model answer is one sample from a distribution. Ask whether a snippet of code is exploitable and the model may say yes on one run and no on the next, each time with a confident-sounding explanation. For high-stakes judgments, one roll of the dice is not enough, and a plausible-sounding reason is not evidence.
How it works
Run the same task several times and compare the answers. The code snippet goes to voter 1, voter 2 and voter 3 at once. They can be the same prompt sampled at a nonzero temperature, or different prompts and personas that approach the question from different angles. Each reasons independently, so their mistakes are less likely to line up.
The answers return at different times. In the diagram two voters say A and one says B. The tally counts the votes, and the winning answer becomes the verdict. For free-form answers, the tally needs a way to decide that two phrasings mean the same thing, which is why the prompts end with a fixed verdict line.
This is the idea behind self-consistency: sample several reasoning paths and take the most common final answer, rather than trusting the first.
Two variants replace the tally. When the answers are paragraphs that never match word for word, an LLM can read every candidate and pick the one most consistent with the rest. And instead of sampling one model several times, you can ask several different models, rank their answers against each other in pairs, and fuse the best ones into a single answer.
When to use
- Mistakes are costly and a wrong single answer is worse than a slower, pricier right one.
- Answers can be compared, such as a label, a number or a yes/no.
- You want confidence, not just an answer. Disagreement itself is a signal worth acting on.
When to avoid
- The task has open-ended output like an essay, where there is nothing to count.
- Errors are systematic. If the model misunderstands the question the same way every time, three votes just repeat the mistake.
- The budget is tight. You pay for every voter.
Trade-offs
Voting trades money for reliability. Cost grows linearly with the number of voters, while latency stays close to a single call because they run in parallel. Accuracy improves with more voters, but with diminishing returns, and three to five is usually the useful range. Use an odd count to avoid ties, or decide in advance what a tie means.
Failure modes
- Correlated errors: voters from the same model with the same prompt often fail together. Vary prompts, personas or models to decorrelate them.
- Unclear tally: “vulnerable in one path” and “partially unsafe” do not match. Force a fixed answer format.
- Ties and splits: with no majority, the code must do something sensible, such as escalating to a person.
- False confidence: a 3-0 vote feels certain but is only as good as the voters. Measure accuracy against labelled examples.
Build it with your AI
Majority vote
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the Parallelization: Voting pattern in this codebase, using the LLM client and language we already use.
## Goal
Decide whether a code snippet is exploitable by asking several independent model calls and returning the majority verdict, or 'needs human review' when there is none.
## How it works
1. Send the snippet to N independent calls at once (default 3) with the Vulnerability audit prompt, sampled at a nonzero temperature; to vary the angle, swap some for the Alternate-perspective prompt with a different persona.
2. Give no call another's output; each one reasons on its own.
3. From each reply, read the last line and accept it only if it is exactly "VERDICT: vulnerable" or "VERDICT: safe". Any other reply is an abstention, not a vote.
4. Count the votes in plain code. If one verdict has more than half of all N calls, return it with the counts and every voter's reasoning.
5. Otherwise return "needs human review" with the counts and the reasoning, so a person sees the disagreement.
## Prompts
### Vulnerability audit prompt
```markdown
Decide whether the code below contains an exploitable
vulnerability. Reason step by step, then end with a final line
of exactly "VERDICT: vulnerable" or "VERDICT: safe".
<code>{{snippet}}</code>
```
### Alternate-perspective prompt
```markdown
You are a {{persona}} reviewing the code below for exploitable
vulnerabilities. Judge only what the code shows, not what it
might be used for. End with "VERDICT: vulnerable" or "VERDICT: safe".
<code>{{snippet}}</code>
```
## Stop rule
One round: N calls, one tally, done. No call is re-sampled to break a tie; a split goes to a person.
## Requirements
- Make N (default 3, odd) and the temperature (default 0.8) parameters.
- Count a majority against all N calls, abstentions included, so one valid vote among failures cannot win.
- If a call errors, retry it once, then count it as an abstention.
- Log every voter's reasoning and verdict next to the final tally, so a wrong majority can be studied.
- Add a test with a stub LLM that returns vulnerable, vulnerable, safe; assert the result is vulnerable with counts {vulnerable: 2, safe: 1}, and that vulnerable, safe plus one malformed reply gives needs human review.
LLM picks
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the Parallelization: Voting pattern (LLM picks variant) in this codebase, using the LLM client and language we already use.
## Goal
Produce a written security finding for a code snippet by sampling several independent findings and having an LLM select the one most consistent with the others.
## How it works
1. Send the snippet to N independent calls at once (default 5) with the Finding prompt, sampled at a nonzero temperature.
2. Number the replies 1 to N; drop any that are empty or errored after one retry.
3. Send all the numbered candidates to one more call with the Selection prompt, which picks the one most consistent with the majority.
4. Parse the selector's reply into a candidate number. If it is not a valid number in range, retry the selector once, then fall back to candidate 1 and mark the result unselected; every candidate is an independent sample, so the first is as good a default as any.
5. Return the chosen candidate verbatim, with its number and all the candidates for audit.
## Prompts
### Finding prompt
```markdown
You are a security reviewer. Write a one-paragraph finding for
the code below: what is exploitable, how an attacker would use
it, and the fix. If nothing is exploitable, say why.
<code>{{snippet}}</code>
```
### Selection prompt
```markdown
I have generated the following responses to the same question:
{{#each candidates}}
Response {{number}}: {{text}}
{{/each}}
Evaluate these responses and select the one most consistent
with the majority. Answer with only: "Response <number>".
```
## Stop rule
One round: N samples and one selection call (plus at most one retry). The selector picks; it never rewrites or merges.
## Requirements
- Make N (default 5) and the sampling temperature (default 0.8) parameters.
- Return the selected candidate exactly as sampled; the selector's reply is used only for its number.
- Put every candidate in the selection prompt in full; if they do not fit the context window, lower N rather than truncating them.
- Log the candidates, the selector's raw reply and the chosen number.
- Add a test with a stub LLM whose selector replies "Response 2"; assert the returned text equals the second sampled candidate exactly.
Model ensemble
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the Parallelization: Voting pattern (Model ensemble variant) in this codebase, using the LLM client and language we already use.
## Goal
Answer a question with several different models, rank their answers by pairwise comparison, and fuse the top-ranked ones into a single answer.
## How it works
1. Send the question to K different models at once (default 3), each configured separately, with the same prompt.
2. For every pair of answers, ask the ranker which is better with the Pairwise ranking prompt; run each pair twice with the order swapped, and count a win only when both orders agree.
3. Score each answer by its number of wins and keep the top 2, breaking ties by the earlier model in the list.
4. Send the question and the top answers, best first, to the fuser with the Fusion prompt, and return its reply.
## Prompts
### Pairwise ranking prompt
```markdown
Which answer to the question is better: more correct, more
complete and clearer?
<question>{{question}}</question>
<answer_a>{{a}}</answer_a>
<answer_b>{{b}}</answer_b>
Reply with exactly one letter: A or B.
```
### Fusion prompt
```markdown
Write the best possible answer to the question by combining
the strengths of these candidate answers, which are ranked best
first. Keep what is correct, drop what is wrong, and do not add
claims none of them support.
<question>{{question}}</question>
<candidates>{{ranked_answers}}</candidates>
```
## Stop rule
One round: K answers, K x (K - 1) ranking calls and one fusion call. Nothing loops back to the answering models.
## Requirements
- Make K (default 3) and the number of answers to fuse (default 2) parameters, and keep the model list as configuration.
- If one model errors or times out, rank the answers that did arrive; with only one answer, return it without fusing.
- If a ranking reply is neither "A" nor "B", retry it once, then count that comparison as a draw.
- Log every pairwise verdict and the final scores, so a model that keeps losing can be dropped.
- Add a test with stub models and a stub ranker that prefers B over A, B over C and A over C; assert the fuser prompt contains B's answer before A's and does not contain C's.
Prompt templates
Majority vote
Decide whether the code below contains an exploitablevulnerability. Reason step by step, then end with a final lineof exactly "VERDICT: vulnerable" or "VERDICT: safe".
<code>{{snippet}}</code>You are a {{persona}} reviewing the code below for exploitablevulnerabilities. Judge only what the code shows, not what itmight be used for. End with "VERDICT: vulnerable" or "VERDICT: safe".
<code>{{snippet}}</code>LLM picks
You are a security reviewer. Write a one-paragraph finding forthe code below: what is exploitable, how an attacker would useit, and the fix. If nothing is exploitable, say why.
<code>{{snippet}}</code>I have generated the following responses to the same question:
{{#each candidates}}Response {{number}}: {{text}}{{/each}}
Evaluate these responses and select the one most consistentwith the majority. Answer with only: "Response <number>".Model ensemble
Which answer to the question is better: more correct, morecomplete and clearer?
<question>{{question}}</question><answer_a>{{a}}</answer_a><answer_b>{{b}}</answer_b>
Reply with exactly one letter: A or B.Write the best possible answer to the question by combiningthe strengths of these candidate answers, which are ranked bestfirst. Keep what is correct, drop what is wrong, and do not addclaims none of them support.
<question>{{question}}</question><candidates>{{ranked_answers}}</candidates>Related patterns
Composes well with:
Sources
From the Agentic Atlas by Joran Kikke · Edit on GitHub · Suggest a correction