skip to content

Tree of Thought

Reasoning as search rather than a single line: generate several candidate thoughts, score the states they lead to, and explore the tree breadth- or depth-first, backtracking out of dead ends. Interviewers use it to check that you can name the tasks where branching pays for its extra model calls.

on this pageshow

explore

questions

24

In Tree of Thought, how do you design the propose and evaluate prompt templates?

level: middleimportance: must knowfreq 62%

answer

  1. Two roles, two output contracts
  2. Hot proposer, cold evaluator
  3. Path rendered by one function
  4. Constant blocks first, variable last
  5. Parse failure is not a low score

basics

~20 s

Write two separate templates with different jobs: a proposer that receives the serialized path and returns candidate next steps as free text, and an evaluator that receives one candidate state and returns a strictly parseable verdict. Keep their shared prefix byte-identical.

solid answer

~50 s

Treat them as two distinct roles with two distinct output contracts. The **proposer** gets the task statement, the rules, and the path so far rendered as an ordered list, and is told to emit only the next step — no commentary, no restating the problem — so the parse is trivial. The **evaluator** gets the same task statement and one candidate state, and is told to emit only a verdict token in a fixed format, which you parse strictly and retry on failure rather than regex-scraping prose. Sampling differs by role: the proposer runs hot (temperature around 1.0) because you want diverse siblings, while the evaluator runs at temperature 0 so the same state scores the same way twice. Two further habits pay for themselves: keep the shared prefix — task plus rules — identical across every call in an expansion so providers can serve it from prompt cache, and do not show the evaluator which model or branch produced a candidate, or you invite self-preference bias.

code

python · 21 lines
python
TASK = "Plan a zero-downtime split of the orders table into orders and order_items."
RULES = "Each step is one reversible DDL or backfill action. No step may lock orders."

PROPOSE = (
    "{task}\n{rules}\n\n"
    "Steps so far:\n{path}\n\n"
    "Give the next step. Output only the step text."
)

EVALUATE = (
    "{task}\n{rules}\n\n"
    "Candidate plan:\n{path}\n\n"
    "Reply with one integer from 0 to 10 and nothing else."
)

def render(template, path):
    body = "\n".join(f"{i + 1}. {s}" for i, s in enumerate(path)) or "(none)"
    return template.format(task=TASK, rules=RULES, path=body)

print(render(PROPOSE, ["Create empty order_items table"]))
print(render(EVALUATE, ["Create empty order_items table", "Backfill in batches"]))

go deeper

for a junior

Know that the loop uses two different prompts, one asking for a next step and one asking for a score, and that the score prompt must return something your code can parse.

for a middle

Explain the output contract, the hot-proposer and cold-evaluator temperature split, and why the path is re-rendered into every prompt by a single function.

for a senior

Demonstrate the operational habits: a stable cached prefix, strict parse-or-retry, provenance-blind evaluation to avoid self-preference, and compact state because the path cost multiplies with branching.

for a principal

Own the templates as versioned interfaces — changing the shared prefix invalidates caches and makes historical runs incomparable, so template versioning belongs in the run log and the rollout plan.

## Why two templates, not one clever one The temptation is a single prompt that says 'propose three next steps and rate each one'. It is cheaper by one round trip and worse in almost every other way. Ratings produced in the same pass as the proposals are conditioned on those proposals — the model is grading its own fresh output inside one autoregressive stream, and it grades generously. You also lose the ability to sample the two roles differently, to route them to different models, to retry one without redoing the other, and to swap the evaluator for a non-model checker later. Two templates is the shape that survives contact with production. ## The proposer template Structure it as four blocks in a fixed order: task statement, rules and constraints, the serialized path so far, and the instruction. The first two blocks are constant for the whole run — that constancy is what makes caching possible. The path block is the only thing that varies per node, and it should be rendered by one function so every call formats it identically: an ordered list of the steps taken, or `(none)` at the root. The instruction should ask for exactly one artefact per call and nothing else. 'Output only the step text' is worth more than any amount of persona framing, because the orchestrator has to parse the result into a node. If you ask for several candidates in one response, you have to parse a list, and a malformed list costs you the whole call; if you ask for one candidate and sample the call several times, each failure costs you one child. Both are defensible; be able to say which you chose and why. ## The evaluator template Same first two blocks — byte-identical to the proposer's, which is the point — then one candidate state, then an output contract. The contract is the whole game. Say exactly what may be emitted and nothing else, parse it with a strict parser, and treat a parse failure as a retryable error rather than something to salvage with a regex. A verdict you cannot parse is not a low score; conflating the two silently biases the search against whichever states happened to trigger chatty responses. The evaluator should be blind to provenance. Do not tell it which branch, which model, or which sampling temperature produced the candidate, and do not include the proposer's own hedging in the state you show it. Models exhibit self-preference — they rate text that looks like their own output higher — and leaked provenance turns a scoring function into a popularity contest between prompts. ## Serializing state back into the prompt Everything the model knows about a node is what you render. Three properties matter: **Compactness.** The path is re-sent on every child expansion and every scoring call, so its token cost is multiplied by the branching factor at every depth. A verbose state representation is the most common reason a tree run costs ten times the estimate. **Determinism.** Render through one function. If two call sites format the same path differently — one with numbering, one without — you break prefix caching and you make two logically identical calls incomparable in your logs. **Completeness.** The rendering must contain everything needed to continue; anything you keep only in your own objects (a constraint discovered at depth 2, say) is invisible to the model at depth 5. ## Sampling parameters as part of the template Treat temperature as part of the template contract, not an afterthought. The proposer at temperature 1.0 (or with top-p loosened) is what makes siblings genuinely different rather than three rewordings of one idea. The evaluator at temperature 0 is what makes scores comparable across nodes: if the same state can score differently on two calls, your pruning decisions are partly noise, and a run is not reproducible even with everything else logged. Some teams go further and average several evaluator samples, but that is a scoring-design decision with its own cost; the baseline discipline is simply cold, deterministic scoring. ## Prefix caching, concretely Providers generally serve a repeated prompt prefix from cache at a large discount on input tokens. In a tree run, the task statement and rules repeat across every single call — often dozens per expansion — so making that prefix stable and putting it first is one of the highest-leverage things you can do for cost. It has a design consequence: anything variable (the node's path, a timestamp, a node id) must go *after* the constant block, never interleaved into it. ## What interviewers listen for They want role separation, a machine-parseable evaluator contract, a single deterministic state renderer, and a reason for each temperature. Candidates who describe one mega-prompt, or who scrape scores out of prose with a regex, have usually not run this loop against a real workload.

  • Why not ask for the candidates and their scores in one call to halve the round trips?
    Because the scores are then generated conditioned on the proposals in the same pass, which makes them systematically generous and correlated. You also lose per-role sampling, per-role retries, the option to route roles to different models, and the ability to drop in a non-model checker later. The saved latency rarely covers a scoring function you cannot trust.
  • The evaluator sometimes replies with a number plus a sentence of justification. How should the orchestrator handle that?
    Treat it as a contract violation: fail the parse and retry the call, optionally with a stricter reminder. Do not regex the first number out of the prose — that silently accepts drifting output and hides the fact that your contract is eroding. If you actually want a rationale, put it in the contract explicitly as a second field, so parsing stays total rather than best-effort.
  • What breaks if the path renderer is duplicated at two call sites?
    Two things. Formatting drift breaks the shared-prefix assumption and quietly loses your cache discount, and it makes logically identical calls non-comparable in logs and replays, so a diff between two runs shows spurious differences. One renderer, called everywhere, is the cheap fix.

saying these in an interview costs you the question

  • Uses one prompt that proposes and scores in the same pass
  • Scrapes evaluator scores out of prose with a regex
  • Runs proposer and evaluator at the same temperature
  • Puts variable text before the constant task block
  • Tells the evaluator which branch or model produced a candidate

context

open as a page

When would you run a Tree of Thoughts search depth-first with backtracking rather than breadth-first with a beam?

level: middleimportance: must knowfreq 70%

basics

~20 s

Go depth-first with backtracking when a partial solution can be checked for contradiction, most branches die early, and any complete answer is worth having quickly. Use breadth-first with a beam when the depth is short and known and you want several equal-length plans compared side by side.

open as a page

In Tree of Thoughts, how do branching factor, depth and beam width set the LLM call count?

level: middleimportance: must knowfreq 62%

basics

~20 s

With a fixed beam, each level generates width x branching candidates, so generation calls total width x branching x depth — linear in depth. Without a beam the tree grows as branching^depth, which is why unpruned breadth-first search is unaffordable past a few levels.

open as a page

In Tree of Thought, how does value prompting differ from vote prompting?

level: middleimportance: must knowfreq 68%

basics

~20 s

Value prompting scores each partial state on its own and returns an independent number or label. Vote prompting shows several sibling states together and asks which is most promising, returning a relative ranking rather than absolute scores.

open as a page

How do you choose how large a single thought should be in a Tree of Thought?

level: middleimportance: must knowfreq 52%

basics

~20 s

Size a thought so the model can produce several meaningfully different versions of it, and so a partial solution built from it can already be judged promising or hopeless. Too fine and siblings look identical; too coarse and there is almost nothing to branch over.

open as a page

In Tree of Thought, when do you sample candidate thoughts independently instead of proposing them in one call?

level: middleimportance: must knowfreq 62%

basics

~20 s

Sample independently when the thought space is rich and open-ended, because separate draws naturally differ. Propose all candidates inside one call when the space is small and constrained, so each new candidate can see the earlier ones and avoid repeating them.

open as a page

When does Tree of Thought beat Chain of Thought, and which task traits predict it?

level: middleimportance: must knowfreq 62%

basics

~20 s

Tree of Thought pays only when a task splits into partial states you can produce several ways and score before committing, so a bad early step can be abandoned. Game of 24 is the classic case; one-pass extraction or recall tasks gain nothing from branching.

open as a page

How do you cap token spend in a Tree of Thought run without losing the answer?

level: seniorimportance: must knowfreq 55%

basics

~20 s

Track tokens per call against an explicit run budget, and gate each expansion on its projected cost rather than on spend already incurred. When the budget is exhausted, return the best-scoring node found so far instead of failing.

open as a page

How do you choose the pruning threshold for Tree of Thought state scores?

level: seniorimportance: must knowfreq 54%

basics

~20 s

Measure it, do not guess it. Run a labelled set of problems, record the scores of states that led to correct answers, and pick the cutoff from that curve — trading the compute saved against the fraction of correct solutions the threshold discards.

open as a page

Why can't Tree of Thought be implemented as a single LLM call?

level: juniorimportance: should knowfreq 50%

basics

~20 s

Tree of Thought is a search loop your own code runs. The model contributes two stateless call types — propose candidate next steps, and score the states they lead to — while your orchestrator holds the tree, the frontier, the budget and the stopping rule.

open as a page

In a Tree of Thoughts search, what does beam width control, and what breaks at width 1?

level: juniorimportance: should knowfreq 55%

basics

~20 s

Beam width is how many partial reasoning states survive at each level of the tree before the next round of expansion. At width 1 only one path survives, so a bad early step can never be recovered.

open as a page

In a Tree of Thought prompt, what should a few-shot exemplar of a thought demonstrate?

level: juniorimportance: should knowfreq 38%

basics

~20 s

An exemplar should show the shape of one step, not a finished solution: a partial state, several candidate continuations of the intended size, and a separable format. Exemplars that solve a problem end to end teach the model to answer instead of to branch.

open as a page

In Tree of Thought, how do you parallelize and retry branch calls safely?

level: middleimportance: should knowfreq 42%

basics

~20 s

Sibling expansions at one depth are independent, so fan them out concurrently through a bounded pool and join before scoring. Treat a failed proposer call as one fewer child, and a failed evaluator call as unknown — never as a low score.

open as a page

Why is using the same model to propose and score Tree of Thought states risky?

level: middleimportance: should knowfreq 50%

basics

~20 s

A model tends to rate its own reasoning favourably, so scores skew high and stay bunched together. The search then finds nothing to prune, keeps expanding weak branches, and spends the extra compute of a tree without gaining the accuracy that pruning was supposed to buy.

open as a page

When is Tree of Thought the wrong tool and ReAct the right one for a task?

level: middleimportance: should knowfreq 38%

basics

~20 s

Tree of Thought searches internally over hypotheses the model invents and scores itself; ReAct interleaves reasoning with actions that fetch real observations from the outside world. When the missing ingredient is a fact or effect the model cannot derive, branching only multiplies confident guesses.

open as a page

In Tree of Thought, when does an external verifier beat an LLM evaluator?

level: seniorimportance: should knowfreq 45%

basics

~20 s

An external verifier — a compiler, a test suite, a schema check, a query planner, a solver — beats a model evaluator whenever a candidate state can be checked mechanically. It refutes soundly, deterministically and cheaply, but it rarely ranks the candidates that pass.

open as a page

What do you log per node so a bad Tree of Thought run can be replayed?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Record one row per node: id, parent id, depth, the rendered prompt and template version, model and sampling parameters, the raw proposer and evaluator responses, the parsed score, tokens, latency, retries and the prune reason. That log makes a run replayable and its failure attributable.

open as a page

How do you bound depth in a Tree of Thoughts run that must answer within a fixed latency budget?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Set a hard depth cap plus a wall-clock and token cap, and keep a best-so-far state at all times so any cap that fires still returns an answer. When the needed depth is unknown, deepen iteratively — search to depth 1, then 2, then 3 — so every bound completed leaves a usable result.

open as a page

When is a learned value model worth training to score Tree of Thought states?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Train one when the same task runs constantly, ground-truth outcomes are cheap to collect, and prompted judging is either too noisy or too expensive per node. Otherwise a rule-based check or a prompted evaluator is faster to build and easier to change.

open as a page

Your Tree of Thought branches are three rewordings of one idea — how do you get real diversity?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Ask for candidates that must differ along a named axis, show the model the siblings it already produced so it can avoid them, and drop near-duplicates before expanding. Then measure the distinct-candidate rate, because paraphrase siblings mean you are paying for width you never got.

open as a page

A Tree of Thought turn costs thirty model calls under a two-second chat SLA — how do you fix it?

level: seniorimportance: should knowfreq 47%

basics

~20 s

Start by asking whether the turn needs search at all: most support turns do not, and the honest fix is a linear chain for them. Where search stays, cut depth and branching, run sibling generation and scoring concurrently so latency tracks depth rather than total calls, and use a cheaper model for evaluation.

open as a page

How much of a Tree of Thought run's compute should state evaluation consume?

level: principalimportance: should knowfreq 33%

basics

~20 s

There is no fixed share; it is an allocation choice. Spend on evaluation up to the point where another unit of judgement improves the final answer more than another branch would, and measure that frontier per workload rather than assuming generation should dominate.

open as a page

In a Tree of Thoughts loop, how is backtracking implemented and how do you avoid re-expanding duplicate states?

level: seniorimportance: nice to knowfreq 33%

basics

~20 s

The tree lives in your orchestrator, not the model. A state is the stored thought prefix, so backtracking means popping the frontier to a parent and re-sending that prefix for its next untried child. Duplicates are suppressed by a visited set keyed on a canonical form of the state.

open as a page