[{"data":1,"prerenderedAt":82},["ShallowReactive",2],{"blog-prompt-engineering-for-developers":3,"blogs-all":20},{"data":4},{"slug":5,"category":6,"title":7,"description":8,"cover":9,"tags":10,"readTime":14,"date":15,"updatedAt":16,"seo":17,"content":19},"prompt-engineering-for-developers","AI","Prompt Engineering for Developers: What Actually Works in Production","Practical techniques I use when integrating Claude and OpenAI APIs into real applications — output format control, system prompts, few-shot examples, and defensive parsing.",null,[6,11,12,13],"Claude API","OpenAI","Laravel","8 min read","2026-05-18","2026-08-07",{"title":7,"description":18,"ogImage":9},"Format control, system prompts, few-shot examples, defensive parsing — practical prompt engineering from a year of integrating Claude and OpenAI APIs.","## Skip the Theory\n\nMost prompt engineering content is either academic papers nobody applies in practice or marketing material from AI companies. This is neither.\n\nI've been integrating Claude and OpenAI APIs into production systems at Smart Provider LLC for over a year. These are the techniques that changed output quality in ways that actually mattered for shipping reliable features.\n\n## Be Explicit About Output Format\n\nVague prompts produce vague outputs. If your code needs to parse the response, the LLM needs to know the exact format to return — not approximately, exactly.\n\n```php\n\u002F\u002F Bad — output shape is unpredictable\n$prompt = \"Extract the customer name and address from this: {$rawData}\";\n\n\u002F\u002F Good — explicit structure the code can parse reliably\n$prompt = \u003C\u003C\u003CPROMPT\nExtract the following fields from the text below.\nReturn ONLY a valid JSON object with this exact structure — no explanation, no markdown, no extra fields:\n\n{\n    \"customer_name\": \"string or null\",\n    \"street_address\": \"string or null\",\n    \"city\": \"string or null\",\n    \"state\": \"string or null\",\n    \"zip_code\": \"string or null\"\n}\n\nText:\n{$rawData}\nPROMPT;\n```\n\nThe second prompt returns parseable JSON consistently. The first returns whatever the model feels like on that particular run.\n\n## System Prompts Are Not Optional\n\nA system prompt sets context for the entire conversation — role, constraints, and behavior when input is ambiguous. Don't skip it.\n\n```php\n$response = Http::withHeaders([...])->post('https:\u002F\u002Fapi.anthropic.com\u002Fv1\u002Fmessages', [\n    'model'      => 'claude-sonnet-4-6',\n    'max_tokens' => 512,\n    'system'     => 'You are a data extraction assistant for a service management platform. Extract structured information from unstructured service documents. Always return valid JSON. If a field is not present in the text, return null — never guess or infer values.',\n    'messages'   => [['role' => 'user', 'content' => $prompt]],\n]);\n```\n\nWithout a system prompt, you're relying on the model's default behavior. With one, you're defining exactly what role it plays.\n\n## Few-Shot Examples Beat Instructions\n\nShowing the model correct input\u002Foutput pairs is more reliable than explaining what to do. For structured extraction tasks, three good examples outperform two paragraphs of instructions.\n\n```php\n$prompt = \u003C\u003C\u003CPROMPT\nExample 1:\nInput: \"Customer: John Smith, 123 Main Street, Atlanta GA 30301\"\nOutput: {\"customer_name\": \"John Smith\", \"street_address\": \"123 Main Street\", \"city\": \"Atlanta\", \"state\": \"GA\", \"zip_code\": \"30301\"}\n\nExample 2:\nInput: \"Service request from ABC Corp - no address on file\"\nOutput: {\"customer_name\": \"ABC Corp\", \"street_address\": null, \"city\": null, \"state\": null, \"zip_code\": null}\n\nNow extract from:\nInput: \"{$rawData}\"\nOutput:\nPROMPT;\n```\n\n## Temperature: Low for Extraction, Higher for Generation\n\nTemperature controls output randomness. For extraction where you need consistent, predictable structure — use 0 or close to it. For content generation where variation is good — use 0.7 or higher.\n\nI've seen developers leave temperature at the default for extraction tasks and then spend days debugging why identical input occasionally produces a slightly different JSON structure.\n\n## Parse Defensively\n\nLLMs sometimes wrap JSON in markdown code blocks. They return valid-looking JSON with wrong types. They include extra fields you didn't ask for.\n\n```php\nfunction parseAIResult(string $raw): ?array\n{\n    \u002F\u002F Strip markdown fences if present\n    $clean = preg_replace('\u002F```json?\\s*(.*?)\\s*```\u002Fs', '$1', $raw);\n\n    $data = json_decode(trim($clean), true);\n\n    if (json_last_error() !== JSON_ERROR_NONE) {\n        Log::warning('AI returned invalid JSON', ['raw' => $raw]);\n        return null;\n    }\n\n    $required = ['customer_name', 'street_address', 'city', 'state', 'zip_code'];\n    foreach ($required as $field) {\n        if (!array_key_exists($field, $data)) {\n            Log::warning('AI response missing field', ['field' => $field]);\n            return null;\n        }\n    }\n\n    return $data;\n}\n```\n\nWhen parsing fails, log the raw output and flag the record for manual review. Never silently discard failures.\n\n## The Test I Run Before Shipping\n\nWrite the prompt, run it against 20 real examples from production data, count how many return correct parseable output. If it's below 95%, the prompt needs more work.\n\nThe LLM isn't the unreliable part. The prompt usually is.",{"data":21},[22,25,37,47,59,70],{"slug":5,"category":6,"title":7,"description":8,"cover":9,"tags":23,"readTime":14,"date":15,"updatedAt":16,"seo":24},[6,11,12,13],{"title":7,"description":18,"ogImage":9},{"slug":26,"category":27,"title":28,"description":29,"cover":9,"tags":30,"readTime":14,"date":33,"updatedAt":16,"seo":34},"mysql-query-optimization-laravel","Database","MySQL Query Optimization in Laravel: What I Fixed in Production","Real slow-query problems I diagnosed and fixed in a production SaaS — N+1 queries, missing indexes, Eloquent gotchas, and when to drop to raw SQL.",[13,31,27,32],"MySQL","Performance","2026-05-10",{"title":35,"description":36,"ogImage":9},"MySQL Query Optimization in Laravel: Real Production Fixes","N+1 queries, missing indexes, Eloquent gotchas — real slow-query problems I diagnosed and fixed in a production Laravel SaaS. Before and after code included.",{"slug":38,"category":6,"title":39,"description":40,"cover":9,"tags":41,"readTime":43,"date":44,"updatedAt":16,"seo":45},"building-ai-features-in-laravel","Building AI Features in Laravel with the Claude API","How I integrated Claude API into a SaaS platform to automate repetitive data entry workflows — and what I got wrong before I got it right.",[13,6,11,42],"SaaS","6 min read","2026-05-01",{"title":39,"description":46,"ogImage":9},"How I integrated Claude API into a Laravel SaaS to automate data entry — queues, caching, defensive parsing, and real production lessons from SP360.",{"slug":48,"category":49,"title":50,"description":51,"cover":9,"tags":52,"readTime":55,"date":56,"updatedAt":16,"seo":57},"nuxt-4-full-stack-with-laravel-api","Full-Stack","Nuxt 4 + Laravel API: The Full-Stack Setup I Actually Ship","How I structure a Nuxt 4 frontend with a Laravel REST API — auth composable, consistent response shape, error handling, and the lessons from two years of running this in production.",[53,13,49,54],"Nuxt","API","7 min read","2026-04-18",{"title":50,"description":58,"ogImage":9},"My production-tested Nuxt 4 + Laravel 11 setup — $fetch composable, Sanctum cookie auth, consistent API responses, lessons from two years running this stack.",{"slug":60,"category":61,"title":62,"description":63,"cover":9,"tags":64,"readTime":55,"date":67,"updatedAt":16,"seo":68},"laravel-queue-jobs-real-world","Backend","Laravel Queues in Production: What Nobody Tells You","Beyond the docs — real patterns for reliable queue jobs, retry strategies, and monitoring that I use in a production SaaS application.",[13,65,61,66],"Queues","Production","2026-04-15",{"title":62,"description":69,"ogImage":9},"Real patterns for reliable Laravel queue jobs — timeouts, idempotency, cache locks, and Horizon config I use in a production SaaS application.",{"slug":71,"category":72,"title":73,"description":74,"cover":9,"tags":75,"readTime":78,"date":79,"updatedAt":16,"seo":80},"vue-3-composition-api-patterns","Frontend","Vue 3 Composition API Patterns I Use Every Day","Practical composable patterns — async state management, form handling, and reusable logic that keeps Vue 3 codebases clean without premature abstraction.",[76,77,72],"Vue","TypeScript","5 min read","2026-04-05",{"title":73,"description":81,"ogImage":9},"Practical composables for async state, form validation, and reusable logic in Vue 3 — patterns I use in every Nuxt project, with real code.",1787446403354]