After a short break (https://no-kill-switch.ghost.io/unobvious-consequences-of-moving-the-bottleneck/), it’s time to go forth with my “I got myself a magic lamp” series. Without further ado, let’s (finally) get into some recommendations - on how to work with agents (effectively).

I’ll use Anthropic/Claude (Code) lingo/concepts, but TBH it looks very similar in Codex, Cursor, or Open Code (there are equivalents/mirror alternatives of techniques/features mentioned).


Fundamentals

It may sound controversial, but I always use English when working with agents (even in a non-English work environment, among my natives whose mother tongue ain’t English). That may sound unnecessary; LLMs are awesome at translation (and they will get better and better), but the issue here isn't about LLMs’ deficiencies.

The truth is that translation is (and always will be) lossy. Vocabularies aren't fully symmetrical, professional lingo is English-based, and some terms have no direct equivalents. That means that you need more effort (& tokens) to proactively address & smoothen potential misunderstandings and imprecisions - which is simply a waste of time (& money).


Anatomy of a prompt matters. A lot.

The idea is to describe the “intent” - the goal (the expected outcome) - rather than activities for the LLM to perform. The better the model “understands” the context, the more likely it is to succeed.

“A problem well stated is a problem half solved.” Charles Kettering

That’s why a good prompt should include (typically):

  1. context (parts of the environment that matter)
  2. goal (and its validation criteria)
  3. “why” (the rationale behind the goal)
  4. assumptions (axioms, invariants)
  5. constraints (what’s not allowed, borderlines)
  6. a clear “ask” (what you expect from the agent)

Let the agent come up with the majority of the “how”, while you focus on “what” and “why”. To support that, embrace a declarative approach instead of an imperative one (aka, don’t micromanage your agent(s)).


Here are some examples of great thought patterns that work really well for prompting:

  • (input) Facts + Assumptions + Constraints + Unknowns + Goal Exit Criteria + Ask
  • (input) Context -> Goal -> Constraints -> Anti-Goals
  • (input) State -> Delta -> Attempted -> Blocker
  • (input) Invariants + Variables -> Optimization Metric
  • (process) Decompose -> Resolve Dependencies -> Synthesize
  • (process) Step Back -> Identify Principles -> Apply Them
  • (process) Diverge -> Evaluate -> Converge
  • (process) Hypotheses -> Discriminating Evidence -> Tests
  • (output) Diagnosis -> Guiding Policy -> Coherent Actions
  • (output) Before -> After -> Bridge
  • (output) Point -> Reason -> Example -> Point
  • (output) Context -> Decision Drivers -> Options Considered -> Decision -> Consequences

Input refers to structures used to organize a prompt (input information). Process refers to suggestions for how the agent should solve the problem (structures the reasoning). Output refers to requirements for the agent regarding the expected response.


Perfectionism in prompting is a direct route to disaster. Build your prompt incrementally. Practice meta-prompting. Start by exploring, probing, ideating (with Claude). Don’t write specs - ask the agent to do that, based on sources provided and your asks.


Make sure that as much as possible of the reasoning and design/knowledge work happens WITHIN the Claude client (so agents are aware of it). If you paste only a final result (e.g., a ready-to-use data model created/documented in some other tool) without comments or clarification of your design choices and the principles you followed, the agents’ understanding will be shallow, and they’ll make stupid decisions. Claude Code is not a code-writing tool; it’s a workspace for building.

Working asynchronously

Agent work is mostly asynchronous. You give them instructions (preferably more declarative than imperative), they clarify the details, ask questions, confirm the plan, and proceed with the execution. This phase can take some time (from minutes to (sic!) days), giving you space to work ahead - on some future prompts, checks, hypotheses, etc. But you never know how much time it will take the agent to complete the task. I mean - yes, you should ask (I ask agents for estimates all the time!) - but the answers are not always accurate (some things never change …).

What is more, the agent may run into a problem, a knowledge gap, or an unexpected situation, which usually ends with a question or a confirmation request. That’s why notifications are so useful (when it’s finished a task, when it has a question, when it’s hit a limit, when it’s asking for permission).

Set up whichever ones work best for you. Options include:


A long-running session launched on macOS will be interrupted if the computer goes to sleep. So it’s a good idea to use caffeinate and lock your computer when you step away. My preferred switches are “-ims” (the display goes off, but the computer doesn’t).


Find yourself a ... place to write prompts “in advance.” Ideally, it should support threading and history tracking. That helps you recreate the “intent”. In my case, I use Obsidian (https://obsidian.md/), and it works like a charm.The main motivation is (of course) to avoid wasting time. While agents are working on something, you already have prompts “in advance” (ready to go). It doesn’t mean you should aim for full-blown, super long and detailed mothers-of-all-prompts. Quite the contrary:

  • Typically, I start by exploring, clarifying direction, asking questions, and probing for opinions/recommendations.
  • I systematically tighten the discussion by parking side threads, solidifying decisions, and noting questions for later.
  • The plan is built gradually, and it’s a joint effort - Claude’s and mine.

It’s a team sport

It’s ABSOLUTELY crucial not to rely on a single model or effort level (or even switch between them manually), but to create agent personas, describe their roles/profiles, and specify which model each profile uses. For example, I have the following profiles on my Claude Code team:

  • architect
  • auditor
  • checkup-lead
  • chore
  • explore
  • gate-runner
  • implementer
  • reviewer
  • scout
  • security-auditor

Here’s my description of the implementer:

---
name: implementer
description: Implement ONE well-specified change (a plan section or a precise instruction) across server/web/e2e following the repo's conventions, run the gates for what it touched, report the diff summary and gate results. Does not plan, does not commit. Use once a plan exists.
model: sonnet
effort: high
tools: Read, Edit, Write, Grep, Glob, Bash, Skill, Agent(scout, gate-runner, chore)
maxTurns: 150
color: green
---

You implement exactly one specified change. The plan or instruction you receive is the scope: do not widen it, do not narrow it, do not redesign it.

## Before editing

- Read the repository's `CLAUDE.md` and every `.claude/docs/*` file the plan names. They define the feature template, the persistence rules, the authz order, the testing harness and the i18n rules — follow them literally.
- If the instruction is ambiguous in a way that changes the code, STOP and report the question with your recommended answer. Never guess a design decision.
- Use `scout` for searches spanning many files; keep your own reads targeted.

## While editing

- Same-commit rule: a spec change ships with the regenerated client; a route ships with its tests, its audit event, its docs line; a migration is never edited after it lands; an e2e test ships with its scenario file and coverage-map line; every UI string has both languages.
- Zero-findings gates: detekt/eslint/knip must stay at zero; fix the code first, extend a config only for a deliberate idiom with its comment.
- Run Gradle/npm from the repo root with absolute paths (the shell cwd drifts). Set `DOCKER_HOST` when the repo's docs say the tests need it.
- Delegate purely mechanical sub-steps (regenerate, bump, changelog line) to `chore`.
- Never `git commit`, `push`, `reset` or `checkout` — the main session commits.
- Never print a secret; never log a full URL.

## Finish

Hand the gates for what you touched to `gate-runner` (or run the narrow ones yourself if that is faster), then report:

1. Outcome in one line (done / done with caveats / blocked on a question).
2. Files changed, one line each, what and why.
3. Gate results as a table (gate, status, key numbers).
4. Anything you deliberately left out and why.

Why? First and foremost: significant cost savings (tokens). You really don’t need Fable to stuff Java code into a simple HTTP controller file. Second, a hierarchy like this, with WELL-defined responsibilities, does a fantastic job of orchestrating sub-agents and parallelizing work so you don’t have to think about it. It works like a micro-team, which further explains why more than one developer shouldn’t work on the same thing.

Backlog as a key abstraction

When working with Claude (or even on the side), TONS of ideas come to mind (mine, but Claude’s too …) about what’s worth building, confirming, checking, and so on. There’s no need to ignore them, but there’s also no need to jump on all of them at once - although CC doesn’t have the slightest problem with interruptions …

From what I’ve learned, it’s worth introducing a ... backlog as an abstraction in the conversation with Claude Code. In other words, have it keep those tasks in “memory” (persisted in an MD file committed to the repo) and manage them like a Kanban board.

Why not keep it in a full-blown task tracker tool (like Jira/Linear/ClickUp)? Because usually these are small tasks that take 15–60 minutes max. Using a heavy app adds too much ceremony and over-complicates things. My backlog with Claude (which a simple, Git-tracked, markdown file managed by Claude) has statuses like these:

  • new — new, not yet analyzed
  • todo — okay, I’ve approved that we’ll do it
  • parked — waiting on the sidelines; not under consideration, but not forgotten
  • blocked — we want to do it ASAP, but something is blocking it
  • next — marked to be done next (there can be more than one)

HUD (Head-Up Display)

Agentic coding may be mostly about setting up textual instructions and success criteria for your agents. Still, there are some “valves” / ”gauges” you should always have in front of your eyes to do that effectively. Some of them land in a so-called status line; some may appear in what Anthropic calls “mods” (widgets that can be used in both CLI and thick client).

Starting with a status line - make sure you don’t run on defaults, but deliberately set one for yourself. The most important information:

  • the model you’re using (router/starter/dispatcher)
  • effort level
  • percentage of context window used
  • percentage of usage limits used

Speaking of mods, they are a great addition to what the “vanilla” client offers. The good news is you can create them by hand, but you don’t have to; Claude can do that on his own, and he excels at it. My tried-and-true set of three mods (https://github.com/liveweird/claude-mods) is:

  • progress-bar — shows which step of the plan we’re on, how many steps are left, how long we’ve been working (overall and on the current step), and how much time remains (for the current step and the whole thing)
  • backlog — shows the current state of the backlog (counts), so you can immediately see whether there’s anything in “next” or “blocked”
  • turn-limits — when an agent launches sub-agents, they get a pool of “turns” (iterations); when they use them up, they drop the task (midway through) and die. Then the supervising agent must assess the state (of the task) and launch another agent to finish it. The turn limit is controlled by the maxTurns variable, which can be set at the agent profile level. If it’s too low, the agent gets interrupted too often, so everything takes longer; if it’s too high, the agent can get “stuck in a loop.” This mod shows me how often (as a percentage) agents of a given type hit the limit. I can use that to tune the parameter.

OK, I think it’s time to stop for now. I’ll follow with more recommendations in the next post. Some topics still to be covered:

  • tips for teamwork
  • role of principles/tenets (for agents)
  • how to properly build a car with Claude Code
  • context management
  • prompting anti-patterns
  • and much more :) so stay tuned
Share this post