AI-Assisted Development: How I Ship Production Code Without a CS Degree
I built my first production agent system six months after leaving corporate strategy. No CS degree, no bootcamp — just Claude, Cursor, and a pressing need to ship. Now I'm running multi-agent workflows on Oracle Cloud, routing between Groq and Anthropic based on latency requirements, with Telegram and WhatsApp interfaces handling real user traffic. Here's the unvarnished reality of AI-assisted development from someone who learned to code this way.
The Executive-to-Builder Pipeline Nobody Talks About
Most "learn to code" stories follow predictable arcs: bootcamps, junior roles, grinding leetcode. Mine doesn't. I went from PowerPoint decks to production TypeScript because AI tools made the learning curve navigable — not easy, but navigable.
The first week with Cursor was humbling. I'd type comments like "make this function handle errors better" and watch Claude generate try-catch blocks I didn't understand. The code worked, but I was cargo-culting. This isn't sustainable for production systems.
What changed: I started treating AI as a senior developer who explains their thinking, not a magic code generator. Instead of "fix this," I'd write: "This webhook handler fails silently when Telegram's API times out. Show me how to add retry logic with exponential backoff, and explain why we need jitter."
The explanations mattered more than the code. Each generated snippet became a learning opportunity. Within two months, I could spot when Claude was hallucinating npm packages or suggesting outdated patterns. Within four months, I was modifying the suggestions rather than accepting them wholesale.
My Daily Workflow: Cursor + Claude as Architecture Partner
Here's my actual setup, warts and all:
Morning architecture session (30 minutes): I open Claude.ai (not Cursor) and sketch the day's work in plain English. Recent example: "I need to add batching to our WhatsApp message queue. Currently sending one-by-one, hitting rate limits. Oracle Cloud Functions have 5-minute timeout. What's the design?"
Claude responds with tradeoffs I hadn't considered: batch size vs latency, handling partial failures, cursor-based pagination for large queues. I push back, refine, and end up with a design doc. This conversation costs about $0.40 and saves hours of wrong implementations.
Coding blocks (2-3 hours): Cursor becomes my primary interface. My typical prompt pattern:
// Current: Simple queue processor that sends one message at a time
// Problem: Hitting WhatsApp rate limits (80 msgs/sec)
// Need: Batch processor that respects rate limits and handles failures
// Constraints: Oracle Cloud Function 5-min timeout, must track partial batch success
[Paste existing code here]
// Implement batching with these specifics:
// - Configurable batch size (default 50)
// - Exponential backoff on 429 errors
// - Return array of results with success/failure for each message
// - Log batch metrics to Oracle monitoring
The specificity matters. Vague prompts generate generic code. Detailed constraints generate production-ready code — sometimes.
The reality check: About 30% of generated code needs significant revision. Common issues:
- Assumes npm packages that don't exist
- Ignores error cases I didn't explicitly mention
- Creates overly complex abstractions for simple problems
- Forgets about TypeScript types until prompted
But here's what non-practitioners miss: even flawed generation accelerates learning. When Claude suggests Promise.allSettled() for batch processing, I learn a pattern I wouldn't have discovered scrolling MDN.
The Oracle Cloud Gotchas AI Doesn't Know
This is where AI-assisted development shows its limits. Oracle Cloud Infrastructure has quirks that aren't in any model's training data:
Resource limits nobody documents properly: Oracle Functions have a 5-minute max timeout, but the actual safe window is 4:30 to account for cold starts. Claude doesn't know this. I learned it from production failures.
The authentication maze: OCI's authentication is... special. Three failed attempts taught me:
- Instance principals work differently in Functions vs Compute
- The Node SDK silently falls back to incomplete auth methods
- You need explicit region configuration even when running in-region
My solution: I maintain a ORACLE_GOTCHAS.md file that I include in every Cursor prompt about infrastructure code. It's my institutional knowledge that AI can't access:
## Oracle Functions Constraints
- Real timeout: 4:30 (not 5:00)
- Memory: 256MB minimum, but 512MB recommended for Node
- Cold starts: 2-3 seconds typical
- No persistent disk, use Object Storage
## Auth Setup That Actually Works
[Code snippet with working auth]
Routing Between Groq and Claude: Production Decisions
Our agent system routes between Groq (Llama 3.1) and Claude based on request type. The routing logic took weeks to optimize, with AI assistance revealing edge cases I'd never considered alone.
Initial approach (naive): Route by task type. Groq for simple queries, Claude for complex reasoning.
Problem: "Simple" isn't binary. A user asking "What's the weather?" might follow up with "Should I cancel my outdoor event?" — suddenly we need reasoning.
Current approach (production-tested):
- Start with Groq (faster, cheaper)
- Analyze response confidence via simple heuristics
- Escalate to Claude if uncertain or user indicates confusion
- Cache routing decisions by conversation pattern
The code emerged through iteration with Cursor:
// Prompt to Cursor:
// "Current routing is too rigid. Need dynamic escalation based on:
// 1. Response uncertainty (look for hedge words)
// 2. User confusion signals ('what?', 'I don't understand')
// 3. Conversation complexity growth
// Show me a pragmatic implementation, not overengineered"
What I got wasn't perfect, but it was a starting point. The hedge word detection was clever — looking for "might," "possibly," "depends" as uncertainty signals. I wouldn't have thought of that approach.
The Feedback Loop That Actually Teaches
Here's what transformed my AI-assisted development from copy-paste to actual understanding:
Production failures as learning moments: When our Telegram bot crashed handling Cyrillic text, I could have asked Claude to "fix Unicode handling." Instead:
"Our bot crashes on this input: [paste]. I think it's a Unicode issue but want to understand why. Walk me through what's happening at each step, then show me a fix with inline comments explaining each part."
The response taught me about JavaScript string normalization, UTF-16 surrogate pairs, and why string.length lies. The fix was three lines. The learning was permanent.
Code review with AI: I review my own code with Claude after it works:
"This batch processor I wrote handles our WhatsApp queue. It works but feels clunky. What would a senior developer change? Be specific about code smells and suggest concrete improvements."
Recent feedback caught:
- Mixing async/await with .then() (consistency issue)
- Not handling the case where batch size exceeds queue length
- Opportunity to use generator functions for memory efficiency
Half the suggestions were overengineering, but half made the code genuinely better.
Real Constraints: What AI-Assisted Development Can't Solve
Let me be clear about the limitations:
Debugging production issues: When our agent started returning empty responses intermittently, AI couldn't help. The issue: Oracle Cloud's load balancer was timing out on cold starts, but only in specific regions. No amount of prompting would surface this.
Performance optimization: Claude can suggest algorithmic improvements, but it can't profile your actual system. Our message queue was slow not because of algorithm choice, but because we were opening new database connections for each batch. AI suggested caching strategies; I needed real profiler data.
Cost architecture: AI doesn't understand your AWS/Oracle bill. It'll happily suggest architectures that work technically but cost 10x more than necessary. Our initial design had every agent interaction hitting Claude directly — $50/day in API costs. The hybrid Groq/Claude routing cut it to $8/day.
Security intuition: AI-generated code often has subtle security issues. SQL injection is obvious, but what about timing attacks in our authentication flow? Or exposing internal error messages that reveal system architecture? These require paranoia that AI doesn't possess.
The Path Forward: AI-Native Development Patterns
Six months in, I've developed patterns that maximize AI assistance while maintaining code quality:
1. Specification-first prompting: Never start with "write a function that..." Instead, specify inputs, outputs, error cases, and constraints. The clearer the spec, the better the generation.
2. Test-driven AI development: Write tests first (with AI help), then ask for implementation. This catches AI hallucinations immediately:
// Write these tests first with AI, then implement:
describe('BatchProcessor', () => {
it('handles partial batch failures without stopping')
it('respects rate limits between batches')
it('returns detailed results for each message')
})
3. Component isolation: AI works better on focused problems. Instead of "build a message queue system," break it down:
- Rate limiter module
- Batch accumulator
- Error handler with retry logic
- Metrics collector
Each piece gets individual attention and better generation quality.
4. Living documentation: Every non-obvious decision gets a comment explaining why. When AI generates clever code, I make it explain itself in comments. Six months later, I thank past me constantly.
The Reality Check
Can you build production systems with AI assistance having no traditional programming background? Yes, with caveats:
- You'll spend 2x more time understanding code than writing it (this is good)
- Your first systems will have architectural debt you'll recognize later
- Debugging skills lag behind building skills — production issues will humble you
- You need exceptional persistence and tolerance for confusion
But also:
- You'll ship faster than traditional learning paths allow
- AI exposure to different patterns accelerates architectural thinking
- You develop intuition for what AI does well vs poorly
- The feedback loop of real users forces rapid improvement
I'm not a computer scientist. I'm a builder who uses AI to bridge knowledge gaps while shipping real systems. My code might not pass FAANG interviews, but it handles thousands of messages daily across Telegram and WhatsApp, routes intelligently between LLM providers, and runs reliably on Oracle's infrastructure.
That's the promise of AI-assisted development: not replacing expertise, but making building accessible to those willing to learn through shipping.
