Make the Model Show Its Work
Chain-of-thought prompting increases accuracy on reasoning tasks by asking the model to produce intermediate steps before reaching a conclusion. The insight: LLMs are next-token predictors, and a token representing βthe answerβ is more likely to be correct when preceded by tokens that represent valid reasoning. CoT trades output length for answer accuracy β a trade-off worth making for any task where correctness matters.
- Your LLM gets multi-step arithmetic or logic problems wrong, even on simple cases
- The model makes classification decisions that seem right until you trace the reasoning
- You need the model to debug code or explain a decision in auditable steps
- Your agent makes confident wrong answers on tasks that require decomposition
Zero-shot CoT is a single appended sentence that consistently improves accuracy on reasoning tasks with zero additional examples.
Zero-Shot CoT
The simplest form: append βLet's think step by stepβ to any prompt. This instruction activates reasoning traces in models trained with CoT examples (which includes most instruction-tuned models today). No examples needed.
flowchart LR
direct["Direct answer
(no reasoning)
Prompt β Answer
Fast, less accurate"]
zeroCoT["Zero-shot CoT
Append 'step by step'
Prompt β Reasoning β Answer
Slower, more accurate"]
fewCoT["Few-shot CoT
Examples with reasoning
Examples + Prompt β Reasoning β Answer
Best for complex tasks"]
direct -->|add 'step by step'| zeroCoT
zeroCoT -->|add examples| fewCoT
// Zero-shot CoT: one phrase changes accuracy significantly
// β Direct β model jumps to conclusion, more error-prone
const directPrompt = `
An API processes 240 requests per minute.
During a traffic spike, the rate triples for 5 minutes then drops to 180 req/min.
If each request uses 2KB of memory and you have 512MB available,
do you have enough memory during the spike?
`;
// β
Zero-shot CoT β model reasons through intermediate steps
const cotPrompt = `
An API processes 240 requests per minute.
During a traffic spike, the rate triples for 5 minutes then drops to 180 req/min.
If each request uses 2KB of memory and you have 512MB available,
do you have enough memory during the spike?
Think through this step by step.
`;
// Model output with CoT:
// Step 1: Normal rate = 240 req/min, spiked rate = 240 Γ 3 = 720 req/min
// Step 2: Memory during spike = 720 Γ 2KB = 1,440KB = 1.44MB per minute of requests
// Step 3: But requests are concurrent β how many at once? Need avg response time...
// [model identifies the ambiguity and addresses it]
// Final answer: [more accurate than direct]Few-Shot CoT
// Few-shot CoT: examples with full reasoning traces
// Most effective for tasks with a consistent reasoning pattern
const fewShotCoTPrompt = `
You are a code review assistant. For each change, reason through its correctness before deciding.
Example 1:
Code change:
const user = await db.users.findOne(userId);
return user.email;
Reasoning:
- findOne could return null if userId doesn't exist
- Accessing .email on null will throw a TypeError at runtime
- This is missing a null check
Decision: REJECT β add null check: if (!user) throw new Error('User not found')
Example 2:
Code change:
const users = await db.users.findMany({ limit: 100 });
return users.map(u => u.email);
Reasoning:
- findMany returns an empty array if no results, never null
- limit: 100 prevents unbounded queries
- map on empty array returns empty array safely
Decision: APPROVE β looks safe
Now review this change:
Code change:
const config = JSON.parse(process.env.APP_CONFIG);
return config.apiKey;
`;
// Model reasons: JSON.parse throws on invalid JSON, env var could be undefined...
// Decision: REJECT β missing error handlingSelf-Consistency
// Self-consistency: generate N reasoning paths, take majority answer
// Improves accuracy further β like an ensemble for reasoning tasks
async function selfConsistentAnswer(
prompt: string,
n = 5
): Promise<string> {
// Generate N independent reasoning paths with temperature > 0
const responses = await Promise.all(
Array.from({ length: n }, () =>
openai.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: `${prompt}
Think step by step.` }],
temperature: 0.7, // Non-zero for diversity
})
)
);
const answers = responses.map(r => {
const text = r.choices[0].message.content ?? '';
// Extract final answer from CoT output
// Common patterns: "Therefore: X", "Final answer: X", last sentence
return extractFinalAnswer(text);
});
// Majority vote
const counts = new Map<string, number>();
for (const answer of answers) {
counts.set(answer, (counts.get(answer) ?? 0) + 1);
}
return [...counts.entries()].sort((a, b) => b[1] - a[1])[0][0];
}
// When to use self-consistency:
// - High-stakes decisions where accuracy outweighs cost (N Γ API calls)
// - Tasks with discrete answers (classification, calculation, yes/no)
// - When you see high variance in single-pass answersCoT for Code Tasks
// Ask the model to explain before implementing
// Catches design errors before they become code errors
const codingPrompt = `
Task: Write a function that deduplicates an array of objects by a given key,
keeping the last occurrence of each duplicate.
Before writing code:
1. State your approach and data structure choice
2. Identify edge cases you'll handle
3. Note any performance considerations
Then write the implementation.
`;
// Model output structure:
// Approach: Use a Map, iterate forward, overwrite on duplicate key (last-wins)
// Edge cases: empty array, key not present on some objects, undefined values
// Performance: O(n) time, O(n) space
//
// function dedupeByKey<T>(arr: T[], key: keyof T): T[] {
// const seen = new Map<unknown, T>();
// for (const item of arr) {
// seen.set(item[key], item); // overwrite = last wins
// }
// return [...seen.values()];
// }
// The pre-code reasoning step surfaces edge cases before they're embedded in code
// Significantly reduces bug rate compared to asking for direct implementationPitfalls
CoT on simple lookup tasks
Adding βthink step by stepβ to βWhat is the capital of France?β adds tokens without adding accuracy. CoT helps reasoning tasks β multi-step math, logic, code analysis, decisions with trade-offs. For factual retrieval, direct prompts are faster and equally accurate.
Hallucinated reasoning steps
A model can produce confident, plausible-looking reasoning steps that are factually wrong β and then correctly derive the answer from the wrong premises. Always verify factual claims in the reasoning chain, especially for domain-specific knowledge. CoT makes the reasoning inspectable, but inspection is still your job.
Wrong final answer despite correct steps
The model can reason correctly up until the final step and then make a non sequitur conclusion. For high-stakes tasks, validate the final answer against the reasoning chain independently. Self-consistency helps here β if 4 of 5 paths reach the same answer through different reasoning, confidence is much higher.

