LATS (Language Agent Tree Search)
An agent framework that unifies ToT, ReAct, Reflexion and MCTS
Contents
An agent framework that binds ToT, ReAct, Reflexion and MCTS into a single tree search and finds better solutions than any of them alone.
Concept
LATS (Language Agent Tree Search) is a framework that unifies four techniques, ToT, ReAct, Reflexion and MCTS:
- Tree of Thought (ToT): exploring multiple paths
- ReAct: interacting with external tools
- Reflexion: learning from failure
- Monte Carlo Tree Search (MCTS): optimizing the search
The six core operations
- Selection — pick the node to explore.
- Expansion — generate new possibilities.
- Evaluation — score how promising each one is.
- Simulation — execute the action and observe the result.
- Backpropagation — propagate the result back up.
- Reflection — reflect on failure.
Each step in detail
| Step | Description | Underlying technique |
|---|---|---|
| Selection | Pick the node to explore | MCTS (UCB1) |
| Expansion | Generate new possibilities | ToT |
| Evaluation | Score how promising it is | ToT |
| Simulation | Execute the action and observe | ReAct |
| Backpropagation | Propagate the result back | MCTS |
| Reflection | Reflect on failure | Reflexion |
The techniques it unifies
| Technique | Role inside LATS |
|---|---|
| Tree Search | The multi-path exploration structure |
| ReAct | Interaction with external tools |
| Reflexion | Learning from failure |
| MCTS | Optimizing search efficiency |
Performance
LATS combines reasoning, tools, search and reflection. The numbers below are as reported in the LATS paper (arXiv:2310.04406), where LATS scores above single techniques such as ReAct and Reflexion under the same conditions. Note that each benchmark uses a different metric, so comparing the percentages directly is misleading.
| Benchmark | Metric | LATS | Notes |
|---|---|---|---|
| HumanEval | pass@1 | 94.4% | GPT-4 based, above Reflexion (91%) |
| HotpotQA | EM | ~0.61 | Above ReAct and Reflexion |
| WebShop | Score (0-100) | 75.9 | Close to gradient-trained methods |
Walkthrough: a coding problem
Problem: "Implement merge sort in Python"
Selection: pick the node with the highest UCB1 score. The recursive implementation approach is selected.
Expansion: generate three implementation approaches — approach 1: plain recursion, approach 2: optimized recursion (in-place), approach 3: iterative implementation.
Evaluation: score how promising each approach is — approach 1: 0.7 (simple but memory-inefficient), approach 2: 0.9 (well balanced), approach 3: 0.6 (complicated).
Simulation (ReAct): implement approach 2.
- Thought: split the array in half and recurse
- Action: write the code
def merge_sort(arr): ...- Observation: code written
- Thought: run the tests
- Action: run
merge_sort([3,1,4,1,5,9])- Observation:
[1,1,3,4,5,9], successBackpropagation: the passing test propagates a score back up, and the UCB1 score along the approach 2 path rises.
Done: return the final code.
Reflection on failure
Simulation failure: running
merge_sort([])raisesIndexError: list index out of rangeReflection: "There was no boundary handling for an empty array. An empty-array check has to be added to the recursion base case."
Retry: add the boundary condition
if len(arr) <= 1: return arrand the problem is fixed.
The UCB1 algorithm
LATS balances exploration against exploitation using UCB1 (Upper Confidence Bound) from MCTS:
- (mean reward): how good this path has been (exploitation)
- (exploration term): a bonus for less-visited paths (exploration)
- : the exploration-exploitation balance constant
Compared to earlier techniques
- CoT: single-path search, no tools, no learning, no optimization
- ToT: multi-path search, no tools, no learning, no optimization
- ReAct: single-path search, tools yes, no learning, no optimization
- Reflexion: single-path search, tools yes, learning yes, no optimization
- LATS: multi-path search, tools yes, learning yes, optimization yes
Implementation structure
class LATS:
def __init__(self, llm, tools):
self.llm = llm
self.tools = tools
self.memory = [] # Reflexion memory
def solve(self, problem):
root = Node(state=problem)
while not self.is_solved(root):
# 1. Selection
node = self.select(root)
# 2. Expansion
children = self.expand(node)
# 3. Evaluation
for child in children:
child.value = self.evaluate(child)
# 4. Simulation (ReAct)
best_child = max(children, key=lambda x: x.value)
result = self.simulate(best_child)
# 5. Backpropagation
self.backpropagate(best_child, result)
# 6. Reflection (only on failure)
if not result.success:
reflection = self.reflect(best_child, result)
self.memory.append(reflection)
return self.get_solution(root)The methods in the solve loop map one to one onto the six-step table above. select is Selection, expand is Expansion, evaluate is Evaluation, simulate is Simulation (ReAct), and backpropagate is Backpropagation. Only on failure does reflect run, accumulating the lesson in memory for the next expansion to consult.
Cost-performance trade-off
| Technique | Relative cost | Relative performance |
|---|---|---|
| CoT | Low | Moderate |
| ToT | Medium | High |
| Reflexion | Medium to high | High |
| LATS | High | Very high |
LATS delivers the highest performance, and it also costs the most.
How to choose
| Situation | Recommendation |
|---|---|
| Simple task | CoT is enough |
| Tools needed | ReAct |
| Search needed | ToT |
| Complex coding | Reflexion |
| Maximum performance needed | LATS |
Related concepts
- Tree of Thought (ToT): multi-path search
- ReAct: tool use
- Reflexion: learning from failure
- Monte Carlo Tree Search: the search algorithm from game AI
Summary
LATS binds the multi-path search of ToT, the tool use of ReAct, the failure learning of Reflexion and the UCB1 search of MCTS into a single tree. It repeats six steps from Selection through Reflection, concentrating resources on promising paths and extracting a lesson from every failure. The call cost is the highest of any of these methods, so CoT or ReAct is enough for simple work, and LATS belongs on complex tasks where accuracy matters more than cost. The benchmark numbers are as reported in the paper, and results will differ depending on the deployment.