Setup and context — "Let AI Handle Everything" Doesn't Work for Mobile
With the evolution of AI app development tools like Rork, the barrier to adding AI features to mobile apps has dropped dramatically. But a "let AI do everything" design doesn't always work well with the constraints unique to mobile environments.
IDC notes that "enterprises seek platforms that support both deterministic and agentic approaches within a single framework." Meanwhile, Gartner predicts that over 40% of Agentic AI projects will be cancelled or significantly scaled back by the end of 2027.
This article applies the fundamental software design principle of Separation of Concerns to AI agent design in mobile apps, showing how to optimize quality, cost, and performance.
Three Challenges of AI Design in Mobile Apps
Challenge 1: Network Dependency and Latency
Mobile apps operate in environments with unreliable connectivity. If every operation depends on cloud-based LLM APIs, the app becomes unusable in subways or remote areas.
Challenge 2: Token Costs and Battery Drain
LLM API calls are billed by token count, and frequent API communication drains battery. Calling AI APIs on every user interaction is inefficient for both cost and UX.
Challenge 3: Response Consistency
Using AI for deterministic tasks like form validation, numerical calculations, or date processing means identical inputs might produce different outputs. Users find it confusing when "the validation check gives different results today than yesterday."
Separation of Concerns: Where to Use AI and Where Not To
Tasks for AI Agents
- Natural language understanding: Interpreting ambiguous instructions and free-text input
- Content generation: Creating text, images, and recommendations
- Conversational interfaces: Chatbots, voice assistants
- Personalization: Dynamic UI adjustments based on user preferences
- Anomaly detection: Identifying inputs or patterns that deviate from normal
Tasks for Deterministic Tools
- Form validation: Email format, phone numbers, date checks
- Numerical calculations: Total amounts, tax calculations, discount rates
- Data transformation: Currency conversion, unit conversion, date formatting
- Local storage operations: Cache management, offline data persistence
- Navigation logic: Screen transitions, deep link routing
- Authentication flows: Login, token management, session control
Case Study: E-Commerce App Architecture with Rork
Let's design an e-commerce app with proper separation between AI and deterministic tools.
Layer Structure
[UI Layer]
├── Product Search (AI: natural language + Local: filter/sort)
├── Product Detail (Local: data display + AI: review summary)
├── Cart (Local: price calculation, stock check)
├── Chat Support (AI: dialogue, problem solving)
└── Checkout (Local: Stripe SDK, validation)
[Business Logic Layer]
├── Pricing Engine (Deterministic)
├── Inventory Management (Deterministic)
├── Recommendations (AI)
└── Fraud Detection (AI)
[Data Layer]
├── Local DB (SQLite / AsyncStorage)
├── Remote API (REST / GraphQL)
└── AI API (Claude / Gemini)
Implementation: Separated Product Search
// React Native / Expo implementation example
// 1. AI-powered natural language search (requires network)
async function aiSearch(query: string): Promise<Product[]> {
// Handles queries like "red dress under $100"
const response = await fetch("/api/ai-search", {
method: "POST",
body: JSON.stringify({ query })
});
return response.json();
}
// 2. Local filtering (offline-capable, deterministic)
function localFilter(
products: Product[],
filters: { minPrice?: number; maxPrice?: number; category?: string }
): Product[] {
return products.filter(p => {
if (filters.minPrice && p.price < filters.minPrice) return false;
if (filters.maxPrice && p.price > filters.maxPrice) return false;
if (filters.category && p.category !== filters.category) return false;
return true;
});
}
// 3. Local sorting (deterministic, fast)
function localSort(
products: Product[],
sortBy: "price_asc" | "price_desc" | "rating" | "newest"
): Product[] {
const sorted = [...products];
switch (sortBy) {
case "price_asc":
return sorted.sort((a, b) => a.price - b.price);
case "price_desc":
return sorted.sort((a, b) => b.price - a.price);
case "rating":
return sorted.sort((a, b) => b.rating - a.rating);
case "newest":
return sorted.sort((a, b) =>
new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
);
}
}
// Combined: AI search → Local filter & sort
async function searchProducts(
query: string,
filters: FilterOptions,
sortBy: SortOption
) {
// AI search only when network is available
const results = navigator.onLine
? await aiSearch(query)
: await localFallbackSearch(query); // Offline fallback
// Filter and sort always run locally (fast, deterministic)
const filtered = localFilter(results, filters);
return localSort(filtered, sortBy);
}Implementation: Cart Calculation (Deterministic)
// Cart calculations should NEVER be delegated to AI
// Identical inputs must always produce identical results
interface CartItem {
productId: string;
name: string;
price: number;
quantity: number;
taxRate: number;
}
function calculateCartTotal(items: CartItem[]) {
const subtotal = items.reduce(
(sum, item) => sum + item.price * item.quantity, 0
);
const tax = items.reduce(
(sum, item) => sum + Math.floor(item.price * item.quantity * item.taxRate),
0
);
const total = subtotal + tax;
return { subtotal, tax, total };
}
// Usage example
const cart: CartItem[] = [
{ productId: "001", name: "T-shirt", price: 29.80, quantity: 2, taxRate: 0.1 },
{ productId: "002", name: "Pants", price: 49.80, quantity: 1, taxRate: 0.1 }
];
const result = calculateCartTotal(cart);
console.log(`Subtotal: $${result.subtotal} / Tax: $${result.tax} / Total: $${result.total}`);
// Output: Subtotal: $109.40 / Tax: $10.94 / Total: $120.34The Importance of Offline-First Design
Offline capability matters in mobile apps. By separating concerns and placing deterministic tasks locally, core functionality works even without network connectivity.
- Cart operations: Complete locally
- Browsing history: Saved to local DB
- Form input: Validation runs locally; submission waits for connectivity
- AI features: Execute asynchronously when network returns
With this design, users can browse products and manage their cart even underground.
Cost Reduction Impact
Let's compare costs between AI-dependent and separated architectures for an app with 100,000 monthly users.
All processing via AI API:
- Product search: 100K calls × token cost
- Filtering: 300K calls × token cost
- Cart calculation: 200K calls × token cost
- Recommendations: 100K calls × token cost
With Separation of Concerns:
- Product search (AI): 100K calls × token cost
- Filtering (local): $0
- Cart calculation (local): $0
- Recommendations (AI): 100K calls × token cost
API call volume drops by roughly 70%, with corresponding improvements in both cost and latency.
Summary
For AI agent design in mobile apps, "concentrate AI where it delivers the most value and delegate the rest to deterministic tools" outperforms "let AI handle everything." Separation of Concerns reliably improves mobile app quality across three dimensions: reduced network dependency, lower costs, and consistent responses.