I had to do therapy on my AI — Tin's Posts — Tin Marković
Skip to content
← Tin's Posts<br>· May 21, 2026<br>· 5 min read
I had to do therapy on my AI
I've had to do "therapy" on my LLM agent last week. Entertaining stuff. I've been writing a skill (as I do), when I realized the LLM was ignoring my instructions. Here's the setup.
I'm working on a codebase that has a lot of boilerplate. We're using certain cloud providers and SDKs, all wrapped in Typescript typing and exposition. Lots of code, lots of verbose typing, all lines of code that describe far less wordy concepts. Stuff that's straightforward enough to review but makes the PR look intimidating and creates a mental load that makes it difficult to start.
I decided I could have an LLM scan the codebase, describe all the pattern-matched work — "funcA() is funcB() with adjusted typing, repeated in 12 files" — and other clusters like that. In the end, it should give me a guided tour of the commit: explaining where's what, and what's actually unique. I like the LLM helping, but I run the show — it assists. I explicitly wanted it to assist me, not do the work.
The first iteration
When I ran the skill over a pending PR... I got a plain old review. Most of my instructions got flat out ignored. I had a good chuckle — this was fun. LLMs are famously non-deterministic and this was a fresh session, let's try again and see if it was a fluke.
bulk-enroll-event-participants.ts — serial insertRecord loop, not batched<br>Each participant gets its own individual DB write inside a for loop. For large participantIds<br>arrays this will be slow and will exhaust write throughput one call at a time. The database<br>adapter almost certainly has a batchInsert or equivalent; this should be a bulk write. For any<br>meaningful batch size this is Nx the latency and Nx the round trips. Worth fixing before this<br>gets used at scale.
It wasn't. The same result appeared again. Now I was getting curious. Let me update the skill.
I added an explicit paragraph:
Note: Your opinion is appreciated, but not the focus of this process. You are primarily to list anything that doesn't follow a predefined pattern, then augment that listing.
It did not work.
The second iteration
I sat with it for a bit, then dug deeper. It's a prediction machine, and it'll follow patterns, right? So let me make a pattern it'll follow — keep things simpler and make it explicit.
First, break the process into two steps, explicitly:
For each piece of logic, provide an explanation first: what was changed, was it new code, existing code changed, formatting/polishing, or typing. Categorize it explicitly (e.g. "New code", "Changed logic", "Type change") and explain what it does — before any opinion.
After the explanation, add a tight observation: whether it's correct, and any gotcha or improvement. Keep it short. You are the assistant to the reviewer, not the reviewer.
The note stayed. Couldn't hurt to reinforce the thought.
Then, also add a template definition:
**`filename`** _(Category)_ — one-line description of what to look at.<br>Explanation of what the code does, in plain terms, no opinion yet.<br>> Observation: is it correct? any gotcha or fix? Keep to one or two sentences.
This ought to work.
bulk-enroll-event-participants.ts — sequential writes inside a loop<br>Category: New code<br>Explanation: For each participantId, an insertRecord is await-ed inside a for…of loop — one database round-trip per record, serially.<br>> Observation: For any bulk operation this will be slow; batchInsert (or at minimum Promise.all) is<br>> the standard pattern here. Worth raising before merge, especially if batch sizes can be large.
... and yet it didn't. See how the explanation still focuses on the one bit of code it wants to criticize?
The deeper dive
We've spent a fair few cycles going through this back and forth, figuring out how to tighten the prompt and get a better result.
Then it dawned on me. I needed to approach this like I'd approach an intern misunderstanding instructions — a human being stubbornly wrong. I remembered principles from Thinking Fast and Slow (Kahnemann): priming and anchoring . Priming: brief exposure to a concept shapes how everything that follows is interpreted — you can't fully un-ring the bell. Anchoring: the first piece of information encountered becomes a reference point; subsequent reasoning adjusts from it, but rarely far enough.
Thought on this a bit, and the root cause formed: the skill description. Simple, concise, technically true.
name: project-code-review-assist<br>description: >-<br>Assists with reviewing code changes in the Project codebase. Separates genuine<br>logic from boilerplate, flags Project-specific gotchas (read skill),<br>and identifies premature complexity. Use when the user asks for a<br>code review, asks what to pay attention to, or invokes /project-code-review-assist.
And now it's obvious. The LLM would enter the entire thing with the wrong framing. Call it a review at the start, prime the LLM...