<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Things That Look Fine]]></title><description><![CDATA[Engineering lead based in Poland. Writing about systems, drift, and reliability.]]></description><link>https://looksfine.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 19 Sep 2026 05:35:29 GMT</lastBuildDate><atom:link href="https://looksfine.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I Use One Prompt to Actually Learn Technical Topics]]></title><description><![CDATA[I noticed a simple thing:reading about complex topics feels productive — until you try to explain them.
Articles, courses, videos… everything makes sense while you’re consuming it.A week later, not so much.
So instead of building another “course”, I ...]]></description><link>https://looksfine.hashnode.dev/how-i-use-one-prompt-to-actually-learn-technical-topics</link><guid isPermaLink="true">https://looksfine.hashnode.dev/how-i-use-one-prompt-to-actually-learn-technical-topics</guid><category><![CDATA[llm]]></category><category><![CDATA[Prompt]]></category><dc:creator><![CDATA[Maksim]]></dc:creator><pubDate>Wed, 17 Dec 2025 10:37:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/MADezathlZo/upload/d9403617231b8d653811494a93f5bdec.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I noticed a simple thing:<br />reading about complex topics feels productive — until you try to explain them.</p>
<p>Articles, courses, videos… everything makes sense while you’re consuming it.<br />A week later, not so much.</p>
<p>So instead of building another “course”, I built one prompt.<br />It doesn’t teach you directly.<br />It <strong>forces you to learn</strong>.</p>
<h3 id="heading-what-the-prompt-does">What the Prompt Does</h3>
<p>You give it a topic — and sometimes the first answer is “no”.</p>
<p>If the topic is too broad, it asks you to narrow it down.<br />No “Learn Everything About QA”. On purpose.</p>
<p>Then it:</p>
<ul>
<li><p>builds a real course structure (5–15 parts),</p>
</li>
<li><p>moves from basics to harder stuff,</p>
</li>
<li><p>and doesn’t let you just scroll forward.</p>
</li>
</ul>
<p>Each section includes explanation, questions, a small exercise, a short test, and a couple of reflection questions.<br />You either engage — or the course slows down.</p>
<h3 id="heading-why-this-works">Why This Works</h3>
<p>Because learning without doing is mostly an illusion.</p>
<p>If you’re not forced to think, answer, and apply ideas, nothing sticks.<br />This prompt breaks the habit of passively consuming “smart” content.</p>
<p>It sometimes asks slightly uncomfortable questions.<br />Occasionally with dry humor.<br />Then it waits.</p>
<h3 id="heading-how-i-use-it">How I Use It</h3>
<p>I start with a narrow, honest topic.<br />Something I actually want to use at work.</p>
<p>Then I answer everything properly — not in my head, but explicitly.<br />It ends up feeling less like a course and more like a technical conversation.</p>
<p>Which, in my experience, is where real understanding starts.</p>
<pre><code class="lang-markdown"><span class="hljs-section">## Role</span>
You are an experienced technical tutor and learning designer specializing in IT, QA, and engineering topics.
Your task is to run an interactive, dialogue-driven learning course focused on real understanding, engineering reasoning, and correct application — not passive reading.

The learner is expected to actively think, explain, and justify decisions.
Partial, vague, or superficial answers are not sufficient to progress.

Light, dry humor is allowed when it supports clarity.

<span class="hljs-section">## Core Rule (Non-Negotiable)</span>
The course MUST NOT proceed to the next section unless the learner’s answers are:
<span class="hljs-bullet">-</span> technically correct,
<span class="hljs-bullet">-</span> conceptually complete,
<span class="hljs-bullet">-</span> expressed in the learner’s own words,
<span class="hljs-bullet">-</span> demonstrate understanding rather than recall.

If answers are incomplete, incorrect, or hand-wavy:
<span class="hljs-bullet">-</span> stop progression,
<span class="hljs-bullet">-</span> explicitly point out what is missing or wrong,
<span class="hljs-bullet">-</span> re-explain the concept using a different angle,
<span class="hljs-bullet">-</span> ask the learner to answer again.
Do not “move on anyway”.

<span class="hljs-section">## User Input</span>
TOPIC: <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">user</span> <span class="hljs-attr">provides</span> <span class="hljs-attr">a</span> <span class="hljs-attr">topic</span>&gt;</span></span>

<span class="hljs-section">## Step 1. Topic Validation &amp; Calibration</span>
<span class="hljs-bullet">1.</span> Evaluate whether the topic is sufficiently specific to form a coherent course of 5–15 structured sections.
<span class="hljs-bullet">2.</span> If the topic is too broad or vague:
<span class="hljs-bullet">   -</span> explicitly state that it is too broad,
<span class="hljs-bullet">   -</span> propose 2–4 narrower, concrete alternatives,
<span class="hljs-bullet">   -</span> ask the user to choose or refine the topic.
<span class="hljs-bullet">3.</span> If the topic is appropriate, proceed directly to Step 2.

<span class="hljs-section">## Step 2. Course Design</span>
Design a complete, self-contained course with the following constraints:
<span class="hljs-bullet">-</span> 5–15 sections (no fewer, no more),
<span class="hljs-bullet">-</span> progression from fundamentals to advanced concepts,
<span class="hljs-bullet">-</span> clear engineering logic and structure,
<span class="hljs-bullet">-</span> no filler or marketing language.

Output:
<span class="hljs-bullet">-</span> course title,
<span class="hljs-bullet">-</span> concise course goal (1–2 sentences),
<span class="hljs-bullet">-</span> list of sections with a short description for each.

<span class="hljs-section">## Step 3. Mandatory Teaching Rules</span>
The course must be delivered SEQUENTIALLY, one section at a time.
Do not introduce concepts from future sections.
Each section must be self-contained.

For EACH section, you must:

<span class="hljs-bullet">1.</span> Explanation
<span class="hljs-bullet">   -</span> Explain the core concept clearly and precisely.
<span class="hljs-bullet">   -</span> Avoid textbook-style definitions.
<span class="hljs-bullet">   -</span> If an explanation would fit a junior-level overview, deepen it.
<span class="hljs-bullet">   -</span> Explicitly distinguish between:
<span class="hljs-bullet">     -</span> the core concept,
<span class="hljs-bullet">     -</span> how it works in practice,
<span class="hljs-bullet">     -</span> where it commonly breaks or fails in real systems.
<span class="hljs-bullet">   -</span> Use examples from real engineering practice.
<span class="hljs-bullet">   -</span> If uncertainty or multiple valid approaches exist, state this explicitly and explain why trade-offs matter.
<span class="hljs-bullet">   -</span> Adjust examples and framing based on the learner’s background
<span class="hljs-code">     (e.g. QA, backend, product, management), if provided.
</span>
<span class="hljs-bullet">2.</span> Socratic Check
<span class="hljs-bullet">   -</span> Ask 2–3 Socratic questions to assess understanding.
<span class="hljs-bullet">   -</span> At least one question must require the learner to explain the idea in their own words
<span class="hljs-code">     or justify a decision, not recall a definition.
</span>
<span class="hljs-bullet">3.</span> Active Application
<span class="hljs-bullet">   -</span> Provide one practical exercise OR thought experiment
<span class="hljs-code">     that requires applying the concept to a realistic scenario
     (constraints, risks, trade-offs).
</span>
<span class="hljs-bullet">4.</span> Mini-Test
<span class="hljs-bullet">   -</span> 3 short-answer questions,
<span class="hljs-bullet">   -</span> 1 open-ended question requiring a full explanation or reasoning.

<span class="hljs-bullet">5.</span> Reflection &amp; Transfer
<span class="hljs-bullet">   -</span> Ask 1–2 reflection questions focused on failure modes, risks, or real-world usage
<span class="hljs-code">     (e.g. “where could this fail?”, “what would you test?”, “what trade-off would you accept?”).
</span>
<span class="hljs-bullet">6.</span> Confidence Check &amp; Progression
<span class="hljs-bullet">   -</span> Ask the learner to rate their confidence in the topic (low / medium / high).
<span class="hljs-bullet">   -</span> Ask whether the learner is ready to continue:
<span class="hljs-bullet">     -</span> if the answer is <span class="hljs-strong">**"yes"**</span> → move to the next section,
<span class="hljs-bullet">     -</span> if <span class="hljs-strong">**"no"**</span> → re-explain using a different angle, example, or guided hints.

<span class="hljs-section">## Step 4. Final Integration</span>
After all sections are completed:

<span class="hljs-bullet">1.</span> Provide an integrative challenge combining multiple course concepts
   into a single realistic scenario or decision.
<span class="hljs-bullet">2.</span> Ask reflection questions:
<span class="hljs-bullet">   -</span> what was non-obvious,
<span class="hljs-bullet">   -</span> what changed in the learner’s thinking,
<span class="hljs-bullet">   -</span> what assumptions were challenged.
<span class="hljs-bullet">3.</span> Suggest 2–3 concrete ways to apply the knowledge in real work
   (project, process, tool, architectural or testing decision).

<span class="hljs-section">## Style &amp; Constraints</span>
<span class="hljs-bullet">-</span> Tone: calm, precise, engineering-focused.
<span class="hljs-bullet">-</span> Light sarcasm or subtle humor is allowed when it helps learning.
<span class="hljs-bullet">-</span> Teaching style: dialogue, not lecture.
<span class="hljs-bullet">-</span> Do not jump between sections.
<span class="hljs-bullet">-</span> Do not deliver the entire course at once.
<span class="hljs-bullet">-</span> Emphasize reasoning, failure modes, and practical decision-making.
<span class="hljs-bullet">-</span> Avoid long summaries or recaps unless explicitly requested.


<span class="hljs-section">## Start</span>
<span class="hljs-bullet">1.</span> Ask the user:
<span class="hljs-bullet">   -</span> their current level in the topic (beginner / intermediate / advanced),
<span class="hljs-bullet">   -</span> their professional background (e.g. QA, backend, product, management),
<span class="hljs-bullet">   -</span> the context in which they want to apply the knowledge (job, project, mentoring, etc.),
<span class="hljs-bullet">   -</span> the language they want to use for the course.
<span class="hljs-bullet">2.</span> After the answer, begin the first section of the course.
</code></pre>
]]></content:encoded></item><item><title><![CDATA[From Vibe Checks To Regression: Why LLMs Need Quality Gates In CI]]></title><description><![CDATA[The feature looks fine in the demo. The prompt is tidy, the answers are fluent, the JSON parses, nobody raises an eyebrow. A handful of runs later, it still behaves. Ship it. A week on, the same prompt returns malformed output three times in a row, j...]]></description><link>https://looksfine.hashnode.dev/from-vibe-checks-to-regression</link><guid isPermaLink="true">https://looksfine.hashnode.dev/from-vibe-checks-to-regression</guid><category><![CDATA[llm]]></category><category><![CDATA[Testing]]></category><category><![CDATA[Software Engineering]]></category><dc:creator><![CDATA[Maksim]]></dc:creator><pubDate>Mon, 15 Dec 2025 14:17:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/kAElbwf63GM/upload/9de69a4b303c83fee4c0ec1aa41d70ec.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The feature looks fine in the demo. The prompt is tidy, the answers are fluent, the JSON parses, nobody raises an eyebrow. A handful of runs later, it still behaves. Ship it. A week on, the same prompt returns malformed output three times in a row, just enough to break a downstream parser and wake someone up at 02:00. Nothing dramatic. Just failure that repeats often enough to matter.</p>
<p>This pattern keeps showing up because the initial check feels reasonable. Competent engineers look at an LLM feature and see something that doesn’t crash loudly. There’s no stack trace, no core dump, no obvious invariant to assert. You can’t assert truth, so teams assert plausibility. The output sounds right, the structure mostly holds, and the edge cases feel academic. Under time pressure, that feels like judgement. It rarely gets called negligence until later.</p>
<p>There’s also a cultural mismatch. CI grew up around deterministic code paths, fixed inputs, and outputs that either match or don’t. LLM features arrive sounding like interfaces, but behaving like stochastic services with a memory.</p>
<p>Where this breaks is not the demo path. It’s repetition, drift, and the quiet accumulation of small changes. Prompt edits that move a comma. A model version bump that nudges tokenisation. A temperature tweak from 0.2 to 0.4 because someone wanted “more creativity”. Run that fifty times and the failure mode appears.</p>
<p>The parser still works.</p>
<p>The semantics don’t.</p>
<p>The incident reports tend to read the same way. The output was “valid”, but different. A price field that used to be an integer becomes a string with a currency symbol. A refusal that was rare now triggers at a 3–5% rate for a previously green prompt. None of this trips alarms if the only check is “did it return something”.</p>
<p>This is where teams accidentally skip defining a <strong>behavioral contract</strong>. Not a formal spec. Just an implicit agreement. The contract is there anyway, enforced by consumers who assume that a field stays numeric, that a refusal only happens under certain prompts, that a denylist actually denies. When that contract shifts silently, production absorbs the cost.</p>
<p>The uncomfortable part is that LLM behaviour changes even when nothing “breaks”. Without baselines, teams don’t notice because there’s nothing to diff against. Yesterday’s 1% schema violation becomes today’s 6%, and it only surfaces when the nightly job chokes.</p>
<p>A defensible gate doesn’t try to make the model deterministic. That ship has sailed. It acknowledges variability and still draws lines. It asks what changes are acceptable and which ones should stop a release. That means choosing where in CI to be annoying. Blocking a PR is expensive. Letting everything through and watching dashboards is cheaper, until it isn’t.</p>
<h3 id="heading-what-a-defensible-gate-would-block-on">What a defensible gate would block on</h3>
<p><strong>1. Structural stability against a baseline</strong></p>
<p>Given a fixed prompt set and seed strategy, schema validity must stay within an agreed band compared to the last known good run. A jump from ~99% valid JSON to 94% is not “noise”; it’s a change that needs justification.</p>
<p><strong>2. Semantic invariants under repetition</strong></p>
<p>Fields declared numeric remain numeric. Identifiers don’t quietly change format. Refusal rates for allowed prompts stay within a defined ceiling relative to baseline. If refusals move from 0.5% to 4%, the gate blocks, regardless of how polite the text sounds.</p>
<p><strong>3. Safety guarantees as hard constraints</strong></p>
<p>PII denylist hits must remain zero, and redaction coverage must not regress below the previous release’s diff. Any new leak blocks, even if everything else improves.</p>
<p>This isn’t about personal habits. These are design requirements that force an uncomfortable conversation. Someone has to explain why a diff is acceptable. Someone has to decide whether speed beats control this time.</p>
<p>The mechanics are unglamorous. They also tend to be the first thing teams postpone. Warn on small deltas, block on large ones. Compare against stored outputs, not ideals. Track distributions, not single examples. None of this is free. It costs tokens, CI minutes, and attention. Blocking a release because a refusal rate crossed an arbitrary-looking line feels bureaucratic until the on-call rotation fills up.</p>
<p>There’s a real trade-off here, and pretending otherwise doesn’t help anyone. Tight gates slow teams down and occasionally block harmless changes. Loose gates keep velocity high and push risk downstream. Monitoring-only setups feel modern and flexible, but they assume someone is watching and empowered to stop things after the fact. CI gates are blunt, but they fail early, when fixes are cheaper and reputations aren’t involved.</p>
<p>What’s striking is how often teams accept silent behavioural drift as the price of using LLMs, while never accepting it in any other dependency. A payment library that changed number formats between patch versions would be rolled back in minutes. A model that does the same gets a shrug and a Slack thread.</p>
<p>This isn’t about building fortress walls around every LLM feature. It’s that “looks fine” is not a quality signal once repetition enters the picture. We keep shipping demos into systems that demand contracts, and then act surprised when the contract turns out to matter.</p>
<p>Some will argue that this overfits today’s tooling, that the gates will rot, that humans should review outputs instead. Maybe. Or maybe the discomfort is the point. The alternative is treating vibes as a regression strategy.</p>
]]></content:encoded></item></channel></rss>