UNPKG

sf-agent-framework

Version:

AI Agent Orchestration Framework for Salesforce Development - Two-phase architecture with 70% context reduction

948 lines (770 loc) 21.6 kB
# Best Practices Guide ## Overview This guide contains proven best practices for using the SF-Agent Framework effectively. Following these practices will help you maximize efficiency, maintain quality, and avoid common pitfalls. ## Phase Management Best Practices ### 1. Choose the Right Phase ```yaml # Planning Phase (128k context) - Use for: planning_phase: appropriate_for: - Requirements gathering - Architecture design - Data modeling - Security planning - Integration design - Comprehensive analysis not_for: - Code implementation - Quick fixes - Simple configurations - Unit testing # Development Phase (32k context) - Use for: development_phase: appropriate_for: - Story implementation - Code generation - Testing - Debugging - Configuration - Deployment not_for: - Architecture redesign - Major refactoring - Requirements analysis ``` ### 2. Phase Transition Strategy ```javascript // Good: Clean phase transition async function transitionPhase() { // Complete current phase work await completeCurrentTasks(); // Create handoff artifacts const artifacts = await createHandoffArtifacts(); // Shard documents for next phase await shardDocuments(artifacts); // Clear unnecessary context await clearContext(); // Switch phase await switchPhase('development'); // Load new phase context await loadPhaseContext(); } // Bad: Abrupt transition function badTransition() { switchPhase('development'); // Lost context and artifacts! } ``` ## Context Management Best Practices ### 1. Optimize Context Loading ```javascript // Good: Selective context loading const contextStrategy = { essential: [ 'current-story.md', // Always needed 'coding-standards.md', // Core reference 'api-contracts.yaml', // Interface definitions ], conditional: { 'apex-patterns.md': task.involves('apex'), 'lwc-guide.md': task.involves('lwc'), 'integration-patterns.md': task.involves('integration'), }, optional: [ 'examples.md', // Load if space available 'troubleshooting.md', // Load if space available ], }; // Bad: Loading everything const badStrategy = { loadAll: true, // Wastes tokens, slower processing }; ``` ### 2. Context Compression ```javascript // Good: Smart compression class ContextCompressor { compress(context) { // Progressive compression if (context.size > limit * 0.9) { context = this.removeComments(context); } if (context.size > limit * 0.8) { context = this.summarizeVerbose(context); } if (context.size > limit * 0.7) { context = this.extractEssential(context); } return context; } } // Bad: Aggressive compression losing information function badCompress(context) { return context.substring(0, limit); // Cuts off mid-content! } ``` ## Agent Usage Best Practices ### 1. Agent Selection ```yaml # Good: Match agent to task agent_selection: requirements: sf-product-manager process_analysis: sf-business-analyst architecture: sf-architect data_modeling: sf-data-architect implementation: sf-developer configuration: sf-admin testing: sf-qa deployment: sf-devops-lead # Bad: Using wrong agent wrong_selection: architecture: sf-developer # Developer doesn't have architecture context requirements: sf-qa # QA doesn't gather requirements ``` ### 2. Agent Collaboration ```javascript // Good: Structured handoff async function structuredHandoff() { const handoff = { from: 'sf-architect', to: 'sf-developer', artifacts: [ 'architecture/solution-design.md', 'architecture/component-diagram.png', 'standards/coding-standards.md', ], instructions: { implement: 'AccountService following singleton pattern', test: 'Minimum 90% coverage', document: 'Include API documentation', }, validation: ['All tests passing', 'Security scan clean', 'Performance < 2s'], }; return await createHandoff(handoff); } // Bad: Informal handoff function badHandoff() { // Just switching agents without context transfer switchAgent('sf-developer'); // Developer has no context about what to build! } ``` ## Workflow Best Practices ### 1. Workflow Design ```yaml # Good: Modular workflow design modular_workflow: phases: - name: planning reusable: true configurable: true validation_gates: true - name: implementation parallel_tracks: true story_based: true incremental: true - name: validation automated_checks: true human_review: conditional rollback_capable: true # Bad: Monolithic workflow monolithic_workflow: single_phase: everything # No modularity no_validation: true # No quality gates no_parallelism: true # Sequential only ``` ### 2. Interactive Workflows ```javascript // Good: Clear user choices const goodChoice = { question: 'Select implementation approach:', options: [ { id: 'comprehensive', label: 'Comprehensive', description: 'Full architecture with all features', timeEstimate: '2 weeks', riskLevel: 'low', }, { id: 'mvp', label: 'MVP', description: 'Minimum viable product', timeEstimate: '3 days', riskLevel: 'medium', }, ], recommendation: 'comprehensive', reasoning: 'Project timeline allows for thorough implementation', }; // Bad: Unclear choices const badChoice = { question: 'Pick one:', options: ['A', 'B', 'C'], // No context for decision }; ``` ## Story Management Best Practices ### 1. Story Creation ```yaml # Good: Complete story context good_story: id: STORY-001 title: 'Implement secure user authentication' epic: 'Customer Portal' context: business: requirement: 'Users need secure login' acceptance_criteria: - 'Email/password login' - 'Password reset' - 'Session management' technical: architecture: 'OAuth 2.0 with JWT' components: - AuthenticationService.cls - loginForm.lwc - sessionManager.cls constraints: - '2-second response time' - 'GDPR compliant' - 'Mobile responsive' implementation: patterns: ['Singleton', 'Builder'] testing: ['Unit', 'Integration', 'E2E'] documentation: ['API', 'User Guide'] # Bad: Incomplete story bad_story: title: 'Do authentication' # Vague description: 'Add login' # No context # Missing everything needed for implementation ``` ### 2. Story Sequencing ```javascript // Good: Dependency-aware sequencing function sequenceStories(stories) { // Build dependency graph const graph = buildDependencyGraph(stories); // Topological sort const sequence = topologicalSort(graph); // Optimize for parallel execution const optimized = optimizeForParallel(sequence); return optimized; } // Bad: Random sequencing function badSequence(stories) { return stories; // No consideration of dependencies } ``` ## Document Management Best Practices ### 1. Document Sharding ```yaml # Good: Semantic sharding semantic_sharding: strategy: semantic max_size: 8000 tokens overlap: 500 tokens preserve: - section_boundaries - code_blocks - tables - relationships metadata: - shard_index - total_shards - cross_references - dependencies # Bad: Arbitrary splitting bad_sharding: strategy: fixed_size size: 1000 lines # Cuts through logical sections no_overlap: true # Loses context no_metadata: true # Can't reconstruct ``` ### 2. Document Organization ``` # Good: Hierarchical organization docs/ ├── 01-requirements/ │ ├── business-requirements.md │ ├── functional-requirements.md │ └── non-functional-requirements.md ├── 02-architecture/ │ ├── solution-architecture.md │ ├── data-model.md │ └── integration-design.md ├── 03-stories/ │ ├── epic-001/ │ │ ├── STORY-001.md │ │ └── STORY-002.md │ └── epic-002/ └── 04-handoffs/ └── HANDOFF-001.md # Bad: Flat structure docs/ ├── doc1.md ├── doc2.md ├── new-doc.md └── stuff.md # No organization or naming convention ``` ## Testing Best Practices ### 1. Test Generation ```apex // Good: Comprehensive test class @isTest private class AccountServiceTest { @TestSetup static void setup() { // Create test data TestDataFactory.createAccounts(200); } @isTest static void testPositivePath() { // Given Account acc = [SELECT Id FROM Account LIMIT 1]; // When Test.startTest(); AccountService.process(acc.Id); Test.stopTest(); // Then Account result = [SELECT Status__c FROM Account WHERE Id = :acc.Id]; System.assertEquals('Processed', result.Status__c); } @isTest static void testBulkOperation() { // Test with 200 records List<Account> accounts = [SELECT Id FROM Account]; Test.startTest(); AccountService.processBulk(accounts); Test.stopTest(); // Verify all processed Integer processed = [SELECT COUNT() FROM Account WHERE Status__c = 'Processed']; System.assertEquals(200, processed); } @isTest static void testErrorHandling() { // Test with invalid input try { AccountService.process(null); System.assert(false, 'Exception expected'); } catch (IllegalArgumentException e) { System.assert(e.getMessage().contains('Invalid')); } } } // Bad: Minimal testing @isTest private class BadTest { @isTest static void test() { AccountService.process('001000000000000'); System.assert(true); // Meaningless assertion } } ``` ### 2. Test Coverage Strategy ```yaml # Good: Strategic coverage coverage_strategy: targets: critical_paths: 100% business_logic: 95% utilities: 85% getters_setters: skip focus_on: - Positive paths - Negative paths - Bulk operations - Edge cases - Error handling - Governor limits validation: - All assertions meaningful - No test without assertions - Mock external dependencies - Test data isolation # Bad: Coverage for coverage's sake bad_coverage: goal: 'Just hit 75%' strategy: "Test whatever's easy" assertions: 'System.assert(true)' ``` ## Security Best Practices ### 1. Secure Coding ```apex // Good: Security-conscious code public with sharing class SecureService { public static List<Account> getAccounts(String searchTerm) { // Sanitize input searchTerm = String.escapeSingleQuotes(searchTerm); // Use WITH SECURITY_ENFORCED return [ SELECT Id, Name, Type FROM Account WHERE Name LIKE :('%' + searchTerm + '%') WITH SECURITY_ENFORCED LIMIT 100 ]; } public static void updateAccount(Account acc) { // Check CRUD permissions if (!Schema.sObjectType.Account.isUpdateable()) { throw new SecurityException('Insufficient privileges'); } // Check FLS if (!Schema.sObjectType.Account.fields.Name.isUpdateable()) { throw new SecurityException('Cannot update Name field'); } update acc; } } // Bad: Security vulnerabilities public without sharing class InsecureService { public static List<Account> getAccounts(String search) { // SQL injection vulnerability String query = 'SELECT Id FROM Account WHERE Name LIKE \'' + search + '\''; return Database.query(query); } } ``` ### 2. Data Protection ```javascript // Good: PII handling class DataProtection { sanitize(data) { // Remove PII data = this.removePII(data); // Encrypt sensitive fields data = this.encryptSensitive(data); // Audit log access this.auditAccess(data); return data; } removePII(data) { const patterns = { ssn: /\d{3}-\d{2}-\d{4}/g, email: /[\w._%+-]+@[\w.-]+\.[A-Za-z]{2,}/g, phone: /\d{3}-\d{3}-\d{4}/g, creditCard: /\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}/g, }; Object.keys(patterns).forEach((key) => { data = data.replace(patterns[key], `[${key.toUpperCase()}_REDACTED]`); }); return data; } } // Bad: Exposing PII function badHandling(data) { console.log(data); // Logs sensitive data return data; // Returns without sanitization } ``` ## Performance Best Practices ### 1. Query Optimization ```apex // Good: Optimized queries public class OptimizedQueries { // Selective query with indexed fields public static List<Account> getRecentAccounts() { return [ SELECT Id, Name, Type, Industry FROM Account WHERE CreatedDate >= :Date.today().addDays(-30) AND IsActive__c = true // Indexed custom field ORDER BY CreatedDate DESC LIMIT 100 ]; } // Bulk-safe query public static Map<Id, List<Contact>> getContactsByAccount(Set<Id> accountIds) { Map<Id, List<Contact>> contactMap = new Map<Id, List<Contact>>(); for (Contact c : [ SELECT Id, Name, Email, AccountId FROM Contact WHERE AccountId IN :accountIds ]) { if (!contactMap.containsKey(c.AccountId)) { contactMap.put(c.AccountId, new List<Contact>()); } contactMap.get(c.AccountId).add(c); } return contactMap; } } // Bad: Inefficient queries public class InefficientQueries { // Non-selective query public static List<Account> getBadQuery() { return [ SELECT Id, Name, (SELECT Id FROM Contacts) FROM Account WHERE Name != null // Non-selective ]; } // Query in loop public static void queryInLoop(List<Account> accounts) { for (Account acc : accounts) { List<Contact> contacts = [ SELECT Id FROM Contact WHERE AccountId = :acc.Id ]; // SOQL in loop! } } } ``` ### 2. Context Optimization ```javascript // Good: Progressive loading class ProgressiveLoader { async load(requirements) { const loaded = []; let remaining = this.contextLimit; // Sort by priority requirements.sort((a, b) => a.priority - b.priority); for (const req of requirements) { if (req.size <= remaining) { loaded.push(await this.loadItem(req)); remaining -= req.size; } else if (req.compressible) { const compressed = await this.compress(req); if (compressed.size <= remaining) { loaded.push(compressed); remaining -= compressed.size; } } } return loaded; } } // Bad: Load everything async function badLoader(requirements) { return Promise.all(requirements.map((r) => load(r))); // May exceed context limit! } ``` ## Deployment Best Practices ### 1. Staged Deployment ```yaml # Good: Progressive deployment deployment_strategy: stages: - name: development validation_only: false tests: LocalTests rollback: automatic - name: qa validation_only: true # Validate first tests: RunSpecifiedTests specified_tests: - AccountServiceTest - ContactServiceTest rollback: automatic - name: uat validation_only: true tests: RunLocalTests approval_required: true rollback: manual - name: production validation_only: true tests: RunLocalTests approval_required: true maintenance_window: true rollback: prepared monitoring: enhanced # Bad: Direct to production bad_deployment: target: production tests: NoTestRun # No tests! validation: false # No validation! rollback: none # No rollback plan! ``` ### 2. Rollback Strategy ```javascript // Good: Prepared rollback class RollbackStrategy { async prepareRollback(deployment) { // Backup current state const backup = await this.backupMetadata(); // Create rollback package const rollbackPackage = await this.createRollbackPackage(backup); // Test rollback in sandbox await this.testRollback(rollbackPackage); // Store for quick access await this.storeRollback(rollbackPackage); return { ready: true, package: rollbackPackage, estimatedTime: '5 minutes', }; } } // Bad: No rollback plan function deployWithoutRollback() { deploy(); // Hope nothing goes wrong! } ``` ## Common Pitfalls to Avoid ### 1. Context Overflow ```javascript // Pitfall: Loading too much context ❌ DON'T: - Load entire codebase into context - Include all documentation - Keep historical data in context ✅ DO: - Load only what's needed for current task - Use references for detailed information - Clear context between tasks ``` ### 2. Phase Confusion ```javascript // Pitfall: Using wrong phase for task ❌ DON'T: - Architecture design in development phase - Code implementation in planning phase - Switch phases frequently ✅ DO: - Complete planning before development - Use appropriate phase for each task - Batch similar tasks in same phase ``` ### 3. Agent Misuse ```javascript // Pitfall: Using wrong agent ❌ DON'T: - Use sf-developer for architecture - Use sf-architect for testing - Skip handoffs between agents ✅ DO: - Match agent expertise to task - Use formal handoff protocol - Validate agent outputs ``` ### 4. Incomplete Stories ```javascript // Pitfall: Stories without context ❌ DON'T: - Create vague story titles - Skip acceptance criteria - Ignore dependencies ✅ DO: - Include complete context - Define clear acceptance criteria - Map dependencies explicitly ``` ## Scenario-Based Examples ### Scenario 1: Adding a New Field to a Custom Object 1. **Phase:** Development 2. **Agent:** `sf-admin` 3. **Task:** `add-field` 4. **Command:** `sf-agent task add-field --object "Project__c" --field "Budget__c" --type "Currency"` ### Scenario 2: Creating a New Apex Class 1. **Phase:** Development 2. **Agent:** `sf-developer` 3. **Task:** `create-apex-class` 4. **Command:** `sf-agent task create-apex-class --name "ProjectController"` ### Scenario 3: Refactoring an Existing LWC 1. **Phase:** Development 2. **Agent:** `sf-developer` 3. **Task:** `refactor-lwc` 4. **Command:** `sf-agent task refactor-lwc --name "projectList" --instructions "Improve performance by using track and wire services correctly."` ### Scenario 4: Adding a New Feature to an Existing Project (Brownfield) 1. **Phase:** Planning 2. **Workflow:** `create-brownfield-prd` 3. **Command:** `sf-agent workflow create-brownfield-prd` 4. **Follow-up:** After the PRD and architecture are created, switch to the development phase and implement the stories. ## Monitoring and Metrics ### 1. Key Metrics to Track ```yaml essential_metrics: efficiency: - Context usage per task - Token consumption rate - Story completion time - Phase transition frequency quality: - Test coverage percentage - Security scan results - Code review pass rate - Deployment success rate productivity: - Stories per sprint - Artifacts generated - Automation percentage - Rework frequency ``` ### 2. Alert Thresholds ```javascript const alertThresholds = { contextUsage: { warning: 0.8, // 80% of limit critical: 0.95, // 95% of limit }, testCoverage: { minimum: 0.75, // 75% minimum target: 0.85, // 85% target }, performanceTime: { warning: 5000, // 5 seconds critical: 10000, // 10 seconds }, errorRate: { warning: 0.05, // 5% errors critical: 0.1, // 10% errors }, }; ``` ## Continuous Improvement ### 1. Regular Reviews ```yaml review_schedule: daily: - Check metrics dashboard - Review error logs - Update story queue weekly: - Analyze performance trends - Review completed stories - Update documentation - Team retrospective monthly: - Architecture review - Security audit - Performance optimization - Framework updates ``` ### 2. Feedback Loop ```javascript class FeedbackLoop { collect() { return { automated: this.collectMetrics(), manual: this.collectUserFeedback(), quality: this.collectQualityMetrics(), }; } analyze(feedback) { const insights = { bottlenecks: this.identifyBottlenecks(feedback), improvements: this.suggestImprovements(feedback), trends: this.analyzeTrends(feedback), }; return insights; } implement(insights) { insights.improvements.forEach((improvement) => { this.updateConfiguration(improvement); this.notifyTeam(improvement); this.trackImpact(improvement); }); } } ``` ## Summary Following these best practices will help you: 1. **Maximize Efficiency**: Use the right phase, agent, and context for each task 2. **Maintain Quality**: Implement comprehensive testing and validation 3. **Ensure Security**: Follow secure coding practices and data protection 4. **Optimize Performance**: Use efficient queries and context management 5. **Enable Scale**: Implement proper organization and monitoring Remember: The framework is powerful, but using it correctly is key to success. Start with these practices and adapt them to your specific needs. --- _Last Updated: 2025-08-11_ _Version: 4.0.0_