TL;DR

AI agents (Claude Code, Cursor, GitHub Copilot, Devin) work fundamentally differently from chatbots. Instead of crafting a single perfect prompt, you write persistent rules files, decompose tasks into clear steps, and build in verification checkpoints. Think of it as managing a capable junior developer rather than querying a search engine.

Why it matters

In 2026, 85% of developers use AI coding tools (JetBrains survey). But most people interact with AI agents the same way they'd chat with ChatGPT — typing a quick request and hoping for the best. This works for simple tasks but falls apart for anything complex.

Agentic prompting is a different skill. An AI agent doesn't just answer your question — it reads your codebase, runs commands, edits files, executes tests, and iterates until the task is done. Getting good results means understanding how agents think and giving them the right kind of instructions.

Chat prompting vs agentic prompting

Aspect Chat prompting Agentic prompting
Interaction You guide every turn Agent works autonomously
Context Your prompt text Entire codebase + rules files + tool outputs
Duration Seconds per response Minutes to hours per task
Feedback loop You read and respond Agent runs tests, checks output, iterates
Scope Single question/task Multi-file, multi-step workflows
Error handling You catch mistakes Agent should catch its own mistakes (if instructed)

Key insight: In chat, you're the driver. With agents, you're the manager. You define what needs to happen and how to verify it worked — then let the agent figure out the implementation details.

Anatomy of good agent instructions

Good agent instructions have four parts:

1. Objective — what, not how

State what you want to achieve, not how to achieve it. Agents are better at figuring out implementation when you give them clear goals.

Weak: "Open the file src/auth/middleware.ts, find the function called validateToken, add a try-catch block around the jwt.verify call, and return a 401 error with message 'Invalid token' if it fails."

Strong: "The validateToken middleware crashes the server when it receives an expired JWT. Fix it so expired tokens return a 401 response instead of crashing."

The weak prompt micromanages. The strong prompt explains the problem and desired outcome — the agent can figure out the best fix (which might not be a try-catch at all).

2. Context — what the agent needs to know

Agents can read your codebase, but they don't know your business logic, preferences, or constraints unless you tell them.

Helpful context:

  • "We use Zod for validation, not Joi"
  • "This is a Next.js 15 app with App Router"
  • "The auth system uses JWTs stored in httpOnly cookies"
  • "Tests are in __tests__/ directories next to the source files"

3. Constraints — what not to do

Tell the agent about guardrails:

  • "Don't modify the database schema"
  • "Keep backward compatibility with the v2 API"
  • "Don't install new dependencies without asking first"
  • "Don't change the public API of exported functions"

4. Verification — how to check success

This is the part most people skip — and it's the most important for agentic workflows. Tell the agent how to verify its own work:

  • "Run pnpm test after making changes"
  • "Verify the build passes with pnpm build"
  • "Check that the endpoint returns 200 for valid tokens and 401 for expired ones"
  • "Make sure TypeScript compiles with no errors"

Rules files: persistent agent instructions

Instead of repeating instructions every time, you can create rules files that agents read automatically. These are like onboarding docs for your AI teammate.

CLAUDE.md (Claude Code)

# CLAUDE.md

## Project
Next.js 15 app with App Router, TypeScript, Tailwind CSS.

## Conventions
- Use Zod for validation
- Tests go in `__tests__/` next to source files
- Use `pnpm`, not `npm`
- Commit messages follow conventional commits format

## Don't
- Don't modify database migrations without asking
- Don't install new dependencies without asking
- Don't use `any` type in TypeScript

Claude Code reads CLAUDE.md from your project root (and parent directories) automatically. You can also add path-specific rules in .claude/rules/ for different parts of your codebase.

.cursorrules (Cursor)

Same concept, different file. Cursor reads .cursorrules from your project root.

AGENTS.md (emerging standard)

Over 40,000 open-source projects now use AGENTS.md as a cross-tool standard. OpenAI Codex, Cursor, and Gemini CLI all support it.

What makes good rules files?

  • Short and scannable — bullet points, not paragraphs
  • Project-specific — don't restate general knowledge ("use meaningful variable names")
  • Actionable — "Use Zod for validation" beats "Consider input validation"
  • Maintained — update them as your project evolves
  • Testable constraints — "Run pnpm lint before committing" is verifiable; "write clean code" is not

Task decomposition

Complex tasks need to be broken into steps. You can do this yourself in the prompt, or instruct the agent to do it.

You decompose:

Implement user profile editing:
1. Add a PATCH /api/users/:id endpoint that accepts { name, bio, avatar }
2. Add Zod validation for the request body
3. Update the User model if needed
4. Add tests for valid updates, partial updates, and invalid data
5. Run the test suite to verify nothing else broke

Agent decomposes:

Implement user profile editing. Users should be able to update their
name, bio, and avatar image. Follow the existing patterns in the
codebase for API endpoints, validation, and testing. Run tests when done.

Both work. Decomposing yourself gives more control. Letting the agent decompose works well when you trust it to follow existing patterns.

Rule of thumb: Decompose yourself when the task involves business decisions. Let the agent decompose when it's purely technical implementation.

Verification patterns

The difference between a good agent interaction and a frustrating one is usually verification. Build checks into your workflow:

Type 1: Automated verification

Tell the agent to run checks after changes:

  • "Run pnpm typecheck after each file change"
  • "Run the relevant test file after modifying a module"
  • "Run pnpm build at the end to verify everything compiles"

Type 2: Self-review

Ask the agent to review its own work:

  • "Before committing, review your changes and check for: leftover debug code, hardcoded values, missing error handling"
  • "Verify your changes don't break the existing API contract"

Type 3: Incremental validation

For large tasks, verify at each step rather than only at the end:

  • "After adding the endpoint, run its tests before moving to the frontend"
  • "Verify the database migration runs cleanly before writing the model code"

Permission boundaries

Agents can do powerful things — which means you need clear boundaries:

What to allow freely

  • Reading files
  • Running tests and linters
  • Editing source code
  • Creating new files

What to gate behind confirmation

  • Installing or removing dependencies
  • Modifying CI/CD configuration
  • Changing database schemas
  • Pushing to remote repositories
  • Deleting files or branches

Most agent tools support permission modes. Claude Code, for instance, lets you choose between permissive and restricted modes, and you can configure auto-approval for specific operations.

Real examples

Example 1: Bug fix

The checkout page crashes when the cart is empty. The error is
"Cannot read properties of undefined (reading 'map')" in
CartSummary.tsx.

Fix the crash so an empty cart shows a friendly "Your cart is empty"
message instead. Run the existing tests after fixing.

Why this works: Clear symptom, specific file, desired outcome, verification step.

Example 2: New feature

Add a "Copy to clipboard" button to all code blocks in our blog posts.
Follow the existing button styles in components/ui/Button.tsx.
Show a brief "Copied!" tooltip after clicking.
The blog uses MDX with our custom CodeBlock component in
components/blog/CodeBlock.tsx.

Why this works: Clear feature, points to existing patterns, specifies UX behaviour, identifies the right file.

Example 3: Refactoring

Migrate the auth module from callbacks to async/await.
Files: src/auth/*.ts

Constraints:
- Don't change the public API (exported function signatures stay the same)
- Don't modify tests yet (they should still pass after migration)
- Run pnpm test -- --testPathPattern=auth after changes

Why this works: Clear scope, explicit constraints, built-in verification.

Common mistakes

  • Micromanaging implementation — telling the agent exactly which lines to change instead of describing the goal
  • No verification step — the agent makes changes but you have no way to know if they're correct
  • Forgetting context — assuming the agent knows your business logic, conventions, or preferences
  • One massive prompt — trying to do 10 things at once instead of breaking into focused tasks
  • Not using rules files — repeating the same instructions every session instead of writing them once
  • Treating agents like chatbots — having a back-and-forth conversation instead of giving clear, complete instructions upfront

What's next?