Welcome to this comprehensive tutorial on using the TreeOfThoughtsAgent! Tree-of-Thoughts (ToT) reasoning is an advanced technique that explores multiple solution paths simultaneously through systematic tree search, enabling superior problem-solving capabilities.
- Introduction
- What is Tree-of-Thoughts Reasoning?
- Setup
- Tutorial 1: Your First ToT Agent
- Tutorial 2: Understanding Search Strategies
- Tutorial 3: Mathematical Problem Solving
- Tutorial 4: Strategic Planning
- Tutorial 5: Design Decisions
- Tutorial 6: Tuning Performance
- Tutorial 7: Production Best Practices
- Common Patterns
- Troubleshooting
- Next Steps
This tutorial will teach you how to leverage Tree-of-Thoughts reasoning to explore complex solution spaces systematically. By the end, you'll be able to:
- Understand when and why to use ToT reasoning
- Implement different search strategies (best-first, breadth-first, depth-first)
- Optimize ToT agents for different problem types
- Build production-ready exploration systems
- Balance exploration vs. token efficiency
Tree-of-Thoughts reasoning explores problem-solving as a tree structure where each node represents a potential approach or step. Unlike linear reasoning (Chain-of-Thought) that follows one path, ToT:
- Generates multiple thoughts at each step (branches)
- Evaluates each thought for quality/feasibility
- Strategically explores the most promising paths
- Backtracks from unpromising approaches
- Selects the best path through the solution space
Chain-of-Thought (Linear):
Problem → Step 1 → Step 2 → Step 3 → Solution
Tree-of-Thoughts (Branching):
Problem
/ | \
Idea1 Idea2 Idea3
/ \ | / \
Step1 Step2 Step3 Step4 Step5
|
Solution
Use Tree-of-Thoughts when:
- Multiple valid approaches exist
- You need to explore alternatives
- Quality matters more than speed
- Problem benefits from backtracking
- Solution space is complex
Use Chain-of-Thought when:
- Problem has clear sequential steps
- Speed/efficiency is critical
- One approach is clearly best
- Simple to moderate complexity
First, install the package and set up your API key:
composer require claude-php-agentSet your Anthropic API key:
export ANTHROPIC_API_KEY='your-api-key-here'Let's create a simple ToT agent to solve a classic problem.
Create a file my_first_tot.php:
<?php
require_once 'vendor/autoload.php';
use ClaudeAgents\Agents\TreeOfThoughtsAgent;
use ClaudePhp\ClaudePhp;
// Initialize the Claude client
$client = new ClaudePhp(apiKey: getenv('ANTHROPIC_API_KEY'));
// Create a ToT agent with best-first search
$agent = new TreeOfThoughtsAgent($client, [
'name' => 'my_first_tot',
'branch_count' => 3, // Generate 3 ideas per node
'max_depth' => 3, // Explore up to 3 levels deep
'search_strategy' => 'best_first',
]);
// Solve the classic "24 game"
$problem = "Use the numbers 3, 5, 7, 11 with basic operations (+, -, *, /) to make 24";
echo "Problem: {$problem}\n\n";
$result = $agent->run($problem);
if ($result->isSuccess()) {
echo "Solution Path:\n";
echo $result->getAnswer() . "\n\n";
// Examine the metadata
$metadata = $result->getMetadata();
echo "Strategy: {$metadata['strategy']}\n";
echo "Nodes explored: {$metadata['total_nodes']}\n";
echo "Tree depth: {$metadata['max_depth']}\n";
echo "Solution path length: {$metadata['path_length']}\n";
echo "Best score: " . round($metadata['best_score'], 2) . "/10\n";
echo "Tokens used: " . ($metadata['tokens']['input'] + $metadata['tokens']['output']) . "\n";
} else {
echo "Error: " . $result->getError() . "\n";
}Run it:
php my_first_tot.phpThe agent will output something like:
Solution Path:
Step 1 (Score: 8.5): Try combining larger numbers first: 11 * 7 = 77
Step 2 (Score: 9.0): Then subtract to reduce: 77 - 5 = 72
Step 3 (Score: 9.5): Divide to reach target: 72 / 3 = 24
Strategy: best_first
Nodes explored: 13
Tree depth: 3
Solution path length: 4
Best score: 9.5/10
Tokens used: 1847
- Root Node: Started with the problem
- First Level: Generated 3 different approaches
- Evaluation: Scored each approach (1-10)
- Exploration: Expanded the best-scored approaches
- Continued: Repeated until max depth reached
- Selection: Returned the highest-scored complete path
ToT supports three search strategies. Let's compare them.
Explores the most promising branches first.
$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 3,
'max_depth' => 3,
'search_strategy' => 'best_first',
]);
$result = $agent->run("How can I reduce my monthly expenses by $500?");Characteristics:
- Most token-efficient
- Focuses on quality over coverage
- May miss alternative solutions
- Best for optimization problems
Explores all nodes at each level before going deeper.
$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 2,
'max_depth' => 3,
'search_strategy' => 'breadth_first',
]);
$result = $agent->run("What are the pros and cons of remote work?");Characteristics:
- Comprehensive exploration
- Sees all options at each level
- Higher token usage
- Best for exploratory problems
Follows one branch completely before exploring others.
$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 2,
'max_depth' => 4,
'search_strategy' => 'depth_first',
]);
$result = $agent->run("Debug this: users can't login after password reset");Characteristics:
- Follows logical sequences
- Lower memory usage
- May miss better alternatives
- Best for sequential problems
<?php
require_once 'vendor/autoload.php';
use ClaudeAgents\Agents\TreeOfThoughtsAgent;
use ClaudePhp\ClaudePhp;
$client = new ClaudePhp(apiKey: getenv('ANTHROPIC_API_KEY'));
$problem = "Plan a healthy dinner for 4 people under $30";
$strategies = ['best_first', 'breadth_first', 'depth_first'];
foreach ($strategies as $strategy) {
echo "\n=== {$strategy} ===\n";
$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 3,
'max_depth' => 2,
'search_strategy' => $strategy,
]);
$result = $agent->run($problem);
if ($result->isSuccess()) {
$metadata = $result->getMetadata();
echo "Nodes explored: {$metadata['total_nodes']}\n";
echo "Tokens used: " . ($metadata['tokens']['input'] + $metadata['tokens']['output']) . "\n";
}
}ToT excels at mathematical problems with multiple solution paths.
<?php
require_once 'vendor/autoload.php';
use ClaudeAgents\Agents\TreeOfThoughtsAgent;
use ClaudePhp\ClaudePhp;
$client = new ClaudePhp(apiKey: getenv('ANTHROPIC_API_KEY'));
$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 4, // More branches for more approaches
'max_depth' => 3,
'search_strategy' => 'best_first',
]);
// Classic math puzzle
$problem = "I'm thinking of a number. If I multiply it by 3, add 7, " .
"then divide by 2, I get 13. What's my number?";
echo "Problem: {$problem}\n\n";
$result = $agent->run($problem);
if ($result->isSuccess()) {
echo $result->getAnswer() . "\n\n";
$metadata = $result->getMetadata();
echo "The agent explored {$metadata['total_nodes']} different approaches\n";
echo "to find the best solution (score: " . round($metadata['best_score'], 1) . "/10)\n";
}$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 3,
'max_depth' => 4,
'search_strategy' => 'best_first',
]);
$problem = "A farmer has 100 feet of fence. What dimensions of a rectangular " .
"pen will maximize the area? Consider different approaches.";
$result = $agent->run($problem);ToT is excellent for planning problems with multiple valid approaches.
<?php
require_once 'vendor/autoload.php';
use ClaudeAgents\Agents\TreeOfThoughtsAgent;
use ClaudePhp\ClaudePhp;
$client = new ClaudePhp(apiKey: getenv('ANTHROPIC_API_KEY'));
// Use breadth-first to explore different strategies
$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 4,
'max_depth' => 3,
'search_strategy' => 'breadth_first',
]);
$problem = "Plan a go-to-market strategy for a new AI-powered task manager. " .
"Consider target audience, pricing, channels, and timeline.";
echo "Strategic Planning Problem:\n{$problem}\n\n";
$result = $agent->run($problem);
if ($result->isSuccess()) {
echo "Recommended Strategy:\n";
echo $result->getAnswer() . "\n\n";
$metadata = $result->getMetadata();
echo "Explored {$metadata['total_nodes']} strategic options\n";
echo "Evaluation depth: {$metadata['max_depth']} levels\n";
}$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 3,
'max_depth' => 3,
'search_strategy' => 'best_first',
]);
$problem = "I have $10,000 to split between marketing, development, " .
"and operations for my startup. How should I allocate it?";
$result = $agent->run($problem);ToT helps explore design alternatives systematically.
<?php
require_once 'vendor/autoload.php';
use ClaudeAgents\Agents\TreeOfThoughtsAgent;
use ClaudePhp\ClaudePhp;
$client = new ClaudePhp(apiKey: getenv('ANTHROPIC_API_KEY'));
$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 3,
'max_depth' => 3,
'search_strategy' => 'best_first',
]);
$problem = "Design a database schema for a social media platform with users, posts, " .
"comments, and likes. Consider scalability, query performance, and data integrity.";
echo "Design Problem:\n{$problem}\n\n";
$result = $agent->run($problem);
if ($result->isSuccess()) {
echo "Recommended Design:\n";
echo $result->getAnswer() . "\n\n";
// The agent explored different normalization approaches,
// indexing strategies, and relationship models
}$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 4,
'max_depth' => 2,
'search_strategy' => 'breadth_first',
]);
$problem = "Design a RESTful API for an e-commerce platform. " .
"What endpoints, resources, and authentication approach should we use?";
$result = $agent->run($problem);Learn to balance exploration quality with token efficiency.
<?php
require_once 'vendor/autoload.php';
use ClaudeAgents\Agents\TreeOfThoughtsAgent;
use ClaudePhp\ClaudePhp;
$client = new ClaudePhp(apiKey: getenv('ANTHROPIC_API_KEY'));
$problem = "Optimize a website's loading time. What are the best approaches?";
// Configuration 1: Quick exploration (low tokens)
$quick = new TreeOfThoughtsAgent($client, [
'branch_count' => 2,
'max_depth' => 2,
'search_strategy' => 'best_first',
]);
// Configuration 2: Balanced
$balanced = new TreeOfThoughtsAgent($client, [
'branch_count' => 3,
'max_depth' => 3,
'search_strategy' => 'best_first',
]);
// Configuration 3: Thorough exploration (high tokens)
$thorough = new TreeOfThoughtsAgent($client, [
'branch_count' => 5,
'max_depth' => 4,
'search_strategy' => 'breadth_first',
]);
// Compare results
foreach (['quick' => $quick, 'balanced' => $balanced, 'thorough' => $thorough] as $name => $agent) {
echo "\n=== {$name} configuration ===\n";
$result = $agent->run($problem);
if ($result->isSuccess()) {
$metadata = $result->getMetadata();
echo "Nodes: {$metadata['total_nodes']}, ";
echo "Tokens: " . ($metadata['tokens']['input'] + $metadata['tokens']['output']) . ", ";
echo "Score: " . round($metadata['best_score'], 1) . "/10\n";
}
}// For prototyping (fast iteration)
$prototype = new TreeOfThoughtsAgent($client, [
'branch_count' => 2,
'max_depth' => 2,
]);
// For production (quality solutions)
$production = new TreeOfThoughtsAgent($client, [
'branch_count' => 3,
'max_depth' => 3,
'search_strategy' => 'best_first',
]);
// For critical decisions (exhaustive search)
$critical = new TreeOfThoughtsAgent($client, [
'branch_count' => 4,
'max_depth' => 4,
'search_strategy' => 'best_first',
]);
// For exploratory analysis (see all options)
$exploratory = new TreeOfThoughtsAgent($client, [
'branch_count' => 4,
'max_depth' => 3,
'search_strategy' => 'breadth_first',
]);Build robust, production-ready ToT systems.
<?php
require_once 'vendor/autoload.php';
use ClaudeAgents\Agents\TreeOfThoughtsAgent;
use ClaudePhp\ClaudePhp;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
// Setup logging
$logger = new Logger('tot-production');
$logger->pushHandler(new StreamHandler('logs/tot.log', Logger::INFO));
// Initialize client
$client = new ClaudePhp(apiKey: getenv('ANTHROPIC_API_KEY'));
// Create production-ready agent
$agent = new TreeOfThoughtsAgent($client, [
'name' => 'production_tot',
'branch_count' => 3,
'max_depth' => 3,
'search_strategy' => 'best_first',
'logger' => $logger,
]);
// Business problem
$problem = "Our SaaS churn rate is 8%. What are the most effective " .
"strategies to reduce it to under 5% in 6 months?";
try {
$logger->info("Starting ToT analysis", ['problem' => $problem]);
$result = $agent->run($problem);
if ($result->isSuccess()) {
// Extract solution
$solution = $result->getAnswer();
$metadata = $result->getMetadata();
// Log success
$logger->info("ToT analysis complete", [
'nodes_explored' => $metadata['total_nodes'],
'best_score' => $metadata['best_score'],
'tokens_used' => $metadata['tokens']['input'] + $metadata['tokens']['output'],
]);
// Store for analysis
$analysisData = [
'problem' => $problem,
'solution' => $solution,
'metadata' => $metadata,
'timestamp' => date('Y-m-d H:i:s'),
];
file_put_contents(
'analysis_results.json',
json_encode($analysisData, JSON_PRETTY_PRINT)
);
// Display results
echo "=== Strategic Analysis Complete ===\n\n";
echo $solution . "\n\n";
echo "Confidence Score: " . round($metadata['best_score'], 1) . "/10\n";
echo "Analysis Depth: {$metadata['path_length']} steps\n";
} else {
// Handle failure
$error = $result->getError();
$logger->error("ToT analysis failed", ['error' => $error]);
echo "Analysis failed: {$error}\n";
}
} catch (\Exception $e) {
$logger->error("Unexpected error", ['exception' => $e->getMessage()]);
echo "Unexpected error: " . $e->getMessage() . "\n";
}class ToTAnalyzer
{
private TreeOfThoughtsAgent $agent;
private LoggerInterface $logger;
private int $maxRetries = 3;
public function analyze(string $problem): array
{
$attempts = 0;
while ($attempts < $this->maxRetries) {
try {
$result = $this->agent->run($problem);
if ($result->isSuccess()) {
return [
'success' => true,
'solution' => $result->getAnswer(),
'metadata' => $result->getMetadata(),
];
}
// Log failure and retry
$this->logger->warning("Analysis failed, retrying", [
'attempt' => $attempts + 1,
'error' => $result->getError(),
]);
$attempts++;
sleep(2 ** $attempts); // Exponential backoff
} catch (\Exception $e) {
$this->logger->error("Exception during analysis", [
'exception' => $e->getMessage(),
]);
$attempts++;
}
}
return [
'success' => false,
'error' => 'Analysis failed after ' . $this->maxRetries . ' attempts',
];
}
}class ToTMetrics
{
private array $metrics = [];
public function recordAnalysis(AgentResult $result): void
{
if (!$result->isSuccess()) {
return;
}
$metadata = $result->getMetadata();
$this->metrics[] = [
'timestamp' => time(),
'nodes_explored' => $metadata['total_nodes'],
'max_depth' => $metadata['max_depth'],
'best_score' => $metadata['best_score'],
'tokens_used' => $metadata['tokens']['input'] + $metadata['tokens']['output'],
'strategy' => $metadata['strategy'],
];
}
public function getAverageTokens(): float
{
$total = array_sum(array_column($this->metrics, 'tokens_used'));
return $total / count($this->metrics);
}
public function getAverageScore(): float
{
$total = array_sum(array_column($this->metrics, 'best_score'));
return $total / count($this->metrics);
}
public function report(): array
{
return [
'total_analyses' => count($this->metrics),
'avg_tokens' => round($this->getAverageTokens(), 0),
'avg_score' => round($this->getAverageScore(), 2),
'avg_nodes' => round(array_sum(array_column($this->metrics, 'nodes_explored')) / count($this->metrics), 0),
];
}
}function compareApproaches(TreeOfThoughtsAgent $agent, string $problem, array $approaches): array
{
$results = [];
foreach ($approaches as $approach) {
$fullProblem = "{$problem}\n\nSpecific approach to explore: {$approach}";
$result = $agent->run($fullProblem);
if ($result->isSuccess()) {
$results[$approach] = [
'solution' => $result->getAnswer(),
'score' => $result->getMetadata()['best_score'],
];
}
}
// Sort by score
uasort($results, fn($a, $b) => $b['score'] <=> $a['score']);
return $results;
}
// Usage
$approaches = [
'Cost-focused approach',
'Speed-focused approach',
'Quality-focused approach',
];
$results = compareApproaches($agent, $problem, $approaches);function iterativeRefinement(TreeOfThoughtsAgent $agent, string $problem, int $iterations = 3): string
{
$bestSolution = '';
$bestScore = 0;
for ($i = 0; $i < $iterations; $i++) {
$prompt = $i === 0
? $problem
: "{$problem}\n\nPrevious attempt: {$bestSolution}\n\nFind a better approach:";
$result = $agent->run($prompt);
if ($result->isSuccess()) {
$score = $result->getMetadata()['best_score'];
if ($score > $bestScore) {
$bestScore = $score;
$bestSolution = $result->getAnswer();
}
}
}
return $bestSolution;
}function parallelExplore(ClaudePhp $client, string $problem, array $strategies): array
{
$results = [];
foreach ($strategies as $strategy) {
$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 3,
'max_depth' => 3,
'search_strategy' => $strategy,
]);
$result = $agent->run($problem);
if ($result->isSuccess()) {
$results[$strategy] = [
'solution' => $result->getAnswer(),
'metadata' => $result->getMetadata(),
];
}
}
return $results;
}
// Usage
$results = parallelExplore($client, $problem, ['best_first', 'breadth_first', 'depth_first']);Symptoms: Solution quality is lower than expected
Solutions:
- Increase branch count for more alternatives
- Use best-first search strategy
- Increase max depth for deeper exploration
$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 5, // More alternatives
'max_depth' => 4, // Deeper exploration
'search_strategy' => 'best_first', // Focus on quality
]);Symptoms: High token usage, long wait times
Solutions:
- Reduce branch count
- Reduce max depth
- Use best-first search
$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 2, // Fewer alternatives
'max_depth' => 2, // Shallower exploration
'search_strategy' => 'best_first',
]);Symptoms: Agent finds one solution but misses others
Solutions:
- Use breadth-first search
- Increase branch count
- Reduce max depth to explore widely but not deeply
$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 4,
'max_depth' => 2,
'search_strategy' => 'breadth_first',
]);Symptoms: Different runs produce very different results
Solutions:
- Increase branch count for more stability
- Use best-first for more consistent quality
- Add logging to understand variations
$agent = new TreeOfThoughtsAgent($client, [
'branch_count' => 4,
'search_strategy' => 'best_first',
'logger' => $logger,
]);-
Combine with Other Agents:
- Use ToT for exploration, then refine with ChainOfThought
- Use IntentClassifier to route to ToT when needed
-
Custom Evaluation:
- Extend the Evaluator class for domain-specific scoring
- Implement custom pruning strategies
-
Integrate with Workflows:
- Build multi-step workflows with ToT at decision points
- Cache and reuse exploration results
Try these problems with ToT:
- Easy: "Plan a week of healthy meals under $100"
- Medium: "Design a caching strategy for a high-traffic API"
- Hard: "Optimize a recommendation algorithm for personalization and performance"
- Check the examples/tot_example.php file
- Read the API documentation
- Review the test files for usage patterns
You now have a comprehensive understanding of Tree-of-Thoughts reasoning! Key takeaways:
- ToT explores multiple paths for better solutions
- Choose your strategy based on your needs (best-first, breadth-first, depth-first)
- Balance branch count and depth for optimal performance
- Use logging and monitoring in production
- Iterate and refine your approach based on results
Happy exploring! 🌳