Custom Agents
Build custom agent logic, register custom tools, integrate with external APIs, and deploy in VPC private subnets.
Custom Agents let you build your own agent logic, register custom tools, and integrate with external APIs. Deploy them in VPC private subnets for secure access to internal services. Use custom agents when built-in RAG, LLM, or workflow agents don’t fit your use case.
Building Custom Agent Logic
Custom agents run your code. You define:
- Input schema — What the agent accepts
- Processing logic — How it processes input (calls to LLMs, tools, APIs)
- Output schema — What it returns
Agent Interface
interface CustomAgent {
name: string;
version: string;
inputSchema: JSONSchema;
outputSchema: JSONSchema;
execute(input: Record<string, unknown>): Promise<Record<string, unknown>>;
}
Example: Custom Routing Agent
export const routingAgent: CustomAgent = {
name: "support-router",
version: "1.0.0",
inputSchema: {
type: "object",
properties: {
message: { type: "string" },
customerTier: { type: "string", enum: ["free", "pro", "enterprise"] }
},
required: ["message"]
},
outputSchema: {
type: "object",
properties: {
route: { type: "string" },
priority: { type: "number" }
}
},
async execute(input) {
const { message, customerTier } = input;
// Call internal API, LLM, or custom logic
const route = await callInternalRoutingAPI(message, customerTier);
return { route: route.destination, priority: route.priority };
}
};
Custom Tool Registration
Register tools that your custom agent (or workflow agents) can call:
Tool Definition
{
"name": "get_inventory",
"description": "Fetch current inventory for a product SKU",
"parameters": {
"type": "object",
"properties": {
"sku": { "type": "string", "description": "Product SKU" }
},
"required": ["sku"]
},
"endpoint": "https://internal-api.company.com/inventory"
}
Register via API
curl -X POST "https://api.yourdomain.com/v1/tools" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "get_inventory",
"description": "Fetch current inventory for a product SKU",
"parameters": {
"type": "object",
"properties": {
"sku": { "type": "string", "description": "Product SKU" }
},
"required": ["sku"]
},
"handler": {
"type": "http",
"url": "https://internal-api.company.com/inventory",
"method": "GET"
}
}'
Tool Handler Types
| Type | Description |
|---|---|
http | Call external HTTP endpoint |
function | Invoke serverless function (e.g., AWS Lambda) |
inline | Execute inline script (sandboxed) |
Integration with External APIs
Custom agents can call any HTTP API. Use environment variables for secrets:
async execute(input: Record<string, unknown>) {
const apiKey = process.env.EXTERNAL_API_KEY;
const response = await fetch("https://api.external.com/v1/process", {
method: "POST",
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json"
},
body: JSON.stringify(input)
});
return response.json();
}
Best Practices
- Secrets — Store API keys in NFYio secrets manager or environment variables, never in code
- Timeouts — Set reasonable timeouts for external calls (e.g., 30s)
- Retries — Implement exponential backoff for transient failures
- Validation — Validate API responses before returning to the workflow
Deployment in VPC Private Subnets
For internal APIs that are not exposed to the internet, deploy custom agents in VPC private subnets:
┌─────────────────────────────────────────────────────────────────┐
│ NFYio VPC │
│ │
│ ┌─────────────────────┐ ┌─────────────────────────────────┐ │
│ │ Public Subnet │ │ Private Subnet │ │
│ │ • Load Balancer │ │ • Custom Agent Pods │ │
│ │ • API Gateway │────►│ • Internal API Access │ │
│ └─────────────────────┘ │ • No Internet Egress │ │
│ └─────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ Internal Services │ │
│ │ • ERP, CRM, Inventory APIs │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Configuration
# deployment.yaml
agent:
name: internal-router
type: custom
vpc:
subnetIds:
- subnet-0abc123 # Private subnet
securityGroupIds:
- sg-0def456
env:
- name: INTERNAL_API_URL
value: "http://internal-api.internal:8080"
Benefits
- No public exposure — Internal APIs stay behind the VPC
- Low latency — Same network as your internal services
- Compliance — Data never leaves your network
Custom Agent SDK
Use the NFYio Agent SDK to build and test custom agents locally:
npm install @nfyio/agent-sdk
import { createCustomAgent, registerTool } from "@nfyio/agent-sdk";
const agent = createCustomAgent({
name: "my-agent",
execute: async (input) => {
const result = await myLogic(input);
return result;
}
});
// Register and deploy
await agent.deploy({ workspaceId: "ws_123" });
Policy Gateway for Custom Tools
Custom tools are subject to the same policy gateway as built-in tools. Add rules for your custom tools:
{
"policyGateway": {
"rules": [
{
"tool": "get_inventory",
"action": "allow",
"scope": ["workspace:ws_123"]
}
]
}
}
Example: Full Custom Agent
{
"name": "order-status-agent",
"type": "custom",
"image": "registry.yourdomain.com/nfyio/order-agent:1.0",
"tools": ["get_inventory", "get_order_status", "notify_customer"],
"vpc": {
"subnetIds": ["subnet-private-1"],
"securityGroupIds": ["sg-agent"]
},
"env": {
"ORDER_API_URL": "https://orders.internal",
"NOTIFY_API_URL": "https://notify.internal"
}
}
Next Steps
- Agent Tools — Built-in tools and custom tool SDK
- Workflow Agents — Use custom agents in workflows
- Embeddings — Add semantic search to custom agents