Blackboard planner¶
make_blackboard_planner returns an agent whose state is a flat
to-do list (set_plan / get_plan / mark_done tools). Simpler
than a DAG for exploratory work where the structure isn't known up
front and the LLM iterates on a checklist.
Canonical name:
make_blackboard_planneris a backward-compat alias forblackboard_orchestrator_agent(inlazybridge.ext.planners). New code can use either; both resolve to the same factory.
Source¶
"""Demo: ``lazybridge.ext.planners.make_blackboard_planner`` with three sub-agents.
The factory itself lives in :mod:`lazybridge.ext.planners.blackboard` — this
file just shows a minimal usage pattern. The blackboard planner manages
a flat to-do list (``set_plan`` / ``get_plan`` / ``mark_done``) instead
of composing a DAG; less precise but easier to prompt for exploratory work.
"""
from lazybridge import Agent, LLMEngine
from lazybridge.ext.planners import make_blackboard_planner
def web_search(query: str) -> str:
"""Look up current facts (stub — wire to a real search API)."""
return f"[stub web result for {query!r}]"
def add(a: float, b: float) -> float:
"""Add two numbers."""
return a + b
def main() -> None:
research = Agent(
engine=LLMEngine("gemini-3-flash-preview", system="Look up facts via web_search."),
tools=[web_search],
name="research",
description="Web lookups. No math.",
)
math = Agent(
engine=LLMEngine("gemini-3-flash-preview", system="Solve arithmetic with add."),
tools=[add],
name="math",
description="Arithmetic only.",
)
writer = Agent(
engine=LLMEngine("gemini-3-flash-preview", system="Synthesise prior results into prose."),
name="writer",
description="Turns prior results into a short paragraph.",
)
planner = make_blackboard_planner([research, math, writer], verbose=True)
queries = [
"What does FAANG stand for?",
"What is 17 * 23 + 5?",
"Research recent agent frameworks and write a one-paragraph summary.",
]
for q in queries:
print(f"\n>>> {q}")
print(planner(q).text())
if __name__ == "__main__":
main()
Walkthrough¶
make_blackboard_planner()wires up anAgentwith three tools (set_plan,get_plan,mark_done) and aStore-backed scratch space. The LLM treats the to-do list as state it can read and update.- No DAG validation — the LLM is free to revise the plan,
reorder tasks, or insert new ones at any point. This is what
makes it "exploratory" relative to the typed
PlanSpecpattern in Agent builds a plan. - Pair with
Memoryto give the planner a running record of what's been tried, why a previous attempt failed, what the current state of the world looks like — useful for tasks that span many iterations.
Variations¶
- Persist the blackboard via
Store(db="planner.sqlite")so a long-running task can be paused and resumed. The to-do list survives across runs. - Add a
verify=judgeto gatemark_done— useful when the planner tends to over-claim completion. - Wrap as a sub-agent (
tools=[planner]) of a higher-level orchestrator that dispatches between blackboard planning and other strategies.
See also¶
- Plan tool — sibling factory; structured decision tree instead of a flat list.
- Agent builds a plan — typed
PlanSpecalternative when the structure IS known. - Store — backs the blackboard state.