Best Practices

Effective AI rule configuration is crucial for maximizing the benefits of AI-powered development tools while maintaining code quality and consistency. This guide explores key best practices for implementing and managing AI rules across your development workflow.

Core Principles

AI rules should be designed to enhance your development process while maintaining high standards. Here are the fundamental principles to consider:

Tip:

AI rules work best when they complement your existing development practices rather than replacing them entirely. Focus on areas where AI can provide the most value while preserving your team's established workflows.

Rule Organization

Organize your AI rules effectively by following these guidelines:

1

Establish Clear Categories

Group related rules into logical categories such as:

  • Language-specific rules (TypeScript, Python, React)
  • Code style and formatting
  • Performance optimization
  • Security best practices
  • Testing requirements
  • Documentation standards
2

Define Priority Levels

Assign priority levels based on impact:

  • Critical: Security vulnerabilities, performance bottlenecks
  • High: Code quality, maintainability issues
  • Medium: Best practices, optimization opportunities
  • Low: Style suggestions, documentation improvements
3

Maintain Version Control

  • Store rules alongside your codebase
  • Track rule changes with clear commit messages
  • Use semantic versioning for rule updates
  • Document breaking changes in rule behavior

Implementation Best Practices

Follow these guidelines for effective rule implementation:

Note:

Start with essential rules that address common issues, then gradually expand based on team feedback and metrics. Focus on rules that provide immediate value and can be automatically fixed.

Rule Configuration Examples

TypeScript Type Safety Rules

# TypeScript Type Safety Rules

## Code Organization and Structure
- Use feature-based or type-based directory structure
- Follow consistent file naming conventions
- Leverage ES Modules for modularity
- Implement component-based architectures
- Use code splitting for performance

## Design Patterns and Best Practices
- Factory Pattern for complex object creation
- Dependency Injection for reduced coupling
- Observer Pattern for reactive programming
- Strategy Pattern for algorithm encapsulation

## Performance Optimization
- Implement memoization techniques
- Use proper lazy loading strategies
- Optimize bundle size with tree shaking
- Follow memory management best practices
- Implement rendering optimization

## Security Considerations
- Prevent XSS attacks through input sanitization
- Implement CSRF protection
- Use proper authentication patterns
- Follow secure API communication practices
- Protect sensitive data

## Common Pitfalls to Avoid
- Overusing the 'any' type
- Ignoring compiler warnings
- Improper async/await handling
- Not handling edge cases
- Neglecting proper error handling

Add typescript example code you want the agent to follow:

// src/features/auth/types.ts
interface User {
  id: string;
  email: string;
  role: UserRole;
}

enum UserRole {
  Admin = 'ADMIN',
  User = 'USER'
}

// Design Pattern: Factory Pattern
class UserFactory {
  static createUser(data: Partial<User>): User {
    return {
      id: data.id || crypto.randomUUID(),
      email: data.email || '',
      role: data.role || UserRole.User
    };
  }
}

// Design Pattern: Observer Pattern
class EventEmitter<T> {
  private listeners: ((data: T) => void)[] = [];

  subscribe(listener: (data: T) => void): () => void {
    this.listeners.push(listener);
    return () => {
      this.listeners = this.listeners.filter(l => l !== listener);
    };
  }

  emit(data: T): void {
    this.listeners.forEach(listener => listener(data));
  }
}

// Performance: Memoization Example
function memoize<T extends object, U>(fn: (arg: T) => U): (arg: T) => U {
  const cache = new Map<string, U>();

  return (arg: T): U => {
    const key = JSON.stringify(arg);
    if (cache.has(key)) return cache.get(key)!;
    
    const result = fn(arg);
    cache.set(key, result);
    return result;
  };
}

// Security: Input Sanitization
function sanitizeInput(input: string): string {
  return input
    .replace(/[<>]/g, '') // Remove potential HTML tags
    .trim()
    .slice(0, 1000); // Limit length
}

// Error Handling Best Practices
interface ApiResponse<T> {
  data?: T;
  error?: {
    code: string;
    message: string;
  };
}

async function fetchUser(id: string): Promise<ApiResponse<User>> {
  try {
    const response = await fetch(`/api/users/${id}`);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json();
    return { data: UserFactory.createUser(data) };
  } catch (error) {
    return {
      error: {
        code: 'FETCH_ERROR',
        message: error instanceof Error ? error.message : 'Unknown error'
      }
    };
  }
}

Python Code Quality Rules

# Python Code Quality Rules

## Code Organization and Structure
- Use package-based directory structure
- Follow PEP 8 naming conventions
- Leverage Python modules and packages
- Implement clean architecture principles
- Use type hints for better maintainability

## Design Patterns and Best Practices
- Factory Pattern for object creation
- Dependency Injection for loose coupling
- Observer Pattern for event handling
- Strategy Pattern for algorithm variants

## Performance Optimization
- Use generators for memory efficiency
- Implement caching strategies
- Optimize imports and dependencies
- Follow memory management best practices
- Use async/await for I/O operations

## Security Considerations
- Input validation and sanitization
- Implement proper authentication
- Use secure dependency versions
- Follow OWASP security guidelines
- Protect sensitive data

## Common Pitfalls to Avoid
- Mutable default arguments
- Global variable misuse
- Improper exception handling
- Ignoring type hints
- Poor resource management

add python example code you want the agent to follow:

# src/features/auth/types.py
from dataclasses import dataclass
from enum import Enum
from typing import Optional, Dict, Any
import uuid

class UserRole(Enum):
    ADMIN = "ADMIN"
    USER = "USER"

@dataclass
class User:
    id: str
    email: str
    role: UserRole

# Design Pattern: Factory Pattern
class UserFactory:
    @staticmethod
    def create_user(data: Dict[str, Any]) -> User:
        return User(
            id=data.get("id", str(uuid.uuid4())),
            email=data.get("email", ""),
            role=data.get("role", UserRole.USER)
        )

# Design Pattern: Observer Pattern
class EventEmitter:
    def __init__(self):
        self._listeners: list = []
    
    def subscribe(self, listener: callable) -> callable:
        self._listeners.append(listener)
        def unsubscribe() -> None:
            self._listeners.remove(listener)
        return unsubscribe
    
    def emit(self, data: Any) -> None:
        for listener in self._listeners:
            listener(data)

# Performance: Caching Example
from functools import lru_cache
from typing import TypeVar, Callable

T = TypeVar('T')
U = TypeVar('U')

def memoize(func: Callable[[T], U]) -> Callable[[T], U]:
    cache: Dict[str, U] = {}
    
    def wrapper(arg: T) -> U:
        key = str(arg)
        if key in cache:
            return cache[key]
        
        result = func(arg)
        cache[key] = result
        return result
    
    return wrapper

# Security: Input Validation
def sanitize_input(input_str: str, max_length: int = 1000) -> str:
    # Remove potentially dangerous characters
    sanitized = "".join(c for c in input_str if c.isprintable())
    # Trim and limit length
    return sanitized.strip()[:max_length]

# Error Handling Best Practices
from dataclasses import dataclass
from typing import Optional, TypeVar, Generic

T = TypeVar('T')

@dataclass
class ApiResponse(Generic[T]):
    data: Optional[T] = None
    error: Optional[Dict[str, str]] = None

async def fetch_user(user_id: str) -> ApiResponse[User]:
    try:
        async with aiohttp.ClientSession() as session:
            async with session.get(f"/api/users/{user_id}") as response:
                if not response.ok:
                    raise ValueError(f"HTTP error! status: {response.status}")
                
                data = await response.json()
                return ApiResponse(data=UserFactory.create_user(data))
    except Exception as e:
        return ApiResponse(
            error={
                "code": "FETCH_ERROR",
                "message": str(e)
            }
        )

Continuous Improvement

Maintain the effectiveness of your AI rules through:

  1. Regular evaluation of:

    • Rule usage patterns
    • False positive rates
    • Developer productivity impact
    • Code quality metrics
  2. Collection and incorporation of:

    • Team feedback
    • Bug patterns
    • Performance bottlenecks
    • Security vulnerabilities
  3. Updates to accommodate:

    • New language features
    • Framework updates
    • Emerging best practices
    • Team workflow changes
  4. Removal or modification of:

    • Redundant rules
    • Low-value checks
    • Outdated patterns
    • Problematic automations
  5. Documentation of:

    • Rule changes
    • Migration guides
    • Configuration updates
    • Best practice evolution

By following these best practices, you can create an effective AI rule system that enhances your development process while maintaining code quality and consistency across different languages and frameworks.