Building Your First Agent
Learn how to build, deploy, and manage your first AI agent using Connix. This tutorial will guide you through creating a simple but powerful agent that can process data and interact with external APIs.
What You’ll Build
Section titled “What You’ll Build”By the end of this guide, you’ll have:
- ✅ A working AI agent deployed on Connix
- ✅ Understanding of agent lifecycle management
- ✅ Knowledge of agent communication patterns
- ✅ Experience with Connix’s orchestration features
Prerequisites
Section titled “Prerequisites”- Connix SDK installed (Installation Guide)
- API key from console.connix.io
- Basic understanding of your chosen programming language
Step 1: Design Your Agent
Section titled “Step 1: Design Your Agent”Let’s build a Data Analysis Agent that can:
- Accept datasets in various formats
- Perform statistical analysis
- Generate insights and summaries
- Return structured results
Agent Architecture
Section titled “Agent Architecture”graph LR A[Input Data] --> B[Data Validation] B --> C[Statistical Analysis] C --> D[Insight Generation] D --> E[Results Output]
Step 2: Create the Project
Section titled “Step 2: Create the Project”First, create a project to house your agent:
import { ConnixClient } from '@connix/sdk';
const client = new ConnixClient();
async function createProject() { const project = await client.createProject({ name: 'data-analysis-workspace', description: 'Workspace for data analysis agents' });
console.log(`📊 Project created: ${project.name} (ID: ${project.id})`); return project;}
const project = await createProject();
import connix
client = connix.Client()
def create_project(): project = client.create_project( name="data-analysis-workspace", description="Workspace for data analysis agents" )
print(f"📊 Project created: {project.name} (ID: {project.id})") return project
project = create_project()
package main
import ( "context" "fmt" "log"
connix "github.com/connix-io/connix-go")
func createProject(client *connix.Client) (*connix.Project, error) { project, err := client.CreateProject(context.Background(), &connix.CreateProjectRequest{ Name: "data-analysis-workspace", }) if err != nil { return nil, err }
fmt.Printf("📊 Project created: %s (ID: %d)\n", project.Name, project.Id) return project, nil}
func main() { client := connix.NewClientFromEnv() project, err := createProject(client) if err != nil { log.Fatal(err) } // Continue with agent creation...}
Step 3: Define Agent Configuration
Section titled “Step 3: Define Agent Configuration”Create a configuration for your data analysis agent:
const agentConfig = { name: 'data-analyzer-v1', projectId: project.id, capabilities: [ 'data-processing', 'statistical-analysis', 'report-generation' ], resources: { memory: '2GB', cpu: '1 core', storage: '10GB' }, environment: { 'PYTHON_VERSION': '3.11', 'PANDAS_VERSION': '2.0.0', 'NUMPY_VERSION': '1.24.0' }};
agent_config = { 'name': 'data-analyzer-v1', 'project_id': project.id, 'capabilities': [ 'data-processing', 'statistical-analysis', 'report-generation' ], 'resources': { 'memory': '2GB', 'cpu': '1 core', 'storage': '10GB' }, 'environment': { 'PYTHON_VERSION': '3.11', 'PANDAS_VERSION': '2.0.0', 'NUMPY_VERSION': '1.24.0' }}
agentConfig := &connix.LaunchAgentRequest{ Name: "data-analyzer-v1", ProjectId: project.Id, // Additional configuration would be in environment or metadata}
Step 4: Launch Your Agent
Section titled “Step 4: Launch Your Agent”Deploy the agent to Connix:
async function launchAgent(config) { try { console.log('🚀 Launching agent...');
const agent = await client.launchAgent({ name: config.name, projectId: config.projectId });
console.log(`✅ Agent launched successfully!`); console.log(` Agent: ${config.name}`); console.log(` Status: ${agent.message}`); console.log(` Project: ${config.projectId}`);
return agent;
} catch (error) { console.error('❌ Failed to launch agent:', error.message); throw error; }}
const agent = await launchAgent(agentConfig);
def launch_agent(config): try: print('🚀 Launching agent...')
agent = client.launch_agent( name=config['name'], project_id=config['project_id'] )
print('✅ Agent launched successfully!') print(f' Agent: {config["name"]}') print(f' Status: {agent.message}') print(f' Project: {config["project_id"]}')
return agent
except Exception as error: print(f'❌ Failed to launch agent: {error}') raise
agent = launch_agent(agent_config)
func launchAgent(client *connix.Client, config *connix.LaunchAgentRequest) (*connix.LaunchAgentResponse, error) { fmt.Println("🚀 Launching agent...")
agent, err := client.LaunchAgent(context.Background(), config) if err != nil { fmt.Printf("❌ Failed to launch agent: %v\n", err) return nil, err }
fmt.Println("✅ Agent launched successfully!") fmt.Printf(" Agent: %s\n", config.Name) fmt.Printf(" Status: %s\n", agent.Message) fmt.Printf(" Project: %d\n", config.ProjectId)
return agent, nil}
agent, err := launchAgent(client, agentConfig)if err != nil { log.Fatal(err)}
Step 5: Implement Agent Logic
Section titled “Step 5: Implement Agent Logic”Now let’s implement the core functionality. In a real scenario, this would be deployed as part of your agent container:
class DataAnalysisAgent { constructor(agentId, projectId) { this.agentId = agentId; this.projectId = projectId; this.client = new ConnixClient(); }
async processDataset(data) { console.log('📊 Processing dataset...');
// Validate input data if (!this.validateData(data)) { throw new Error('Invalid data format'); }
// Perform statistical analysis const stats = this.calculateStatistics(data);
// Generate insights const insights = this.generateInsights(stats);
// Return structured results return { summary: stats, insights: insights, processedAt: new Date().toISOString(), agentId: this.agentId }; }
validateData(data) { return Array.isArray(data) && data.length > 0; }
calculateStatistics(data) { const numbers = data.filter(item => typeof item === 'number');
if (numbers.length === 0) { throw new Error('No numeric data found'); }
const sum = numbers.reduce((a, b) => a + b, 0); const mean = sum / numbers.length; const sorted = numbers.sort((a, b) => a - b); const median = sorted[Math.floor(sorted.length / 2)];
return { count: numbers.length, sum: sum, mean: mean, median: median, min: Math.min(...numbers), max: Math.max(...numbers) }; }
generateInsights(stats) { const insights = [];
if (stats.mean > stats.median) { insights.push('Data is right-skewed (mean > median)'); } else if (stats.mean < stats.median) { insights.push('Data is left-skewed (mean < median)'); } else { insights.push('Data appears to be normally distributed'); }
const range = stats.max - stats.min; insights.push(`Data range: ${range} (${stats.min} to ${stats.max})`);
return insights; }}
// Example usageconst analysisAgent = new DataAnalysisAgent(agent.id, project.id);
// Test with sample dataconst sampleData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20];const results = await analysisAgent.processDataset(sampleData);
console.log('📈 Analysis Results:');console.log(JSON.stringify(results, null, 2));
import statisticsfrom datetime import datetimefrom typing import List, Dict, Any
class DataAnalysisAgent: def __init__(self, agent_id: str, project_id: int): self.agent_id = agent_id self.project_id = project_id self.client = connix.Client()
def process_dataset(self, data: List[Any]) -> Dict[str, Any]: print('📊 Processing dataset...')
# Validate input data if not self.validate_data(data): raise ValueError('Invalid data format')
# Perform statistical analysis stats = self.calculate_statistics(data)
# Generate insights insights = self.generate_insights(stats)
# Return structured results return { 'summary': stats, 'insights': insights, 'processed_at': datetime.now().isoformat(), 'agent_id': self.agent_id }
def validate_data(self, data: List[Any]) -> bool: return isinstance(data, list) and len(data) > 0
def calculate_statistics(self, data: List[Any]) -> Dict[str, float]: # Filter numeric data numbers = [item for item in data if isinstance(item, (int, float))]
if not numbers: raise ValueError('No numeric data found')
return { 'count': len(numbers), 'sum': sum(numbers), 'mean': statistics.mean(numbers), 'median': statistics.median(numbers), 'min': min(numbers), 'max': max(numbers), 'std_dev': statistics.stdev(numbers) if len(numbers) > 1 else 0 }
def generate_insights(self, stats: Dict[str, float]) -> List[str]: insights = []
if stats['mean'] > stats['median']: insights.append('Data is right-skewed (mean > median)') elif stats['mean'] < stats['median']: insights.append('Data is left-skewed (mean < median)') else: insights.append('Data appears to be normally distributed')
data_range = stats['max'] - stats['min'] insights.append(f'Data range: {data_range} ({stats["min"]} to {stats["max"]})')
if stats['std_dev'] > 0: cv = (stats['std_dev'] / stats['mean']) * 100 insights.append(f'Coefficient of variation: {cv:.2f}%')
return insights
# Example usageanalysis_agent = DataAnalysisAgent(agent.id, project.id)
# Test with sample datasample_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20]results = analysis_agent.process_dataset(sample_data)
print('📈 Analysis Results:')for key, value in results.items(): print(f'{key}: {value}')
Step 6: Monitor Agent Performance
Section titled “Step 6: Monitor Agent Performance”Implement monitoring to track your agent’s performance:
class AgentMonitor { constructor(client, projectId) { this.client = client; this.projectId = projectId; this.metrics = { requestsProcessed: 0, totalProcessingTime: 0, errors: 0, lastActivity: null }; }
async logActivity(activity, duration = null, error = null) { this.metrics.lastActivity = new Date();
if (error) { this.metrics.errors++; console.error(`❌ Agent error in ${activity}:`, error.message); } else { this.metrics.requestsProcessed++; if (duration) { this.metrics.totalProcessingTime += duration; } console.log(`✅ Agent completed ${activity} ${duration ? `in ${duration}ms` : ''}`); }
// Log metrics every 10 requests if (this.metrics.requestsProcessed % 10 === 0) { this.printMetrics(); } }
printMetrics() { const avgProcessingTime = this.metrics.totalProcessingTime / this.metrics.requestsProcessed;
console.log('\n📊 Agent Performance Metrics:'); console.log(` Requests Processed: ${this.metrics.requestsProcessed}`); console.log(` Average Processing Time: ${avgProcessingTime.toFixed(2)}ms`); console.log(` Errors: ${this.metrics.errors}`); console.log(` Success Rate: ${((this.metrics.requestsProcessed - this.metrics.errors) / this.metrics.requestsProcessed * 100).toFixed(2)}%`); console.log(` Last Activity: ${this.metrics.lastActivity}\n`); }}
// Enhanced agent with monitoringclass MonitoredDataAnalysisAgent extends DataAnalysisAgent { constructor(agentId, projectId) { super(agentId, projectId); this.monitor = new AgentMonitor(this.client, projectId); }
async processDataset(data) { const startTime = Date.now();
try { const result = await super.processDataset(data); const duration = Date.now() - startTime;
await this.monitor.logActivity('data processing', duration); return result;
} catch (error) { await this.monitor.logActivity('data processing', null, error); throw error; } }}
import timefrom dataclasses import dataclassfrom datetime import datetimefrom typing import Optional
@dataclassclass AgentMetrics: requests_processed: int = 0 total_processing_time: float = 0 errors: int = 0 last_activity: Optional[datetime] = None
class AgentMonitor: def __init__(self, client, project_id: int): self.client = client self.project_id = project_id self.metrics = AgentMetrics()
def log_activity(self, activity: str, duration: Optional[float] = None, error: Optional[Exception] = None): self.metrics.last_activity = datetime.now()
if error: self.metrics.errors += 1 print(f'❌ Agent error in {activity}: {error}') else: self.metrics.requests_processed += 1 if duration: self.metrics.total_processing_time += duration duration_str = f' in {duration:.2f}s' if duration else '' print(f'✅ Agent completed {activity}{duration_str}')
# Log metrics every 10 requests if self.metrics.requests_processed % 10 == 0: self.print_metrics()
def print_metrics(self): if self.metrics.requests_processed > 0: avg_processing_time = self.metrics.total_processing_time / self.metrics.requests_processed success_rate = ((self.metrics.requests_processed - self.metrics.errors) / self.metrics.requests_processed * 100)
print('\n📊 Agent Performance Metrics:') print(f' Requests Processed: {self.metrics.requests_processed}') print(f' Average Processing Time: {avg_processing_time:.2f}s') print(f' Errors: {self.metrics.errors}') print(f' Success Rate: {success_rate:.2f}%') print(f' Last Activity: {self.metrics.last_activity}\n')
class MonitoredDataAnalysisAgent(DataAnalysisAgent): def __init__(self, agent_id: str, project_id: int): super().__init__(agent_id, project_id) self.monitor = AgentMonitor(self.client, project_id)
def process_dataset(self, data: List[Any]) -> Dict[str, Any]: start_time = time.time()
try: result = super().process_dataset(data) duration = time.time() - start_time
self.monitor.log_activity('data processing', duration) return result
except Exception as error: self.monitor.log_activity('data processing', None, error) raise
Step 7: Test Your Agent
Section titled “Step 7: Test Your Agent”Run comprehensive tests to ensure your agent works correctly:
async function testAgent() { console.log('🧪 Testing Data Analysis Agent...\n');
const agent = new MonitoredDataAnalysisAgent('test-agent', project.id);
// Test cases const testCases = [ { name: 'Normal Distribution', data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, { name: 'Right Skewed', data: [1, 1, 2, 2, 3, 8, 9, 10, 15, 20] }, { name: 'Mixed Data Types', data: [1, 'text', 2, null, 3, 4, 'more text', 5] }, { name: 'Large Dataset', data: Array.from({length: 1000}, () => Math.random() * 100) } ];
for (const testCase of testCases) { try { console.log(`Testing: ${testCase.name}`); const result = await agent.processDataset(testCase.data); console.log(`✅ ${testCase.name}: Passed`); console.log(` Insights: ${result.insights.join(', ')}\n`); } catch (error) { console.log(`❌ ${testCase.name}: Failed - ${error.message}\n`); } }
console.log('🎉 Agent testing completed!');}
await testAgent();
import random
def test_agent(): print('🧪 Testing Data Analysis Agent...\n')
agent = MonitoredDataAnalysisAgent('test-agent', project.id)
# Test cases test_cases = [ { 'name': 'Normal Distribution', 'data': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, { 'name': 'Right Skewed', 'data': [1, 1, 2, 2, 3, 8, 9, 10, 15, 20] }, { 'name': 'Mixed Data Types', 'data': [1, 'text', 2, None, 3, 4, 'more text', 5] }, { 'name': 'Large Dataset', 'data': [random.random() * 100 for _ in range(1000)] } ]
for test_case in test_cases: try: print(f'Testing: {test_case["name"]}') result = agent.process_dataset(test_case['data']) print(f'✅ {test_case["name"]}: Passed') print(f' Insights: {", ".join(result["insights"])}\n') except Exception as error: print(f'❌ {test_case["name"]}: Failed - {error}\n')
print('🎉 Agent testing completed!')
test_agent()
Step 8: Verify Agent Status
Section titled “Step 8: Verify Agent Status”Check that your agent is running correctly in the Connix platform:
async function checkAgentStatus() { try { // List all projects to verify our agent's project exists const projects = await client.listProjects(); const ourProject = projects.projects.find(p => p.id === project.id);
if (ourProject) { console.log('✅ Project found:', ourProject.name);
// In a real implementation, you would have endpoints to check agent status // For now, we'll simulate this console.log('✅ Agent status: Running'); console.log('✅ Agent health: Good'); console.log('✅ Last heartbeat:', new Date().toISOString());
} else { console.log('❌ Project not found'); }
} catch (error) { console.error('❌ Failed to check agent status:', error.message); }}
await checkAgentStatus();
def check_agent_status(): try: # List all projects to verify our agent's project exists projects = client.list_projects() our_project = next((p for p in projects.projects if p.id == project.id), None)
if our_project: print(f'✅ Project found: {our_project.name}')
# In a real implementation, you would have endpoints to check agent status # For now, we'll simulate this print('✅ Agent status: Running') print('✅ Agent health: Good') print(f'✅ Last heartbeat: {datetime.now().isoformat()}')
else: print('❌ Project not found')
except Exception as error: print(f'❌ Failed to check agent status: {error}')
check_agent_status()
Next Steps
Section titled “Next Steps”Congratulations! You’ve successfully built and deployed your first AI agent. Here’s what you can do next:
Enhance Your Agent
Section titled “Enhance Your Agent”- Add more capabilities: Extend the analysis with visualization, machine learning, or external API integrations
- Implement real-time processing: Handle streaming data or real-time requests
- Add persistence: Store results in databases or file systems
- Create agent networks: Build multiple agents that work together
Production Deployment
Section titled “Production Deployment”- Environment configuration: Set up proper environment variables and secrets
- Monitoring & alerting: Implement comprehensive logging and monitoring
- Error handling: Add robust error handling and recovery mechanisms
- Security: Implement proper authentication and authorization
Learn More
Section titled “Learn More”- Container Orchestration - Advanced deployment patterns
- Authentication Guide - Secure your deployments
- API Reference - Explore all available endpoints
Community & Support
Section titled “Community & Support”- 💬 Community: Discord
- 📚 Documentation: docs.connix.io
- 🐛 Issues: GitHub
- 📧 Support: engineering@connix.io
Happy building! 🚀