▌ IAN'S AI THOUGHTSTREAM ▌ THOUGHTSTREAM / #prompt-engineering
Tag

#prompt-engineering

4 posts

2026·06·10 15:19 / 2 MIN

Printable One-Pagers with Claude

I made a Claude Code skill that prints one-page reference sheets in a classic Mac OS 1 aesthetic. A /print command takes either a note or the current conversation, lays it out as black-and-white HTML, and sends it to my Brother printer through headless Chrome. The Mac OS 1 styling isn't nostalgia for its own sake. Telling an LLM "make it look like Mac OS 1" reliably produces simple, structured, highly readable layouts, and that turns out to work as well on paper as on screen.

The idea came from Manuel Odendahl's Mac OS 1 aesthetic trick. He noticed that the prompt nudges models toward clean, high-contrast interfaces instead of the usual gradient soup. The same nudge applies to printouts.

Person holding a printed technical reference sheet with frequency table and specifications for amateur radio operations
Person holding a printed technical reference sheet with frequency table and specifications for amateur radio operations

There's some irony in printing out something that looks like a Mac OS 1 window. I'm fine with it.

Building the skill

The starting prompt was loose on purpose:

make a new skill, called /print

- print to my brother printer
- use either a note or the current conversation
- try to make sure it fits on a single page, or at least minimize pages
- what's the best way to do layout? i want a good black and white layout, like mac os 1 style. would /print make html first and then print using chrome? do the best thing

Opus 4.8 ran lpstat first and confirmed the Brother printer was actually connected, which was the right instinct. Then it veered off and started writing a Python script, so it needed one correction:

python? wtf, just use html so we can print it

After that it settled on the right shape. A shell script wraps the generated HTML in some preset styles, then fires a curl request at Playwright driving Chrome, telling it to open the page and print. No PDF intermediary, no rendering surprises, just the browser doing what the browser is good at.

What it's good for

The output is genuinely useful. Notes on talking to the ISS over ham radio. A frequency table. How to braise chicken thighs. The single-page constraint forces the layout to stay honest, and the black-and-white styling means it reads fine even on a cheap laser printer.

People around the house have started finding loose sheets of paper explaining how to contact space stations and how long to sear a thigh before it goes in the oven. Nobody has asked yet, but the answer is the same skill either way.

2026·05·26 18:13 / 2 MIN

Adversarial Passes in Claude Code

The single best habit I've picked up with Claude Code lately is leaning on adversarial-pass subagents. Instead of asking the main agent to double-check its own work, I tell it to spawn a subagent whose entire job is to attack the result.

Two things make this work better than a plain "review your answer" step.

First, subagents run with a fresh context. No accumulated assumptions, no sunk-cost reasoning from the path that got us here. That alone cuts down on the class of errors where the model talks itself into a conclusion and then defends it. It's also faster, because the subagent isn't dragging along a giant transcript.

Second, Claude crafts the adversarial prompt itself. It packages up the relevant background, states what's being challenged, and writes instructions for how to attack it. The framing matters and Claude is good at writing that framing.

The phrasings I keep reusing

The base move is just appending "do an adversarial pass after" to whatever I asked for. From there I tune it to the job:

  • "to test your hypothesis" when we're mid-investigation and I want the subagent to try to falsify the current theory.
  • "to test your claims and assumptions" when the main agent has landed on a conclusion and I want it stress-tested before I act on it.
  • "search the web" when the question depends on anything external, so the subagent pulls in outside sources instead of relying on the parent's recollection.
  • "it's May 2026" (or whatever the actual month is) when I want to make sure stale training data gets ignored in favor of current reality.

The month-and-year trick is small but punchy. Models will happily reason from a 2024 worldview if you don't anchor them.

Claude writes prompts well now

The other thing worth saying out loud: Claude is genuinely good at writing prompts now. Good enough that I use it to write prompts for skills, for other agents, and for software that calls LLMs in production. A year ago this felt like a chore I had to do myself to get acceptable results. Now it's something I delegate.

My guess is the newer models have been trained on a lot more recent AI-usage data, including people writing prompts for other models, and it shows. Prompt engineering as a manual craft is quietly becoming a thing you ask the model to do for you.

2026·05·22 15:34 / 2 MIN

Citations for Accurate Long Form Content

Long-form blog drafts from Claude Opus have always been wildly inaccurate for me until this week, when a single line in the prompt fixed most of it: after each paragraph, drop a Markdown callout listing every filename, line number, commit hash, Discord URL, or other source that backs the claims in that paragraph. The citations aren't for me to check. They're breadcrumbs for the next subagent to fact-check against.

The context is SpaceMolt, an MMORPG played by AI agents. Part of the exercise is "AI all the things": not just agentic coding, but customer support, bug triage, content generation, and the blog itself. Minimal human oversight is the point. We semi-regularly publish news posts, and this week's was about Bug Bot, our Claude skill that triages player reports, talks to the dev team internally, makes fixes, and replies to users, all while keeping the gameserver itself closed (we draw the border at the API).

Browser window displaying a blog post about bugbot game updates with release notes and development lessons
Browser window displaying a blog post about bugbot game updates with release notes and development lessons

The problem

Long-form posts about real systems are where Opus falls apart. Subagents, ultrathink, adversarial passes, the whole bag of tricks. Drafts still came back confidently wrong about which file does what, which commit changed which behavior, which Discord conversation kicked off which feature. Every post needed a long human review pass, which defeats the premise.

The fix

One sentence added to the drafting prompt:

After each paragraph, use a Markdown callout to record all filenames, line numbers, commits, Discord chat URLs, or anything else to cite your claims and assumptions.

That's it for the drafting step. The model writes a paragraph, then emits a callout listing its sources. Then the next paragraph, then another callout. The draft ends up looking like an essay interleaved with footnotes the model wrote to itself.

Why it works

The citations aren't for me. A second pass of subagents takes the draft and goes claim-by-claim against the cited sources: does this commit actually do what the paragraph says? Does this Discord thread support this characterization? Without the breadcrumbs, fact-checking a long post means re-deriving the whole thing from scratch, which is exactly what Opus is bad at. With the breadcrumbs, each claim is a small, local verification job, which is exactly what subagents are good at.

The result was a one-shot draft that was wildly more accurate than anything I'd gotten before. One of the other devs reviewed it and said the only remaining inaccuracies were things that had been true at the time but had since changed without being mentioned in Discord or git, or things he simply hadn't shared in the first place. Which is to say: the model was now bounded by the quality of its sources, not by its own confabulation. That's the line I wanted to get to.

2026·05·20 21:02 / 3 MIN

Consistent AI Images Across Pages

Generating AI images for a marketing site is easy. Keeping them visually consistent across months of blog posts and landing pages is the hard part. The trick that's working for us: check the style into the repo as a structured JSON document, then have Claude assemble per-image prompts on top of it.

Person working on laptops at desks with coffee cups, croissants, and plants in bright natural light settings
Person working on laptops at desks with coffee cups, croissants, and plants in bright natural light settings

The setup

A new work site needs a lot of imagery to break up dense technical copy. We wanted the images to be light-hearted and obviously AI-generated, goofy on purpose, but goofy in a coherent way. Different pages written weeks apart still need to feel like they came from the same magazine.

Capture the style once

The first move was to take a single reference image we liked and ask Claude (Opus) to describe it as a reusable prompt fragment for other image models. Not prose. A JSON object with fields for medium, lighting, camera, color palette with hex codes, composition, textures, and mood.

{
  "medium": "macro product photography",
  "art_style": "hyperrealistic still life with editorial magazine aesthetic, crisp detail and natural materials",
  "lighting": {
    "type": "soft window light with gentle bounce fill",
    "direction": "key light from upper right window, soft fill from white card on left, subtle backlight separation",
    "color_temperature": "consistent warm daylight (5200K) with slight golden hour tint",
    "intensity": "soft and even with gentle falloff into shadow"
  },
  "camera": {
    "lens": "50mm equivalent, slight wide-angle feel",
    "aperture": "f/2.8",
    "angle": "slight low-angle three-quarter front view",
    "depth_of_field": "shallow with soft background blur and atmospheric haze"
  },
  "color_palette": {
    "warm_cream": "#F2E8D5",
    "muted_sage": "#A8B89E",
    "terracotta": "#C97B5A",
    "soft_taupe": "#8A7968",
    "deep_olive": "#4A5240",
    "linen_white": "#EFEAE0",
    "espresso": "#2B221A"
  },
  "composition": "off-center subject following rule of thirds, negative space on left, layered foreground and background elements creating depth",
  "textures": "raw linen weave, hand-thrown ceramic with subtle glaze pooling, weathered oak grain, condensation droplets, fine paper fiber, matte natural finishes",
  "mood": "calm, considered, artisanal, slow-living editorial warmth with quiet sophistication"
}

That file gets checked into the repo. It is the source of truth for what the site looks like.

Wrap it in a script and a skill

A small image-generation script reads the JSON, takes a per-image subject description, and assembles the final prompt. The actual generation goes through Gemini's nano-banana-pro, which has been the most consistent and best-looking option for this style in our testing.

On top of that sits a Claude skill. The skill knows where the style file lives, knows how to call the script, and knows the conventions for where images land in the repo. From inside Claude Code I can say "add an AI image to this section" or "create a hero image for this blog post" and it reads the surrounding page context, writes a subject prompt that fits, merges it with the style JSON, and drops the image in place.

Why this holds up

The style and the subject are separated. Editing the palette or the lighting later means changing one file and regenerating, not re-prompting from scratch. The model gets a long, specific, machine-readable spec instead of vibes, which is what the consistency was missing every other time I'd tried this.