Building Production AI Features Without Becoming an ML Engineer
You don't need a PhD in machine learning to ship AI features. Seriously. I've watched developers over-engineer solutions when they could've grabbed Claude's API, thrown some prompts at it, and shipped.
Here's the real talk: the hardest part isn't the ML. It's knowing what to actually build and not gold-plating it.
What Changed (And Why You Should Care)
Two years ago, using AI in production meant dealing with model deployment, scaling issues, and weird edge cases. Now? You call an API. The model sits somewhere else. Your job is wiring it into your app smartly.
The shift: from "build ML systems" to "integrate intelligence into your existing app."
Three Patterns That Actually Work
1. The Classifier (Replace Your Decision Trees)
Got complex logic for routing, categorization, or prioritization? Stop writing cascading if-statements.
Real example: Triaging support tickets by urgency and category.
async function classifyTicket(ticketText) {
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'x-api-key': process.env.ANTHROPIC_API_KEY,
'content-type': 'application/json'
},
body: JSON.stringify({
model: 'claude-opus',
max_tokens: 200,
messages: [{
role: 'user',
content: `Classify this support ticket:
Ticket: "${ticketText}"
Respond in JSON:
{
"category": "billing|technical|feature_request|other",
"urgency": "critical|high|normal|low",
"reason": "one sentence why"
}`
}]
})
});
const text = response.content[0].text;
return JSON.parse(text);
}
Why this beats hardcoded rules:
- New edge case comes up? Retrain is literally just... running it again
- Your rules scale with real-world messiness, not your imagination
- Takes 20 minutes instead of 3 hours of conditional hell
2. The Extractor (Stop Writing Regex)
Parsing semi-structured text is a nightmare. Regex lies to you. Parsing libraries are overkill.
Real example: Extracting structured data from invoice PDFs or email content.
async function extractInvoiceData(invoiceText) {
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'x-api-key': process.env.ANTHROPIC_API_KEY,
'content-type': 'application/json'
},
body: JSON.stringify({
model: 'claude-opus',
max_tokens: 500,
messages: [{
role: 'user',
content: `Extract structured data from this invoice:
${invoiceText}
Return JSON:
{
"vendor": "company name",
"invoice_number": "string",
"amount": number,
"due_date": "YYYY-MM-DD",
"line_items": [
{ "description": string, "quantity": number, "price": number }
]
}`
}]
})
});
const text = response.content[0].text;
return JSON.parse(text);
}
Why this beats parsing libraries:
- Handles fuzzy, human-written formats naturally
- Extracts meaning, not just patterns
- One function handles 10 different invoice formats
3. The Brainstormer (Augment, Don't Replace, Users)
This one trips people up. Don't ask AI to make decisions for your users. Ask it to give them options or spark ideas.
Real example: Content recommendation or idea generation.
async function generatePostIdeas(topic, tone) {
const response = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'x-api-key': process.env.ANTHROPIC_API_KEY,
'content-type': 'application/json'
},
body: JSON.stringify({
model: 'claude-opus',
max_tokens: 1000,
messages: [{
role: 'user',
content: `Generate 5 blog post ideas about "${topic}" in a ${tone} tone.
For each idea:
- Title (under 60 chars)
- Angle (what's different about this take)
- Why readers will click
Make them concrete, not generic.`
}]
})
});
return response.content[0].text;
}
Why this works:
- Users make the final call (they should)
- Saves them 10 minutes of blank page syndrome
- You're helping, not automating away the human part
The Gotchas (Real Ones)
Cost creeps up quietly. Log your token usage. A classifier running 10k times/day at $0.015 per 1k tokens adds up.
Latency matters more than you think. If your classifier takes 2 seconds, that's a bad UX when it was instant before. Use streaming for longer outputs.
Bad prompts = bad output. Spend 15 minutes on the prompt. Iterate. Test edge cases. Your prompt IS your model.
Context is cheap until it isn't. Send relevant context, not your whole database. 100k tokens gets expensive fast.
The Practical Setup
Pick a provider. Claude (Anthropic), OpenAI, Cohere. They're all solid. Pick one and learn it deeply instead of context-switching.
Environment variables, not hardcoding.
process.env.ANTHROPIC_API_KEY. Every time.Timeouts and retries. APIs go down. Network hiccups happen. Handle gracefully:
async function callAIWithRetry(prompt, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(..., { timeout: 30000 });
return response;
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(r => setTimeout(r, 1000 * (i + 1)));
}
}
}
- Test the outputs. Have a human review sample results. Bad data will hide until production.
What You Actually Need to Learn
- Prompt engineering (the real skill now)
- Token counting (so cost surprises don't happen)
- How to frame problems so the API understands them
- Error handling (APIs are flakey)
You don't need to learn transformers, backpropagation, or linear algebra.
Next Steps
Pick one small thing in your app that could use intelligence:
- Classifying something
- Extracting data from text
- Generating variations of content
Build it in an afternoon. Deploy it Monday. Measure if it actually helps.
Don't wait for the perfect setup. The barrier is lower than you think.
Want more on AI in production? Subscribe to LearnAI Weekly for practical tips on shipping AI features without the hype. Real examples, real code, no buzzwords.
Top comments (0)