The Agent base class lets you build custom agents without relying on an external framework.
import superserve
from superserve import Agent
@superserve.tool
def search(query: str) -> str:
"""Search the web."""
return f"Results for {query}"
class MyAgent(Agent):
tools = [search]
async def run(self, query: str) -> str:
result = await self.call_tool("search", query=query)
return f"Found: {result}"
# Serve with resources
superserve.serve(MyAgent, name="my-agent", num_cpus=2, memory="4GB", replicas=3)
Each agent runs as a Ray Actor with dedicated resources, enabling:
- Statefulness: Maintain state across requests
- Resource isolation: Guaranteed CPU, GPU, and memory allocation
- Horizontal scaling: Multiple replicas for high availability
Use call_tool() to execute a registered tool by name:
class MyAgent(Agent):
tools = [search, analyze]
async def run(self, query: str) -> str:
result = await self.call_tool("search", query=query)
return result
Use call_tools_parallel() to run multiple tools concurrently:
class MyAgent(Agent):
tools = [search, analyze, summarize]
async def run(self, query: str) -> str:
results = await self.call_tools_parallel([
("search", {"query": query}),
("analyze", {"data": query}),
])
search_result, analysis = results
return f"Search: {search_result}, Analysis: {analysis}"
Helper Methods
| Method | Description |
|---|
call_tool(name, **kwargs) | Call a tool by name and await the result |
call_tools_parallel(calls) | Call multiple tools in parallel |
get_tool_names() | Get list of registered tool names |
get_tool_descriptions() | Get dict of tool names to descriptions |
Serving Agents
Configure resources when serving with superserve.serve():
superserve.serve(
MyAgent,
name="my-agent",
num_cpus=2,
memory="4GB",
replicas=3,
)
See Serving for full options.
For framework-based agents, pass your agent directly to superserve.serve() - no base class needed.