You can bring your custom agents developed in Python and deploy them to Blaxel with our developer tools (Blaxel CLI, GitHub app, GitHub action, etc.). You can develop agents using frameworks like LangChain, Google ADK, OpenAI Agents SDK; or your own custom code.

Quickstart

It is required to have uv installed to use the following command.
You can quickly initialize a new project from scratch by using CLI command bl create-agent-app.
bl create-agent-app myagent
This will create a pre-scaffolded local repo where your entire code can be added. You can choose the base agentic framework for the template. In the generated folder, you’ll find a standard server in the entrypoint file main.py. While you typically won’t need to modify this file, you can add specific logic there if needed. Your main work will focus on the agent.py file. Blaxel’s development paradigm lets you leverage its hosting capabilities without modifying your agent’s core logic.

Requirements & limitations

Agents Hosting have few requirements or limitations:
  • The only requirement to deploy an app on Agents Hosting is that it exposes an HTTP API server which is bound on BL_SERVER_HOST (for the host) and BL_SERVER_PORT (for the port). These two environment variables are required for the host+port combo.
  • Deployed agents have a runtime limit after which executions time out. This timeout duration is determined by your chosen infrastructure generation. For Mk 2 generation, the maximum timeout is 10 minutes.
  • The synchronous endpoint has a timeout of 100 seconds for keeping the connection open when no data flows through the API. If your agent streams back responses, the 100-second timeout resets with each chunk streamed. For example, if your agent processes a request for 5 minutes while streaming data, the connection stays open. However, if it goes 100 seconds without sending any data — even while calling external APIs — the connection will timeout.

Accessing resources with Blaxel SDK

Blaxel SDK provides methods to programmatically access and integrate various resources hosted on Blaxel into your agent’s code, such as: model APIs, tool servers, sandboxes, batch jobs, or other agents. The SDK handles authentication, secure connection management and telemetry automatically.

Connect to a model API

Blaxel SDK provides a helper to connect to a model API defined on Blaxel from your code. This allows you to avoid managing a connection with the model API by yourself. Credentials remain stored securely on Blaxel.
from blaxel.{FRAMEWORK_NAME} import bl_model

model = await bl_model("Model-name-on-Blaxel");
The model is automatically converted to your chosen framework’s format based on the FRAMEWORK_NAME specified in the import. Available frameworks : For example, to connect to model my-model in a LlamaIndex agent:
from blaxel.llamaindex import bl_model

model = await bl_model("my-model")

Connect to tools

Blaxel SDK provides a helper to connect to pre-built or custom tool servers (MCP servers) hosted on Blaxel from your code. This allows you to avoid managing a connection with the server by yourself. Credentials remain stored securely on Blaxel. The following method retrieves all the tools discoverable in the tool server.
from blaxel.{FRAMEWORK_NAME} import bl_tools

await bl_tools(['Tool-Server-name-on-Blaxel'])
Like for a model, the retrieved tools are automatically converted to the format of the framework you want to use based on the Blaxel SDK package imported. Available frameworks are langgraph (LangGraph/Langchain), llamaindex (LlamaIndex), crewai (CrewAI), openai (OpenAI Agents), pydantic (PydanticAI Agents) and googleadk (Google ADK). You can develop agents by mixing tools defined locally in your agents, and tools defined as remote servers. Using separated tools prevents monolithic designs which make maintenance easier in the long run. Let’s look at a practical example combining remote and local tools. The code below uses two tools:
  1. blaxel-search: A remote tool server on Blaxel providing web search functionality (learn how to create your own MCP servers here)
  2. weather: A local tool that accepts a city parameter and returns a mock weather response (always “sunny”)

from typing import AsyncGenerator

from blaxel.langgraph import bl_model, bl_tools
from langchain.tools import tool
from langchain_core.messages import AIMessageChunk
from langgraph.prebuilt import create_react_agent

@tool
def weather(city: str) -> str:
    """Get the weather in a given city"""
    return f"The weather in {city} is sunny"

async def agent(input: str) -> AsyncGenerator[str, None]:
    prompt = "You are a helpful assistant that can answer questions and help with tasks."
    ### Load tools dynamically from Blaxel, and adding a tool defined locally:
    tools = await bl_tools(["blaxel-search"]) + [weather]
    ### Load model API dynamically from Blaxel:
    model = await bl_model("gpt-4o-mini")
    agent = create_react_agent(model=model, tools=tools, prompt=prompt)
    messages = {"messages": [("user", input)]}
    async for chunk in agent.astream(messages, stream_mode=["updates", "messages"]):
        type_, stream_chunk = chunk
        # This is to stream the response from the agent, filtering response from tools
        if type_ == "messages" and len(stream_chunk) > 0 and isinstance(stream_chunk[0], AIMessageChunk):
            msg = stream_chunk[0]
            if msg.content:
                if not msg.tool_calls:
                   yield msg.content
        # This to show a call has been made to a tool, usefull if you want to show the tool call in your interface
        if type_ == "updates":
            if "tools" in stream_chunk:
                for msg in stream_chunk["tools"]["messages"]:
                    yield f"Tool call: {msg.name}\n"

Connect to another agent (multi-agent chaining)

Rather than using a “quick and dirty” approach where you would combine all your agents and capabilities into a single deployment, Blaxel provides a structured development paradigm based on two key principles:
  • Agents can grow significantly in complexity. Monolithic architectures make long-term maintenance difficult.
  • Individual agents should be reusable across multiple projects.
Blaxel supports a microservice architecture for handoffs, allowing you to call one agent from another using bl_agent().run() rather than combining all functionality into a single codebase.
from blaxel.core.agents import bl_agent

first_agent_response = await bl_agent("first_agent").run(input);
second_agent_response = await bl_agent("second_agent").run(first_agent_response);

Customize the agent deployment

You can set custom parameters for an agent deployment (e.g. specify the agent name, etc.) in the blaxel.toml file at the root of your directory. Read the file structure section down below for more details.

Instrumentation

Instrumentation happens automatically when workloads run on Blaxel. To enable telemetry, simply require the SDK in your project’s entry point.
import blaxel.core
When agents and tools are deployed on Blaxel, request logging and tracing happens automatically. To add your own custom logs that you can view in the Blaxel Console, use the Python default logger.
import logging

logger = getLogger(__name__)
logger.info("Hello, world!");

Template directory reference

Overview

pyproject.toml          # Mandatory. This file is the standard pyproject.toml file, it defines dependencies.
blaxel.toml             # This file lists configurations dedicated to Blaxel to customize the deployment. It is not mandatory.
.blaxel                 # This folder allows you to define custom resources using the Blaxel API specifications. These resources will be deployed along with your agent.
├── blaxel-search.yaml  # Here, blaxel-search is a sandbox Web search tool we provide so you can develop your first agent. It has a low rate limit, so we recommend you use a dedicated MCP server for production.
src/
└── main.py             # This file is the standard entrypoint of the project. It is used to start the server and create an endpoint bound with agent.py file.
├── agent.py            # This file is the main file of your agent. It is loaded from main.py. In the template, all the agent logic is implemented here.

blaxel.toml

This file is used to configure the deployment of the agent on Blaxel. The only mandatory parameter is the type so Blaxel knows which kind of entity to deploy. Others are not mandatory but allow you to customize the deployment.
name = "my-agent"
workspace = "my-workspace"
type = "agent"

agents = []
functions = ["blaxel-search"]
models = ["gpt-4o-mini"]

[env]
DEFAULT_CITY = "San Francisco"

[runtime]
timeout = 900
memory = 1024

[[triggers]]
  id = "trigger-async-my-agent"
  type = "http-async"
[triggers.configuration]
  path = "agents/my-agent/async" # This will create this endpoint on the following base URL: https://run.blaxel.ai/{YOUR-WORKSPACE} 
  retry = 1

[[triggers]]
  id = "trigger-my-agent"
  type = "http"
[triggers.configuration]
  path = "agents/my-agent/sync"
  retry = 1
  authenticationType = "public"
  • name, workspace, and type fields are optional and serve as default values. Any bl command run in the folder will use these defaults rather than prompting you for input.
  • agents, functions, and models fields are also optional. They specify which resources to deploy with the agent. These resources are preloaded during build, eliminating runtime dependencies on the Blaxel control plane and dramatically improving performance.
  • [env] section defines environment variables that the agent can access via the SDK. Note that these are NOT secrets.
  • [runtime] section allows to override agent deployment parameters: timeout (in s) or memory (in MB) to allocate.
  • [[triggers]] and [triggers.configuration] sections defines ways to send requests to the agent. You can create both synchronous and asynchronous trigger endpoints. You can also make them either private (default) or public. A private synchronous HTTP endpoint is always created by default, even if you don’t define any trigger here.
Additionally, you can define an [entrypoint] section to specify how Blaxel is going to start your server:
...

[entrypoint]
prod = "python src/main.py"
dev = "fastapi dev"

...
  • prod: this is the command that will be used to serve your agent
python src/main.py
  • dev: same as prod in dev mode, it will be used with the command --hotreload. Example:
fastapi dev
This entrypoint section is optional. If not specified, Blaxel will automatically detect in the agent’s content and configure your agent startup settings.

Troubleshooting

Wrong port or host

Default STARTUP TCP probe failed 1 time consecutively for container "agent" on port 80. The instance was not started.
Connection failed with status DEADLINE_EXCEEDED.
If you encounter this error when deploying your agent on Blaxel, ensure that your agent properly exposes an API server that binds to a host and port with the required environment variables: BL_SERVER_HOST & BL_SERVER_PORT. Blaxel automatically injects these variables during deployment.

Deploy an agent

Learn how to deploy your custom AI agents on Blaxel as a serverless endpoint.