Agent integration
Ploton is not an agent framework. It’s infrastructure that any agent can call.
Building with LangChain, CrewAI, AutoGPT, Semantic Kernel, or your own custom agent loop — doesn’t matter. Your agent lists its available subagents in the system prompt. When it needs real-world capabilities, it routes the request to the right subagent. No adapter, no plugin system, no vendor lock-in.
System prompt setup
Add your deployed subagents to your agent’s system prompt:
You have access to these Ploton subagents:
- crm-agent: CRM and sales data
- billing-agent: Payments and invoices
- media-agent: Image and video processing
When a request needs capabilities you don't have,
delegate to the relevant subagent.
If no subagent fits, decline the request.Your agent reads this list and decides which subagent handles each request based on the user’s ask. The agent does the routing; Ploton does the execution.
The agent-subagent loop
The typical flow:
sequenceDiagram
participant App as Your App
participant Agent as Your Agent
participant Ploton
participant Subagent
participant Service as External Service
App->>Agent: Assign task
Agent->>Agent: Check system prompt for subagents
Agent->>Ploton: POST /v1/tasks + sub_agent
Ploton->>Subagent: Route to scoped subagent
Ploton-->>Agent: 200 OK (task_id)
Note over Agent: Continues other work
Subagent->>Service: Auth, fetch, execute
Service-->>Subagent: Response
Ploton->>App: Webhook (task.complete)
App->>Agent: Resume with result
In code:
// Inside your agent's tool handler
async function handleExternalDataRequest(agentContext: AgentContext) {
// Agent routes to the right subagent
const response = await fetch("https://api.ploton.ai/v1/tasks", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PLOTON_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
prompt: `Pull all active subscriptions for ${agentContext.userId}. Return plan name, amount, and next billing date.`,
sub_agent: "billing-agent",
user_id: agentContext.userId,
metadata: {
agent_session: agentContext.sessionId,
step: "fetch_subscription_data",
},
}),
});
const task = await response.json();
// Agent continues — doesn't block on the subagent
return {
status: "delegated_to_subagent",
task_id: task.id,
sub_agent: "billing-agent",
message: "Subscription data request submitted. Will resume on webhook.",
};
}The metadata field is how you correlate Ploton results with your agent’s state. When the webhook comes back, use agent_session and step to resume the right agent at the right point.
Framework integration patterns
LangChain / LangGraph
Register a routing tool that delegates to the appropriate subagent:
from langchain.tools import Tool
def call_ploton_subagent(input_str: str) -> str:
"""Parse subagent name and prompt from input, route to Ploton."""
# Your routing logic here
return call_ploton_api(prompt=input_str, sub_agent=determine_subagent(input_str))
ploton_tool = Tool(
name="ploton_subagent",
description="Route tasks to Ploton subagents. Available subagents: crm-agent (CRM and sales data), billing-agent (payments and invoices), media-agent (image and video processing). Use when you need external service access.",
func=call_ploton_subagent,
)
agent = initialize_agent(
tools=[ploton_tool, ...other_tools],
llm=llm,
)The tool description lists available subagents so the LLM knows when and where to route.
CrewAI
from crewai import Tool
ploton_tool = Tool(
name="Ploton Subagent Router",
description="Routes tasks to specialized Ploton subagents: crm-agent, billing-agent, media-agent. Returns a task ID — results arrive via webhook.",
func=call_ploton_subagent,
)Custom agent loops
If you’re running your own agent loop, subagent routing slots into the tool-use step:
const SUBAGENTS = ["crm-agent", "billing-agent", "media-agent"];
while (!task.isComplete()) {
const action = await agent.decide(task.context);
if (action.type === "external_service") {
// Route to the right subagent
const subAgent = determineSubagent(action.prompt, SUBAGENTS);
const plotonTask = await createPlotonTask(action.prompt, subAgent, task.userId);
task.awaitCallback(plotonTask.id);
continue; // Process next task in queue
}
if (action.type === "internal") {
await executeInternally(action);
}
}Agent design considerations
When to route to a subagent
Route to a subagent when your agent needs to:
- Authenticate with a third-party service — OAuth flows, token management, credential handling
- Fetch data from external APIs — CRM records, payment data, calendar events, file storage
- Take actions on external services — send emails, post messages, create records, upload files
- Handle user interaction — collect approvals, preferences, or missing data
Don’t route to a subagent for internal computations, reasoning, or queries against your own database. If it doesn’t touch an external service, you don’t need a subagent.
Keep prompts specific
Subagent output quality tracks directly with prompt quality. Vague prompts get vague results. See the Prompt Engineering guide for patterns that work.
Handle the async gap
Between creating a task and receiving the webhook, your agent needs a strategy:
- Queue-based — agent enqueues tasks and processes results as they arrive. Best for high-throughput systems.
- Polling fallback — agent periodically checks task status. Useful when webhooks aren’t available.
- Hybrid — webhooks as primary delivery, polling as a fallback for missed events.
Use metadata for correlation
Include enough metadata to pick up where you left off when the result arrives:
{
"metadata": {
"agent_session_id": "sess_abc123",
"workflow_step": "enrich_contact_data",
"attempt": 1,
"parent_task_id": "your_internal_task_id"
}
}Next steps
- Subagents — How subagents work under the hood
- Authentication — Set up API keys and OAuth
- Prompt Engineering — Write prompts that agents can reliably generate
- API Overview — REST API conventions and limits