Yeda AI Knowledge Base

Yeda AI Knowledge Base

Short, practical tips on AI and AI-assisted engineering — plain-language explainers and hands-on techniques from the Yeda AI team.

Español

Intro to AI →

7 articles

Plain-language explainers on how modern AI actually works — no math required.

AI-Assisted Coding →

81 articles

Practical techniques for shipping real software with AI coding agents.

Tip #001

ADRs Are AI Agent Fuel

Architecture Decision Records give AI coding assistants the one thing your code can’t: why you chose what you chose.

Tip #002

The 5-Second AI Hallucination Detector

AI-generated code can call APIs that never existed. A type checker in pure-check mode catches it in seconds.

Tip #003

Run Two AI Agents at Once with Git Worktrees

Two agents in one folder overwrite each other’s files. Git worktrees give each its own directory and branch on the same repo.

Tip #101

Review the Tests First, Split Big Diffs

Read the tests before the implementation to learn intent first — then keep diffs near 100 lines and split anything approaching 1,000 by stacking, file group, or vertical slice.

Tip #102

Big Refactor? Write a Codemod, Not Hand Edits

When a refactor touches hundreds of lines, stop hand-editing — write a codemod, sed script, or AST transform so one rule applies everywhere and the diff stays reviewable.

Tip #103

That Ugly Code Is Load-Bearing

Chesterton’s Fence for AI-assisted refactoring: run git blame and answer 3 questions before you let an agent delete code it doesn’t understand.

Tip #104

Early Returns Kill Nesting, Named Constants Kill Magic Numbers

Two thirty-second refactors that make AI-generated code readable: flip nested ifs into guard clauses, and pull unexplained numbers into named constants.

Tip #105

Never Cast an Env Var to Bool

bool(\“false\”) is True — a raw cast silently inverts your kill switch. Parse booleans through one shared true/false vocabulary for env vars and config alike.

Tip #106

A Malformed Config Value Should Log and Fall Back

Route every setting through one typed reader that logs a bad value and degrades to a documented default — so a typo becomes a log line, not an outage.

Tip #107

Result And Wait Are Deadlocks Waiting

Why blocking on .Result or .Wait deadlocks C# web apps under load — and how to go async all the way down, with cancellation tokens where they matter.

Tip #109

Your Site Screams AI-Generated: Grep the Three Tells

The AI-slop look is greppable: purple gradients, centered-everything, one uniform 16px+ radius — three commands find it, three fixes break it.

Tip #110

outline: none Without a Replacement Focus Style

One line of CSS locks keyboard users out of your app — how :focus-visible gives them back a focus ring without cluttering the mouse UI.

Tip #111

Server State Belongs in a Cache Layer, Not Global State

Backend-owned data doesn’t belong in your global store — put it in a data-fetching cache layer and get caching, dedup, and invalidation for free.

Tip #112

AI-Generated UIs Skip the Empty States — Prompt for Every One

AI builds your UI’s happy path; users live on the sad path. A checklist for prompting loading, empty, error, and overflow states — every single time.

Tip #113

Never Launch a Goroutine Without an Owner

Goroutines are not garbage collected — every `go` statement in AI-generated Go code needs a cancellation path, a channel owner, and a WaitGroup, or it leaks until the service falls over.

Tip #115

Use ?? For Defaults, Not ||

Why `config.port || 3000` silently discards 0, empty string, and false — and how nullish coalescing (`??`) only falls back on null/undefined.

Tip #116

forEach Doesn’t Await Anything

Why an async callback inside forEach silently races ahead — and how to choose between for...of + await and Promise.all deliberately.

Tip #117

Reject Double Bang in Generated Kotlin

Why every !! in AI-generated Kotlin is a deferred crash, and how explicit nullables and sealed results make the empty case impossible to skip.

Tip #118

Ban GlobalScope.launch in Code Reviews

Unscoped coroutines leak work and swallow cancellation — make GlobalScope.launch an automatic review reject and keep every coroutine tied to an owner.

Tip #121

That Innocent `if exists` Check Is a Race Condition

Why check-then-act filesystem code is a TOCTOU race, and how one parameter — exist_ok=True — deletes the bug and a line of code at the same time.

Tip #122

sum() Streams Lazily, sum([]) Builds First

Drop the square brackets inside sum() and a million-item memory spike becomes a lazy stream — same result, one character less.

Tip #123

Two Ifs In A Comprehension? Give It A Function Name

When a list comprehension grows a second condition, expand it into a named generator function — readable, testable, and a pattern your coding agent will copy.

Tip #124

Threads Won’t Fix CPU-Bound Python

Threads or asyncio for I/O-bound work, ProcessPoolExecutor for CPU-bound — the one-line decision AI assistants get wrong, and how to check which bound you’re fighting.

Tip #125

String += In A Loop Is O(n²), Use Join

Why += on strings inside a loop is quadratic, and the two linear fixes — ''.join() on a list of parts, or io.StringIO for streaming builds.

Tip #126

Always Chain Exceptions With 'from e'

Re-raising a wrapped exception without 'from e' buries the original traceback — two words keep the stack trace pointing at the real cause.

Tip #127

Protocol Over Inheritance: Structural Test Seams in Python

Use typing.Protocol to swap real dependencies for test fakes with zero base-class coupling — structural typing the checker still verifies.

Tip #130

Reject AI-Generated Rails Callbacks That Do Slow Work

AI assistants love after_save callbacks that call APIs — one review rule keeps saves fast, tests offline, and slow work retrying safely in jobs.

Tip #131

Enforce Uniqueness in the Database, Not Just the Model

Rails' validates_uniqueness_of is race-prone under concurrent load — keep it for friendly errors, but add a database unique index for the guarantee.

Tip #132

Every unsafe Block Needs a Safety Comment

An unsafe block suspends the compiler’s checks — write a // SAFETY comment stating the invariant it upholds, and let reviewers and AI agents verify instead of guess.

Tip #133

Never Build Shell Commands As Strings

One unquoted variable can delete the wrong directory. Use Bash arrays for argument lists, quote every expansion, and start scripts with set -euo pipefail.

Tip #134

Swap Offset Pagination for Keyset Pagination

On a large, changing table, LIMIT/OFFSET silently skips and repeats rows — keyset pagination pages by the last row’s key instead and stays consistent while the table mutates underneath you.

Tip #135

Audit AI-Generated Swift for Task.detached

See Task.detached in AI-generated Swift? Stop and check it — a detached task silently drops cancellation, priority, and actor isolation, and it’s almost always the wrong default.

Tip #136

Give Every Suppression an Expiry Date: ts-expect-error over ts-ignore

@ts-ignore stays silent forever; @ts-expect-error errors the moment the underlying bug is fixed, so type suppressions can’t rot in your codebase.

Tip #55

Comment The Why, Never The What

Delete the comments that restate your code and keep the one kind that never rots — why-comments that record intent for humans and AI assistants alike.

Tip #56

Never Leave Commented-Out Code

Delete dead code instead of commenting it out — git remembers every line, and your AI assistant reasons better over files with zero graveyards.

Tip #57

Keep a Rules File for Your Agent

Document your conventions once in a rules file — CLAUDE.md, AGENTS.md, .cursor/rules — and every AI session follows them without you retyping a thing.

Tip #58

Document Gotchas Inline, Where They Bite

The bug that cost you a day belongs as a comment right where the next person will hit it — not in a wiki nobody opens.

Tip #59

Docs Are Executable Context Now

Nobody read your docs — until your coding agent started reading every word. Why decision records are the highest-leverage context you can write, and how to keep one in 10 minutes.

Tip #60

The ADR Alternatives Section Is Gold

Record the options you rejected — pros, cons, and one line on why each lost — so your AI coding agent stops re-proposing ideas you already ruled out.

Tip #61

Onboard AI To A New Codebase Like A Human

Give your coding agent the same onboarding a new hire gets — a fixed five-step recon order plus one traced request — so its code matches your conventions.

Tip #62

Trace One Real Request End-To-End

The fastest way to understand any codebase: follow one real request from the entry point to the database and back — then hand that map to your AI agent.

Tip #63

Record the Local Dialect So AI Code Blends In

A 3-item conventions checklist — naming, patterns, house rules — that makes AI-generated code match your codebase instead of a generic default.

Tip #64

The SMIG Rule: Situation, Mechanism, Implication, Gotcha

A four-part rule for onboarding docs and code tours: skip what the code shows, spend your words on implications and gotchas.

Tip #65

Don’t Dump A File Tree And Call It Onboarding

A folder listing tells your coding agent what exists, not what to act on — replace the raw dump with five narrated moves that trace the real path through the system.

Tip #66

Tour Files: Persona-Targeted Code Walkthroughs

Turn onboarding into a guided route: .tour files anchor step-by-step walkthroughs to real files and lines, one tour per persona, played back inside the editor.

Tip #67

Verify Every Claim Against the Code

READMEs drift; the code doesn’t. How to onboard to any repo by tracing one real request end to end and verifying every claim against source.

Tip #68

Run Your Native Test Suite Under Sanitizers

Why ASan, UBSan, and TSan catch the C/C++ bugs a green line-coverage report ships — and how to wire them into the tests you already have.

Tip #69

Trap Every Crash Before You Fix It

Write the failing regression test before the fix, run it under a sanitizer, and the bug can never silently come back.

Tip #70

Don’t Trust In-Memory Database Tests

In-memory database fakes skip SQL translation — the query that passes in tests can still break in production. When and how to test against the real engine.

Tip #71

Assert All Four UI States

Most widget tests only check the happy render — here’s how to assert loading, empty, error, and success, with the mocking patterns that make each state reachable.

Tip #72

Never waitForTimeout — Wait for the Actual Network

Fixed sleeps make E2E tests slow AND flaky at the same time — replace every one with a wait on the real condition: a network response or an auto-retrying assertion.

Tip #73

Make a Flaky Test Fail Ten Times on Purpose

Reproduce a flaky test locally with --repeat-each=10 (and its pytest/Go equivalents) instead of burning a week of CI retries.

Tip #74

Inject Clocks, Random Seeds, and Temp Dirs

Flaky tests almost always read a hidden input — the real clock, a shared RNG, or a common temp dir. Inject all three and the same inputs give the same result on every run.

Tip #75

Slice Tests, Not a Full Boot

Why @SpringBootTest should be the exception, not the default — use @WebMvcTest and @DataJpaTest slices for faster feedback, and teach your AI assistant the same habit.

Tip #76

Shuffle Your Test Suite to Expose Order-Dependent Tests

Run your suite in random order to surface shared-state bugs on your machine — with the exact shuffle and seed flags for Vitest, Jest, pytest, Go, and RSpec.

Tip #77

A Test That Passes Against Empty Code Tests Nothing

If your suite stays green after you delete the production code, it asserts nothing. The five-minute audit, the placeholder smells, and the tools that automate the check.

Tip #78

Never Launch Real Coroutines in Tests

Why real dispatchers make async tests flake in CI — and how injected TestDispatchers, virtual time, and full Flow lifecycle tests make them deterministic.

Tip #79

One Fixture, Three Databases

Parametrize one pytest fixture across SQLite, PostgreSQL, and MySQL and every test that uses it runs once per backend — 3x coverage from one decorator.

Tip #80

Tag the Slow Tests, Get Your Inner Loop Back

Use pytest markers to split slow integration tests from fast unit tests, so every save runs in under a second while CI runs everything.

Tip #81

Always Mock With Autospec True

A plain Mock says yes to methods that don’t exist — patch with autospec=True so your tests fail when AI-generated code misuses a real API.

Tip #82

Async Mocks: Assert Awaited, Not Called

assert_called_once passes even when your code forgot the await — assert_awaited_once is the assertion that actually catches the bug.

Tip #83

Never Disable Warnings in Pytest

Deprecation warnings are early failure signals — why silencing pytest warnings trades a noisy test run today for a production break tomorrow, and how to filter with precision instead.

Tip #84

pytest --lf: Re-run Only What Broke

Shrink your debug loop from minutes to seconds with pytest --lf, -x, --ff, and --sw — and why it matters even more when an AI agent is doing the debugging.

Tip #85

100% Test Coverage Is a Red Flag, Not a Badge

Why chasing 100% coverage suite-wide wastes effort — target ~80% overall and push auth, payments, and data mutation toward 100% branch coverage instead.

Tip #86

Test Background Jobs for Idempotency and Retries

Queues deliver at-least-once, so every job will eventually run twice — here’s how to test that a duplicate run charges once, emails once, and recovers cleanly after a crash.

Tip #87

Flaky Tests Trace To Time, IO, Or Randomness

A test that passes sometimes almost always touches real time, real files, or real randomness — inject all three and the flake disappears.

Tip #88

Make Docs Executable: Doc Tests

Compile the examples in your docs as part of the test suite — Rust doc tests, Python doctest, and pytest patterns that make stale documentation fail CI.

Tip #89

Run Shell Scripts Through ShellCheck First

Lint AI-generated bash with ShellCheck before you test it — most shell bugs are static quoting and portability issues a linter catches in seconds.

Tip #90

Test Shell Scripts From a Path With Spaces

Run your shell scripts from a temp directory whose path contains a space — quoting and cwd bugs break loudly, for free, before they break in production.

Tip #91

Test Data Invariants at the Database Layer

Why app-layer validation isn’t enough — prove unique keys, foreign keys, and check constraints on a real, disposable database that matches production.

Tip #92

Fake the Network, Persistence, Clocks — and Permission State

You already fake the network and the database in tests — inject a fake for permission state too, so the denied branch stops shipping broken.

Tip #93

Prove The Bug Before You Fix It

Make your AI coding agent write a failing test that reproduces the bug before touching the fix — proof it exists, proof it’s gone, and a permanent guard.

Tip #94

Have a Separate Subagent Write the Reproduction Test

Split the reproduction test from the fix — a fresh subagent writes the failing test without seeing the fix, so shared blind spots can’t rubber-stamp a broken patch.

Tip #95

The Tautology Mock

When a mock returns the exact value the test asserts, the test passes with zero production code running — how to spot tautology mocks and replace them with real implementations or in-memory fakes.

Tip #96

Keep Tests DAMP, Not DRY

Why duplication is fine in tests: DAMP (Descriptive And Meaningful Phrases) beats DRY when a failing test has to explain itself.

Tip #97

Have the Agent Discover the Project’s Own Commands

Stop your AI agent from guessing pytest or npm test — make it read package.json, pyproject.toml, the Makefile, and CI to find the repo’s canonical commands.

Tip #98

Never Trust AI-Written Tests To Validate AI-Written Code

When one model writes both the code and its tests, they can share the same wrong assumption — a green suite proves consistency, not correctness. Here’s how to break the loop.

Tip #99

A Raw Owning Pointer in C++ Is a Review Blocker

Why a raw owning pointer should fail C++ code review — and the RAII checklist (unique_ptr, shared_ptr, span, rule of zero) to enforce on AI-generated code.

Tip

Check context.mounted After Every await

Why Flutter apps crash after slow async calls — and the one-line context.mounted guard that fixes use-after-dispose for good.

Tip

One Model Writes, a Different Model Reviews

Why the model that wrote your code can’t be trusted to review it — and how a two-model write/review loop with a human final call catches far more bugs.

Tip

Java Optional Is a Return Type Only

Optional was designed for one job — method return types. Why fields, parameters, and unchecked .get() fight the design, and the patterns to use instead.

Claude Code →

5 articles

Getting more out of Anthropic’s coding agent: context, plans, rules, and subagents.

Prompt Engineering →

5 articles

The structure, context, and examples that turn a vague prompt into reliable output.

Agentic Workflows →

25 articles

Tool-agnostic habits for getting dependable work out of any coding agent.

Tip #019

Write The Spec First

A short spec — what, why, constraints, tasks — stops your coding agent from guessing the details you didn’t mention.

Tip #020

Match Effort To Task Size

Running several agent sessions at once? Set each one’s reasoning effort to match its task so quick questions don’t wait behind deep ones.

Tip #021

Bash Or MCP

Don’t wire an MCP server for tools your agent can already reach with bash. A decision rule for when a server actually earns its keep.

Tip #137

Order CI Stages Cheapest and Most Likely to Fail First

Stop wasting ten minutes to catch a typo — order your CI so the cheapest, most likely-to-fail checks run first and fail fast.

Tip #138

Never Make a Flaky Test a Required Gate

A test that passes on retry is a defect, not a hiccup — quarantine it so the required gate keeps meaning something and your team never learns to just hit retry.

Tip #141

Plan the Funeral Before You Build

When you design anything new, ask how you’d delete it in three years — the answer forces clean interfaces, flags, and a small surface area that stays cheap to kill.

Tip #142

Hyrum’s Law: With Enough Users, Even Bugs Get Depended On

With enough users, every observable behavior of your system becomes an API someone depends on — which is why deprecation is a migration you run, not a memo you send.

Tip #143

Ask What Your Agent Didn’t Touch

Make every agent change end with a Changes / Didn’t-touch / Concerns summary so scope creep surfaces before your reviewer finds it.

Tip #146

Stop Your Agent Every 100 Lines to Test

Never let a coding agent write more than ~100 lines before you test — thin vertical slices keep bugs small, local, and cheap to fix.

Tip #147

Tell Your Agent to Note, Not Fix, Out-of-Scope Issues

One CLAUDE.md rule keeps a coding agent from bloating your pull request — when it spots an unrelated problem, it writes it down instead of fixing it.

Tip #148

Make Your First Task a Tracer Bullet

Your first task should be a tracer bullet: the thinnest slice through every layer that proves the path before you build wide.

Tip #149

If a Task Title Contains “And”, Split It

The word “and” in a task title usually hides two tasks. Split until each fits in ~5 files, ≤3 acceptance bullets, and one focused agent session.

Tip #150

The Bug in an AI PR Lives in the Callers

The bug in an AI-generated PR usually isn’t in the diff — it’s in the callers the diff never shows you. Review the blast radius, not just the changed lines.

Tip #151

Read the Tests Before the Code

In a pull request, read the tests first and the code second — the tests encode the author’s intent, and a risky path with no test is itself a finding.

Tip #152

Make Your AI List Its Assumptions Before It Writes Code

One instruction — 'list every assumption, then wait for my correction' — catches the misunderstanding while it still costs a sentence to fix instead of an afternoon of rework.

Tip #153

An Untested Rollback Is Not a Rollback

A rollback plan you have never exercised is a hope, not a plan. Prove the kill switch turns the feature off in seconds — before launch, not during the incident.

Tip #184

Add One Line to Every AI Research Prompt

Ask an AI a broad research question and it mirrors back what you already believe. One line forcing contrarian evidence and downside cases turns confirmation bias into a real decision brief.

Tip #185

When Structure Won’t Come, Skip the Outline

Forcing an outline before you have the spine of a piece builds a skeleton you write to, and it reads like it. Dump every fragment into one file and let structure emerge one paragraph at a time.

Tip #186

Ban AI From Simulating Specificity

AI cold email’s deadliest move is faking specificity. Ban the model from inventing anchors and require one real, verifiable observation per email, or flag the draft as not ready.

Tip #188

Force Ambiguous Choices Into a Strict 3-Line Brief

When an AI hits an ambiguous choice it hands back three hedged paragraphs that end in 'it depends.' Force a three-line decision brief — ELI10, Stakes, Recommendation — so it must commit to one pick.

Tip #189

Make the Stakes Concrete: Blast Radius, Reversibility, Time Cost

'Could cause issues' is not a risk assessment. When an agent surfaces a decision, make it name the blast radius, whether it’s reversible, and the time cost of getting it wrong.

Tip #190

Never Pass Your Conclusion to a Reviewer Agent

Hand an AI reviewer your conclusion and it validates your conclusion. Give it only the artifact and the contract, prompt it to find what is wrong, and it surfaces the issues you could not see.

Tip #191

Cap Adversarial Review at Three Cycles

Adversarial self-review catches blind spots, but looping it forever just stalls on the same findings. Cap it at three cycles; if real issues survive, that’s information about the artifact, not a reason to loop again.

Tip #192

Block Your AI’s First Edit

Agents edit files they never actually read. Block the first mutation until the agent lists importers, names affected public functions, and shows real data shapes. No facts, no edit.

Tip #193

Make Your AI Quote Your Instruction Verbatim

Agents quietly reinterpret your request and build a polished version of something you never asked for. One line — quote my instruction back word for word before touching code — surfaces the drift instantly.

Skills & MCP →

12 articles

Extending agents with skills and tools that actually fire when they should.

Tip #022

Let Claude Write Your Skills

Stop hand-writing SKILL.md files. Anthropic’s official skill-creator skill interviews you in plain English, then drafts, tests, and packages the skill for you.

Tip #023

Skill Triggers That Fire

Claude decides whether to use a skill from its name and description alone, never the full file — here’s how to write a description that actually fires.

Tip #024

Give Your Skill a Report Card

Numeric self-scores lie. Build a pass/fail evals file for your skill’s output, grade it with a separate clean-context agent, and loop until every check passes.

Tip #187

Index Your Docs, Don’t Dump Them

Stuffing every methodology doc into your agent’s context burns the budget and buries the one file the task needs. Build a lightweight index that maps task to doc, and load only what’s needed.

Tip #195

Adapting Someone Else’s Methodology? Rewrite It and Sign It

The moment you adapt someone’s AI rules or methodology into your workspace, you own it. Rewrite it in your own voice, strip the vendor branding, and sign it — a stale copy of someone else’s file rots.

Tip #196

Keep Skills Flat, Keep Helpers in Source

Nesting scripts and helpers inside each AI skill duplicates untested logic that quietly drifts. Keep skills as flat, self-contained methodology files; put deterministic code in your real, tested source tree.

Tip #197

Audit Your Skill Library Quarterly With Grep

AI skills rot like code, silently. Every quarter, grep your skill library for unreferenced files, front-matter drift, and stale tool names so your agent stops loading the wrong thing.

Tip #198

Past 700 Lines, Split the Skill

An 800-line AI skill file gets skimmed, not read. Past about 700 lines or when it covers multiple topics, split it via progressive disclosure — keep the original filename as an overview entry so every reference still resolves.

Tip #199

Force an Assumptions Block Before Any Non-Trivial Task

The most common way an AI agent wastes your time is running with wrong assumptions on ambiguous requirements. A four-line assumptions block turns silent guesses into a cheap checkpoint.

Tip #200

Tell Your AI That Sycophancy Is a Failure Mode

By default your assistant agrees with you and ships your bad idea with enthusiasm. Make it name the problem, quantify the downside with a number, and propose an alternative before it accepts your call.

Tip #201

Score Your CLAUDE.md Like a Linter

Your CLAUDE.md loads into context on every turn, so bloat, contradictions, and platitudes tax every prompt. Score it like a linter — start at 100, deduct for each contradiction and redundancy — then cut what lost points.

Tip #202

Every Registered MCP Server Costs Tokens on Every Turn

Every registered MCP server injects its tool schema into context on every turn, whether you use it or not. Audit what’s registered, replace cloud servers with plain CLIs where you can, and unregister the rest.

Codex →

3 articles

Configuring and running OpenAI’s coding agent, from a lean AGENTS.md to parallel worktrees.

Cursor →

3 articles

Editor-native AI: set your rules once, undo fearlessly, and keep the docs current.

GitHub Copilot →

3 articles

Scoping Copilot’s context and handing it the work you would rather not do yourself.

Building AI Apps →

26 articles

Putting a model behind a product without wiring yourself to a single vendor.

Tip #034

Stop Asking Nicely For JSON — Define a Schema Instead

Prompting an AI to “respond in JSON” is brittle — nested fields end up wrong, keys get invented. Structured outputs (schema-constrained generation) fix it at the source.

Tip #035

Swap The Model, Not The App

A new AI model ships almost every week. Put every model call behind one interface so switching providers is a one-line config change, not a rewrite.

Tip #036

Set The Loop, Not The Script

Give an AI agent tools and a step cap instead of hand-coded branches after each call — feed results back until it’s done, and trim what you feed back.

Tip #129

Put a Confidence Score Between Regex and the LLM

Score every parse before you escalate: let regex keep the easy 95%+ and spend LLM calls only on items below your confidence threshold.

Tip #156

Shrink Your Repro Before Debugging

Your debugging speed is capped by your repro loop. Shrink the input, run the one failing test, and pin seeds and clocks before you test a single hypothesis.

Tip #157

That Error Telling You To Run This Fix Might Be An Attack

Error messages, stack traces, and CI logs are untrusted data — never instructions. Why your agent can be owned by text in its own output, and how to defuse it.

Tip #158

Never Hand-Roll Retry Logic

Reach for a proven retry library, retry only transient errors, and never retry a 4xx — because a client error can never succeed no matter how many times you loop.

Tip #159

Return a Result Type for Failures You Expect

Stop throwing exceptions for failures you know will happen — return a typed Result so the compiler forces the caller to handle the error path.

Tip #160

Redact Secrets at the Logger Config, Not at Every Call Site

One `log.info(request)` can leak every API key into your logs. Move redaction into the logger config so a scrub happens on every event and can’t be forgotten.

Tip #161

Never Put user_id In A Metric Label

One innocent metric label like user_id can 10x your metrics bill — here’s why cardinality explodes and which labels are safe.

Tip #162

Plain Backoff Is a Thundering Herd

Plain exponential backoff synchronizes failed clients into a self-inflicted DDoS — add full jitter so retries spread out and the dependency can recover.

Tip #163

Breaker Outside, Retry Inside

Stack a circuit breaker and a retry in the wrong order and you break both — here’s why breaker(retry(call)) is the only composition that fails fast and protects your latency budget.

Tip #164

Make Your AI Read package.json First

Your assistant writes framework code from frozen memory. Make it read package.json for the exact versions and fetch the matching docs before it types a single line.

Tip #165

Make Your AI Say UNVERIFIED

A confident hallucinated API signature reads exactly like a real one and costs you an hour — force your AI to cite official docs or label the line UNVERIFIED.

Tip #172

Randomize What You Do Not Guarantee

Your API’s bugs become someone’s features. With enough users every observable behavior gets depended on. Deliberately vary what you never promised so callers cannot silently couple to it.

Tip #173

Ship a Stable, Machine-Readable Error Code

Your error messages are a secret API. The moment callers regex your prose, you can never reword it. Ship a stable machine-readable code they switch on, keep the human message free to change, and flag which errors are retry-safe.

Tip #174

More Services Than Engineers Is a Smell

Microservices earn their keep when teams own services independently at scale. When your deployable artifacts outnumber your engineers, you pay the distributed-systems tax every day and never see the benefit. Match services to team size, not to hype.

Tip #175

Delete It. Did Things Get Simpler?

A module whose interface is nearly as complex as its implementation hides no complexity — it just adds a hop. Run the delete-and-inline test: if folding it back in makes the system simpler, it was a shallow passthrough. Prefer deep modules.

Tip #176

Any Bash Script Past 200 Lines Belongs in Python

Bash lacks data structures, real error handling, and testability. Once a script passes ~200 lines with conditionals, rewrite it in Python or another real language — you get shorter code, real error handling, and a test suite instead of crossed fingers.

Tip #177

Use a Postgres Table Before You Reach for a Queue

Teams reach for SQS or RabbitMQ by reflex, then operate a whole new system for low-volume work. If you already run Postgres and your producers and consumers share a deployment, a plain table is a fine queue — and you can graduate later if you truly outgrow it.

Tip #178

Score Every Tool by Its 12-Month Cost

A tool’s landing page sells the first week. The real bill arrives in month twelve as on-call pages, hiring drag, licensing, and lock-in. Score every choice by its 12-month cost.

Tip #179

Make Your Rules File a Map, Not a Library

Every line in an always-on rules file is a tax paid on every turn. Stuff it with detail and you drown the signal. Keep a small durable core, then point to files the agent loads only when a task needs them.

Tip #180

Prune Your MCP Servers: Every Tool Schema Is Always-On Cost

Each connected tool’s schema is loaded on every turn, and too many tools degrade selection accuracy, not just token count. Expose the few tools a task needs and cut the rest.

Tip #181

Grep AI-Written Data Fetching for the N+1 Query

AI loves to put a query inside a for-loop: fetch a list, then hit the database once per row. That’s the classic N+1, and it scales terribly. Grep for it before you merge and replace it with a single join.

Tip #182

Overusing React.memo and useMemo Is a Red Flag

useMemo everywhere is not making your app faster. Memoizing every value and component adds complexity and comparison cost. Profile first, then memoize only the bottleneck the numbers prove matters.

Tip

Regex First, Model for the Edges

For consistent-format text, regex handles ~95–98% of extractions deterministically — route only the low-confidence leftovers to an LLM and cut your bill dramatically.

Building AI Agents →

8 articles

The design decisions that separate agents which work from agents which merely demo well.

Tip #037

Agent or Workflow? Ask Before You Build

Not every automation needs an AI agent. Learn how to tell a predictable process from a genuinely unpredictable one, and build the cheaper, more reliable option.

Tip #038

Describe Your Tools Like You’re Training Someone New

An agent only picks the right tool if the description tells it exactly what the tool does and when to use it. Here’s how to write descriptions and docstrings that actually work.

Tip #039

One Agent, One Job: Why Specialist Crews Beat Generalists

One agent trying to research, judge risk, and write the report isn’t one job — it’s three. Split bloated single-agent workflows into a crew of specialists.

Tip #144

Force Three Genuinely Different Approaches

Ask an AI for a plan and it converges on the first idea, then pads it with strawmen — force at least three genuinely different approaches to widen the option space before you narrow.

Tip #145

Never Accept Your AI’s First Plan Without the Loser

A recommendation with no rejected alternative is a default, not a decision. Force your agent to diverge, then converge — and always demand the runner-up and why it lost.

Tip #154

Log a Hash of the Messages Array Before Every Call

Your agent looks broken but the model is fine — your wrapper is rewriting history between calls. Hash the messages array before each request and the mutation shows up in one log line.

Tip #155

Count Your Model Calls Per Turn

One user turn can fire five model calls when a framework silently re-asks on a bad answer — here’s how to count the real number and bound the loop.

Tip #183

Don’t Ask AI to Research. Ask It Five Questions

A vague research this topic prompt gives a shallow answer. Break the topic into three to five sub-questions, fan them out to parallel subagents that read real sources, then synthesize one cited report.

RAG & Vector DBs →

3 articles

Retrieval that finds the right chunk — and refuses to answer when it doesn’t.

Fine-Tuning →

3 articles

When to adapt a model instead of prompting it, and how to do it without burning a GPU budget.

Local LLMs →

3 articles

Running open models on your own hardware: private, offline, and free.

LLM Evals & Safety →

12 articles

Measuring whether your AI actually works, and containing the damage when it doesn’t.

Tip #049

Guardrails Are Two Checkpoints, Not One

Most AI guardrail setups only check one side of the conversation. Here’s why you need an input check and an output check, and how to build both.

Tip #050

A Prompt Will Break, So Limit the Blast Radius

You can’t filter out every prompt injection. Here’s how to limit what a hijacked AI agent can actually do with least-privilege tools and human approval.

Tip #051

Your A.I. Judge Has Favorites, Check For Them

LLM-as-judge scales evaluation past manual review, but it inherits biases. Here’s how to run a positional-swap test before you trust the score.

Tip #139

Run One Unit Before You Scale

Before you run 10,000 AI calls, run one. Measure the real cost, then scale — with the exact per-unit math and the 50% batch discount.

Tip #140

Put a Hard Per-Job Cap on Every Automated AI Call

A bug in an automated AI job should produce a bounded bill, not an unbounded one — cap tokens, items, and time per call, then put a budget alarm on the account.

Tip #166

Secrets Deleted in a Later Docker Layer Still Live in History

A secret copied or used in a Dockerfile RUN step is baked into that layer forever — deleting it later doesn’t erase it, and anyone can extract it with one command. Use build secrets instead.

Tip #167

Replace Long-Lived AWS Keys With OIDC

Static AWS access keys in CI never expire, so a single leak works until someone notices. Swap them for OIDC role assumption and get short-lived credentials with nothing stored to steal.

Tip #168

Audit Postinstall Scripts on Any Package

npm install can run a stranger’s shell script the moment you install. Audit postinstall and prepare hooks and flag any that reach the network or shell, so you catch supply-chain code execution before it runs.

Tip #169

The System Prompt Is Not a Security Boundary, Code Is

A do-not-reveal instruction in your system prompt stops nothing, because a motivated user can talk the model out of any instruction. Enforce security with deterministic code that brackets the model call: an input screen before, an output scrub after.

Tip #170

Your Agent Config Is an Attack Surface

Instruction files, settings, and MCP server configs steer your coding agent, so a hidden instruction or a leaked key in there is a real breach path. Scan them like code for wildcard permissions, hardcoded secrets, and injected instructions.

Tip #171

When Your Pipeline Reads Uploads, the Content Is the Attacker

When your AI pipeline ingests uploads or scraped pages, the content itself is the attacker. Treat untrusted content as data, never instructions: delimit it before the model sees it, and never let it flow unescaped into a shell, SQL, or a file path.

Tip #194

Give Each Severity Level a Confidence Floor

When every AI finding is flagged critical, people stop reading. Gate each severity on a confidence floor and downgrade a tier under uncertainty, so a critical actually means stop and fix.

Model Comparisons →

3 articles

Compare models on work that resembles yours, then route each task to the right one.

Open Source vs Closed Source →

6 articles

Open-weight vs proprietary models: what open really means, the true cost of a token, and when each one wins.