Calling an LLM (from the right place)
The AI feature is an API call like any other — made from the server, never the browser, with the key in an env file and the prompt treated as product.
Here's the demystifying truth of this module: adding AI to your app is adding one more API call — your server asks a model provider's server a question and gets JSON back. Every pattern you learned in Module 4 applies; two new disciplines join them:
- The call happens server-side, always. Your API key is a payment credential — anyone holding it can spend your money. Browser code is public code (Module 1's oldest lesson), so the key lives on the server: the browser knocks on your door (
/api/ai/draft), your route calls the model provider, and the key never crosses the line. Any tutorial showing an API key in frontend code is teaching you to get robbed. - The key lives in `.env.local`, which lives in `.gitignore`. Environment files hold secrets outside the code; the gitignore keeps them out of the repo forever (a key committed once is compromised forever — history remembers).
ANTHROPIC_API_KEY=sk-...in the env file,process.env.ANTHROPIC_API_KEYin the route, and a.env.examplewith fake values so future-you remembers what's needed. This is the exact hygiene every production system in this company's product line runs on; you're learning it on day one of your first app. - The prompt is product, not plumbing. Replyable's draft-reply prompt encodes real decisions: the tone options from Settings, the 'reply to what they actually said' instruction, the sign-off, the length cap, the 'if the message needs information you don't have, say [NEEDS INFO: what] instead of inventing' escape (a contract prompt — Prompt Engineering graduates will recognize the genre). Keep it in its own file (
lib/prompts.ts), version it in git like the code it is.
The economics, so nothing surprises you
Model APIs charge per token (word-ish pieces) in and out. A Replyable draft — a feedback message in, a five-sentence reply out — costs a fraction of a cent on a mid-tier model. You'll set a spending cap in the provider dashboard today (the lab's first step), and Module 6 adds a rate limit so a stuck loop (or a stranger who finds your door) can't turn pennies into a phone bill. Choose a current mid-tier model for drafting; frontier-tier is overkill for this task and you can swap models by changing one string — which is the point of keeping the call in one place.
The AI call is your app's first dependency on someone else's uptime. Before building the happy path, decide the unhappy ones: model API down → the reply box still works by hand (the feature assists, never gates); slow response → visible drafting state with a cancel; weird output → the human edits before sending anyway (your approval-gate design absorbs imperfect drafts by construction). Apps that treat AI as an enhancement degrade gracefully; apps that treat it as a load-bearing wall fall over with it.