A failing test points to a helper you've never seen. You don't know where it lives or what behavior it owns. If you choose a mode before you know what you need, Copilot may explain when you wanted a patch, or edit several files when you only needed an explanation. The mode sets the kind of work you're asking it to do.
A mode is a work contract
Ask, Edit, and Agent are three levels of action. Choosing one means choosing how much you're authorizing Copilot to do. Treat the mode plus your prompt as a contract:
Use the least action that can produce the result you need. Start with Ask when you still need to understand the behavior. Choose Edit when you can describe the change and name the files, which gives you a smaller diff to inspect. Use Agent when the task requires investigation and commands, and give it a stopping condition. The mode changes the work Copilot may attempt. You still own the result.
Edit handles diffs. Agent handles tasks.
Once you know the behavior you want, the question is how much autonomy the job needs. Reach for Edit when you can name the files that may change and describe the change precisely: the required behavior, what must stay the same, the error policy, and the tests that would prove it. A good Edit prompt produces a small diff you can read line by line.
"Bounded" describes the scope your request set. The mode doesn't enforce the boundary for you: your prompt does, and your review confirms it. Always check the actual file list and diff rather than assuming the change stayed where you asked.
Choose Agent when completion requires a sequence of actions, such as inspecting files, editing code, running a command, and responding to the result. State the guardrails before it starts. Name the outcome, allowed files, prohibited actions, verification command, passing behavior, and stopping condition. Without that last boundary, a small fix can keep expanding after the original task is already lost.
Agent mode in your IDE is also a different thing from GitHub's cloud coding agent, which runs in a GitHub Actions-powered environment and opens a pull request for review. Choosing Agent locally does not hand your task to that cloud workflow.
Where does a suggestion come from?
The path from your keystroke to the displayed suggestion explains why "Copilot said so" isn't evidence. Use this sequence as a reasoning model:
Editor input → context selection and prompt building → proxy filtering
→ model generation → post-processing → suggestion displayed
→ human review and validation
Your input is the comment, partial function, selection, or chat request that starts things off. Precise input gives you a clearer contract to judge against. Context is the bounded package of material the request can see: the code near your cursor, a selection, an explicitly attached file, applicable instructions, prior messages. Nothing wider than that counts as context, so don't assume Copilot considered a file you never attached. The middle stages, proxy filtering, model generation, post-processing, are real architectural topics, but their exact internal rules aren't something you can observe from the editor. Record what you see and resist inventing a hidden cause for it.
Proxy filtering is one stage in this reasoning model. Content exclusion is different: it is a configured safeguard for specific files, and you'll meet it later in the module. Never disable a safeguard just to make a practice exercise produce output. When a suggestion doesn't appear, record "no suggestion." That observation alone does not show that a filter blocked it.
The last stage is yours. Model generation only establishes that a candidate appeared, not that the candidate is correct. Accepting it changes your editor, and only a real check tells you anything about behavior. The earlier lesson's habit holds at every level: an explicit contract plus executed checks is the only thing that turns a displayed candidate into code you can trust.
Context is evidence, so control it
Copilot reasons from the context it receives, so keep that evidence deliberate. Name the file when one file owns the behavior. Select the function when the question is local. Include the error text when you're diagnosing a failure. Ask it to inspect the repository only when you genuinely don't know where the relevant code lives.
This also matters when you compare two responses to learn what changed. If you change the prompt, the selection, the attached file, and the conversation history all at once, you can't attribute the difference to any single factor. Change one variable at a time. For a real comparison, keep the prompt, selection, cursor, and output rubric fixed and vary only the attached context. Don't lean on half-remembered "magic" syntax for references. If your editor shows a control for adding files or selections, use it. Otherwise, name the paths, symbols, diagnostics, and error text directly in the prompt. A durable request doesn't depend on a token spelling that changes between releases.
Whichever mode you're in, the same review loop applies: state the outcome you want, supply the relevant evidence, set the scope and constraints, inspect the response or diff or tool actions, run the narrowest useful check, then refine using a specific discrepancy. That last step is where people slip. Answering a weak result with "try again" tells Copilot nothing. It can't act on a shrug. Name what failed instead: "the patch changed the public return type," or "the test doesn't cover the upper discount boundary." A precise complaint is an instruction Copilot can execute. A vague one rolls the dice. Turn these prompts into testable specifications in Prompting for Code.