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
Markdown
# 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_