wikillm

Paper · 2022-10-07 · cs.CL, cs.AI

Automatic Chain of Thought Prompting in Large Language Models

Auto-CoT writes its own few-shot chain-of-thought demonstrations: it k-means clusters the test questions by Sentence-BERT embedding and keeps one zero-shot chain per cluster, nearest the centre and passing length and answer filters. Author-reported on GPT-3 text-davinci-002: at or above Manual-CoT on all ten reasoning datasets (MultiArith 92.0 vs 91.7).

Chain-of-thought promptingFew-shot example selectionIn-context learningpromptingchain-of-thoughtin-context-learningdemonstration-selectionclustering

arXivPDFCodeMarkdown11 min read

AI-compiled by claude-haiku-5-5 on 2026-10-24, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.

In plain words

Chain-of-thought prompting gets a language model to write out its steps before it gives an answer, which helps on arithmetic and logic questions. The usual way to do this is to write a few example questions by hand, each with a worked answer, and put them in front of the real question. Writing good examples takes effort, and they have to suit the task.

This paper asks whether the model can write those examples itself. The method groups the task's questions by how alike they are, then asks the model to answer one question from each group with the plain prompt "Let's think step by step." Taking one question from each group, rather than the most similar questions, keeps the examples varied. The model's answers are sometimes wrong, so the method keeps only short questions and short worked answers, and for arithmetic questions, the final answer has to show up in the working. The examples are then pasted in front of each new question. No answer key is needed.

It matters because the hand-writing step goes away, and the paper reports that the automatically built examples match or beat hand-written ones on ten reasoning tasks.

TL;DR

  • Auto-CoT builds the few-shot demonstrations for chain-of-thought prompting without hand-written examples or gold labels: it clusters the test questions and turns one zero-shot chain per cluster into a demonstration §4 §4.1 §4.2.
  • The chains come from zero-shot "Let's think step by step" prompting, so some are wrong. Diversity across clusters and simple length and answer filters are the paper's defences against that §3.3 §4.2 app. C.2.
  • Author-reported, GPT-3 text-davinci-002 (175B), ten reasoning datasets: Auto-CoT is at or above Manual-CoT on every dataset, averaged over three runs. Few-Shot is still higher on CSQA and StrategyQA tab. 3 §5.2.
  • Read "Paper vs code" before reimplementing. The released code applies selection rules the paper does not state, uses an encoder the paper does not name, and expects a chain log in a format its own inference script does not write.

Problem

Chain-of-thought (CoT) prompting with hand-written demonstrations (Manual-CoT) performs better than zero-shot prompting, but the demonstrations take effort to write for each task and dataset §1 §2.1. The paper assumes that only a set of test questions is available, with no training set and no reference chains §1 §3.

Retrieving similar questions as demonstrations works when reference chains are available §3. Without them, the demonstrations are zero-shot chains, which can be wrong. On MultiArith, the similarity-retrieved demonstrations (Retrieval- Q-CoT) score 82.8% against 86.2% for randomly chosen ones (Random-Q-CoT) tab. 1 §3. Among the 128 questions that zero-shot CoT got wrong, 46.9% stayed wrong under Retrieval-Q-CoT, against 25.8% under Random-Q-CoT §3.1 fig. 2. The authors call this "misleading by similarity": similar questions carry the same mistakes into the prompt §3.1.

Errors also cluster. With k-means at k = 8 on MultiArith, one cluster had a zero-shot error rate of 52.3% §3.2 fig. 3. A similarity-based method that pulls several questions from that cluster copies the same mistake. The paper argues that sampling from different clusters limits the damage, because only one or two wrong demonstrations out of eight are tolerated §3.3.

Method

Auto-CoT has two stages §4:

  1. Question clustering §4.1 alg. 1. Each test question is encoded with Sentence-BERT, and its token vectors are averaged into one fixed-size vector. k-means partitions the vectors into k clusters. Within each cluster, questions are sorted by distance to the cluster centre, nearest first.
  2. Demonstration sampling §4.2 alg. 2. For each cluster in turn, walk its sorted list. Give the model the question followed by the trigger "Let's think step by step" and take its rationale and extracted answer as a zero-shot chain. Keep the first candidate that passes the selection filter, then move to the next cluster. Each cluster yields one demonstration.

The test-time prompt is all k demonstrations in order, followed by the test question and the same trigger. The model decodes greedily, and the final answer is read from the end of its output §4.2 fig. 4 app. B.2. The code does a second decoding pass for zero-shot chains to extract the answer; the paper does not describe this step run_inference.py.

The paper has no numbered equations. Algorithm 1 gives the sort rule and Algorithm 2 gives the sampling loop alg. 1 alg. 2.

Pseudocode
# Auto-CoT demonstration construction  [alg. 1] [alg. 2] [§4]
# Input:  test questions (list of str), k (number of demos)
# Output: list of k demonstrations

def build_demonstrations(questions, k):
    # Encode every question and average its token vectors  [§4.1]
    vectors = [sentence_encoder(q) for q in questions]  # (N, d)

    # Partition the questions into k clusters with k-means  [§4.1] [alg. 1]
    clusters = kmeans(vectors, k)

    demonstrations = []
    for cluster in clusters:
        # Order the cluster by distance to its centre, nearest first  [§4.1]
        ordered = sort_by_distance_to_centre(cluster)
        for question in ordered:
            # Zero-shot chain: question followed by the trigger  [§4.2]
            chain = llm(question + "\nA: " + TRIGGER)
            # Keep the first candidate that passes the filter  [§4.2] [alg. 2]
            if passes_filter(question, chain):
                demonstrations.append(make_demo(question, chain))
                break
    return demonstrations
Pseudocode
# Selection filter for one candidate chain  [§4.2] [app. C.2]
# Input:  question (str), chain with rationale and answer
# Output: True if the candidate may become a demonstration

def passes_filter(question, chain):
    # Question length: no more than 60 tokens  [§4.2]
    if count_tokens(question) > 60:
        return False
    # Rationale length: no more than 5 reasoning steps  [§4.2]
    if count_steps(chain.rationale) > 5:
        return False
    # Arithmetic tasks except AQuA: the answer must be non-empty and
    # must appear in the rationale  [app. C.2]
    if is_arithmetic and not answer_in_rationale(chain):
        return False
    return True
Pseudocode
# Test-time input: demonstrations, then the test question  [§4.2] [fig. 4]
# Input:  demonstrations (list), test_question (str)
# Output: prompt string for the LLM

def build_prompt(demonstrations, test_question):
    # Demos in cluster order, each as question, rationale and answer  [§4.2]
    demo_text = "".join(format_demo(d) for d in demonstrations)
    # Test question with the trigger, decoded greedily  [app. B.2]
    return demo_text + test_question + "\nA: " + TRIGGER

Streaming variant (Auto-CoT*) §5.6 app. C.3. Questions arrive in batches of m (m = 30 on MultiArith). Batch 1 has no clustering: each question gets a zero-shot chain. For batch b > 1, demonstrations are built from the question-chain pairs collected so far, the batch is answered with them, and the batch's pairs are added to the pool.

Baselines §5.1. Zero-Shot appends "The answer is" to the question. Zero-Shot-CoT uses the trigger. Few-Shot uses hand-written demonstrations without rationales. Manual-CoT uses hand-written demonstrations with rationales. Retrieval-Q-CoT and Random-Q-CoT are the Section 3 variants that choose demonstration questions by similarity or at random §3.

Hyperparameters

NameValueWhereNotes
LLMGPT-3 text-davinci-002, 175Bapp. B.2Accessed via the OpenAI API. Code maps it to engine text-davinci-002 utils.py
Second LLMCodex code-davinci-002§5.4 tab. 4Evaluated only on three datasets
Demonstrations k8 default§5.1 app. B.2Same as the number of clusters
k for AQuA and Last Letter4§5.1 app. B.2Code: run_demo.py
k for CSQA7§5.1 app. B.2Code: run_demo.py
k for StrategyQA6§5.1 app. B.2Code: run_demo.py
Question length cap60 tokens§4.2Code counts whitespace-separated words, not model tokens run_demo.py
Rationale cap5 reasoning steps§4.2Paper counts "\n" tokens (footnote). Code uses 7 for Last Letter, not stated in the paper run_demo.py run_demo.py
Sentence encoderSentence-BERT, model not named§4.1Code default all-MiniLM-L6-v2 run_demo.py
k-means seednot stated§4.1Code random_state 192 run_demo.py run_demo.py
Temperature0 (greedy)app. B.2run_inference.py
Max tokens, reasoning256app. B.2run_inference.py
Max tokens, answer extractionnot stated—Code uses 32 run_inference.py
Top-p, frequency and presence penaltiesnot stated—Code: 1, 0, 0 utils.py
Zero-shot trigger"Let's think step by step."§1 fig. 1 §4.2§4.2 text reads "step to step". Code uses "step by step" run_inference.py
Answer trigger in demos"The answer is"not stated in main textCode run_inference.py
Experiment seednot stated—Code default 1 run_inference.py
Streaming batch size m30§5.6MultiArith only

Results

Author-reported. Setup: GPT-3 text-davinci-002 (175B), greedy decoding, max 256 tokens, ten datasets in three groups §5.1 app. B.2. Auto-CoT is averaged over three random runs. Zero-Shot and Zero-Shot-CoT rows are taken from Kojima et al.; Few-Shot and Manual-CoT rows are taken from Wei et al. §5.2. The paper's table does not report standard deviations tab. 3.

Main results tab. 3 (accuracy, %; rows as in the paper):

ModelMultiArithGSM8KAddSubAQuASingleEqSVAMPCSQAStrategyQALetterCoin
Zero-Shot22.712.577.022.478.758.872.654.30.253.8
Zero-Shot-CoT78.740.774.733.578.763.764.654.857.691.4
Few-Shot33.815.683.324.882.765.779.565.90.257.2
Manual-CoT91.746.981.335.886.668.973.565.459.097.2
Auto-CoT92.047.984.836.587.069.574.465.459.799.9

Auto-CoT is at or above Manual-CoT on all ten columns, with StrategyQA tied tab. 3. Few-Shot is higher on CSQA (79.5 vs 74.4) and StrategyQA (65.9 vs 65.4) tab. 3.

Codex (code-davinci-002) tab. 4 (accuracy, %):

MethodMultiArithGSM8KAddSub
Zero-Shot-CoT64.831.865.6
Manual-CoT96.859.484.6
Auto-CoT93.262.891.9

Wrong demonstrations §5.5 fig. 6. The paper injects wrong demonstrations at four rates (12.5% to 50%) on MultiArith. Auto-CoT is compared with In-Cluster Sampling, which draws demonstrations from the same cluster as the test question. Values read from the plot data in the LaTeX source: Auto-CoT goes from 93.7 (12.5% wrong) to 90.2 (50% wrong), and In-Cluster Sampling from 91.2 to 80.5 over the same range. The paper says Auto-CoT "does not degrade significantly" at 50% §5.5.

Streaming §5.6 fig. 7. From batch 2 on, Auto-CoT* is described as performing comparably with Manual-CoT. Batch 1 equals Zero-Shot-CoT by construction.

Analysis (appendix):

  • Demonstration components on MultiArith app. A.1 tab. 5: Manual-CoT 91.7; shuffling questions 73.8; shuffling rationales 43.8; shuffling answers 17.0.
  • Sampling rule on MultiArith, correct demonstrations only app. C.1 tab. 8: Auto-CoT (closest to centre) 93.7; In-Cluster Min Dist 93.7; In-Cluster Random 89.2; In-Cluster Max Dist 88.7.
  • Average mistakes in three construction runs app. C.2 tab. 9, with the simple heuristics and without them:
MultiArithAddSubGSM8KAQuASingleEqSVAMPCSQAStrategyLetterCoin
Demos (k)8884887648
With heuristics0.31.71.7110.72.72.300
Without heuristics1.3532.723.33.32.331

Paper vs code

Official code: amazon-research/auto-cot, linked from the abstract, at code_commit (Apache-2.0). Three authors are at Amazon Web Services and one at Shanghai Jiao Tong University (title page).

  • Encoder. Paper: Sentence-BERT, no model named §4.1. Code: the sentence transformer all-MiniLM-L6-v2 run_demo.py.
  • Clustering seed. Paper: not stated. Code: k-means random_state 192, from the script's seed default run_demo.py run_demo.py.
  • Cluster counts. Paper and code agree: 8 by default, 4 for AQuA and Last Letter, 7 for CSQA, 6 for StrategyQA §5.1 run_demo.py.
  • Question length. Paper: no more than 60 tokens §4.2. Code: no more than 60 whitespace-separated words run_demo.py.
  • Rationale length. Paper: no more than 5 steps, counted by "\n" §4.2 (footnote). Code: a line count after collapsing blank lines, default 5 run_demo.py run_demo.py. Code uses 7 for Last Letter run_demo.py, not in the paper.
  • Extra filters in code. Code requires that the rationale ends with "." and that the predicted answer is non-empty, for every task run_demo.py. The paper states neither.
  • Answer-in-rationale check. Paper: the answer must appear in the rationale app. C.2. Code: it must appear in the last sentence or in the last 10 words, and only for GSM8K, MultiArith, SingleEq, AddSub and SVAMP run_demo.py.
  • Algorithm 2 vs code. Algorithm 2 generates each candidate chain on demand alg. 2. Code instead reads zero-shot chains precomputed for the whole dataset from a log file, then selects from that log run_demo.py.
  • Log format. run_demo.py looks for pred_mode and GT : lines run_demo.py. run_inference.py writes JSON lines and prints GT : and pred :, with no pred_mode line run_inference.py. The repository therefore has no script that produces the log in the form run_demo.py reads. This is a reproduction gap, not a difference in method.
  • Answer extraction. Code: a second decoding pass after "Therefore, the answer (arabic numerals) is", with 32 tokens run_inference.py. Paper: not described.
  • Answer cleansing. Code: for few-shot style outputs, the first number after the last "The answer is"; otherwise the last number in the output. A trailing period is removed utils.py. Paper: not described.
  • Zero-shot trigger text. Paper §4.2 writes "Let's think step to step". The introduction and Figure 1 use "Let's think step by step" §1 fig. 1. Code uses "step by step" run_inference.py.
  • Decoding. Code sets top-p 1 and both penalties 0 utils.py. Code uses stop=["\n"] only for Codex with few-shot or Auto-CoT prompts utils.py. Paper: neither is stated.
  • Seeds for the three runs. Paper: "averaged over three random runs", seeds not stated §5.2. Code: default seed 1 for inference run_inference.py.

The per-dataset demonstration files (app. D) were not compared line by line with the paper.

Pitfalls

  • Demonstrations come from the test set. The paper builds demonstrations from the same questions it evaluates, and it does not say whether a test question can be chosen as its own demonstration. The code builds one fixed set per dataset and reuses it for every test question, so a question can appear as a demonstration while also being evaluated. No gold answers are used, but the leakage question should be settled in your own evaluation.
  • Fewer than k demonstrations can come out. If no question in a cluster passes the filter, that cluster adds nothing. Algorithm 2 has no fallback, and the paper says "there will be k constructed demonstrations" §4.2 alg. 2. The code appends only passing candidates, so the count can drop silently run_demo.py.
  • Cost of building demonstrations. Each candidate needs one zero-shot chain. The code needs zero-shot chains for every question in the dataset before it can cluster, for example 600 for MultiArith and 1319 for GSM8K app. B.1 tab. 7. The paper does not report the number of extra calls.
  • Filter thresholds are heuristics. The 60-word and 5-step caps are not justified beyond citing Wei et al. §4.2. The paper's own footnote shows that step counts depend on how the model writes newlines §4.2.
  • "Matches or exceeds" needs a qualifier. Auto-CoT is at or above Manual-CoT on all ten columns, but Few-Shot beats it on CSQA and StrategyQA tab. 3. The baselines are copied from earlier papers and may have different setups and prompts §5.2.
  • Variance is unreported. The three runs' spread is not in the table, and what varies between runs (demo construction, sampling, or decoding) is not stated §5.2 tab. 3.
  • Model access. Experiments ran between July and September 2022 [app. B.2 footnote]. The code calls the OpenAI Completions endpoint utils.py. Reproducing the numbers needs that engine; the paper does not say what to do if it is unavailable.
  • Wrong-demonstration injection is unspecified. The paper does not say how the 12.5% to 50% wrong demonstrations were chosen or injected §5.5.
  • Robustness to the encoder. The paper names no encoder model and gives no ablation on encoder choice. Results with a different sentence encoder may differ.
  • Streaming numbers are plot-only. Figure 11 covers all 20 batches (600 MultiArith questions), but the per-batch values exist only in the plot data of the LaTeX source app. C.3 fig. 11.

Lineage

  • Builds on: Zero-Shot-CoT, Kojima et al., arXiv:2205.11916 (not compiled here), for the zero-shot chain generation §2.1 §4.2. Manual-CoT, Wei et al., /papers/2201.11903, for the demonstration format, the baseline and the dataset selection §2.1 §5.1.
  • Uses Sentence-BERT, /papers/1908.10084, for question encoding §4.1.
  • Compared against: Zero-Shot, Zero-Shot-CoT, Few-Shot, Manual-CoT, Retrieval-Q-CoT, Random-Q-CoT §3 §5.1.
  • Superseded by: none recorded in this wiki.

Source and license

Adapted from “Automatic Chain of Thought Prompting in Large Language Models” by Zhuosheng Zhang, Aston Zhang, Mu Li, Alex Smola (arXiv:2210.03493), used under CC BY-SA 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. This page is licensed under CC BY-SA 4.0. Code citations refer to https://github.com/amazon-research/auto-cot at commit ec9caa32a69c (Apache-2.0). Any quoted code is shown under that license.