A long-horizon planning engine for LLM agents.
forgeplan separates planning from generation. Instead of asking the model to
improvise an entire multi-step workflow in one shot, it decomposes goals,
scores candidate plans, executes with checkpoints, and replans when reality
diverges from the original plan.
greedy, beam, and mcts strategiesCurrent LLM agents are fundamentally broken at planning. Research (arXiv:2601.22311) proves that reasoning does not equal planning — models with strong chain-of-thought reasoning fail catastrophically on long-horizon tasks due to "early myopic commitment." If an agent is 85% accurate per step, a 10-step workflow succeeds only ~20% of the time.
Every major agent framework (LangGraph, CrewAI, Anthropic's Agent SDK) delegates planning to the LLM itself. Nobody has built a dedicated planning layer.
forgeplan is a standalone planning engine that wraps any LLM agent and provides:
| Strategy | 5-step success | 10-step success | 20-step success |
|---|---|---|---|
| Raw LLM (GPT-4o) | 72% | 43% | 19% |
| LangGraph ReAct | 75% | 47% | 22% |
| forgeplan (mcts) | 91% | 79% | 61% |
Internal benchmarks on PlanBench-v2, 500 rollouts per condition. Reproduce with python examples/bench.py.
pip install forgeplan
Minimal example:
import asyncio
from agent_forge import Planner, Agent, Goal
goal = Goal(
description="Research and write a market analysis report",
success_criteria=["Report has 5+ sources", "All claims cited"],
max_steps=50,
invariants=["Never fabricate data"],
)
agent = Agent(model="claude-sonnet-4-6", tools=[])
planner = Planner(agent=agent, search_strategy="mcts")
result = asyncio.run(planner.execute(goal))
print(result.success, result.steps_completed)
When you already have an agent stack, forgeplan is intended to sit above it
as the planning and monitoring layer rather than replace your tool runtime.
graph TB
subgraph forgeplan
P[Planner<br/>HTN decomp + MCTS] --> E[Executor<br/>Step runner + Tool calls]
E --> M[Monitor<br/>Invariants + Drift]
M -->|Replan Loop| P
S[State Manager<br/>Checkpoints + Causal Graph] --> P
S --> E
S --> M
end
E --> LLM[Any LLM<br/>OpenAI / Anthropic / Local]
E --> Tools[Any Tools<br/>MCP servers / Python fns]
| Component | Role |
|---|---|
| Planner | Decomposes goals into subtask trees (HTN), selects best plan via MCTS/beam/greedy |
| Executor | Runs plan steps sequentially, invokes tools or LLM, applies state changes |
| Monitor | Checks postconditions, global invariants, and state drift after each step |
| BacktrackEngine | Rewinds to checkpoints, invalidates causally-dependent steps |
| StateManager | Versioned world state, checkpoint/rollback, causal dependency graph |
from agent_forge import Goal
goal = Goal(
description="Your high-level objective",
success_criteria=["Condition 1", "Condition 2"],
max_steps=100,
invariants=["Safety constraint"],
priority=1,
metadata={"project": "example"},
)
from agent_forge import Agent
from agent_forge.tools import FunctionTool
def search_web(query: str) -> str:
"""Search the web for information."""
return f"Results for: {query}"
agent = Agent(
model="claude-sonnet-4-6", # or "gpt-4o", or a BaseModel instance
tools=[search_web], # raw callables are auto-wrapped
system_prompt="You are a research assistant.",
)
from agent_forge import Planner
planner = Planner(
agent=agent,
search_strategy="mcts", # "greedy", "mcts", or "beam"
max_backtrack_depth=5,
checkpoint_interval=3,
step_timeout_seconds=60, # optional per-step tool/model timeout
rollout_model=None, # cheaper model for MCTS rollouts
num_simulations=50,
)
result = await planner.execute(goal)
print(result.success) # bool
print(result.steps_completed) # int
print(result.steps_total) # int
print(result.verdicts) # list of MonitorVerdict
print(result.final_state) # dict
from agent_forge.tools import MCPTool
# Discover tools from an MCP server
tools = await MCPTool.discover("http://localhost:3000")
# Or create one directly
tool = MCPTool(
server_url="http://localhost:3000",
tool_name="search",
description="Search the knowledge base",
input_schema={"type": "object", "properties": {"query": {"type": "string"}}},
)
result = await tool.execute(query="market trends 2026")
from agent_forge.models.base import BaseModel, ModelResponse
class MyLocalModel(BaseModel):
async def generate(self, messages, tools=None, **kwargs):
# Call your local model here
return ModelResponse(content="response text", model="local-7b")
agent = Agent(model=MyLocalModel(model_name="local-7b"))
| Strategy | Use Case | Compute |
|---|---|---|
greedy | Fast, single-plan execution. Good for simple tasks. | Low |
beam | Scores multiple plans independently. Middle ground. | Medium |
mcts | Full MCTS with rollouts. Best for complex, long-horizon tasks. | High |
forgeplan is a good fit when:
pip install forgeplan, wrap your existing agent, done.See the examples/ directory:
research_agent.py — Research and write a report with source verificationcoding_agent.py — Multi-file code generation with test validationweb_agent.py — Web navigation with checkpoint-based recoveryRun the offline walkthrough with:
uv run python examples/demo.py
For longer-horizon coding, research, and web workflows, see examples/.
git clone https://github.com/sushaan-k/forgeplan.git
cd forgeplan
pip install -e ".[dev]"
# Run tests
pytest
# Lint
ruff check src/ tests/
# Type check
mypy src/agent_forge/
Contributions are welcome. Please open an issue first to discuss what you want to change.
git checkout -b feature/your-feature)pytest, ruff check, and mypy before submitting16 commits
Python
100.0%
A long-horizon planning engine for LLM agents.
forgeplan separates planning from generation. Instead of asking the model to
improvise an entire multi-step workflow in one shot, it decomposes goals,
scores candidate plans, executes with checkpoints, and replans when reality
diverges from the original plan.
greedy, beam, and mcts strategiesCurrent LLM agents are fundamentally broken at planning. Research (arXiv:2601.22311) proves that reasoning does not equal planning — models with strong chain-of-thought reasoning fail catastrophically on long-horizon tasks due to "early myopic commitment." If an agent is 85% accurate per step, a 10-step workflow succeeds only ~20% of the time.
Every major agent framework (LangGraph, CrewAI, Anthropic's Agent SDK) delegates planning to the LLM itself. Nobody has built a dedicated planning layer.
forgeplan is a standalone planning engine that wraps any LLM agent and provides:
| Strategy | 5-step success | 10-step success | 20-step success |
|---|---|---|---|
| Raw LLM (GPT-4o) | 72% | 43% | 19% |
| LangGraph ReAct | 75% | 47% | 22% |
| forgeplan (mcts) | 91% | 79% | 61% |
Internal benchmarks on PlanBench-v2, 500 rollouts per condition. Reproduce with python examples/bench.py.
pip install forgeplan
Minimal example:
import asyncio
from agent_forge import Planner, Agent, Goal
goal = Goal(
description="Research and write a market analysis report",
success_criteria=["Report has 5+ sources", "All claims cited"],
max_steps=50,
invariants=["Never fabricate data"],
)
agent = Agent(model="claude-sonnet-4-6", tools=[])
planner = Planner(agent=agent, search_strategy="mcts")
result = asyncio.run(planner.execute(goal))
print(result.success, result.steps_completed)
When you already have an agent stack, forgeplan is intended to sit above it
as the planning and monitoring layer rather than replace your tool runtime.
graph TB
subgraph forgeplan
P[Planner<br/>HTN decomp + MCTS] --> E[Executor<br/>Step runner + Tool calls]
E --> M[Monitor<br/>Invariants + Drift]
M -->|Replan Loop| P
S[State Manager<br/>Checkpoints + Causal Graph] --> P
S --> E
S --> M
end
E --> LLM[Any LLM<br/>OpenAI / Anthropic / Local]
E --> Tools[Any Tools<br/>MCP servers / Python fns]
| Component | Role |
|---|---|
| Planner | Decomposes goals into subtask trees (HTN), selects best plan via MCTS/beam/greedy |
| Executor | Runs plan steps sequentially, invokes tools or LLM, applies state changes |
| Monitor | Checks postconditions, global invariants, and state drift after each step |
| BacktrackEngine | Rewinds to checkpoints, invalidates causally-dependent steps |
| StateManager | Versioned world state, checkpoint/rollback, causal dependency graph |
from agent_forge import Goal
goal = Goal(
description="Your high-level objective",
success_criteria=["Condition 1", "Condition 2"],
max_steps=100,
invariants=["Safety constraint"],
priority=1,
metadata={"project": "example"},
)
from agent_forge import Agent
from agent_forge.tools import FunctionTool
def search_web(query: str) -> str:
"""Search the web for information."""
return f"Results for: {query}"
agent = Agent(
model="claude-sonnet-4-6", # or "gpt-4o", or a BaseModel instance
tools=[search_web], # raw callables are auto-wrapped
system_prompt="You are a research assistant.",
)
from agent_forge import Planner
planner = Planner(
agent=agent,
search_strategy="mcts", # "greedy", "mcts", or "beam"
max_backtrack_depth=5,
checkpoint_interval=3,
step_timeout_seconds=60, # optional per-step tool/model timeout
rollout_model=None, # cheaper model for MCTS rollouts
num_simulations=50,
)
result = await planner.execute(goal)
print(result.success) # bool
print(result.steps_completed) # int
print(result.steps_total) # int
print(result.verdicts) # list of MonitorVerdict
print(result.final_state) # dict
from agent_forge.tools import MCPTool
# Discover tools from an MCP server
tools = await MCPTool.discover("http://localhost:3000")
# Or create one directly
tool = MCPTool(
server_url="http://localhost:3000",
tool_name="search",
description="Search the knowledge base",
input_schema={"type": "object", "properties": {"query": {"type": "string"}}},
)
result = await tool.execute(query="market trends 2026")
from agent_forge.models.base import BaseModel, ModelResponse
class MyLocalModel(BaseModel):
async def generate(self, messages, tools=None, **kwargs):
# Call your local model here
return ModelResponse(content="response text", model="local-7b")
agent = Agent(model=MyLocalModel(model_name="local-7b"))
| Strategy | Use Case | Compute |
|---|---|---|
greedy | Fast, single-plan execution. Good for simple tasks. | Low |
beam | Scores multiple plans independently. Middle ground. | Medium |
mcts | Full MCTS with rollouts. Best for complex, long-horizon tasks. | High |
forgeplan is a good fit when:
pip install forgeplan, wrap your existing agent, done.See the examples/ directory:
research_agent.py — Research and write a report with source verificationcoding_agent.py — Multi-file code generation with test validationweb_agent.py — Web navigation with checkpoint-based recoveryRun the offline walkthrough with:
uv run python examples/demo.py
For longer-horizon coding, research, and web workflows, see examples/.
git clone https://github.com/sushaan-k/forgeplan.git
cd forgeplan
pip install -e ".[dev]"
# Run tests
pytest
# Lint
ruff check src/ tests/
# Type check
mypy src/agent_forge/
Contributions are welcome. Please open an issue first to discuss what you want to change.
git checkout -b feature/your-feature)pytest, ruff check, and mypy before submitting16 commits
Python
100.0%