0Pricing
AI Prompt Engineering · Lekcja

Eksploracja Tree-of-Thought

Rozgałęzianie i ocenianie myśli

Eksploracja Tree-of-Thought to bezpłatna lekcja AI Prompt Engineering na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Prompt Engineering, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Prompt Engineering zawiera 4 lekcji w sumie.

Od łańcuchów do drzew

Tree-of-Thought (ToT, Yao i in., 2023) uogólnia chain-of-thought z pojedynczej ścieżki liniowej do drzewa wyszukiwania częściowych rozwiązań. Każdy węzeł reprezentuje spójną myśl pośrednią, a gałęzie badają alternatywne kontynuacje.

Pozwala to modelowi prowadzić rozumowanie: generować wiele kolejnych kroków, oceniać je, zachowywać obiecujące oraz wracać z błędnych ścieżek, naśladując systematyczne rozwiązywanie problemów zamiast angażować się w pierwszy pomysł.

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 score

Cztery elementy ToT

System ToT obejmuje cztery decyzje projektowe: dekompozycję myśli (co stanowi krok), generator myśli (jak proponować kolejne kroki), ewaluator stanu (jak oceniać rozwiązania częściowe) oraz algorytm wyszukiwania (BFS, DFS lub best-first).

Każdy z tych elementów jest osobnym promptem lub osobną polityką. Projektowanie ToT oznacza określenie wszystkich czterech elementów dla danego zadania.

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
}

Generowanie myśli kandydujących

Istnieją dwie strategie generowania: próbkowanie kilku niezależnych myśli przy umiarkowanej temperaturze (dobre, gdy przestrzeń możliwości jest bogata) albo proponowanie zestawu różnych kolejnych kroków w jednym prompcie (dobre, gdy potrzebne są jawnie odmienne opcje).

Należy używać niewielkiego współczynnika rozgałęzienia (często od 3 do 5); zbyt duża liczba kandydatów gwałtownie zwiększa rozmiar wyszukiwania i koszt.

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))

Ocena stanów

Ewaluator stanu sprawia, że ToT jest czymś więcej niż losowym próbkowaniem. Ocenia on, jak obiecujące jest rozwiązanie częściowe, korzystając z promptu wartościującego (oceń ten stan w skali od 1 do 10 pod kątem rozwiązania problemu) albo z promptu głosowania (który z tych stanów jest najbardziej obiecujący).

Głosowanie między kandydatami jest często bardziej odporne niż ocena bezwzględna, ponieważ względne osądy są dla modelu łatwiejsze.

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 z wyszukiwaniem wiązkowym

Wszerz działający ToT rozwija wszystkie węzły na froncie o jeden poziom naraz, a następnie zachowuje tylko b najlepszych według wyniku ewaluatora (tworząc wiązkę). Ogranicza to eksplozję rozmiaru wyszukiwania, jednocześnie badając wiele linii równolegle.

Szerokość wiązki b wyznacza kompromis między zakresem eksploracji a kosztem; szerokość 5 i głębokość 3 to częsty punkt wyjścia dla łamigłówek o ustrukturyzowanej formie.

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 z nawrotami

W głąb działający ToT zagłębia się w najbardziej obiecującą gałąź i cofa się, gdy ewaluator uzna stan za beznadziejny. Sprawdza się to w problemach, w których można jasno określić, że stan częściowy jest niedopuszczalny, takich jak łamigłówki z ograniczeniami.

Wczesne odrzucanie niemożliwych gałęzi zapewnia największy wzrost wydajności, ponieważ pozwala uniknąć niepotrzebnego rozwijania skazanych na porażkę poddrzew.

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 None

ToT a self-consistency

Self-consistency próbuje niezależne kompletne łańcuchy i przeprowadza głosowanie. ToT aktywnie ukierunkowuje eksplorację za pomocą oceny pośredniej i nawrotów, przeznaczając obliczenia na obiecujące obszary.

ToT sprawdza się w problemach wymagających planowania lub wyszukiwania oraz tam, gdzie wczesne błędy są nieodwracalne (Game of 24, krzyżówki, planowanie). W zadaniach, dla których można tanio wygenerować różnorodne łańcuchy i które mają dyskretną odpowiedź, self-consistency jest prostsza i często wystarczająca.

# 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 calls

Eksplozja kosztów i budżety

ToT jest kosztowny: każdy węzeł wymaga wywołań generowania i oceny. Całkowity koszt skaluje się w przybliżeniu jako branch x depth x beam, powiększone o wywołania ewaluatora. Bez twardego budżetu może gwałtownie wzrosnąć.

Należy ograniczyć łączną liczbę wywołań LLM, używać wyszukiwania best-first, aby przeznaczać budżet na front o największej wartości, oraz w razie wyczerpania budżetu zwracać najlepsze rozwiązanie częściowe.

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 best

Niezawodność ewaluatora

ToT jest tylko tak dobry, jak jego ewaluator. Źle skalibrowany ewaluator może odrzucać poprawne gałęzie lub podążać za ślepymi zaułkami. Można go ulepszyć za pomocą głosowania (wielu ocen dla każdego stanu), przykładów few-shot dobrych i złych stanów albo zewnętrznego weryfikatora (testu jednostkowego, solvera, checkera).

Jeśli istnieje obiektywne sprawdzenie (czy równanie jest spełnione, czy kod przechodzi testy), należy preferować je względem oceny 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 available

Praktyczne zastosowanie

ToT sprawdza się w wąskiej, ale wartościowej klasie problemów: planowaniu wieloetapowym, łamigłówkach kombinatorycznych oraz zadaniach, w których weryfikacja kroku jest tańsza niż rozwiązanie całości. W większości codziennych zastosowań promptów ToT jest przerostem formy nad treścią.

W przypadku modeli z natywnym rozumowaniem i silnymi wbudowanymi mechanizmami wyszukiwania jawny szkielet ToT często zwiększa koszty bez znaczących korzyści; przed jego przyjęciem należy wykonać testy porównawcze.

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'

Minimalny solver ToT

Kompletny przebieg obejmuje: zdefiniowanie kroku, zaproponowanie niewielkiej gałęzi myśli, ocenę każdej z nich (za pomocą głosowania lub weryfikatora), wyszukiwanie metodą BFS z wiązką albo DFS z nawrotami w ramach budżetu wywołań oraz zwrócenie najlepszego stanu końcowego.

Należy rejestrować liczbę węzłów i wyniki ewaluatora, aby empirycznie dostrajać współczynnik rozgałęzienia, głębokość i wiązkę dla poszczególnych zadań.

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)

Szybkie sprawdzenie

Proszę wybrać właściwą strategię rozumowania.

Podsumowanie

Najważniejsze wnioski:

  • ToT uogólnia CoT do drzewa wyszukiwania z generowaniem myśli, oceną stanów i algorytmem wyszukiwania.
  • Należy używać BFS z wiązką lub DFS z nawrotami, a współczynnik rozgałęzienia utrzymywać na niskim poziomie, aby kontrolować eksplozję rozmiaru wyszukiwania.
  • Ewaluator stanu ma kluczowe znaczenie; należy zwiększać jego odporność za pomocą głosowania lub zewnętrznego weryfikatora.
  • Koszt skaluje się jako branch x depth x beam, dlatego należy narzucić budżet wywołań, często korzystając z wyszukiwania best-first.
  • ToT należy rezerwować dla problemów planistycznych i kombinatorycznych, w których można weryfikować poszczególne kroki; w codziennych zastosowaniach promptów jest przerostem formy nad treścią.

Często zadawane pytania

Czy lekcja „Eksploracja Tree-of-Thought” jest bezpłatna?

Tak — pełny tekst „Eksploracja Tree-of-Thought” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Prompt Engineering, przejdź na CoddyKit PRO. Kurs AI Prompt Engineering zawiera 4 lekcji w sumie.

Co nauczysz się w „Eksploracja Tree-of-Thought”?

Rozgałęzianie i ocenianie myśli Ćwiczysz AI Prompt Engineering z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć AI Prompt Engineering?

Nie wymagamy żadnego doświadczenia. AI Prompt Engineering w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Eksploracja Tree-of-Thought”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji AI Prompt Engineering?

Tak. Każda lekcja AI Prompt Engineering zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Promptowanie Chain-of-Thought
  2. Próbkowanie self-consistency
  3. Eksploracja Tree-of-Thought
  4. Kiedy prompty rozumowania pomagają
← Powrót do AI Prompt Engineering