# gtmnow learnings

Real, hand-checked lessons from people building AI agents and doing growth with AI.
Drop this into your AI assistant as context, or read them at https://gtmnow.in/learnings

---
## Adding instructions to a model often makes it worse

I had an agent that worked, and I wanted it sharper. So I did the obvious thing: I added a line telling the model to be careful, think it through, and only answer when it was sure. Every instinct says that should help.

Accuracy dropped. Not by a little. The agent started refusing cases it used to get right, and talking itself out of good answers.

I deleted the line. Accuracy climbed back up, past where it started. The 'be careful' text was not making the model smarter, it was making it hesitant. It read caution as permission to bail.

The lesson I keep relearning: with a strong model, most of your prompt is friction. The skill is not writing the perfect instruction, it is noticing which instruction is quietly hurting you and taking it out. When the output is off, try removing a line before you add one.

Category: AGENTS. By Teja.
Link: https://gtmnow.in/learnings/more-instructions-usually-worse

---

## Build the eval before you build the agent

Anyone can ship an agent that returns an answer. You can wire a model, a couple of tools, and a prompt in an afternoon and get a demo that looks great. The trap is that a demo tells you nothing about whether the answers are actually right.

So now, before I build the agent, I build the test. I hand label a small set of real cases where I already know the correct answer, because I checked each one myself. Fifty is plenty to start. That set becomes the gate: a new version has to beat the old one on it, or it does not ship.

The first time you do this it feels slow and a little pointless. Then it catches a 'better' version that was quietly worse on a whole class of inputs, and you stop arguing with it.

The payoff is that you can finally say one version is better than another instead of feeling like it is. Without the eval you are shipping vibes. With it, 'more accurate' means something.

Category: EVALS. By Teja.
Link: https://gtmnow.in/learnings/build-the-eval-first

---

## Recompute any number that makes everything look fine

A batch finished and the dashboard said the success rate was basically perfect. That is exactly the moment to get suspicious, not relieved.

I pulled the raw rows and recomputed it by hand. A big chunk of the 'successes' were empty results that got counted as wins because the code checked 'did it run' instead of 'did it return something real'. The real number was a lot lower, and a lot more useful.

This pattern shows up everywhere: empty results counted as passes, coverage mistaken for accuracy, a flattering match rate nobody re-derived, an average hiding a broken segment. A number that makes everyone comfortable is the one most likely to be wrong, because nobody wants to poke it.

The habit that saved me: when a metric looks too good, recompute it from the raw data before you repeat it to anyone. The honest number is sometimes worse in the moment and always better in the long run.

Category: EVALS. By Teja.
Link: https://gtmnow.in/learnings/re-derive-the-good-number

---

## Write the boring version before you reach for a model

I had a step that needed a yes or no judgment on some messy data, and my first instinct was to hand it to an LLM. It felt like the modern, obvious choice.

On a lark I wrote the dumb version first: a plain set of rules, no model, a few lines of logic. Then I ran both against a labeled set. The rules won. They were more accurate, ran instantly, and cost nothing per call. The model was confidently wrong often enough to lose.

A model is the right tool when the problem is genuinely fuzzy and language heavy. A lot of the steps we reach for it on are not that. They are rules we did not feel like writing.

Now I write the deterministic version first and only bring in a model when the simple thing actually falls short on the eval. Reach for the model last, not first. It is usually cheaper and often better.

Category: AGENTS. By Teja.
Link: https://gtmnow.in/learnings/try-the-simple-thing-first

---

## When the new approach wins, rebuild clean instead of patching

There is a moment where your benchmark says a new approach is clearly better, and you have to decide how to ship it. The tempting path is to graft the new idea onto the old code so you keep everything that already works.

I have learned to resist that. The old code carries assumptions from the old approach, and stacking a new idea on top of them gives you something nobody can fully reason about. Once I threw away a broken piece that had a pile of failing tests and rebuilt it clean from the new approach. It took a fraction of the time that untangling it would have.

This only works because the parts around it are cheap to recreate: the eval that proves the rebuild is better, the small tools, the glue. Versions are cheap. Iteration is cheap.

What is not cheap is complexity you cannot hold in your head. When the approach changes, let the code change with it, all the way down.

Category: AGENTS. By Teja.
Link: https://gtmnow.in/learnings/rebuild-dont-patch

---

## Cost gate the big run before you fire it

It is easy to burn real money on a batch that was never going to work, and find out only after it finishes. I have done it. The fix is boring and it has never failed me.

Before the full run, I do three things. Set a budget I am willing to spend. Run a small sample and actually look at the outputs, not just the exit code. Wire a hard spend cap into the job so it cannot run away.

More than once the sample killed a run that looked completely ready. The prompt was subtly wrong, or a source had gone stale, or the cost per item was triple what I assumed. Catching that on a hundred items instead of a hundred thousand is the whole game.

The rule: if the small sample does not earn the full run, the full run does not happen. The cap is always cheaper than the lesson.

Category: AGENTS. By Teja.
Link: https://gtmnow.in/learnings/cost-gate-the-big-run

---

## Let agents produce, let a hard gate decide

When you run agents in parallel to move faster, the thing that breaks is not the producing, it is the quality. You end up with a pile of output and no trust in any of it.

What worked for me was separating the two jobs completely. Agents produce, freely and in parallel. Then a hard gate decides what survives: a reviewer that scores each output against a written rubric, and a second pass that actively tries to break it and find where it is wrong.

The key is that the gate is real. It has a clear standard, it can fail things, and a reviewer error counts as a fail, not a silent pass. Once the gate is trustworthy, you stop treating scale and quality as a tradeoff, because volume flows through the same standard every time.

Producers make things. Gates decide. Keep them separate and you can scale without lowering the bar.

Category: AGENTS. By Teja.
Link: https://gtmnow.in/learnings/let-agents-produce-gates-decide

---

## Cheaper at the same accuracy is a real win, so chase it

I rewrote a working extractor and it came out a lot cheaper per run with no accuracy loss. That sounds boring next to a new feature, but at any real volume the cost line is what decides whether a thing can run at all. When something works, it is worth a pass just to make it cheaper. Same output, smaller bill, is a feature.

Category: AGENTS. By Teja.
Link: https://gtmnow.in/learnings/chase-cheaper-at-equal-quality

---

## When something is slow, find what is blocking before you add machines

A scraper was slow and the obvious fix was to throw more workers at it. That instinct is almost always wrong, and it is expensive.

I profiled it first. The real problem was that a heavy parsing step was running on the main loop and blocking everything else, including the network calls that were supposed to be happening in parallel. More workers would have just given me more things to block.

Moving that parsing off the main path gave a big throughput jump with the same number of machines and no new rate limit errors, because the work was finally overlapping the way I assumed it already was.

The lesson: slow almost always means something is blocking, not that you need more of everything. Profile for the bottleneck before you spend on scale. The fix is usually smaller and cheaper than the workaround.

Category: DATA. By Teja.
Link: https://gtmnow.in/learnings/profile-before-you-scale

---

## Verify bought or vendor data against reality before you act on it

A vendor handed me a dataset with a confident headline number attached. It would have been easy to take it at face value and build on top of it. I sampled it against the real source instead, and the headline was flat wrong.

This happens far more than you would expect. Purchased lists, enrichment vendors, even internal marketing numbers all tend to arrive polished and unchecked. The polish is not evidence. It is just formatting.

The cheap habit that keeps saving me: before anyone sends, dials, or reports against third party data, pull a small random sample and check it by hand against the source of truth. Ten or twenty rows is enough to smell a problem.

A five minute spot check up front beats discovering three weeks later that a whole campaign or analysis was built on a claim that was never true.

Category: DATA. By Teja.
Link: https://gtmnow.in/learnings/verify-bought-data-from-source

---

## Programmatic SEO only works if every page answers a real question

Most programmatic SEO fails for one reason: the pages are empty templates with the keyword swapped in. Search engines and readers both see straight through them, and you end up with a thousand pages and no traffic.

The ones that actually rank do the opposite. Each page answers one real question a person actually types, and it puts a real answer on the page: a number, a comparison, a specific fact that is genuinely useful whether or not the reader ever buys anything.

The part people skip is the filter. You need a check that looks at each generated page and kills it if it has nothing to say. Publishing a page that cannot answer its own question is worse than not publishing it, because it drags down everything around it.

So the recipe is boring and it works: one page, one question, something true and specific on it, and a gate that refuses the empties. Scale is the easy part once each page earns its place.

Category: SEO. By Teja.
More: https://data-page-qa-rubric.vercel.app/
Link: https://gtmnow.in/learnings/seo-pages-must-answer-a-real-question

---

## Pick who to contact from fresh signals, not last week's memory

Most outbound gets prioritized by gut feel and whoever the team happens to remember. That means the same names get worked over and over while genuinely warm accounts sit untouched because nobody thought of them this week.

The change that worked was making the list re-rank itself on a fixed schedule. Every account goes through the same door: fresh signals in, like hiring, growth, a change in the tools they use, or activity on your site, and a ranked priority list out.

The quiet benefit is that yesterday's hot lead cools down on its own when the signal fades, instead of lingering as a zombie in someone's head. You are not maintaining a mental list anymore, the system is.

So the week starts with who to talk to right now, backed by a reason, instead of who you happened to recall. Same team, same hours, aimed at the accounts that actually moved.

Category: GROWTH. By Teja.
Link: https://gtmnow.in/learnings/re-rank-on-intent-not-memory

---
