Creating Agents (Python SDK)
Relevant source files
The following files were used as context for generating this wiki page:The Loom Python SDK provides the tools to build event-driven, multi-agent systems. Agents created with the SDK serve as the "Brain" in Loom's "Brain/Hand" architecture, responsible for handling business logic, cognitive reasoning, and LLM interactions. These Python agents connect to the Rust Core runtime, which acts as the "Hands" for secure tool execution, event bus management, and system integration.
This page details how to create, configure, and run agents using the Python SDK. It covers basic event-driven agents as well as more advanced Cognitive Agents that perform autonomous reasoning.
Sources: README.md, ARCHITECTURE.md, loom-py/README.md
Core Concepts
At the heart of the SDK is the Agent class, which provides the foundation for connecting to the Loom runtime and communicating on the event bus. The architecture is designed to separate the rapidly-iterating logic of an agent from the stable, secure infrastructure of the runtime.
This diagram illustrates the "Brain/Hand" separation, with the Python Agent connecting to the Rust Core via gRPC.
This diagram shows the Python agent handling high-level logic and making tool calls to the Rust Core.
Sources: ARCHITECTURE.md, ROADMAP.md
Basic Agent Creation
A basic agent subscribes to topics on the event bus and processes incoming events using a handler function.
Agent Class
The primary class for creating an agent is loom.Agent. It is initialized with parameters that define its identity and behavior.
from loom import Agent, tool
@tool("web.search", description="Search the web for information")
def web_search(query: str) -> dict:
return {"query": query, "results": ["example.com"]}
async def on_event(ctx, topic, event):
# Echo payload back
await ctx.emit(topic, type="echo", payload=event.payload)
agent = Agent(
agent_id="py-agent-1",
topics=["topic.test"],
tools=[web_search],
on_event=on_event,
address="127.0.0.1:50051",
)
if __name__ == "__main__":
agent.run()
Sources: loom-py/README.md:36-55
Agent Constructor Parameters
| Parameter | Type | Description |
|---|---|---|
agent_id | str | A unique identifier for the agent. |
topics | List[str] | A list of event topics the agent will subscribe to. |
on_event | Callable | An async function to handle incoming events. |
tools | List[Callable] | A list of functions decorated with @tool that the agent can execute. |
address | str | The gRPC address of the Loom Bridge. Can also be set via LOOM_BRIDGE_ADDR env var. |
Sources: loom-py/README.md:46-51, loom-py/src/loom/agent/base.py
Agent Lifecycle
The agent lifecycle is managed by the run() method, which handles connecting to the runtime, processing events, and shutting down gracefully.
The following sequence diagram shows the agent's startup and execution flow.
Cognitive Agents
For tasks requiring autonomous reasoning, the CognitiveAgent provides a pre-built "perceive-think-act" loop. It is designed to understand a high-level goal, use tools to gather information, and generate a final answer.
from loom import Agent, CognitiveAgent, LLMProvider
agent = Agent(agent_id="assistant")
await agent.start()
cognitive = CognitiveAgent(
ctx=agent._ctx,
llm=LLMProvider.from_env("deepseek"),
available_tools=["web:search", "fs:read_file", "fs:write_file"],
)
result = await cognitive.run("Research Bitcoin price trends and save a summary to report.md")
Sources: README.md:73-84
Key Components of CognitiveAgent
CognitiveConfig: Configures the agent's behavior, such as the maximum number of iterations and the thinking strategy.ThinkingStrategy: Defines the reasoning pattern. The default and recommended strategy isREACT(Reasoning and Acting).LLMProvider: A client for making direct HTTP calls to an LLM API.available_tools: A list of tool names the agent is permitted to use. These tools are executed by the Rust Core.
Sources: loom-py/src/loom/cognitive/README.md:65-83
ReAct Strategy Flow
The ReAct (Thought -> Action -> Observation) strategy allows the agent to iteratively reason and use tools to accomplish a goal.
This flowchart shows the iterative reasoning loop of a Cognitive Agent using the ReAct strategy.
Sources: loom-py/src/loom/cognitive/README.md:144-162
Event Handling
Agents react to events via an on_event handler. This async function receives the agent's EventContext, the event topic, and the event object itself.
# From apps/deep-research/agents/researcher.py
async def researcher_handler(ctx, topic: str, event) -> None:
# Only handle research requests
if event.type != "research.request":
return
# ... parse event payload ...
try:
report = await execute_research(ctx, request)
# Send report back to Lead agent
await ctx.emit(
"researcher.report",
type="researcher.report",
payload=json.dumps(report).encode("utf-8"),
)
except Exception as e:
# ... handle error ...
Sources: apps/deep-research/agents/researcher.py:251-299
EventContext (ctx)
The ctx object is the primary interface for an agent to interact with the Loom runtime. Key methods include:
ctx.emit(topic, type, payload): Publishes a new event to a topic.ctx.reply(event, type, payload): Sends a reply directly correlated to an incoming event.ctx.tool(name, payload, timeout_ms): Invokes a tool registered with the Rust Core.
Sources: loom-py/README.md:42-44, loom-py/src/loom/cognitive/README.md:90-97
Tool Integration
Tools are Python functions that can be called by an agent. They are defined using the @tool decorator and executed securely within the Rust Core sandbox.
Defining a Tool
from loom import tool
@tool("web.search", description="Search the web for information")
def web_search(query: str) -> dict:
# This is a mock implementation. In a real agent,
# this function might not be called directly.
# The agent uses ctx.tool("web:search", ...)
# which is handled by the Rust Core.
return {"query": query, "results": ["example.com"]}
Sources: loom-py/README.md:38-40
Invoking a Tool
Agents invoke tools via the EventContext. This decouples the agent's logic from the tool's implementation and allows the Rust Core to manage execution.
This diagram shows the flow of a tool call from the Python agent to the Rust Core and back.
Sources: ARCHITECTURE.md, README.md:61-64
Agent Configuration (loom.toml)
Projects can define and configure agents in a loom.toml file. The loom run command discovers and launches these agents automatically.
# apps/deep-research/loom.toml
[agents.lead-agent]
# Lead Agent orchestrates research, spawns sub-agents, aggregates results
topics = ["user.query", "researcher.report"]
llm_provider = "deepseek"
max_researchers = 3
aggregation_timeout_sec = 60
[agents.researcher-agent]
# Research Agent template - spawned dynamically by Lead
topics = [] # Assigned dynamically via thread topics
llm_provider = "deepseek"
max_sources = 5
search_timeout_sec = 10
Sources: apps/deep-research/loom.toml:13-26
Common Configuration Options
| Key | Description | Example |
|---|---|---|
topics | List of topics the agent subscribes to. | ["market.price.BTC"] |
llm_provider | The name of the LLM provider configured in the [llm] section. | "deepseek" |
enable_trading | A boolean flag for business logic (specific to market-analyst). | false |
max_researchers | A custom parameter for the lead agent in deep-research. | 3 |
Sources: apps/deep-research/loom.toml:13-26, apps/market-analyst/README.md:105-115
Summary
The Loom Python SDK provides a powerful and flexible way to create AI agents. Developers can build simple, event-driven agents using the base Agent class for specific tasks, or leverage the CognitiveAgent for complex, autonomous reasoning that requires planning and tool use. By adhering to the "Brain/Hand" architecture, the SDK allows for rapid iteration on agent logic in Python while relying on the secure and performant Rust Core for low-level execution and system-wide orchestration.