{"slug": "ai-session-1-html", "title": "ai-session-1.html", "summary": "GenAI Foundations & Prompt Engineering for Developers is a technical session that teaches developers how to build with generative AI, covering prompt engineering techniques and foundational concepts. The session includes hands-on examples and best practices for integrating large language models into applications.", "body_md": "| <!DOCTYPE html> | |\n| <html lang=\"en\"> | |\n| <head> | |\n| <meta charset=\"utf-8\"> | |\n| <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> | |\n| <title>GenAI Foundations & Prompt Engineering for Developers</title> | |\n| <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\"> | |\n| <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin> | |\n| <link href=\"https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=IBM+Plex+Sans:ital,wght@0,400;0,500;0,600;1,400&family=IBM+Plex+Mono:wght@400;500;600&display=swap\" rel=\"stylesheet\"> | |\n| <style> | |\n| :root{ | |\n| --paper:#F6F7F9; | |\n| --card:#FFFFFF; | |\n| --ink:#12161D; | |\n| --ink-2:#495264; | |\n| --ink-3:#7C879B; | |\n| --rule:#DDE2EA; | |\n| --signal:#3B34C4; | |\n| --signal-soft:#ECEBFB; | |\n| --good:#0E7462; | |\n| --good-soft:#E3F3F0; | |\n| --warn:#A9530A; | |\n| --warn-soft:#FBEFE2; | |\n| --bad:#B02A37; | |\n| --bad-soft:#FBE9EB; | |\n| --shadow:0 1px 2px rgba(18,22,29,.05), 0 8px 24px -14px rgba(18,22,29,.22); | |\n| } | |\n| *{box-sizing:border-box} | |\n| html{scroll-behavior:smooth;scroll-padding-top:84px} | |\n| body{ | |\n| margin:0;background:var(--paper);color:var(--ink); | |\n| font-family:\"IBM Plex Sans\",system-ui,sans-serif; | |\n| font-size:16.5px;line-height:1.62; | |\n| -webkit-font-smoothing:antialiased; | |\n| } | |\n| h1,h2,h3,h4{font-family:\"Space Grotesk\",system-ui,sans-serif;line-height:1.15;margin:0} | |\n| code,kbd,pre,.mono{font-family:\"IBM Plex Mono\",ui-monospace,monospace} | |\n| /* ---------- top bar ---------- */ | |\n| .topbar{ | |\n| position:sticky;top:0;z-index:50;background:rgba(246,247,249,.88); | |\n| backdrop-filter:blur(10px);border-bottom:1px solid var(--rule); | |\n| } | |\n| .topbar-in{max-width:1180px;margin:0 auto;padding:12px 24px;display:flex;gap:20px;align-items:center;flex-wrap:wrap} | |\n| .brand{font-family:\"Space Grotesk\";font-weight:700;font-size:15px;letter-spacing:-.01em;white-space:nowrap} | |\n| .brand span{color:var(--signal)} | |\n| .tocbar{display:flex;gap:4px;overflow-x:auto;flex:1;scrollbar-width:none} | |\n| .tocbar::-webkit-scrollbar{display:none} | |\n| .tocbar a{ | |\n| font-size:12.5px;font-weight:500;color:var(--ink-2);text-decoration:none; | |\n| padding:5px 10px;border-radius:999px;white-space:nowrap; | |\n| } | |\n| .tocbar a:hover{background:var(--signal-soft);color:var(--signal)} | |\n| .tocbar a.on{background:var(--ink);color:#fff} | |\n| /* ---------- layout ---------- */ | |\n| .wrap{max-width:1180px;margin:0 auto;padding:0 24px 120px} | |\n| section{padding:76px 0 8px;border-top:1px solid var(--rule)} | |\n| section:first-of-type{border-top:none} | |\n| .eyebrow{ | |\n| font-family:\"IBM Plex Mono\";font-size:11.5px;font-weight:600;letter-spacing:.14em; | |\n| text-transform:uppercase;color:var(--signal);margin-bottom:14px;display:flex;gap:10px;align-items:center; | |\n| } | |\n| .eyebrow::after{content:\"\";height:1px;flex:1;background:var(--rule)} | |\n| h2{font-size:clamp(28px,3.6vw,40px);font-weight:600;letter-spacing:-.025em;margin-bottom:14px} | |\n| h3{font-size:20px;font-weight:600;letter-spacing:-.01em;margin:34px 0 10px} | |\n| h4{font-size:15.5px;font-weight:600;margin:0 0 6px} | |\n| p{margin:0 0 14px;max-width:74ch;color:var(--ink-2)} | |\n| p strong,li strong{color:var(--ink);font-weight:600} | |\n| ul,ol{max-width:74ch;color:var(--ink-2);padding-left:22px;margin:0 0 16px} | |\n| li{margin-bottom:7px} | |\n| .lead{font-size:18.5px;color:var(--ink);max-width:70ch} | |\n| /* ---------- hero ---------- */ | |\n| .hero{padding:64px 0 12px;border:none} | |\n| .hero h1{font-size:clamp(34px,5.4vw,60px);font-weight:700;letter-spacing:-.035em;max-width:19ch} | |\n| .hero .sub{font-size:19px;color:var(--ink-2);max-width:64ch;margin-top:18px} | |\n| .meta{display:flex;gap:10px;flex-wrap:wrap;margin:26px 0 34px} | |\n| .pill{ | |\n| font-family:\"IBM Plex Mono\";font-size:12px;font-weight:500;padding:6px 12px; | |\n| border:1px solid var(--rule);border-radius:999px;background:var(--card);color:var(--ink-2); | |\n| } | |\n| /* ---------- signature: token strip ---------- */ | |\n| .tokenstrip{ | |\n| background:var(--card);border:1px solid var(--rule);border-radius:14px; | |\n| padding:22px;box-shadow:var(--shadow);margin:8px 0 6px; | |\n| } | |\n| .tokenstrip .cap{font-family:\"IBM Plex Mono\";font-size:11.5px;color:var(--ink-3);letter-spacing:.08em;text-transform:uppercase;margin-bottom:14px} | |\n| .toks{display:flex;flex-wrap:wrap;gap:3px;align-items:center} | |\n| .tok{ | |\n| font-family:\"IBM Plex Mono\";font-size:14.5px;padding:5px 7px;border-radius:5px; | |\n| background:var(--signal-soft);color:var(--ink);border:1px solid #DAD8F6; | |\n| } | |\n| .tok.alt{background:#EAF6F3;border-color:#CFE8E1} | |\n| .tok.next{background:var(--ink);color:#fff;border-color:var(--ink)} | |\n| .tok.ghost{background:transparent;border:1px dashed var(--rule);color:var(--ink-3)} | |\n| /* ---------- cards ---------- */ | |\n| .grid{display:grid;gap:16px;margin:20px 0} | |\n| .g2{grid-template-columns:repeat(2,1fr)} | |\n| .g3{grid-template-columns:repeat(3,1fr)} | |\n| .g4{grid-template-columns:repeat(4,1fr)} | |\n| .card{ | |\n| background:var(--card);border:1px solid var(--rule);border-radius:12px; | |\n| padding:18px 20px;box-shadow:var(--shadow); | |\n| } | |\n| .card p:last-child,.card ul:last-child{margin-bottom:0} | |\n| .card .tag{ | |\n| font-family:\"IBM Plex Mono\";font-size:10.5px;font-weight:600;letter-spacing:.1em; | |\n| text-transform:uppercase;color:var(--ink-3);display:block;margin-bottom:8px; | |\n| } | |\n| .num{ | |\n| font-family:\"Space Grotesk\";font-size:13px;font-weight:700;color:var(--signal); | |\n| display:block;margin-bottom:6px; | |\n| } | |\n| /* ---------- prompt blocks ---------- */ | |\n| .prompt{ | |\n| border:1px solid var(--rule);border-radius:12px;background:var(--card); | |\n| overflow:hidden;margin:14px 0;box-shadow:var(--shadow); | |\n| } | |\n| .prompt-head{ | |\n| display:flex;gap:10px;align-items:center;padding:10px 16px; | |\n| border-bottom:1px solid var(--rule);background:#FBFCFD; | |\n| } | |\n| .prompt-head .label{font-family:\"IBM Plex Mono\";font-size:11.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase} | |\n| .prompt-body{padding:16px;font-family:\"IBM Plex Mono\";font-size:13.5px;line-height:1.7;white-space:pre-wrap;color:var(--ink)} | |\n| .prompt.bad .prompt-head{background:var(--bad-soft);border-bottom-color:#F1D2D6} | |\n| .prompt.bad .prompt-head .label{color:var(--bad)} | |\n| .prompt.good .prompt-head{background:var(--good-soft);border-bottom-color:#CBE6DF} | |\n| .prompt.good .prompt-head .label{color:var(--good)} | |\n| .prompt.plain .prompt-head .label{color:var(--ink-2)} | |\n| .outcome{ | |\n| padding:12px 16px;border-top:1px dashed var(--rule);background:#FBFCFD; | |\n| font-size:14.5px;color:var(--ink-2); | |\n| } | |\n| .outcome b{color:var(--ink)} | |\n| /* ---------- table ---------- */ | |\n| .tablewrap{overflow-x:auto;margin:20px 0;border:1px solid var(--rule);border-radius:12px;background:var(--card);box-shadow:var(--shadow)} | |\n| table{border-collapse:collapse;width:100%;font-size:15px;min-width:620px} | |\n| th,td{text-align:left;padding:12px 16px;border-bottom:1px solid var(--rule);vertical-align:top} | |\n| th{font-family:\"Space Grotesk\";font-size:12.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);background:#FBFCFD} | |\n| tr:last-child td{border-bottom:none} | |\n| td:first-child{font-weight:500;color:var(--ink)} | |\n| .dot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:8px;vertical-align:middle} | |\n| .dot.g{background:var(--good)}.dot.w{background:var(--warn)}.dot.b{background:var(--bad)} | |\n| /* ---------- callout ---------- */ | |\n| .callout{ | |\n| border-left:3px solid var(--signal);background:var(--signal-soft); | |\n| padding:16px 20px;border-radius:0 10px 10px 0;margin:22px 0; | |\n| } | |\n| .callout p{color:var(--ink);margin:0;max-width:78ch} | |\n| .callout.warn{border-left-color:var(--warn);background:var(--warn-soft)} | |\n| .callout.stop{border-left-color:var(--bad);background:var(--bad-soft)} | |\n| /* ---------- reveal ---------- */ | |\n| details.reveal{ | |\n| border:1px solid var(--rule);border-radius:10px;background:var(--card); | |\n| margin:10px 0;overflow:hidden;box-shadow:var(--shadow); | |\n| } | |\n| details.reveal summary{ | |\n| cursor:pointer;padding:14px 18px;font-family:\"IBM Plex Mono\";font-size:13.5px; | |\n| color:var(--ink);list-style:none;display:flex;gap:12px;align-items:flex-start; | |\n| } | |\n| details.reveal summary::-webkit-details-marker{display:none} | |\n| details.reveal summary::before{ | |\n| content:\"+\";font-weight:600;color:var(--signal);font-size:16px;line-height:1.4;flex-shrink:0; | |\n| } | |\n| details.reveal[open] summary::before{content:\"–\"} | |\n| details.reveal[open] summary{border-bottom:1px solid var(--rule);background:#FBFCFD} | |\n| details.reveal .ans{padding:14px 18px 16px 44px;font-size:15px;color:var(--ink-2)} | |\n| details.reveal .ans strong{color:var(--ink)} | |\n| /* ---------- run sheet ---------- */ | |\n| .run{border:1px solid var(--rule);border-radius:12px;overflow:hidden;background:var(--card);box-shadow:var(--shadow);margin:20px 0} | |\n| .run-row{display:grid;grid-template-columns:88px 1fr;gap:0;border-bottom:1px solid var(--rule)} | |\n| .run-row:last-child{border-bottom:none} | |\n| .run-row .t{ | |\n| font-family:\"IBM Plex Mono\";font-size:13px;font-weight:600;color:var(--signal); | |\n| padding:13px 16px;background:#FBFCFD;border-right:1px solid var(--rule); | |\n| } | |\n| .run-row .d{padding:13px 18px;font-size:15px} | |\n| .run-row .d b{font-weight:600} | |\n| .run-break .t{color:var(--ink-3)} | |\n| .run-break .d{color:var(--ink-3);font-style:italic} | |\n| /* ---------- misc ---------- */ | |\n| .kbdlist{list-style:none;padding:0;max-width:74ch} | |\n| .kbdlist li{ | |\n| padding:12px 0;border-bottom:1px solid var(--rule);display:flex;gap:14px;align-items:baseline; | |\n| } | |\n| .kbdlist li:last-child{border-bottom:none} | |\n| .kbdlist .k{ | |\n| font-family:\"IBM Plex Mono\";font-size:12px;font-weight:600;color:#fff;background:var(--ink); | |\n| padding:3px 9px;border-radius:5px;flex-shrink:0; | |\n| } | |\n| code.inl{background:#EEF0F4;padding:2px 6px;border-radius:4px;font-size:13.5px;color:var(--ink)} | |\n| .footer{margin-top:70px;padding-top:26px;border-top:1px solid var(--rule);color:var(--ink-3);font-size:14px} | |\n| @media (max-width:900px){ | |\n| .g4{grid-template-columns:repeat(2,1fr)} | |\n| .g3{grid-template-columns:1fr} | |\n| .g2{grid-template-columns:1fr} | |\n| } | |\n| @media (max-width:600px){ | |\n| body{font-size:16px} | |\n| .g4{grid-template-columns:1fr} | |\n| .wrap{padding:0 16px 80px} | |\n| .run-row{grid-template-columns:70px 1fr} | |\n| } | |\n| @media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}} | |\n| :focus-visible{outline:2px solid var(--signal);outline-offset:3px;border-radius:4px} | |\n| @media print{ | |\n| .topbar{display:none} | |\n| details.reveal[open] .ans,details.reveal .ans{display:block} | |\n| section{page-break-inside:avoid} | |\n| } | |\n| </style> | |\n| </head> | |\n| <body> | |\n| <div class=\"topbar\"> | |\n| <div class=\"topbar-in\"> | |\n| <div class=\"brand\">AI Session <span>01</span></div> | |\n| <nav class=\"tocbar\" id=\"toc\"> | |\n| <a href=\"#agenda\">Agenda</a> | |\n| <a href=\"#howitworks\">How it works</a> | |\n| <a href=\"#hallucination\">Hallucination</a> | |\n| <a href=\"#reliable\">Reliable vs risky</a> | |\n| <a href=\"#anatomy\">Prompt anatomy</a> | |\n| <a href=\"#ladder\">Refinement</a> | |\n| <a href=\"#fewshot\">Few-shot</a> | |\n| <a href=\"#cot\">Chain of thought</a> | |\n| <a href=\"#patterns\">Dev patterns</a> | |\n| <a href=\"#context\">Context</a> | |\n| <a href=\"#antipatterns\">Anti-patterns</a> | |\n| <a href=\"#worksheet\">Worksheet</a> | |\n| <a href=\"#close\">Non-negotiables</a> | |\n| </nav> | |\n| </div> | |\n| </div> | |\n| <div class=\"wrap\"> | |\n| <!-- ===================== HERO ===================== --> | |\n| <section class=\"hero\" id=\"top\"> | |\n| <h1>GenAI Foundations & Prompt Engineering for Developers</h1> | |\n| <p class=\"sub\">A working model of what a language model actually does, and the prompting technique that follows from it. Everything here is aimed at one outcome: getting code you would be willing to put your name on.</p> | |\n| <div class=\"meta\"> | |\n| <span class=\"pill\">Session 1 of 2</span> | |\n| <span class=\"pill\">2 hours + 2 hours</span> | |\n| <span class=\"pill\">MERN + Java cohorts</span> | |\n| <span class=\"pill\">Tools: any chat LLM</span> | |\n| </div> | |\n| <div class=\"tokenstrip\"> | |\n| <div class=\"cap\">A model does exactly one thing, over and over</div> | |\n| <div class=\"toks\"> | |\n| <span class=\"tok\">The</span><span class=\"tok\">function</span><span class=\"tok\">returns</span><span class=\"tok\">an</span><span class=\"tok\">empty</span><span class=\"tok next\">array</span><span class=\"tok ghost\">?</span><span class=\"tok ghost\">?</span><span class=\"tok ghost\">?</span> | |\n| </div> | |\n| <p style=\"margin:16px 0 0;font-size:15px\">Given everything so far, predict the next piece. Append it. Repeat. Every capability and every failure in this session comes out of that single loop.</p> | |\n| </div> | |\n| <h3>By the end of the session</h3> | |\n| <ul> | |\n| <li>Explain in plain terms how an LLM produces output, and why it invents things that do not exist.</li> | |\n| <li>Separate tasks where AI is reliable from tasks where it is risky.</li> | |\n| <li>Structure a prompt with role, context, task and output format, and improve it by iterating.</li> | |\n| <li>Use few-shot examples and constraints to get consistent, usable code.</li> | |\n| <li>Supply the right context — error output, data shapes, surrounding code, conventions — for debugging and generation.</li> | |\n| <li>Take a failing prompt, rewrite it, and say precisely why the rewrite worked.</li> | |\n| </ul> | |\n| </section> | |\n| <!-- ===================== AGENDA ===================== --> | |\n| <section id=\"agenda\"> | |\n| <div class=\"eyebrow\">Run sheet</div> | |\n| <h2>How the four hours are spent</h2> | |\n| <p>Two blocks of two hours. The first block builds the mental model and the prompt structure. The second applies it to real developer tasks and ends with a rewrite exercise.</p> | |\n| <h3>Block 1 — Foundations</h3> | |\n| <div class=\"run\"> | |\n| <div class=\"run-row\"><div class=\"t\">35 min</div><div class=\"d\"><b>How an LLM generates output</b> — tokens, next-token prediction, context window, temperature</div></div> | |\n| <div class=\"run-row\"><div class=\"t\">20 min</div><div class=\"d\"><b>Why models hallucinate</b> — live demonstrations of confident wrong answers</div></div> | |\n| <div class=\"run-row\"><div class=\"t\">20 min</div><div class=\"d\"><b>Reliable vs risky</b> — building the task map</div></div> | |\n| <div class=\"run-row run-break\"><div class=\"t\">10 min</div><div class=\"d\">Break</div></div> | |\n| <div class=\"run-row\"><div class=\"t\">35 min</div><div class=\"d\"><b>Prompt anatomy</b> — role, context, task, output format</div></div> | |\n| </div> | |\n| <h3>Block 2 — Applied prompting</h3> | |\n| <div class=\"run\"> | |\n| <div class=\"run-row\"><div class=\"t\">30 min</div><div class=\"d\"><b>The refinement ladder</b> — one task taken from useless to usable in six rounds</div></div> | |\n| <div class=\"run-row\"><div class=\"t\">25 min</div><div class=\"d\"><b>Constraints and few-shot</b> — forcing a house style, in both JavaScript and Java</div></div> | |\n| <div class=\"run-row\"><div class=\"t\">10 min</div><div class=\"d\"><b>Chain of thought</b> — where step-by-step reasoning earns its cost</div></div> | |\n| <div class=\"run-row run-break\"><div class=\"t\">10 min</div><div class=\"d\">Break</div></div> | |\n| <div class=\"run-row\"><div class=\"t\">25 min</div><div class=\"d\"><b>Developer patterns</b> — explain, scaffold, test, debug, refactor</div></div> | |\n| <div class=\"run-row\"><div class=\"t\">15 min</div><div class=\"d\"><b>Anti-patterns</b> — six broken prompts and the flaw in each</div></div> | |\n| <div class=\"run-row\"><div class=\"t\">15 min</div><div class=\"d\"><b>Rewrite worksheet</b> — the one hands-on piece</div></div> | |\n| <div class=\"run-row\"><div class=\"t\">10 min</div><div class=\"d\"><b>Non-negotiables and what Session 2 covers</b></div></div> | |\n| </div> | |\n| <div class=\"callout\"> | |\n| <p>Most of this session is demonstrated live on screen rather than typed along with. Every prompt on this page is reproducible afterwards in any free chat tool — the value is in re-running them yourself once you have access.</p> | |\n| </div> | |\n| </section> | |\n| <!-- ===================== HOW IT WORKS ===================== --> | |\n| <section id=\"howitworks\"> | |\n| <div class=\"eyebrow\">Part 1 · Mental model</div> | |\n| <h2>How an LLM generates output</h2> | |\n| <p class=\"lead\">There is no database of answers inside the model, no lookup, no compiler, no execution. There is a single repeated prediction, and everything else is a consequence of it.</p> | |\n| <h3>Tokens: the unit the model actually sees</h3> | |\n| <p>Text is split into <strong>tokens</strong> before the model touches it. A token is roughly a word, a word fragment, or a piece of punctuation. Common words are one token. Rare words, identifiers and non-English text split into several.</p> | |\n| <div class=\"tokenstrip\"> | |\n| <div class=\"cap\">The same sentence, as a human reads it and as a model receives it</div> | |\n| <div class=\"toks\" style=\"margin-bottom:14px\"> | |\n| <span class=\"tok alt\">useState</span><span class=\"tok alt\"> returns</span><span class=\"tok alt\"> an</span><span class=\"tok alt\"> array</span><span class=\"tok alt\"> of</span><span class=\"tok alt\"> two</span><span class=\"tok alt\"> values</span><span class=\"tok alt\">.</span> | |\n| </div> | |\n| <div class=\"toks\"> | |\n| <span class=\"tok\">use</span><span class=\"tok\">State</span><span class=\"tok\"> returns</span><span class=\"tok\"> an</span><span class=\"tok\"> array</span><span class=\"tok\"> of</span><span class=\"tok\"> two</span><span class=\"tok\"> values</span><span class=\"tok\">.</span> | |\n| </div> | |\n| <p style=\"margin:16px 0 0;font-size:15px\"><code class=\"inl\">useState</code> is not one thing to the model. It is two fragments that very often appear together.</p> | |\n| </div> | |\n| <p>Three consequences worth carrying with you:</p> | |\n| <ul> | |\n| <li><strong>Character-level tasks are unreliable.</strong> Counting letters, reversing strings by hand, or counting words are exactly the tasks the tokenisation hides from the model.</li> | |\n| <li><strong>Token count is not word count.</strong> Code, JSON and long identifiers consume more tokens than prose of the same length.</li> | |\n| <li><strong>Tokens are the billing and limit unit.</strong> Everything you paste, and everything the model writes back, is counted.</li> | |\n| </ul> | |\n| <h3>Next-token prediction</h3> | |\n| <p>At each step the model produces a probability distribution over every possible next token, picks one, appends it, and runs again with the longer text. That is the whole generation loop.</p> | |\n| <p>The model is optimising for <strong>what plausibly comes next</strong>, given everything before it. It is not optimising for what is true, what compiles, or what exists. When the plausible thing and the true thing coincide — which is often — the output is excellent. When they diverge, the output is confidently wrong.</p> | |\n| <div class=\"callout\"> | |\n| <p>This single sentence explains most of what follows: <strong>the model is a plausibility engine, not a truth engine.</strong> Every prompting technique in this session is a way of making the true answer also the most plausible one.</p> | |\n| </div> | |\n| <h3>Context window</h3> | |\n| <p>The context window is the total amount of text — your instructions, the code you pasted, the conversation history, and the response being written — that the model can consider at once. It is finite.</p> | |\n| <ul> | |\n| <li><strong>Nothing outside the window exists.</strong> A file you did not paste is not \"missing\"; from the model's position it was never mentioned.</li> | |\n| <li><strong>Long conversations degrade.</strong> As a chat grows, early instructions compete with a large volume of later text. Constraints given twenty messages ago quietly stop being honoured.</li> | |\n| <li><strong>More context is not automatically better.</strong> Pasting an entire project buries the three relevant functions among hundreds of irrelevant ones. Precision beats volume.</li> | |\n| <li><strong>Fresh chat for a fresh task.</strong> A new problem in an old, cluttered conversation inherits all of that clutter.</li> | |\n| </ul> | |\n| <h3>Temperature</h3> | |\n| <p>Temperature controls how the next token is chosen from the probability distribution. Low temperature concentrates on the highest-probability tokens. High temperature flattens the distribution and allows less likely choices.</p> | |\n| <div class=\"grid g3\"> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">Low · near 0</span> | |\n| <h4>Focused, repeatable</h4> | |\n| <p>The same prompt gives near-identical output. Correct default for code, refactoring, data transformation, anything with a right answer.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">Medium</span> | |\n| <h4>Balanced</h4> | |\n| <p>Normal conversation, explanation, documentation. Enough variation to phrase things well without wandering.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">High</span> | |\n| <h4>Varied, surprising</h4> | |\n| <p>Brainstorming names, generating varied test data, exploring alternative approaches. Not for code you intend to keep.</p> | |\n| </div> | |\n| </div> | |\n| <p>Chat interfaces usually do not expose this control, but the behaviour is still visible: ask the same question twice in two fresh chats and compare. <strong>Low temperature does not mean correct.</strong> It means consistent. A model can be consistently wrong.</p> | |\n| </section> | |\n| <!-- ===================== HALLUCINATION ===================== --> | |\n| <section id=\"hallucination\"> | |\n| <div class=\"eyebrow\">Part 2 · Failure mode</div> | |\n| <h2>Why models hallucinate</h2> | |\n| <p class=\"lead\">A hallucination is not a malfunction. It is the generation loop working exactly as designed, in a region where the plausible answer and the real answer are not the same thing.</p> | |\n| <p>When a model has seen thousands of examples of <code class=\"inl\">array.someMethod()</code> patterns, a method name that <em>fits the pattern</em> is highly probable — whether or not that method exists. The model has no mechanism to check. It cannot run the code, open the docs, or fail to find something.</p> | |\n| <h3>The four shapes hallucination takes in code</h3> | |\n| <div class=\"grid g2\"> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">Shape 1</span> | |\n| <h4>Invented APIs</h4> | |\n| <p>A method, hook or utility that does not exist, but sits perfectly inside the naming conventions of a real library. Frequently the most useful-sounding function in the answer.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">Shape 2</span> | |\n| <h4>Real API, wrong signature</h4> | |\n| <p>The function exists. The argument order, option names, or return shape are subtly wrong — often matching an older or newer version than yours.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">Shape 3</span> | |\n| <h4>Confident factual claims</h4> | |\n| <p>Complexity analysis, browser support, version behaviour, performance comparisons — stated in the same assured tone as everything else, with no signal of uncertainty.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">Shape 4</span> | |\n| <h4>Fabricated specifics about your code</h4> | |\n| <p>Referring to fields, props, files or functions you never showed it. The model fills the gap you left with something reasonable.</p> | |\n| </div> | |\n| </div> | |\n| <h3>Live demonstrations</h3> | |\n| <div class=\"prompt plain\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Demo A · character-level blindness</span></div> | |\n| <div class=\"prompt-body\">How many times does the letter \"r\" appear in \"refactoring\"?</div> | |\n| <div class=\"outcome\"><b>What to watch for:</b> the answer arrives instantly and confidently. The model never saw the individual characters — it saw two or three tokens.</div> | |\n| </div> | |\n| <div class=\"prompt plain\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Demo B · invented API</span></div> | |\n| <div class=\"prompt-body\">Which built-in React hook should I use to debounce a value so my search input does not fire on every keystroke?</div> | |\n| <div class=\"outcome\"><b>What to watch for:</b> pressure toward a built-in answer where none exists. A confident, well-named, non-existent hook is a common result.</div> | |\n| </div> | |\n| <div class=\"prompt plain\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Demo C · fabricated specifics</span></div> | |\n| <div class=\"prompt-body\">Fix the bug in my ProductCard component where the price is not displaying.</div> | |\n| <div class=\"outcome\"><b>What to watch for:</b> no component was provided, yet the answer names props and fields with total assurance. Everything after the first line is invention.</div> | |\n| </div> | |\n| <div class=\"prompt plain\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Demo D · confident wrong analysis</span></div> | |\n| <div class=\"prompt-body\">What is the time complexity of the algorithm below? Answer in one line. | |\n| function mystery(arr) { | |\n| let out = []; | |\n| for (let i = 0; i < arr.length; i++) { | |\n| if (out.includes(arr[i]) === false) out.push(arr[i]); | |\n| } | |\n| return out; | |\n| }</div> | |\n| <div class=\"outcome\"><b>What to watch for:</b> the hidden cost of <code>includes</code> inside the loop makes this quadratic. A quick, plausible \"O(n)\" is a common answer, and it reads exactly as confidently as a correct one.</div> | |\n| </div> | |\n| <div class=\"callout warn\"> | |\n| <p><strong>The tell is that there is no tell.</strong> A hallucinated answer is written with the same fluency, structure and confidence as a correct one. Tone carries no information about accuracy. The only defence is verification.</p> | |\n| </div> | |\n| <h3>What reduces it</h3> | |\n| <ul> | |\n| <li><strong>Supply the ground truth.</strong> Paste the actual code, the actual error, the actual data shape. The model cannot invent what you have already specified.</li> | |\n| <li><strong>Name versions explicitly.</strong> \"React 18\", \"Java 17\", \"Express 4\" removes an entire class of version-mismatch errors.</li> | |\n| <li><strong>Give permission to not know.</strong> Asking it to say when it is unsure, or to flag which parts need verification, changes what it produces.</li> | |\n| <li><strong>Ask for verifiable output.</strong> Something you can run, compile or check beats something you can only read and nod at.</li> | |\n| <li><strong>Prefer familiar territory.</strong> Widely used, stable libraries produce far fewer inventions than niche or fast-moving ones.</li> | |\n| </ul> | |\n| </section> | |\n| <!-- ===================== RELIABLE VS RISKY ===================== --> | |\n| <section id=\"reliable\"> | |\n| <div class=\"eyebrow\">Part 3 · Judgement</div> | |\n| <h2>Where AI is reliable, and where it is risky</h2> | |\n| <p class=\"lead\">The useful question is never \"is AI good at coding\". It is \"can I cheaply verify this particular output, and what happens if it is wrong\".</p> | |\n| <h3>Two axes decide it</h3> | |\n| <div class=\"grid g2\"> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">Axis 1</span> | |\n| <h4>Verification cost</h4> | |\n| <p>How long does it take you to know the output is correct? Running a function takes seconds. Confirming an authorisation rule is watertight takes real effort. Low verification cost makes AI safe even when it is often wrong.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">Axis 2</span> | |\n| <h4>Cost of being wrong</h4> | |\n| <p>A malformed test file wastes a minute. A subtly wrong interest calculation or an access-control gap can reach production and cause real damage. High blast radius demands human authorship.</p> | |\n| </div> | |\n| </div> | |\n| <div class=\"tablewrap\"> | |\n| <table> | |\n| <thead><tr><th>Task</th><th>Verdict</th><th>Why</th></tr></thead> | |\n| <tbody> | |\n| <tr><td>Explaining unfamiliar code</td><td><span class=\"dot g\"></span>Reliable</td><td>You still read the code afterwards; errors surface immediately.</td></tr> | |\n| <tr><td>Boilerplate and scaffolding</td><td><span class=\"dot g\"></span>Reliable</td><td>Highly patterned, and it either runs or it does not.</td></tr> | |\n| <tr><td>Syntax translation between languages</td><td><span class=\"dot g\"></span>Reliable</td><td>Structure is preserved; mistakes are visible on reading.</td></tr> | |\n| <tr><td>Regex and string transformations</td><td><span class=\"dot g\"></span>Reliable</td><td>Instantly testable against your own examples.</td></tr> | |\n| <tr><td>Decoding an error message or stack trace</td><td><span class=\"dot g\"></span>Reliable</td><td>You have the ground truth in hand and can confirm the fix.</td></tr> | |\n| <tr><td>Test scaffolding and edge-case suggestions</td><td><span class=\"dot g\"></span>Reliable</td><td>Tests are self-checking; a wrong test fails loudly.</td></tr> | |\n| <tr><td>Naming, docs, commit messages</td><td><span class=\"dot g\"></span>Reliable</td><td>You are the judge, and the cost of a bad suggestion is zero.</td></tr> | |\n| <tr><td>Exact API signatures and options</td><td><span class=\"dot w\"></span>Verify</td><td>Classic invention territory. Confirm against real documentation.</td></tr> | |\n| <tr><td>Version-specific behaviour</td><td><span class=\"dot w\"></span>Verify</td><td>Training data blends versions. Always state yours.</td></tr> | |\n| <tr><td>Performance and complexity claims</td><td><span class=\"dot w\"></span>Verify</td><td>Plausible reasoning, unverified conclusions. Measure instead.</td></tr> | |\n| <tr><td>Large multi-file refactors</td><td><span class=\"dot w\"></span>Verify</td><td>Too much changes at once to review honestly. Break it up.</td></tr> | |\n| <tr><td>Authentication and authorisation logic</td><td><span class=\"dot b\"></span>Risky</td><td>Failures are silent, and the blast radius is the whole system.</td></tr> | |\n| <tr><td>Business rules unique to your product</td><td><span class=\"dot b\"></span>Risky</td><td>The model has never seen your rules. It will produce a generic guess.</td></tr> | |\n| <tr><td>Financial or regulatory calculations</td><td><span class=\"dot b\"></span>Risky</td><td>Wrong answers look right and carry real consequences.</td></tr> | |\n| <tr><td>Anything involving real credentials or customer data</td><td><span class=\"dot b\"></span>Risky</td><td>Never paste it. Covered under non-negotiables.</td></tr> | |\n| <tr><td>Learning a fundamental you will be assessed on</td><td><span class=\"dot b\"></span>Risky</td><td>The output is correct and you still cannot do it. The cost arrives later.</td></tr> | |\n| </tbody> | |\n| </table> | |\n| </div> | |\n| <div class=\"callout\"> | |\n| <p>A useful reframing: AI raises your ceiling, never your floor. It makes a strong engineer faster at things they could already check. It does not make an engineer who cannot review the output safer — it makes them faster at shipping things nobody has reviewed.</p> | |\n| </div> | |\n| </section> | |\n| <!-- ===================== ANATOMY ===================== --> | |\n| <section id=\"anatomy\"> | |\n| <div class=\"eyebrow\">Part 4 · Structure</div> | |\n| <h2>The anatomy of a working prompt</h2> | |\n| <p class=\"lead\">Four components. Not every prompt needs all four, but when output is disappointing, the cause is almost always a missing one.</p> | |\n| <div class=\"grid g4\"> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">01</span> | |\n| <h4>Role</h4> | |\n| <p>Who the model should answer as. Sets vocabulary, depth and assumptions.</p> | |\n| <p style=\"font-size:14px;color:var(--ink-3);margin-top:8px\">\"You are a senior React developer reviewing code from a junior teammate.\"</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">02</span> | |\n| <h4>Context</h4> | |\n| <p>Everything the model cannot see: the code, the error, the data shape, the versions, the conventions, what you already tried.</p> | |\n| <p style=\"font-size:14px;color:var(--ink-3);margin-top:8px\">The component that breaks, and the exact console output.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">03</span> | |\n| <h4>Task</h4> | |\n| <p>One specific thing to do, stated as an action. Not a topic, not a wish.</p> | |\n| <p style=\"font-size:14px;color:var(--ink-3);margin-top:8px\">\"Identify why the list re-renders on every keystroke and fix it.\"</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">04</span> | |\n| <h4>Output format</h4> | |\n| <p>The exact shape you want back. Removes the guesswork about how much, in what form, with what around it.</p> | |\n| <p style=\"font-size:14px;color:var(--ink-3);margin-top:8px\">\"One code block, no explanation before or after, comments only where the logic is non-obvious.\"</p> | |\n| </div> | |\n| </div> | |\n| <h3>Same task, with and without the structure</h3> | |\n| <div class=\"prompt bad\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Unstructured</span></div> | |\n| <div class=\"prompt-body\">write a search bar in react</div> | |\n| <div class=\"outcome\"><b>What comes back:</b> a generic component with an invented data source, arbitrary styling, a state pattern you may not use, and three paragraphs of explanation you did not ask for. Nothing about it fits your project.</div> | |\n| </div> | |\n| <div class=\"prompt good\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Structured</span></div> | |\n| <div class=\"prompt-body\">You are a senior React developer writing code for a beginner-friendly codebase. | |\n| CONTEXT | |\n| - React 18, function components, plain CSS. No TypeScript, no Tailwind, no external libraries. | |\n| - State is managed with useState only. No useEffect in this component. | |\n| - The parent already holds the full list and passes it down. | |\n| - Props: items (array of { id, name, category, price }), onSelect (function). | |\n| TASK | |\n| Write a SearchableList component that renders the items and filters them | |\n| as the user types in a text input. Matching is case-insensitive on name only. | |\n| CONSTRAINTS | |\n| - Do not fetch data. Filter the items prop. | |\n| - Do not mutate the items prop. | |\n| - Show a message when nothing matches. | |\n| - Every list item must have a stable key. | |\n| OUTPUT FORMAT | |\n| One code block containing the complete component. No prose before or after. | |\n| Add a comment only where the logic is not obvious from the code.</div> | |\n| <div class=\"outcome\"><b>What comes back:</b> code that drops into the project unmodified, uses only patterns already in use, and can be reviewed in under a minute because you already know what it should look like.</div> | |\n| </div> | |\n| <div class=\"callout\"> | |\n| <p>The structured version takes about ninety seconds to write. It replaces four rounds of \"no, not like that\" — and more importantly, it forces you to decide what you actually want before asking, which is where most of the value sits.</p> | |\n| </div> | |\n| </section> | |\n| <!-- ===================== LADDER ===================== --> | |\n| <section id=\"ladder\"> | |\n| <div class=\"eyebrow\">Part 5 · Iteration</div> | |\n| <h2>The refinement ladder</h2> | |\n| <p class=\"lead\">One task, six rounds. Each round adds a single element, and the change in output is attributable to that element alone.</p> | |\n| <p>The task: a component that shows a list of items with a search box and a sort control.</p> | |\n| <div class=\"prompt bad\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Round 1 · bare task</span></div> | |\n| <div class=\"prompt-body\">make a list with search and sort</div> | |\n| <div class=\"outcome\"><b>Result:</b> unusable. No language specified, no framework, no data. The model picks all of it for you, and it picks wrong.</div> | |\n| </div> | |\n| <div class=\"prompt plain\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Round 2 · + stack and versions</span></div> | |\n| <div class=\"prompt-body\">Write a React 18 function component that renders a list of items | |\n| with a search box and a sort control. Plain CSS, no libraries.</div> | |\n| <div class=\"outcome\"><b>Result:</b> runnable React, but with invented data hardcoded inside, and possibly hooks or patterns the codebase does not use. <b>Change:</b> the stack is now fixed.</div> | |\n| </div> | |\n| <div class=\"prompt plain\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Round 3 · + the real data shape</span></div> | |\n| <div class=\"prompt-body\">... as above ... | |\n| The component receives this prop: | |\n| items: [ | |\n| { id: 1, name: \"Laptop Stand\", category: \"accessories\", price: 1299 }, | |\n| { id: 2, name: \"Mechanical Keyboard\", category: \"input\", price: 4599 } | |\n| ] | |\n| Search filters on name. Sort toggles between price ascending and descending.</div> | |\n| <div class=\"outcome\"><b>Result:</b> the field names are now correct. This single addition eliminates the most common category of unusable output — code written against a data shape that does not exist. <b>Change:</b> no more invented fields.</div> | |\n| </div> | |\n| <div class=\"prompt plain\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Round 4 · + constraints</span></div> | |\n| <div class=\"prompt-body\">... as above ... | |\n| CONSTRAINTS | |\n| - useState only. Do not use useEffect. | |\n| - Do not mutate the items prop when sorting. | |\n| - Do not fetch anything. | |\n| - Handle the empty-results case. | |\n| - Stable key on every list item.</div> | |\n| <div class=\"outcome\"><b>Result:</b> the two bugs that would otherwise have appeared — an in-place <code>.sort()</code> mutating the prop, and an unnecessary effect — are now prevented rather than corrected later. <b>Change:</b> known failure modes closed off in advance.</div> | |\n| </div> | |\n| <div class=\"prompt plain\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Round 5 · + role and output format</span></div> | |\n| <div class=\"prompt-body\">You are a senior React developer writing code for a beginner-friendly codebase. | |\n| Prefer clarity over cleverness. | |\n| ... context, task and constraints as above ... | |\n| OUTPUT FORMAT | |\n| One code block, complete component, no prose before or after. | |\n| Comments only where the logic is not obvious.</div> | |\n| <div class=\"outcome\"><b>Result:</b> readable code at the right level, delivered in a form you can copy directly. <b>Change:</b> tone, complexity and packaging are now controlled.</div> | |\n| </div> | |\n| <div class=\"prompt good\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Round 6 · targeted follow-up</span></div> | |\n| <div class=\"prompt-body\">Keep everything else identical. Two changes: | |\n| 1. Search should also match category, not just name. | |\n| 2. Pull the filter-and-sort logic into a helper function above the component | |\n| so it can be tested independently. | |\n| Return only the changed parts, not the whole file.</div> | |\n| <div class=\"outcome\"><b>Result:</b> a small reviewable diff instead of a fresh rewrite. <b>Change:</b> iteration is now surgical, which means review stays honest.</div> | |\n| </div> | |\n| <h3>What the ladder teaches</h3> | |\n| <ul> | |\n| <li><strong>Change one thing per round.</strong> If you add context, constraints and a role simultaneously and the output improves, you have learned nothing about which mattered.</li> | |\n| <li><strong>\"Keep everything else identical\" is the highest-value phrase in iterative prompting.</strong> Without it, follow-ups silently rewrite parts you had already accepted.</li> | |\n| <li><strong>Ask for changed parts only.</strong> A full re-emission of the file makes it impossible to see what actually moved.</li> | |\n| <li><strong>Restart rather than repair.</strong> After three or four failed rounds, the conversation is polluted with rejected attempts. A fresh chat with everything you have learned folded into round one beats a fifth correction.</li> | |\n| </ul> | |\n| <h3>The same ladder in Java</h3> | |\n| <p>The technique is not language-specific. The identical progression applies to a backend task — and the components map one for one.</p> | |\n| <div class=\"prompt good\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Java equivalent, fully specified</span></div> | |\n| <div class=\"prompt-body\">You are a senior Java developer writing code for a beginner-friendly codebase. | |\n| CONTEXT | |\n| - Java 17. No Lombok, no external libraries beyond the JDK. | |\n| - Existing record: record Item(int id, String name, String category, int price) {} | |\n| - Callers pass an unmodifiable List<Item>. | |\n| TASK | |\n| Write a utility class ItemFilter with one public static method that filters | |\n| items by a case-insensitive substring match on name or category, then sorts | |\n| by price. Sort direction is a parameter. | |\n| CONSTRAINTS | |\n| - Do not modify the input list. | |\n| - Return an empty list rather than null when nothing matches. | |\n| - Handle a null or blank search term by returning everything, sorted. | |\n| OUTPUT FORMAT | |\n| One code block. No prose. Javadoc on the public method only.</div> | |\n| <div class=\"outcome\"><b>The point:</b> role, context, task, constraints, output format — same five parts, different stack. The structure is the transferable skill; the syntax is not.</div> | |\n| </div> | |\n| </section> | |\n| <!-- ===================== FEW SHOT ===================== --> | |\n| <section id=\"fewshot\"> | |\n| <div class=\"eyebrow\">Part 6 · Consistency</div> | |\n| <h2>Constraints and few-shot examples</h2> | |\n| <p class=\"lead\">Describing a style is unreliable. Demonstrating it is reliable. When output needs to match an existing convention, examples beat adjectives every time.</p> | |\n| <h3>Zero-shot vs few-shot</h3> | |\n| <div class=\"grid g2\"> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">Zero-shot</span> | |\n| <h4>Instruction only</h4> | |\n| <p>You describe what you want. Correct default for most tasks — it is faster and the model is genuinely good at following clear instructions.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">Few-shot</span> | |\n| <h4>Instruction plus two or three worked examples</h4> | |\n| <p>You show what you want. Worth the extra tokens when the output must match a specific format, house style, or existing convention.</p> | |\n| </div> | |\n| </div> | |\n| <h3>Demonstration: enforcing a house style</h3> | |\n| <p>The goal is DSA solutions in a fixed format — a required header comment block, a specific function signature, and a complexity note in a set position.</p> | |\n| <div class=\"prompt bad\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Zero-shot · described style</span></div> | |\n| <div class=\"prompt-body\">Write a function to check if a string is a palindrome. | |\n| Use our standard format with a header comment, clear naming, | |\n| and complexity analysis at the end.</div> | |\n| <div class=\"outcome\"><b>Result:</b> some kind of header, some kind of complexity note, in some position. Ask three times and get three different layouts. \"Our standard format\" means nothing to a model that has never seen it.</div> | |\n| </div> | |\n| <div class=\"prompt good\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Few-shot · demonstrated style</span></div> | |\n| <div class=\"prompt-body\">Write solutions in exactly this format. Two examples follow. | |\n| EXAMPLE 1 | |\n| /** | |\n| * Problem: Two Sum | |\n| * Approach: Single-pass hash map storing complements. | |\n| */ | |\n| function twoSum(nums, target) { | |\n| const seen = new Map(); | |\n| for (let i = 0; i < nums.length; i++) { | |\n| const need = target - nums[i]; | |\n| if (seen.has(need)) return [seen.get(need), i]; | |\n| seen.set(nums[i], i); | |\n| } | |\n| return []; | |\n| } | |\n| // Time: O(n) | Space: O(n) | |\n| EXAMPLE 2 | |\n| /** | |\n| * Problem: Maximum Subarray | |\n| * Approach: Kadane's algorithm, running local and global maxima. | |\n| */ | |\n| function maxSubArray(nums) { | |\n| let best = nums[0]; | |\n| let current = nums[0]; | |\n| for (let i = 1; i < nums.length; i++) { | |\n| current = Math.max(nums[i], current + nums[i]); | |\n| best = Math.max(best, current); | |\n| } | |\n| return best; | |\n| } | |\n| // Time: O(n) | Space: O(1) | |\n| NOW SOLVE | |\n| Problem: Valid Palindrome — ignore non-alphanumeric characters and case. | |\n| Follow the format above exactly. No prose outside the code block.</div> | |\n| <div class=\"outcome\"><b>Result:</b> the header block, the comment fields, the trailing complexity line and its exact separator all match. Run it five times and the shape is stable. <b>Two examples are usually enough; a third helps when the pattern has variation the first two do not show.</b></div> | |\n| </div> | |\n| <div class=\"callout\"> | |\n| <p>The practical version of this at work: when adding a file to an existing codebase, paste one similar existing file as the example. You are not asking for good code in the abstract — you are asking for code that looks like it belongs.</p> | |\n| </div> | |\n| <h3>Constraints that consistently earn their place</h3> | |\n| <ul> | |\n| <li><strong>Negative constraints.</strong> \"Do not use external libraries.\" \"Do not use TypeScript.\" \"Do not add error handling I did not ask for.\" Naming what to avoid is often more effective than naming what to do.</li> | |\n| <li><strong>Scope limits.</strong> \"Change only the function I pasted.\" \"Do not restructure the file.\" Prevents unrequested rewrites.</li> | |\n| <li><strong>Length and shape.</strong> \"Under 40 lines.\" \"One code block.\" \"No explanation.\"</li> | |\n| <li><strong>Level.</strong> \"Written for someone three months into React.\" Controls how clever the solution gets.</li> | |\n| <li><strong>Uncertainty handling.</strong> \"If a detail is missing, ask instead of assuming.\" Converts silent invention into a question you can answer.</li> | |\n| </ul> | |\n| </section> | |\n| <!-- ===================== COT ===================== --> | |\n| <section id=\"cot\"> | |\n| <div class=\"eyebrow\">Part 7 · Reasoning</div> | |\n| <h2>Chain of thought</h2> | |\n| <p class=\"lead\">Asking for reasoning before the answer changes the answer. It also costs time and tokens, so it belongs on some tasks and not others.</p> | |\n| <p>Because output is generated one token at a time with each token conditioned on the ones before it, text that works through the problem gives later tokens something better to condition on. Reasoning written first genuinely improves what comes after — it is not a formality.</p> | |\n| <div class=\"grid g2\"> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">Worth it</span> | |\n| <h4>Multi-step and diagnostic work</h4> | |\n| <ul style=\"margin-bottom:0\"> | |\n| <li>Debugging where the cause is not obvious</li> | |\n| <li>Choosing between design approaches</li> | |\n| <li>Tracing why a value ends up wrong</li> | |\n| <li>Anything with several interacting conditions</li> | |\n| <li>Complexity analysis, done properly</li> | |\n| </ul> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"tag\">Not worth it</span> | |\n| <h4>Pattern work with a known shape</h4> | |\n| <ul style=\"margin-bottom:0\"> | |\n| <li>Boilerplate and scaffolding</li> | |\n| <li>Syntax conversion</li> | |\n| <li>Renaming and formatting</li> | |\n| <li>Simple, well-specified components</li> | |\n| <li>Anything where you already know the answer's shape</li> | |\n| </ul> | |\n| </div> | |\n| </div> | |\n| <div class=\"prompt good\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Reasoning first, then the fix</span></div> | |\n| <div class=\"prompt-body\">Before writing any code, work through this in order: | |\n| 1. State what the code currently does, line by line, for the input given. | |\n| 2. Identify the exact point where actual behaviour diverges from expected. | |\n| 3. Explain the root cause in one or two sentences. | |\n| 4. Only then, give the corrected code. | |\n| Do not skip to step 4.</div> | |\n| <div class=\"outcome\"><b>Why the last line matters:</b> without it, the model frequently jumps straight to a plausible fix and the reasoning steps become a retroactive justification of a guess.</div> | |\n| </div> | |\n| <div class=\"callout warn\"> | |\n| <p>Reasoning that reads convincingly can still reach a wrong conclusion. Chain of thought improves the odds and makes the mistake <em>visible</em> — you can now see which step went wrong. It does not make the answer verified.</p> | |\n| </div> | |\n| </section> | |\n| <!-- ===================== DEV PATTERNS ===================== --> | |\n| <section id=\"patterns\"> | |\n| <div class=\"eyebrow\">Part 8 · Application</div> | |\n| <h2>Developer prompting patterns</h2> | |\n| <p class=\"lead\">Five recurring tasks, each with a prompt shape that reliably works.</p> | |\n| <h3>Pattern 1 — Explaining code</h3> | |\n| <div class=\"prompt good\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Explain</span></div> | |\n| <div class=\"prompt-body\">Explain the code below to someone comfortable with JavaScript | |\n| but new to React. | |\n| Structure the explanation as: | |\n| 1. What this component does, in two sentences. | |\n| 2. What each hook and handler is responsible for. | |\n| 3. The order things happen when the user types in the input. | |\n| 4. Anything here that would surprise someone new to React. | |\n| Do not suggest improvements. I only want to understand it. | |\n| [paste code]</div> | |\n| <div class=\"outcome\"><b>Why it works:</b> the audience level controls vocabulary, the numbered structure controls organisation, and the last line prevents the answer drifting into a code review you did not request.</div> | |\n| </div> | |\n| <h3>Pattern 2 — Generating boilerplate</h3> | |\n| <div class=\"prompt good\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Scaffold</span></div> | |\n| <div class=\"prompt-body\">Generate the starting file for a new React component following | |\n| the conventions in the example file below. | |\n| Component name: OrderSummary | |\n| Props: orders (array of { id, total, status }), onCancel (function) | |\n| Behaviour: render each order; show a Cancel button only when status is \"pending\". | |\n| Match the example's import order, export style, prop handling and | |\n| file structure exactly. Same stack: React 18, plain CSS, useState only. | |\n| EXAMPLE FILE | |\n| [paste one existing component]</div> | |\n| <div class=\"outcome\"><b>Why it works:</b> the example carries every convention you would otherwise have to describe and would probably describe incompletely.</div> | |\n| </div> | |\n| <h3>Pattern 3 — Writing tests</h3> | |\n| <div class=\"prompt good\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Test</span></div> | |\n| <div class=\"prompt-body\">Write unit tests for the function below. | |\n| Before writing them, list the edge cases you intend to cover | |\n| and wait for me to confirm. | |\n| Constraints once confirmed: | |\n| - Plain Jest, no extra libraries | |\n| - One assertion per test where reasonable | |\n| - Test names describe behaviour, not implementation | |\n| - Cover empty input, single element, duplicates, and invalid input | |\n| [paste function]</div> | |\n| <div class=\"outcome\"><b>Why it works:</b> the pause is the valuable part. The edge-case list is often more useful than the tests themselves, and reviewing it costs ten seconds while reviewing twenty generated tests costs ten minutes.</div> | |\n| </div> | |\n| <h3>Pattern 4 — Debugging</h3> | |\n| <div class=\"prompt good\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Debug</span></div> | |\n| <div class=\"prompt-body\">A bug I cannot locate. | |\n| EXPECTED: the list filters as I type. | |\n| ACTUAL: the input accepts one character, then loses focus, and | |\n| the list does not filter. | |\n| EXACT ERROR (browser console): | |\n| [paste the full message and stack, unedited] | |\n| CODE (the whole component, unmodified): | |\n| [paste] | |\n| ALREADY TRIED: | |\n| - Confirmed the items prop arrives correctly (logged it) | |\n| - Removing the key prop changed nothing | |\n| Environment: React 18.2, Vite dev server, Chrome. | |\n| Give the most likely root cause first with your reasoning, then the fix. | |\n| If you need to see another file to be sure, say which one instead of guessing.</div> | |\n| <div class=\"outcome\"><b>Why it works:</b> expected versus actual defines the target, the unedited error is the ground truth, \"already tried\" prevents the first two suggestions being things you have done, and the last line converts invention into a request.</div> | |\n| </div> | |\n| <h3>Pattern 5 — Refactoring</h3> | |\n| <div class=\"prompt good\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">Refactor</span></div> | |\n| <div class=\"prompt-body\">Refactor the function below for readability only. | |\n| RULES | |\n| - Behaviour must be identical. Same inputs, same outputs, same errors. | |\n| - Do not rename anything exported. | |\n| - Do not change the file structure or add dependencies. | |\n| - Do not add features, validation or error handling. | |\n| After the code, list each change you made and why, one line each, | |\n| so I can review them individually. | |\n| [paste function]</div> | |\n| <div class=\"outcome\"><b>Why it works:</b> refactoring prompts fail by quietly changing behaviour. The rules block that, and the change list makes review a checklist rather than a diff hunt.</div> | |\n| </div> | |\n| </section> | |\n| <!-- ===================== CONTEXT ===================== --> | |\n| <section id=\"context\"> | |\n| <div class=\"eyebrow\">Part 9 · Context</div> | |\n| <h2>Giving the right context</h2> | |\n| <p class=\"lead\">The single highest-leverage skill in this session. Most disappointing output is not a model failure — it is a context failure.</p> | |\n| <p>The model knows only what is inside the context window. Every gap you leave is filled with something plausible and generic. Deciding what to include is the actual work.</p> | |\n| <h3>What counts as context</h3> | |\n| <ul class=\"kbdlist\"> | |\n| <li><span class=\"k\">ERROR</span><span><strong>The exact error output, unedited.</strong> Full message, full stack trace, the line it points to. Paraphrasing an error — \"it says something about undefined\" — throws away the most information-dense text you have.</span></li> | |\n| <li><span class=\"k\">DATA</span><span><strong>The real shape of your data.</strong> A sample API response, a props list, a record definition, a config object. This eliminates the most common cause of unusable code: correct logic written against field names that do not exist.</span></li> | |\n| <li><span class=\"k\">CODE</span><span><strong>The surrounding code, not just the broken line.</strong> The whole function, the component it lives in, the caller. A bug is rarely on the line where it surfaces.</span></li> | |\n| <li><span class=\"k\">CONV</span><span><strong>Your conventions.</strong> One existing file that does something similar communicates naming, structure, import order and style more completely than a paragraph describing them.</span></li> | |\n| <li><span class=\"k\">VER</span><span><strong>Versions and environment.</strong> React 18, Java 17, Node 20, which build tool, which browser. Removes an entire class of confidently outdated answers.</span></li> | |\n| <li><span class=\"k\">DIFF</span><span><strong>Expected versus actual.</strong> Both halves. \"It does not work\" describes a feeling; \"expected X, got Y\" describes a problem.</span></li> | |\n| <li><span class=\"k\">TRIED</span><span><strong>What you already ruled out.</strong> Otherwise the first suggestions are the things you spent an hour eliminating.</span></li> | |\n| <li><span class=\"k\">LIMIT</span><span><strong>Constraints you are working under.</strong> Cannot change the API, cannot add dependencies, must keep the existing signature, must work on old browsers.</span></li> | |\n| </ul> | |\n| <h3>Same bug, two prompts</h3> | |\n| <div class=\"prompt bad\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">No context</span></div> | |\n| <div class=\"prompt-body\">my react app crashes when the data loads, how do I fix it</div> | |\n| <div class=\"outcome\"><b>Result:</b> a list of five generic possibilities, none specific to your code, and confident references to components and props that were never mentioned. You now have to test five guesses.</div> | |\n| </div> | |\n| <div class=\"prompt good\"> | |\n| <div class=\"prompt-head\"><span class=\"label\">With context</span></div> | |\n| <div class=\"prompt-body\">EXPECTED: the product list renders once data arrives. | |\n| ACTUAL: white screen the moment the fetch resolves. | |\n| CONSOLE (exact): | |\n| Uncaught TypeError: Cannot read properties of undefined (reading 'map') | |\n| at ProductList (ProductList.jsx:14:23) | |\n| API RESPONSE (actual, from the Network tab): | |\n| { \"status\": \"ok\", \"data\": { \"products\": [ { \"id\": 1, \"name\": \"Laptop Stand\", \"price\": 1299 } ] } } | |\n| COMPONENT (unmodified, full file): | |\n| [paste] | |\n| ALREADY TRIED: confirmed the request returns 200 and the payload above. | |\n| Environment: React 18.2, Vite, fetch in a useEffect. | |\n| Identify the root cause, then give the minimal fix. | |\n| Do not restructure the component.</div> | |\n| <div class=\"outcome\"><b>Result:</b> the mismatch between the response shape and what the component reads is immediately visible in the context provided. The answer is specific, correct, and checkable in seconds.</div> | |\n| </div> | |\n| <h3>Precision beats volume</h3> | |\n| <p>Pasting more is not the same as pasting better. Three relevant files beat thirty. Signs you have pasted too much: the answer addresses code you did not ask about, earlier constraints stop being honoured, or the response becomes vague and hedged. Signs you have pasted too little: the answer references things you never mentioned, or opens with a list of assumptions.</p> | |\n| <div class=\"callout stop\"> | |\n| <p><strong>Before pasting anything, check what is in it.</strong> API keys, connection strings, tokens, customer records, internal URLs, proprietary business logic. Context is the most valuable thing you give a model and the most dangerous. This is covered in full under non-negotiables.</p> | |\n| </div> | |\n| </section> | |\n| <!-- ===================== ANTI PATTERNS ===================== --> | |\n| <section id=\"antipatterns\"> | |\n| <div class=\"eyebrow\">Part 10 · Diagnosis</div> | |\n| <h2>Anti-patterns</h2> | |\n| <p class=\"lead\">Six prompts that fail. The flaw in each is named after the prompt — worth attempting the diagnosis before opening it.</p> | |\n| <details class=\"reveal\"> | |\n| <summary>1 · \"make my code better\"</summary> | |\n| <div class=\"ans\"><strong>Vague ask.</strong> \"Better\" is undefined — faster, shorter, more readable, more testable, safer? The model picks one at random, usually by rewriting everything. Fix: name the single dimension and the boundary. \"Reduce this function to under 30 lines without changing behaviour.\"</div> | |\n| </details> | |\n| <details class=\"reveal\"> | |\n| <summary>2 · \"write a react component for a product page and also set up routing and add authentication and write the tests and explain everything\"</summary> | |\n| <div class=\"ans\"><strong>Overloaded prompt.</strong> Five tasks in one request. Quality drops across all of them, the response is too large to review honestly, and correcting one part forces a regeneration of the rest. Fix: one task per prompt, in sequence, reviewing each before the next.</div> | |\n| </details> | |\n| <details class=\"reveal\"> | |\n| <summary>3 · \"why isn't my useEffect working\"</summary> | |\n| <div class=\"ans\"><strong>Missing context.</strong> No code, no error, no expected-versus-actual. The model answers about useEffect in general, which you could have read in the docs. Fix: the component, the exact console output, what you expected, what happened, what you already tried.</div> | |\n| </details> | |\n| <details class=\"reveal\"> | |\n| <summary>4 · \"fix the bug in the checkout function\"</summary> | |\n| <div class=\"ans\"><strong>Assumed context.</strong> Referring to code the model has never seen. It will not say \"I cannot see that file\" — it will invent a checkout function and fix a bug in the invention. Fix: paste it. Every time. Assume nothing carries over, including from earlier in the same chat once it grows long.</div> | |\n| </details> | |\n| <details class=\"reveal\"> | |\n| <summary>5 · \"write a function to sort products by price\"</summary> | |\n| <div class=\"ans\"><strong>Missing constraints.</strong> Ascending or descending? Mutate or return a copy? What about equal prices, missing prices, string prices? The model chooses, and it commonly chooses in-place <code class=\"inl\">.sort()</code>, which mutates your input. Fix: state the direction, the immutability requirement, and the edge cases before asking.</div> | |\n| </details> | |\n| <details class=\"reveal\"> | |\n| <summary>6 · \"what's the fastest way to deep clone an object in javascript in 2026\"</summary> | |\n| <div class=\"ans\"><strong>Wrong tool for the job.</strong> This is a current-facts-and-measurement question. The model's knowledge has a cutoff, performance depends on your data and runtime, and \"fastest\" cannot be answered without measuring. It will still answer confidently. Fix: use it to generate the benchmark, then run the benchmark.</div> | |\n| </details> | |\n| <h3>The pattern behind the patterns</h3> | |\n| <p>Every one of these is a version of the same mistake: <strong>assuming the model knows something it does not.</strong> Your intent, your codebase, your definition of better, your constraints, or the current state of the world. It never says \"I do not have that.\" It produces something plausible in the shape of the gap.</p> | |\n| </section> | |\n| <!-- ===================== WORKSHEET ===================== --> | |\n| <section id=\"worksheet\"> | |\n| <div class=\"eyebrow\">Part 11 · Exercise</div> | |\n| <h2>Rewrite worksheet</h2> | |\n| <p class=\"lead\">Five failing prompts. For each: name the flaw, rewrite it, and write one sentence on why the rewrite is better. No AI tool required — the rewriting is the skill being practised.</p> | |\n| <div class=\"grid g2\"> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">01</span> | |\n| <h4>\"add error handling to my api call\"</h4> | |\n| <p style=\"font-size:14.5px\">Which call? What should happen on failure — retry, message, fallback, log? What does the rest of the codebase do?</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">02</span> | |\n| <h4>\"convert this to java\"</h4> | |\n| <p style=\"font-size:14.5px\">Which Java version? Preserve structure or idiomatic rewrite? What about the JavaScript-specific behaviour that has no direct equivalent?</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">03</span> | |\n| <h4>\"my form doesn't submit\"</h4> | |\n| <p style=\"font-size:14.5px\">Expected versus actual. Any console output. The form code. Already ruled out.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">04</span> | |\n| <h4>\"write tests for this and also fix any bugs you find and improve the naming\"</h4> | |\n| <p style=\"font-size:14.5px\">Three tasks. Which one first, and how do you review the result of all three at once?</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">05</span> | |\n| <h4>\"is my code secure?\"</h4> | |\n| <p style=\"font-size:14.5px\">Secure against what? Which code? What is the threat you are worried about, and is this a question a model can answer definitively at all?</p> | |\n| </div> | |\n| </div> | |\n| <h3>Marking your own rewrite</h3> | |\n| <p>A rewrite is good when it satisfies all of these:</p> | |\n| <ul> | |\n| <li>Someone unfamiliar with your project could act on it without asking a question.</li> | |\n| <li>It asks for exactly one thing.</li> | |\n| <li>Every piece of information the answer depends on is present in the prompt.</li> | |\n| <li>The output shape is specified.</li> | |\n| <li>You can tell, by reading the result, whether it followed the instructions.</li> | |\n| </ul> | |\n| <p>The last one matters most. A prompt so vague that any output looks acceptable has not been improved — it has only been lengthened.</p> | |\n| </section> | |\n| <!-- ===================== CLOSE ===================== --> | |\n| <section id=\"close\"> | |\n| <div class=\"eyebrow\">Part 12 · Close</div> | |\n| <h2>Non-negotiables</h2> | |\n| <p class=\"lead\">Five rules. These do not change with tool, model, seniority or deadline.</p> | |\n| <div class=\"grid g2\"> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">01</span> | |\n| <h4>Never ship code you have not read and understood</h4> | |\n| <p>If you cannot explain each line, you cannot maintain it, review it, or debug it at 2am. The code carries your name in the commit history regardless of who wrote it.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">02</span> | |\n| <h4>Never paste secrets, credentials or customer data</h4> | |\n| <p>API keys, connection strings, tokens, real customer records, internal system details, proprietary business logic. Once it leaves your machine you do not control it. Replace with realistic dummy values before pasting.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">03</span> | |\n| <h4>Always run and test what it writes</h4> | |\n| <p>Reading is not verification. Code that looks correct and code that is correct are different things, and the gap is exactly where subtle bugs live.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">04</span> | |\n| <h4>Verify every API, method and factual claim</h4> | |\n| <p>Especially the ones that solve your problem most conveniently. Confident tone is not evidence. Check the real documentation.</p> | |\n| </div> | |\n| <div class=\"card\"> | |\n| <span class=\"num\">05</span> | |\n| <h4>Do not outsource the fundamentals</h4> | |\n| <p>Using AI on something you could not do yourself feels productive and leaves you exactly where you were. Interviews, incidents and design discussions all test the floor, not the ceiling.</p> | |\n| </div> | |\n| <div class=\"card\" style=\"background:var(--ink);color:#fff;border-color:var(--ink)\"> | |\n| <span class=\"tag\" style=\"color:#8E9AB2\">Where an employer is involved</span> | |\n| <h4 style=\"color:#fff\">Follow your organisation's AI policy</h4> | |\n| <p style=\"color:#C3CBD9\">Many companies restrict which tools may be used and what may be entered into them. These rules are the floor. Your workplace policy sits on top and always wins.</p> | |\n| </div> | |\n| </div> | |\n| <h3>Session 2 · AI-Assisted Development</h3> | |\n| <p>The next session moves from a chat box to tools that read your files, run commands and make multi-step changes: the AI coding tool landscape, Claude Code, what an agent actually is and when it helps or hurts, reviewing generated diffs line by line, and finding deliberately planted flaws in AI-written code.</p> | |\n| <p>Everything today carries forward. The role–context–task–format structure becomes the specification an agent works from, and reliable-versus-risky becomes the judgement about what to let an agent attempt at all.</p> | |\n| <div class=\"callout\"> | |\n| <p><strong>Between now and then:</strong> re-run the prompts on this page in whichever tool you have access to. The refinement ladder is the one worth doing carefully — running rounds 1 through 6 yourself, in order, is the fastest way to internalise what each element actually contributes.</p> | |\n| </div> | |\n| <div class=\"footer\"> | |\n| GenAI Foundations & Prompt Engineering for Developers · Session 1 of 2 · MERN and Java cohorts | |\n| </div> | |\n| </section> | |\n| </div> | |\n| <script> | |\n| (function(){ | |\n| var links = Array.prototype.slice.call(document.querySelectorAll('#toc a')); | |\n| var map = {}; | |\n| links.forEach(function(a){ | |\n| var el = document.querySelector(a.getAttribute('href')); | |\n| if (el) map[a.getAttribute('href').slice(1)] = a; | |\n| }); | |\n| var obs = new IntersectionObserver(function(entries){ | |\n| entries.forEach(function(e){ | |\n| if (e.isIntersecting) { | |\n| links.forEach(function(l){ l.classList.remove('on'); }); | |\n| var a = map[e.target.id]; | |\n| if (a) { | |\n| a.classList.add('on'); | |\n| a.scrollIntoView({block:'nearest', inline:'nearest'}); | |\n| } | |\n| } | |\n| }); | |\n| }, { rootMargin: '-70px 0px -75% 0px', threshold: 0 }); | |\n| Object.keys(map).forEach(function(id){ | |\n| var el = document.getElementById(id); | |\n| if (el) obs.observe(el); | |\n| }); | |\n| })(); | |\n| </script> | |\n| </body> | |\n| </html> |", "url": "https://wpnews.pro/news/ai-session-1-html", "canonical_source": "https://gist.github.com/niftynihal/fc1276151deaa991af761ea964b6ac36", "published_at": "2026-08-14 08:29:03+00:00", "updated_at": "2026-08-17 05:10:55.484499+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "generative-ai", "developer-tools"], "entities": [], "alternates": {"html": "https://wpnews.pro/news/ai-session-1-html", "markdown": "https://wpnews.pro/news/ai-session-1-html.md", "text": "https://wpnews.pro/news/ai-session-1-html.txt", "jsonld": "https://wpnews.pro/news/ai-session-1-html.jsonld"}}