Prompt Engineering Isn't a Trick, It's an Interface Design Problem
The phrase "prompt engineering" gets a bad reputation because most people treat it as finding a magic sentence that unlocks better output. In practice, writing a good system prompt is closer to designing an API contract: you're specifying inputs, constraints, output format, and failure behavior for a component that happens to be a language model instead of a function.
I've had to get this right in two very different contexts: the AI JobCopilot pipeline, where an LLM generates a personalized recruiter email and an ATS-optimized LaTeX resume from a raw LinkedIn job description, and the chatbot on my own portfolio site, a client-side assistant running on Groq that has to answer questions about my background accurately without hallucinating experience I don't have. Both taught me the same lessons, applied differently.
Lesson 1: Say What the Model Should NOT Do, Explicitly
The single highest-leverage sentence in any system prompt I write is a negative constraint. Left unconstrained, an LLM will happily invent plausible-sounding details to fill gaps — a fabricated job title, a metric that sounds reasonable, a skill I don't actually have. For the portfolio chatbot, this is non-negotiable: it's representing me to recruiters.
You are Rishab's portfolio assistant. You answer questions about his
background, skills, and projects using ONLY the information provided
in the CONTEXT block below.
Rules:
- Never invent employers, job titles, metrics, or projects not present
in the CONTEXT block.
- If a question asks about something not covered in CONTEXT, say you
don't have that information and suggest contacting Rishab directly.
- Do not speculate about his availability, rates, or opinions on
topics not covered in CONTEXT.
Without that explicit "never invent" instruction, I found the model would confidently answer questions about experience it had no basis for, just because the question was phrased as if the answer should exist.
Lesson 2: Structure the Output Before You Ask for Content
For AI JobCopilot, the LLM needs to produce two very different artifacts from one job description: a short, personalized recruiter email and a full LaTeX resume tailored to that role. Asking for both in free-form prose is a recipe for inconsistent formatting that breaks downstream automation. Instead, I specify the exact output shape up front:
You will receive a job description. Produce a JSON object with exactly
these keys:
{
"recruiter_email": {
"subject": string,
"body": string
},
"resume_latex": string,
"key_skills_matched": string[]
}
Rules:
- recruiter_email.body must be under 150 words, professional tone,
no generic filler like "I am excited to apply."
- resume_latex must be valid LaTeX using the \\resumeItem and
\\resumeSubheading macros already defined in the template — do not
redefine them.
- key_skills_matched must only include skills that appear in both the
job description and the candidate's real skill list provided below.
Downstream, this JSON gets parsed and routed by the n8n workflow — one branch sends the email via Gmail API, another compiles the LaTeX resume, another logs key_skills_matched to Google Sheets for tracking which job descriptions matched well. None of that automation is possible if the model is free to respond in whatever prose format it feels like that day. A rigid output contract is what makes an LLM usable as a pipeline component rather than a chat toy.
Lesson 3: Ground the Model With Real Context, Not Just Instructions
Instructions alone don't stop hallucination — grounding does. For the portfolio chatbot, the system prompt doesn't just say "don't make things up," it's paired with an actual context block containing my real skills, projects, and experience, refreshed whenever my background changes:
CONTEXT:
- Current role: RPA Developer Intern at Avent IQ (Jan 2026 – present)
- Previous role: AI Intern at Draskenlabs (Oct 2025 – Dec 2025)
- Projects: AI JobCopilot (Chrome extension, n8n, LLM resume generation),
Elevate Fitness (Next.js, Supabase, agentic AI fitness app), Automated
Image Filtering (Python, OpenCV, InsightFace)
- Certifications: n8n Level 1, Claude Code in Action, IBM SkillsBuild
Virtual Intelligent Agents, Automation Anywhere Essentials
The instruction "only use CONTEXT" is only as good as the CONTEXT itself. If the context block is incomplete or stale, the model either hallucinates to fill the gap or gives unhelpfully vague answers. Keeping this block accurate is as much a part of "prompt engineering" as the wording of the instructions themselves.
Lesson 4: Temperature and Determinism Depend on the Task
For the resume/email generation in AI JobCopilot, I want low temperature — the output needs to be reliably parseable JSON and consistent in tone every time, since it's driving an unattended automation. For the portfolio chatbot answering open-ended visitor questions, a slightly higher temperature makes responses feel more natural without sacrificing factual grounding, since factual accuracy is enforced by the context block and rules, not by randomness.
The general principle: temperature should be a function of how much you need consistency vs. naturalness for that specific call, not a single global setting applied everywhere in your system.
Lesson 5: Test the Prompt Against Adversarial and Edge-Case Inputs
A system prompt that works on the five examples you tested during development will still break on inputs you didn't anticipate. For the portfolio chatbot, that meant testing:
- Direct attempts to get it to claim skills or experience I don't have ("Does Rishab know Kubernetes?")
- Off-topic questions it should gracefully decline ("What's the weather today?")
- Questions phrased to imply false premises ("Tell me about Rishab's team of 10 engineers")
For AI JobCopilot, that meant testing job descriptions with unusual formatting, missing sections, or non-English text, and confirming the JSON contract held even when the LLM was working with messy input.
The Real Takeaway
Prompt engineering that survives contact with production isn't about clever wording — it's about treating the system prompt as a contract with three parts: explicit negative constraints, a rigid output schema when the output feeds automation, and real grounding data instead of relying on instructions alone. Get those three right, and the "prompt engineering" part becomes far less mysterious.
Want to Talk Prompt Design?
If you're building an LLM-driven pipeline — whether it's automation, a chatbot, or something in between — and want to compare notes on system prompt design, reach out at rishabnishad22@gmail.com or on WhatsApp. More on my projects at rishab-nishad.vercel.app.