Esplorazione tree-of-thought
Creare diramazioni e valutare i ragionamenti.
Esplorazione tree-of-thought è una lezione AI Prompt Engineering gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Prompt Engineering, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Prompt Engineering include 4 lezioni in totale.
Dalle catene agli alberi
Tree-of-Thought (ToT, Yao et al., 2023) generalizza la chain-of-thought da un singolo percorso lineare a un albero di ricerca di soluzioni parziali. Ogni nodo rappresenta un passaggio intermedio coerente; i rami esplorano continuazioni alternative.
Questo consente al modello di ragionare in modo ponderato: generare più passaggi successivi, valutarli, conservare quelli promettenti e tornare indietro dai vicoli ciechi, imitando una risoluzione sistematica dei problemi anziché impegnarsi sulla prima idea.
class ThoughtNode:
def __init__(self, state, parent=None):
self.state = state # partial solution / reasoning so far
self.parent = parent
self.children = []
self.value = None # evaluator scoreI quattro componenti di ToT
Un sistema ToT prevede quattro scelte progettuali: la scomposizione del ragionamento (che cosa costituisce un passaggio), il generatore dei passaggi (come proporre i passaggi successivi), il valutatore dello stato (come assegnare un punteggio alle soluzioni parziali) e l'algoritmo di ricerca (BFS, DFS o best-first).
Ognuno di questi elementi è un prompt o una policy separata. Progettare un sistema ToT significa specificare tutti e quattro gli elementi per l'attività in questione.
tot = {
'decompose': step_definition, # e.g. one equation, one move
'generate': propose_thoughts, # sampling or proposal prompt
'evaluate': score_state, # value/vote prompt
'search': bfs_with_beam, # BFS | DFS | best-first
}Generazione dei passaggi candidati
Esistono due strategie di generazione: campionare diversi passaggi indipendenti a temperatura moderata (utile quando lo spazio delle possibilità è ampio) oppure proporre un insieme di passaggi successivi distinti in un unico prompt (utile quando si desiderano opzioni esplicitamente diverse).
Generare un fattore di ramificazione ridotto (spesso da 3 a 5); un numero eccessivo di candidati fa esplodere la ricerca e i costi.
def propose_thoughts(state, k=4):
prompt = (
'Given the partial solution below, propose ' + str(k) +
' DISTINCT possible next steps.\n' + state
)
return parse_list(llm(prompt, temperature=0.7))Valutazione degli stati
Il valutatore dello stato è ciò che rende ToT qualcosa di più del semplice campionamento casuale. Assegna un punteggio al potenziale di una soluzione parziale, tramite un prompt di valutazione (assegnare allo stato un valore da 1 a 10 in base a quanto avvicina alla soluzione) oppure un prompt di votazione (quale di questi stati è più promettente).
Votare tra i candidati è spesso più robusto dei punteggi assoluti, perché per il modello i giudizi relativi sono più semplici.
def score_state(state):
prompt = (
'Rate how likely this partial solution leads to a correct '
'final answer. Reply sure / likely / impossible.\n' + state
)
label = llm(prompt, temperature=0).strip().lower()
return {'sure': 1.0, 'likely': 0.5, 'impossible': 0.0}.get(label, 0.3)BFS con beam search
Il ToT breadth-first espande tutti i nodi della frontiera di un livello alla volta, quindi conserva solo i primi b in base al punteggio del valutatore (un beam). In questo modo limita l'esplosione della ricerca esplorando più linee in parallelo.
L'ampiezza del beam b stabilisce un compromesso tra l'ampiezza dell'esplorazione e il costo; per i rompicapi strutturati, un'ampiezza pari a 5 e una profondità pari a 3 sono un punto di partenza comune.
def bfs_with_beam(root, depth, branch, beam):
frontier = [root]
for _ in range(depth):
nxt = []
for node in frontier:
for t in propose_thoughts(node.state, branch):
child = ThoughtNode(node.state + '\n' + t, node)
child.value = score_state(child.state)
nxt.append(child)
frontier = sorted(nxt, key=lambda n: -n.value)[:beam]
return max(frontier, key=lambda n: n.value)DFS con backtracking
Il ToT depth-first si addentra nel ramo più promettente e ricorre al backtracking quando il valutatore considera senza speranza uno stato. È adatto ai problemi in cui è chiara la nozione di stato parziale non ammissibile, come i rompicapi a vincoli.
Potare precocemente i rami impossibili è il principale vantaggio in termini di efficienza, perché evita di espandere sottoalberi destinati a fallire.
def dfs(node, depth, branch, prune=0.2):
if depth == 0 or is_solution(node.state):
return node
for t in propose_thoughts(node.state, branch):
child = ThoughtNode(node.state + '\n' + t, node)
child.value = score_state(child.state)
if child.value < prune:
continue # backtrack: prune dead end
res = dfs(child, depth - 1, branch, prune)
if res and is_solution(res.state):
return res
return NoneToT e self-consistency a confronto
La self-consistency campiona catene complete e indipendenti, quindi vota le risposte. ToT invece guida attivamente l'esplorazione mediante la valutazione intermedia e il backtracking, investendo il calcolo nei percorsi promettenti.
ToT è particolarmente efficace nei problemi che richiedono pianificazione o ricerca, oppure in cui gli errori iniziali sono fatali (Game of 24, cruciverba, pianificazione). Per le attività con catene diverse a basso costo e una risposta discreta, la self-consistency è più semplice e spesso sufficiente.
# Rule of thumb
# - reachable by diverse single passes -> self-consistency
# - needs lookahead / pruning / backtrack -> tree-of-thought
# ToT cost ~ branch * depth * beam * (gen + eval) LLM callsEsplosione dei costi e budget
ToT è costoso: ogni nodo genera chiamate di generazione e valutazione. Il costo totale cresce all'incirca come ramificazione x profondità x ampiezza del beam, oltre alle chiamate al valutatore. Senza un budget rigido, può aumentare rapidamente.
Limitare il numero totale di chiamate LLM, usare la ricerca best-first per destinare il budget alla frontiera di maggior valore e ricorrere alla soluzione parziale migliore se il budget si esaurisce.
import heapq
def best_first(root, max_calls):
heap = [(-root.value, root)]
best, calls = root, 0
while heap and calls < max_calls:
_, node = heapq.heappop(heap)
for t in propose_thoughts(node.state, 3):
calls += 1
child = ThoughtNode(node.state + '\n' + t, node)
child.value = score_state(child.state); calls += 1
if child.value > best.value:
best = child
heapq.heappush(heap, (-child.value, child))
return bestAffidabilità del valutatore
ToT è valido solo quanto il suo valutatore. Un valutatore mal calibrato può potare rami corretti o inseguire vicoli ciechi. È possibile migliorarlo con la votazione (più valutazioni per ogni stato), esempi few-shot di stati validi e non validi oppure un verificatore esterno (un unit test, un risolutore o un checker).
Quando esiste un controllo oggettivo (l'equazione è verificata? il codice supera i test?), è preferibile usarlo al posto del giudizio di un LLM.
def robust_eval(state, votes=3):
scores = [score_state(state) for _ in range(votes)]
return sum(scores) / votes # average to reduce judge noise
# Even better: replace with a deterministic verifier when availableApplicabilità pratica
ToT è utile per una classe ristretta ma importante di problemi: pianificazione in più passaggi, rompicapi combinatori e attività in cui verificare un passaggio è più economico che risolvere il problema completo. Per la maggior parte dei prompt quotidiani, ToT è eccessivo.
Con i modelli dotati di ragionamento nativo e di solide capacità di ricerca integrate, uno schema ToT esplicito spesso aggiunge costi senza produrre grandi vantaggi; eseguire benchmark prima di adottarlo.
def choose_strategy(task):
if task.requires_search and task.step_verifiable:
return 'tree-of-thought'
if task.discrete_answer:
return 'self-consistency'
return 'single chain-of-thought'Un risolutore ToT minimale
Dall'inizio alla fine: definire un passaggio, proporre una piccola ramificazione di passaggi, valutare ciascuno di essi (tramite votazione o un verificatore), cercare con BFS-beam o DFS-backtrack entro un budget di chiamate e restituire lo stato terminale migliore.
Registrare il numero di nodi e i punteggi del valutatore per poter regolare empiricamente ramificazione, profondità e beam in base all'attività.
def solve(problem, branch=4, depth=3, beam=5, budget=200):
root = ThoughtNode(problem)
root.value = score_state(root.state)
node = bfs_with_beam(root, depth, branch, beam)
return extract_solution(node.state)Verifica rapida
Scegliere la strategia di deliberazione appropriata.
Riepilogo
Punti chiave:
- ToT generalizza la CoT in un albero di ricerca con generazione dei passaggi, valutazione degli stati e un algoritmo di ricerca.
- Usare BFS con un beam oppure DFS con backtracking; mantenere ridotto il fattore di ramificazione per controllare l'esplosione.
- Il valutatore dello stato è l'elemento cruciale; renderlo più robusto con la votazione o un verificatore esterno.
- Il costo cresce come ramificazione x profondità x beam, quindi imporre un budget di chiamate, spesso tramite la ricerca best-first.
- Riservare ToT ai problemi di pianificazione o combinatori in cui i passaggi sono verificabili; è eccessivo per i prompt quotidiani.
Domande Frequenti
La lezione «Esplorazione tree-of-thought» è gratuita?
Sì — il testo completo di «Esplorazione tree-of-thought» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Prompt Engineering, passa a CoddyKit PRO. Il corso AI Prompt Engineering include 4 lezioni in totale.
Cosa imparerò in «Esplorazione tree-of-thought»?
Creare diramazioni e valutare i ragionamenti. Eserciti AI Prompt Engineering con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare AI Prompt Engineering?
Non è richiesta alcuna esperienza precedente. AI Prompt Engineering su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.
Quanto tempo richiede la lezione «Esplorazione tree-of-thought»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione AI Prompt Engineering?
Sì. Ogni lezione AI Prompt Engineering include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Prompting chain-of-thought
- Campionamento self-consistency
- Esplorazione tree-of-thought
- Quando i prompt di ragionamento sono utili