Tree Search#
Source: examples/patterns/tree_search.py
Introduction#
Tree of Thoughts motivates explicit branching and ranking instead of single-pass revision. This example uses dedicated generator/evaluator delegates and a bounded beam search to show search-policy behavior (expand, score, prune) in a traceable way.
Note
This example’s checked-in local LlamaCppServerLLMClient config uses a
Qwen3-4B GGUF model. On lower-RAM machines, swap in a smaller local
model or start with Ollama Local Client.
Technical Implementation#
Configure
Tracerwith JSONL + console output so each run emits machine-readable traces and lifecycle logs.Build generator and evaluator delegates with
DirectLLMCalland a managedLlamaCppServerLLMClient.Execute
TreeSearchPattern.run(...)with explicit search controls and preserve frontier diagnostics.Print a compact JSON payload including
trace_infofor deterministic tests and docs examples.
flowchart LR
A["Input prompt or scenario"] --> B["main(): runtime wiring"]
B --> C["TreeSearchPattern.run(...)"]
C --> D["generator/evaluator delegates expand and score candidate nodes"]
C --> E["Tracer JSONL + console events"]
D --> F["ExecutionResult/payload"]
E --> F
F --> G["Printed JSON output"]
1from __future__ import annotations
2
3import json
4from pathlib import Path
5
6from design_research_agents import DirectLLMCall, LlamaCppServerLLMClient, Tracer
7from design_research_agents.patterns import TreeSearchPattern
8
9# This checked-in local config uses a Qwen3-4B GGUF model to exercise a richer
10# multi-step path. On lower-RAM machines, swap in a smaller local model or
11# start with the lighter Ollama local client example first.
12_EXAMPLE_LLAMA_CLIENT_KWARGS = {
13 "model": "Qwen_Qwen3-4B-Instruct-2507-Q4_K_M.gguf",
14 "hf_model_repo_id": "bartowski/Qwen_Qwen3-4B-Instruct-2507-GGUF",
15 "api_model": "qwen3-4b-instruct-2507-q4km",
16 "context_window": 8192,
17 "startup_timeout_seconds": 240.0,
18 "request_timeout_seconds": 240.0,
19}
20
21
22def main() -> None:
23 """Run one tree-search workflow and print JSON summary."""
24 # Fixed request id keeps traces and docs output deterministic across runs.
25 request_id = "example-pattern-tree-search-design-001"
26 tracer = Tracer(
27 enabled=True,
28 trace_dir=Path("artifacts/examples/traces"),
29 enable_jsonl=True,
30 enable_console=True,
31 )
32 with LlamaCppServerLLMClient(**_EXAMPLE_LLAMA_CLIENT_KWARGS) as llm_client:
33 generator_delegate = DirectLLMCall(
34 llm_client=llm_client,
35 system_prompt=(
36 "You are a search-node generator. Return JSON with key `candidates` mapped to a list of"
37 " 1-2 short candidate objects. Keep output concise."
38 ),
39 tracer=tracer,
40 )
41 evaluator_delegate = DirectLLMCall(
42 llm_client=llm_client,
43 system_prompt=(
44 "You are a search-node evaluator. Return JSON with numeric key `score` in [0,1]"
45 " for the candidate provided by the user."
46 ),
47 tracer=tracer,
48 )
49 pattern = TreeSearchPattern(
50 generator_delegate=generator_delegate,
51 evaluator_delegate=evaluator_delegate,
52 max_depth=2,
53 branch_factor=2,
54 beam_width=1,
55 search_strategy="beam",
56 tracer=tracer,
57 )
58 result = pattern.run(
59 "Find the most robust concept architecture for a serviceable edge-device enclosure.",
60 request_id=request_id,
61 )
62 # Print the results
63 summary = result.summary()
64 print(json.dumps(summary, ensure_ascii=True, indent=2, sort_keys=True))
65
66
67if __name__ == "__main__":
68 main()
Expected Results#
Run Command
PYTHONPATH=src python3 examples/patterns/tree_search.py
Example output shape (values vary by run):
{
"success": true,
"final_output": "<example-specific payload>",
"terminated_reason": "<string-or-null>",
"error": null,
"trace": {
"request_id": "<request-id>",
"trace_dir": "artifacts/examples/traces",
"trace_path": "artifacts/examples/traces/run_<timestamp>_<request_id>.jsonl"
}
}