AI EngineeringZero to ProductionHome·About·Contact
AI-Assisted Development · Chapter V2

AI-Powered Development with Cursor AI

Cursor is an AI-first code editor — a VS Code fork rebuilt around the model living inside the editor rather than bolted on. This chapter tours its core surfaces (Tab, inline edit, chat, agent), the context system that makes it accurate, and how to keep control as its autonomy climbs.

⏱️ ~1.5 hours🧪 1 labs🎯 Beginner→Tech-lead

Learning objectives

  • Set up Cursor and use its core surfaces (Tab, Cmd-K, chat, agent).
  • Feed the model the right context for good edits.
  • Use rules and the agent for multi-file changes safely.
  • Adopt Cursor across a team with governance.
▶ Runnable companionEvery code block in this lesson is also a standalone file under code/ad2-cursor/ in the course, with a README on how to run it. Read here, run there — no need to copy-paste.

1 · What Cursor is essential

Cursor is a VS Code fork rebuilt around the model. The AI isn't a side panel — it edits your files, reads your repo, and runs multi-step changes. Four surfaces: Tab (autocomplete), Cmd-K (inline edit), chat (ask about the codebase), and the agent (multi-file tasks).

2 · The four surfaces essential

SurfaceTriggerUse for
Tabtypingnext-edit prediction, boilerplate
Cmd-Kselect + Cmd-Kedit this selection/function
ChatCmd-Lunderstand code, plan a change
Agentchat + agent modemulti-file feature, run + fix

3 · Intermediate — context is everything intermediate

Cursor is only as good as the context you give it. Use @file, @folder, @docs, and @web to point it at exactly what matters. Vague prompt + no context = generic code; precise prompt + the right files = a correct edit.

Example code for learning — review, test, and adapt it before running against real or production systems. Commands can create, change, or delete resources. See the Terms & Disclaimer.
Python · score how well-specified a Cursor request is (runs)
prompt_quality.pydef prompt_quality(text, at_refs, has_acceptance):
    score = 0
    score += 2 if len(text.split()) >= 8 else 0     # specific ask
    score += min(len(at_refs), 3)                   # @file/@folder context
    score += 1 if has_acceptance else 0             # "it should ..." criteria
    verdict = "good" if score >= 4 else "too vague — add context/criteria"
    return score, verdict

print(prompt_quality("add pagination to the users endpoint",
                     at_refs=["@users.py", "@schema.sql"], has_acceptance=True))
print(prompt_quality("fix it", at_refs=[], has_acceptance=False))
(6, 'good')
(0, 'too vague — add context/criteria')
▶ How this works

This little program scores how well you asked Cursor for something. The idea: the AI can only give a good edit if your request is specific and points at the right files. So this function turns that intuition into a number you can check before you hit send.

  1. def prompt_quality(text, at_refs, has_acceptance): takes three inputs — the words of your request (text), a list of @file/@folder references you attached (at_refs), and whether you stated success criteria (has_acceptance).
  2. score += 2 if len(text.split()) >= 8 else 0text.split() breaks the sentence into words and len(...) counts them. A request with 8+ words earns 2 points for being specific; a two-word ask like "fix it" earns 0.
  3. score += min(len(at_refs), 3) adds one point per attached file, but caps at 3 — pointing the AI at the exact files is the biggest win, so it's rewarded most.
  4. score += 1 if has_acceptance else 0 gives a point for telling the AI what "done" looks like (an acceptance criterion, e.g. "it should return 404 on unknown id").
  5. verdict = "good" if score >= 4 else "too vague ..." — 4 or more means the request is worth sending; below that, add context or criteria first. The function hands back both the score and the verdict.

What the output means: The first call (a clear ask + two @ files + criteria) scores (6, 'good'). The second call, just "fix it" with nothing attached, scores (0, 'too vague — add context/criteria') — exactly the kind of prompt that makes the AI guess.

Try this: Take a real request you'd type into Cursor and run it through this function. If it scores below 4, add an @file and a one-line "it should…" until it reaches good — that habit alone dramatically improves the edits you get back.

4 · Advanced — rules & the agent advanced

.cursor/rules (project rules) inject standing instructions into every request — your conventions, stack, do/don'ts. The agent then executes multi-file tasks: it plans, edits across files, runs commands, and fixes its own errors. Review its diff before accepting.

.cursor/rules/conventions.mdc · project rules
conventions.mdc---
description: Team conventions Cursor must follow
alwaysApply: true
---
- Python: type hints on all public functions; use pytest, not unittest.
- Never edit files under `generated/` or `migrations/`.
- Prefer stdlib; ask before adding a dependency.
- All new endpoints need a test in tests/ and an entry in the OpenAPI spec.
▶ How this works

This is a Cursor rules file — a small config you commit into your project at .cursor/rules/. Whatever you put here gets quietly added to every request you make to Cursor, so the AI follows your team's conventions without you re-typing them each time.

  1. The block between the two --- lines is called front matter — settings, not instructions. description: is a human label, and alwaysApply: true means "attach this to every request in the project" (rather than only when relevant).
  2. Everything below the front matter is the actual guidance, written as plain-English bullet points. Python: type hints on all public functions; use pytest, not unittest. tells the AI which style and test framework you expect — so its generated code matches your codebase.
  3. Never edit files under `generated/` or `migrations/`. is a guardrail: these folders are produced by tools, so hand-edits (even the AI's) would be overwritten or break things.
  4. Prefer stdlib; ask before adding a dependency. keeps the AI from silently pulling in new packages — a common way AI edits bloat a project.
  5. The last rule ties new endpoints to a test and an OpenAPI entry, so the AI's work stays complete and reviewable, not just "code that runs".

What the output means: This file produces no output on its own — it's not run like a program. Instead Cursor reads it and silently prepends these rules to your prompts, so the AI's answers already respect them.

Try this: Create .cursor/rules/conventions.mdc in a small project, add one rule you care about (e.g. "always add a docstring"), then ask Cursor to write a function and watch it follow the rule without being reminded. Committing this file means every teammate's Cursor behaves the same way.

5 · Professional — review the diff, always professional

The agent can touch many files fast — that's the power and the risk. Treat every agent run like a PR from a junior dev: read the diff, run the tests, don't accept blindly. Speed without review is how AI edits introduce subtle bugs.

6 · Tech-lead — rolling Cursor out to a team tech-lead

A lead standardizes the setup: shared .cursor/rules in the repo, a model policy (which models, privacy mode for sensitive code), a norm that agent diffs go through review, and guidance on when to use Tab vs agent. This turns individual speedups into a consistent team gain without a quality regression.

Rules in the repo = consistent AI across the teamCommitting .cursor/rules means every engineer's Cursor follows the same conventions — the AI becomes part of your codebase's standards, not a per-person wildcard. This is the single highest-leverage team setup step.

Exercise AD2.1 — A well-specified agent task

Context: A well-specified agent task combines the levers you just learned: a rules file, precise @ context, and explicit acceptance criteria — then reviewing the diff before accepting. This is the full Cursor loop in one exercise.

Your task: Write a .cursor/rules file for a small project, craft an agent request with proper @ context and acceptance criteria, score it, run it, and review the diff.

Requirements:

  • Write a .cursor/rules file encoding the project's conventions
  • Craft the agent request with proper @file/@folder/@symbol context and explicit acceptance criteria
  • Score the prompt with prompt_quality.py and aim for ≥4
  • Run it, then review the full diff before accepting

💡 Hint: The score rewards attached context most heavily — point the model at the exact relevant files before you tune the wording.

🪜 Practice ladder beginner → industry

Six graded exercises, easy to real-world. Try each before opening its solution.

Exercise 1 · Match the surface to the taskBeginner

Context: Cursor exposes four surfaces and the core skill is matching the surface to the task so verification stays cheap. Use the lightest surface that fits.

Your task: For each task pick the right Cursor surface: rename a variable everywhere, ask ‘how does auth work here’, finish a line, implement a feature across files.

Requirements:

  • Finish a line → tab/autocomplete (lowest friction, instant verify)
  • Rename everywhere → inline edit (or agent for cross-file) — a scoped mechanical change
  • ‘How does auth work?’ → chat (a question, no edit)
  • Feature across files → agent (multi-file, needs planning and tool use)
  • State the principle: use the lightest surface that fits so verification stays cheap

💡 Hint: Match surface to task by how bounded the change is and how fast you can check it.

Show solution
TaskSurface
Finish a lineTab / autocomplete — lowest friction, instant verify
Rename a variable everywhereInline edit (or agent for cross-file) — a scoped mechanical change
‘How does auth work here?’Chat — a question, no edit needed
Implement a feature across filesAgent — multi-file, needs planning & tool use

Matching surface to task is the core Cursor skill: use the lightest surface that fits so verification stays cheap.

Exercise 2 · Context is everythingIntermediate

Context: The model only knows what's in its context window, so the same prompt with the right files attached goes from guessing to grounded. Adding context is the highest-leverage move in Cursor.

Your task: Explain why the same prompt gives better results with the right context, list the concrete ways to add context in Cursor, and give a worked example.

Requirements:

  • Explain that the model is limited to its context window — right files turn guessing into grounding
  • List the context mechanisms (@file/@folder, @symbol, the open file, pasted errors, codebase indexing)
  • Give a worked before/after (‘fix this bug’ vs the same with the failing function, its type, and the stack trace attached)
  • Conclude that adding context is the highest-leverage move in Cursor

💡 Hint: Attach the exact function, the type it operates on, and the error — precise context in, targeted fix out.

Show solution

The model only knows what is in its context window. The same prompt with the right files attached goes from guessing to grounded.

Ways to add context in Cursor: @file/@folder to attach code, @symbol for a specific function/type, referencing the open file, pasting an error, and codebase indexing for whole-repo search.

Worked example: ‘fix this bug’ alone → the model guesses. ‘fix this bug — @auth.py @User here's the stack trace [paste]’ → it sees the failing function, the type it operates on, and the exact error line, so the fix is targeted. Adding context is the highest-leverage move in Cursor.

Exercise 3 · Rules that actually steer the agentAdvanced

Context: Project rules apply to every request, so good ones encode your conventions and make the agent's output look like your codebase instead of a generic one.

Your task: Write three project rules that would meaningfully change generated code quality and say what each prevents.

Requirements:

  • Write three concrete rules that steer the agent (e.g. use the existing DB session, validate with existing schemas, write tests alongside code)
  • For each rule, name what it prevents
  • Make the rules encode your conventions, not generic best practices
  • Explain that good rules make the agent's output match your codebase

💡 Hint: The best rules point at existing patterns to reuse — they stop the agent inventing a second, inconsistent way to do a thing you already do.

Show solution
1. Use the existing `db.session` for DB access; never open raw connections.
2. All new endpoints must validate input with the Pydantic models in schemas/.
3. Write pytest tests alongside new functions; match the style in tests/.
RulePrevents
Use existing db.sessionThe agent inventing a second, inconsistent DB access pattern
Validate with existing schemasUnvalidated endpoints & duplicated ad-hoc validation
Tests alongside codeUntested generated logic slipping in

Good rules encode your conventions, not generic best practices — they make the agent's output look like your codebase instead of a generic one.

Exercise 4 · Why the agent went wrongExpert

Context: Rules are strong hints in context, not hard constraints — they compete for attention with a big diff and can lose, especially to a deprecated API that's common in training data or still present in the repo. Making them stick needs enforcement outside the model.

Your task: Diagnose why an agent used a rule-forbidden deprecated API even though it had the rule, and how to make rules stick.

Requirements:

  • Explain that rules are soft hints that compete for attention and can lose
  • Remove the temptation: delete the deprecated API from the repo or fail CI on its use
  • Make the rule specific and local (‘never X; use Y — example: [snippet]’) not vague
  • Enforce non-negotiables outside the model with a linter/CI gate the model can't overrule
  • State the lesson: shape the common case with rules, enforce ‘must never’ with tooling

💡 Hint: For a hard ‘must never’ requirement, back the rule with a mechanical gate; a prompt instruction alone is overrulable.

Show solution

Rules are strong hints in context, not hard constraints — they compete for attention with a large diff and can lose, especially when the deprecated API is more common in the training data or still present in the codebase.

  1. Remove the temptation: if the deprecated API still exists in the repo, the agent will pattern-match to it. Delete it or add a lint rule that fails CI on its use.
  2. Make the rule specific & local: ‘never use X; use Y instead — example: [snippet]’ beats a vague ‘follow best practices’.
  3. Enforce outside the model: a linter/CI check is a hard constraint; a rule is a soft one. For ‘must never’ requirements, back the rule with a mechanical gate.

Lesson: use rules to shape the common case, but enforce non-negotiables with tooling the model can't overrule.

Exercise 5 · Always review the diffProfessional

Context: ‘Tests pass’ proves the code doesn't break what you tested — it misses everything untested. The reviewer's job doesn't shrink because a machine wrote the code; it shifts from typing to judging.

Your task: Explain what ‘tests pass’ misses on a Cursor agent change and the review discipline you'd require before merge.

Requirements:

  • Name what green tests miss (unnecessary in-passing changes, wrong logic in untested branches, security/secrets, scope creep, unmaintainable-but-working code)
  • Require reading every line of the diff — edits are a proposal, not a fact
  • Require questioning surprise changes and understanding or reverting unexpected file edits
  • Require checking the negative space (tests for new branches, nothing wrongly removed) and keeping changes scoped
  • State that the reviewer's job shifts from typing to judging

💡 Hint: Treat every agent run like a PR from a junior developer: read the whole diff and question anything you didn't ask for.

Show solution

Green tests prove the code does not break what you tested. They miss: unnecessary changes the agent made in passing, subtly wrong logic in untested branches, security/secret issues, scope creep, and ‘works but is unmaintainable’ code.

  1. Read every line of the diff — the agent's edits are a proposal, not a fact.
  2. Question surprise changes: if it touched a file you didn't expect, understand why or revert it.
  3. Check the negative space: did it add tests for the new branches? Did it remove anything it shouldn't?
  4. Keep changes scoped: reject giant multi-concern diffs; ask the agent to split them.

The reviewer's job doesn't shrink because a machine wrote the code — it shifts from typing to judging.

Exercise 6 · Rolling Cursor out to a 30-person teamIndustry scenario

Context: Rolling an AI tool out to 30 engineers succeeds on process — shared rules and review discipline — not on the license. Measuring quality, not just speed, is what catches a speed-for-quality trade before it becomes incidents.

Your task: As the tech lead adopting Cursor across a 30-engineer org, design the rollout: standards, guardrails, and how you'll know it worked.

Requirements:

  • Start with a small pilot before org-wide rollout
  • Ship shared project rules so everyone's agent produces consistent code, not 30 personal styles
  • Set the review standard (AI-authored code reviewed like any code; author accountable; scoped, tested diffs)
  • Add guardrails: secret-scanning in CI, indexing/data settings that respect the network boundary, off-limits repos
  • Invest in training the verify + context-attachment habits, not just handing out licenses
  • Measure quality (bug/incident rate, review time) alongside speed to catch a bad trade

💡 Hint: The failure mode is treating it as a license rollout and measuring only speed — watch quality signals too.

Show solution
  1. Start with a pilot: 3-5 volunteers for 2 weeks; collect what worked and what bit them before org-wide.
  2. Ship shared rules: commit a project .cursor/rules encoding team conventions so everyone's agent produces consistent code — not 30 personal styles.
  3. Set the review standard: AI-authored code is reviewed like any other; author is accountable; diffs stay scoped and tested (reuse the PR standard).
  4. Guardrails: secret-scanning in CI, codebase indexing settings that respect what may leave the network, and a policy on which repos are off-limits.
  5. Training, not just licenses: teach context-attachment and the verify habit — the tool's value is bimodal on skill.
Success signalWatch for
PR cycle time downReview time up (unreviewed dumps)
Bug rate flat or downRising incident rate from unowned code
Devs report less toilOver-reliance on unverified generations

Lesson: the rollout succeeds on process (shared rules + review discipline), not on the license. Measure quality, not just speed.

✓ Checkpoint — you can move on when you can…

  • Use Tab/Cmd-K/chat/agent for the right jobs.
  • Feed context with @file/@folder/@docs.
  • Write project rules and drive the agent.
  • Review every diff; roll out with shared rules + a model policy.

Knowledge check check yourself

✓ Knowledge check

Cursor's prompt_quality scorer weights attached @file/@folder references most heavily (up to 3 points). What does that design choice say about what most improves a Cursor edit?

Show answer
Pointing the model at the exact relevant files is the single biggest lever on edit quality — precise context in yields a correct edit out, whereas a specific ask with no context still leaves the model guessing at your codebase.
✓ Knowledge check

Why does the lesson insist you treat every Cursor agent run like a PR from a junior developer, reviewing the diff before accepting?

Show answer
The agent can touch many files fast, so its speed is both the power and the risk; without reading the diff and running tests, that velocity silently introduces subtle bugs across the codebase.
© 2026 studybydoing.in · AI Engineering: Zero to Production · All rights reserved. · About · Privacy Policy · Terms · Contact
Educational content, provided as-is and without warranty. Code samples are examples — review, test, and adapt them before using in production. See the Terms of Use & Disclaimer. Use at your own risk.
© studybydoing.in