How to use prebuilt agents
In shortGuide to ReactAgent, PlanActReflectAgent, StructuredOutputAgent, SupervisorTeamAgent, SwarmAgent, and RAGAgent as compiled graph factories.
- 6 min read
- 9 sections
- Updated
- v0.9.2
- Markdown
10xGraph ships six prebuilt agent classes that wrap a fully wired StateGraph behind a single compile() call. Each class exposes the same surface as a raw StateGraph: you get a CompiledGraph you can invoke() or astream().
from tenxgraph.prebuilt.agent import (
ReactAgent,
PlanActReflectAgent,
StructuredOutputAgent,
SupervisorTeamAgent,
SwarmAgent,
RAGAgent,
)ReactAgent
The most common pattern: an LLM agent that can call tools in a loop until it has enough information to answer.
from tenxgraph.prebuilt.agent import ReactAgent
from tenxgraph.prebuilt.tools import fetch_url, safe_calculator
agent = ReactAgent(
model="gpt-4o",
tools=[fetch_url, safe_calculator],
system_prompt=[{"role": "system", "content": "You are a research assistant."}],
)
app = agent.compile()
result = app.invoke(
{"messages": [Message.text_message("What is 1234 * 5678?")]},
config={"thread_id": "react-1"},
)
print(result["messages"][-1].content)ReactAgent constructor
ReactAgent(
model: str,
state: StateT | None = None, # custom AgentState subclass
context_manager: BaseContextManager | None = None,
publisher: BasePublisher | None = None,
id_generator: BaseIDGenerator = DefaultIDGenerator(),
container: InjectQ | None = None,
*,
output_type: str = "text",
system_prompt: list[dict] | None = None,
tools: Iterable[Callable] | None = None,
client: Any = None, # FastMCP client for MCP tools
pass_user_info_to_mcp: bool = False,
extra_messages: list[Message] | None = None,
trim_context: bool = False,
tools_tags: set[str] | None = None,
reasoning_config: dict | bool | None = True,
skills: SkillConfig | None = None,
memory: MemoryConfig | None = None,
retry_config: RetryConfig | bool = True,
fallback_models: list[str | tuple[str, str]] | None = None,
multimodal_config: MultimodalConfig | None = None,
output_schema: type[BaseModel] | None = None,
main_node_name: str = "MAIN",
tool_node_name: str = "TOOL",
**agent_kwargs,
)ReactAgent.compile() accepts the same arguments as StateGraph.compile(): checkpointer, store, interrupt_before, interrupt_after, callback_manager, media_store, shutdown_timeout.
ReactAgent with MCP
from fastmcp import Client
mcp_client = Client("path/to/mcp/server")
agent = ReactAgent(
model="gpt-4o",
tools=[],
client=mcp_client,
pass_user_info_to_mcp=True, # forward config["user"] to MCP metadata
)
app = agent.compile()PlanActReflectAgent
Breaks complex tasks into a Plan → Act → Reflect loop. The planner creates a step-by-step plan; the actor executes each step using tools; the reflector evaluates success and decides whether to replan.
from tenxgraph.prebuilt.agent import PlanActReflectAgent
from tenxgraph.prebuilt.tools import fetch_url, google_web_search
agent = PlanActReflectAgent(
model="gpt-4o",
tools=[fetch_url, google_web_search],
system_prompt=[{"role": "system", "content": "You are a thorough research agent."}],
)
app = agent.compile()
result = app.invoke(
{"messages": [Message.text_message("Research the top 3 Python web frameworks and compare them.")]},
config={"thread_id": "par-1"},
)Good for tasks that require multi-step reasoning and self-correction.
StructuredOutputAgent
Guarantees the response is a JSON object matching a Pydantic schema. Useful for data extraction, classification, and form filling.
from pydantic import BaseModel
from tenxgraph.prebuilt.agent import StructuredOutputAgent
class ProductReview(BaseModel):
sentiment: str # "positive" | "negative" | "neutral"
score: float # 0.0 – 5.0
summary: str
key_points: list[str]
agent = StructuredOutputAgent(
model="gpt-4o",
output_schema=ProductReview,
system_prompt=[{"role": "system", "content": "Extract structured product review data."}],
)
app = agent.compile()
result = app.invoke(
{"messages": [Message.text_message("This laptop is amazing! Fast, light, great battery. 5 stars.")]},
config={"thread_id": "struct-1"},
)
print(result["messages"][-1].content) # JSON string conforming to ProductReviewSupervisorTeamAgent
A supervisor LLM routes tasks to specialist worker agents. Each worker is a pre-built agent (usually an Agent) that you configure yourself, so every worker can have its own model, tools and prompt.
from tenxgraph.core.graph import Agent, ToolNode
from tenxgraph.core.state import Message
from tenxgraph.prebuilt.agent import SupervisorTeamAgent, WorkerConfig
def lookup_order(order_id: str) -> str:
"""Look up the status of a customer order."""
return f"Order {order_id}: shipped, delivered 2026-09-30."
def refund_order(order_id: str, amount: float) -> str:
"""Refund an order."""
return f"Refunded {amount} for order {order_id}."
agent = SupervisorTeamAgent(
supervisor_model="gpt-4o",
provider="openai", # forwarded to the supervisor Agent only
workers={
"ORDERS": WorkerConfig(
agent=Agent(
model="gpt-4o-mini",
provider="openai",
tool_node=ToolNode([lookup_order]),
system_prompt=[{"role": "system", "content": "Answer order status questions."}],
),
description="Looks up order status and delivery details.",
),
"REFUNDS": WorkerConfig(
agent=Agent(
model="gpt-4o",
provider="openai",
tool_node=ToolNode([refund_order]),
system_prompt=[{"role": "system", "content": "Issue refunds when asked."}],
),
description="Issues refunds for orders.",
),
},
supervisor_system_prompt=None, # None builds the prompt from the worker descriptions
max_rounds=10,
)
app = agent.compile()
result = app.invoke(
{"messages": [Message.text_message("Order A-1042 arrived damaged. Refund 25.00.")]},
config={"thread_id": "supervisor-1"},
)Constructor and WorkerConfig
SupervisorTeamAgent(
supervisor_model: str,
workers: dict[str, WorkerConfig], # worker name -> config
supervisor_system_prompt: list[dict] | None = None,
max_rounds: int = 10,
state=None, context_manager=None, publisher=None, id_generator=..., container=None,
**supervisor_kwargs, # forwarded to the supervisor Agent (provider, temperature, ...)
)
WorkerConfig(
agent: BaseAgent, # a fully configured Agent
description: str = "", # injected into the supervisor prompt to aid routing
)SUPERVISOR is a reserved worker name. See SupervisorTeamAgent for the graph layout.
SwarmAgent
Agents hand off directly to each other. There is no central supervisor: each member decides who handles the task next. Handoff tools are injected automatically, so do not add them to a member’s ToolNode.
from tenxgraph.prebuilt.agent import SwarmAgent, SwarmMemberConfig
triage = Agent(model="gpt-4o-mini", provider="openai",
system_prompt=[{"role": "system", "content": "Route the request to a specialist."}])
orders = Agent(model="gpt-4o", provider="openai", tool_node=ToolNode([lookup_order]),
system_prompt=[{"role": "system", "content": "Answer order questions."}])
refunds = Agent(model="gpt-4o", provider="openai", tool_node=ToolNode([refund_order]),
system_prompt=[{"role": "system", "content": "Handle refunds."}])
swarm = SwarmAgent(
members={
"TRIAGE": SwarmMemberConfig(
agent=triage,
can_handoff_to=["ORDERS", "REFUNDS"],
description="Classifies requests and routes them to the right specialist.",
),
"ORDERS": SwarmMemberConfig(
agent=orders,
can_handoff_to=["REFUNDS"],
description="Handles order status questions.",
),
"REFUNDS": SwarmMemberConfig(
agent=refunds,
can_handoff_to=[], # terminal: no handoffs out
description="Issues refunds.",
),
},
entry="TRIAGE", # member that receives the first message
)
app = swarm.compile()
result = app.invoke(
{"messages": [Message.text_message("Where is order A-1042?")]},
config={"thread_id": "swarm-1"},
)SwarmMemberConfig fields
SwarmMemberConfig(
agent: BaseAgent,
can_handoff_to: list[str] | None = None, # None = may hand off to every other member
description: str = "", # shown to other members' handoff tools
)See SwarmAgent for details.
RAGAgent
A retrieval-augmented generation agent. It retrieves documents from a store before the LLM call, optionally reranks them, and passes them to the wrapped agent as context.
from tenxgraph.core.graph import Agent
from tenxgraph.core.state import Message
from tenxgraph.prebuilt.agent import RAGAgent
from tenxgraph.storage import create_local_qdrant_store
from tenxgraph.storage.store.embedding import OpenAIEmbedding
store = create_local_qdrant_store(
path="./knowledge_base",
embedding=OpenAIEmbedding(model="text-embedding-3-small"),
)
rag = RAGAgent(
store=store,
agent=Agent(
model="gpt-4o-mini",
provider="openai",
system_prompt=[{
"role": "system",
"content": "Answer using only the provided context. If it is missing, say so.",
}],
),
top_k=5, # candidates retrieved from the store
)
app = rag.compile()
result = app.invoke(
{"messages": [Message.text_message("What is the refund policy?")]},
config={"thread_id": "rag-1"},
)Full signature:
RAGAgent(
store: BaseStore,
agent: BaseAgent,
reranker: BaseReranker | None = None,
top_k: int = 5,
top_n: int = 3, # kept after reranking
retrieval_strategy: RetrievalStrategy = RetrievalStrategy.SIMILARITY,
score_threshold: float | None = None,
store_config: dict | None = None, # extra kwargs for every store.asearch call
state=None, context_manager=None, publisher=None, id_generator=..., container=None,
)Add a reranker (CohereReranker, CrossEncoderReranker, or your own BaseReranker) to rerank retrieved chunks:
from tenxgraph.prebuilt.agent import CohereReranker
rag = RAGAgent(
store=store,
agent=Agent(model="gpt-4o-mini", provider="openai"),
reranker=CohereReranker(api_key="your-cohere-key"),
top_k=20,
top_n=5,
)See RAGAgent for where the answer is read from and the full node layout.
Compile options (all prebuilt agents)
All prebuilt agents expose the same compile() signature:
app = agent.compile(
checkpointer=None, # BaseCheckpointer for state persistence
store=None, # BaseStore for memory
interrupt_before=[], # pause before these nodes
interrupt_after=[], # pause after these nodes
callback_manager=CallbackManager(),
media_store=None, # BaseMediaStore for multimodal content
shutdown_timeout=30.0,
)What you learned
ReactAgentis the standard tool-calling loop. Use it for most tasks.PlanActReflectAgentadds planning and self-reflection for complex multi-step tasks.StructuredOutputAgentforces JSON output conforming to a Pydantic schema.SupervisorTeamAgentroutes tasks from a central supervisor to specialist workers.SwarmAgentroutes tasks peer-to-peer without a central supervisor.RAGAgentretrieves relevant context from a vector store before each LLM call.
Next steps
- Use prebuilt tools for web fetch, file operations, and search.
- Build a graph for custom workflows beyond the prebuilt patterns.