Module 3 of 10 · CLI Comparison Track
30%
AI CLI Tools Compared  ·  M03

Prompting & Context Compared

Same prompt. Three tools. Wildly different results. This module dissects exactly how Claude Code, Gemini CLI, and GitHub Copilot CLI interpret context — from project-level instruction files to per-call file references — and shows you how to prompt each one for maximum value.

Claude Code
Gemini CLI
GitHub Copilot CLI
Section 1

Context Files: CLAUDE.md vs GEMINI.md vs copilot-instructions.md

Why Context Files Exist

BEFORE: You join a new team and on day one you're asked to fix a bug. You don't know the coding conventions, which dependencies are banned, which API version to use, or that "never commit .env files" is a cardinal rule. You make 4 mistakes before lunch that every senior dev considers obvious. The problem isn't your skills — it's missing context.

PAIN: Without a persistent briefing document, every new AI session starts cold. You re-explain the stack, the constraints, and the team preferences — over and over — costing minutes per session, which adds up to hours per week. The AI gives generic advice because it has no project-specific knowledge.

MAPPING: A context file is the onboarding document you hand your AI assistant on session zero, and it stays in effect for every subsequent conversation. Instead of repeating "we use Pydantic v2, not v1" forty times, you write it once in CLAUDE.md and forget about it.

Context file: CLAUDE.md
CLAUDE.md # Payment Service — Project Context ## Stack Python 3.12, FastAPI, PostgreSQL 16, Stripe SDK Node 20 / TypeScript for the webhook worker ## Rules - NEVER commit .env files - All DB migrations must be reversible (alembic) - Tests required for every new endpoint - Use pydantic v2 models, not v1 ## Run Locally uvicorn main:app --reload pytest tests/ -v ## Claude-Specific Hints - Use subagents for parallel test + implementation tasks - Prefer /plan before large refactors - model: claude-sonnet-4-5 (haiku for quick tasks)
GEMINI.md # Payment Service — Project Context ## Stack Python 3.12, FastAPI, PostgreSQL 16, Stripe SDK Node 20 / TypeScript for the webhook worker ## Rules - NEVER commit .env files - All DB migrations must be reversible (alembic) - Tests required for every new endpoint - Use pydantic v2 models, not v1 ## Run Locally uvicorn main:app --reload pytest tests/ -v ## Claude-Specific Hints - Use subagents for parallel test + implementation tasks - Prefer /plan before large refactors - model: claude-sonnet-4-5 (haiku for quick tasks) ## Gemini-Specific Hints - Use @ syntax to load @src/ before architecture questions - /memory add "use pydantic v2" once — persists across sessions - model: gemini-2.5-pro (flash for quick tasks)
copilot-instructions.md # Note: this file is for GitHub Copilot in IDE/PRs only. # It is NOT loaded by Copilot CLI (gh copilot suggest). # Payment Service Python 3.12 FastAPI service. PostgreSQL 16. Stripe billing. - Never commit .env files - Pydantic v2 only - Tests for every endpoint # Model hints, subagent config, slash commands: # none of these are supported by copilot-instructions.md

The side-by-side reveals the pattern: CLAUDE.md and GEMINI.md are nearly identical — the stack, rules, and run commands are copy-paste portable. Only the last section changes to swap out tool-specific hints. copilot-instructions.md is much simpler because the CLI tool doesn't load it, and the IDE version has a more limited scope.

Feature CLAUDE.md GEMINI.md copilot-instructions.md
Loaded in terminal ✓ Yes ✓ Yes ✗ IDE/PR only
Global scope (~/ home) ✓ ~/.claude/ ✓ ~/.gemini/ ✗ Project only
Model hints ✓ Supported ✓ Supported ✗ Not supported
Slash command / skill definitions ✓ Slash cmds ✓ Skills ✗ Not supported
Cross-session memory ✓ Always loaded ✓ /memory add ✗ N/A (stateless CLI)
Transferability Copy → rename to GEMINI.md, swap last section Copy → rename to CLAUDE.md, swap last section Rewrite needed (different scope)
Pro tip: maintain one file, symlink the other

Many teams create a single project-context.md with shared content and use a build step or simple shell alias to generate both CLAUDE.md and GEMINI.md. When you update the shared doc, both tools get the update automatically.

Section 2

@ Context Syntax Compared

All three tools can reference specific files in your prompt — but the mechanism is different for each. This is one of the most practically important differences for day-to-day use.

Claude Code
Natural language file references. Describe what you want; Claude reads it automatically. Use /add in interactive mode to pin files.
Gemini CLI
Explicit @ prefix for files, directories, and URLs. Most powerful: can load an entire directory or a live API spec with one token.
Copilot CLI
No file context syntax. Shell-command-focused. Ask it to "show the content of a file" and it suggests cat — not an AI analysis.
BASH — @ Context Syntax
# ── CLAUDE CODE ──────────────────────────────────────────────
# No @ syntax — describe files naturally in your prompt
claude "Look at src/auth.js and explain the session management"

# In interactive mode, pin a file so Claude always reads it:
#   /add src/auth.js
# Claude will then reference it in every subsequent response.

# ── GEMINI CLI ───────────────────────────────────────────────
# @ prefix for a single file
gemini "@src/auth.js explain the session management"

# @ prefix for an entire directory (uses 1M context window)
gemini "@src/ summarize every module and its responsibilities"

# @ prefix for a live URL — loads an API spec and generates client code
gemini "@https://api.stripe.com/openapi.json generate a Python client"

# Combine multiple @ references in one prompt
gemini "@src/auth.js @tests/auth.test.js what's not covered by tests?"

# ── GITHUB COPILOT CLI ───────────────────────────────────────
# No file @ syntax — translates requests to shell commands
gh copilot suggest "show the content of src/auth.js and summarize it"
# Result: suggests `cat src/auth.js` — not an AI analysis of the file
POWERSHELL — @ Context Syntax
# ── CLAUDE CODE ──────────────────────────────────────────────
# No @ syntax — describe files naturally in your prompt
claude "Look at src/auth.js and explain the session management"

# In interactive mode, pin a file:
#   /add src/auth.js

# ── GEMINI CLI ───────────────────────────────────────────────
# @ prefix for a single file
gemini "@src/auth.js explain the session management"

# @ prefix for a directory
gemini "@src/ summarize every module and its responsibilities"

# @ prefix for a live URL
gemini "@https://api.stripe.com/openapi.json generate a Python client"

# Combine multiple @ references
gemini "@src/auth.js @tests/auth.test.js what's not covered by tests?"

# ── GITHUB COPILOT CLI ───────────────────────────────────────
# Copilot CLI translates to shell commands, not file analysis
gh copilot suggest "show the content of src/auth.js and summarize it"
# Suggests: Get-Content src/auth.js — not an AI analysis
Best for file context: ★ Gemini CLI — explicit @syntax, loads dirs + URLs Claude Code — natural language, reads files automatically Copilot — not designed for this use case
Section 3

The Same Prompt, Three Tools

The clearest way to understand the behavioral difference between these tools is to run the exact same prompt on all three and compare output style, depth, and approach. Here's the test prompt:

PROMPT (run against all three tools)
"Explain what this codebase does, identify the main entry point,
and list the top 3 things a new developer should understand first."
Response style comparison — same prompt, three tools
Claude Code Structured
Reading project files… What it does: A Stripe billing service for SaaS subscriptions. Handles plan changes, invoices, and webhook events from Stripe. Entry point: main.py — FastAPI app, mounts all routers, loads config from settings.py. Top 3 for new devs:
1. Webhooks use idempotency keys — re-processing is intentional.
2. Plan changes are async — don't expect synchronous DB updates.
3. .env.example shows all required secrets before first run.
Note: I didn't find test coverage for the webhook retry logic — worth asking about.
Gemini CLI Broad scan
Scanning entire codebase… Overview: Payment microservice integrating Stripe for B2B SaaS billing. Python/FastAPI backend, TypeScript webhook worker, PostgreSQL persistence. Entry points: main.py (API server), worker/index.ts (webhook processor). Top 3:
1. Dual-language codebase — API in Python, worker in TypeScript.
2. Alembic migrations are the source of truth for DB schema.
3. Stripe webhook signatures validated in webhooks/verify.py.
I read all 47 source files in one pass. Want a full dependency map?
Copilot CLI Shell-first
Reformulating as shell commands… To understand the codebase, run these commands: cat README.md — read the overview find . -name "*.py" | head -20 — list Python files grep -r "if __name__" . --include="*.py" — find entry points Copilot CLI translates your prompt into shell commands — it doesn't analyze the codebase itself. Use it to discover the right commands, then read the output yourself.
What Just Happened?

All three tools responded usefully — but to very different kinds of usefulness. Notice:

  • Claude Code reads specific files, explains architecture in prose, and proactively flags gaps (the missing test coverage).
  • Gemini CLI loads the entire codebase at once (its 1M window advantage), identifies both entry points (including the TypeScript worker), and offers to go deeper.
  • Copilot CLI doesn't analyze — it suggests the shell commands you would use to analyze. That's its design. It's genuinely useful if you forgot the right grep syntax.
Section 4

Multi-Turn Conversation Patterns

How each tool handles memory and context across multiple messages is one of the most consequential differences for long-running tasks. A tool that forgets context after each message forces you to re-explain everything — just like repeating yourself to a new colleague every morning.

Memory model comparison — what each tool remembers
Claude Code
CLAUDE.md (auto-loaded every session) PERSISTENT
Full session history — Claude remembers everything you've said SESSION
Subagents spin up and report back to main context SUBAGENT
/clear resets session; CLAUDE.md persists RESET
Gemini CLI
GEMINI.md (auto-loaded every session) PERSISTENT
Current session history maintained in memory SESSION
/memory add "use pydantic v2" — persists across sessions PERSISTENT
/chat save <name> / /chat resume <name> — named sessions NAMED
Copilot CLI
No context file loaded by CLI (copilot-instructions.md is IDE-only) NONE
Stateless — each gh copilot suggest call is independent STATELESS
No cross-call memory. Every call starts fresh. NONE
Best for: one-shot command lookups, not long workflows USE CASE
BASH — Multi-Turn & Session Management
# ── CLAUDE CODE ──────────────────────────────────────────────
# Session context is maintained automatically.
# Subagent example: parallel tasks within one session
claude "Write the implementation of the payment retry logic
        AND write tests for it at the same time."
# Claude spins up a subagent for tests, main agent for impl,
# both report back — you see both files when done.

# Reset session when starting a new task:
#   /clear
# CLAUDE.md is still loaded — only the conversation resets.

# ── GEMINI CLI ───────────────────────────────────────────────
# Save a named session to resume later
gemini
# (interactive mode)
# > Analyze the payment service architecture
# > /chat save payment-analysis

# Next day — resume exactly where you left off
gemini
# > /chat resume payment-analysis
# > Now add the retry logic we discussed

# Add a persistent memory note (survives session restarts)
# > /memory add "This project uses pydantic v2 exclusively"

# ── GITHUB COPILOT CLI ───────────────────────────────────────
# Each call is completely stateless
gh copilot suggest "list files in src directory"
# Returns: ls src/ or Get-ChildItem src/

# Next call has NO memory of the previous one
gh copilot suggest "now show me the auth module"
# Returns: cat src/auth.js  (no "now" context — clean slate)
POWERSHELL — Multi-Turn & Session Management
# ── CLAUDE CODE ──────────────────────────────────────────────
# Session context maintained automatically (200K token window).
# Subagent example: spawn parallel tasks
claude "Write the payment retry implementation AND its tests simultaneously."
# A subagent handles tests; main agent handles implementation.
# Both results appear in session context when complete.

# Reset session (CLAUDE.md still loaded after /clear):
#   /clear

# ── GEMINI CLI ───────────────────────────────────────────────
# Interactive session with named-session save/resume
gemini
# In interactive mode:
# > Analyze the payment service architecture
# > /chat save payment-analysis

# Resume the named session in a new terminal session
gemini
# > /chat resume payment-analysis
# > Now add the retry logic we discussed

# Persistent memory across all sessions
# > /memory add "This project uses pydantic v2 exclusively"

# ── GITHUB COPILOT CLI ───────────────────────────────────────
# Stateless — every gh copilot suggest is a fresh start
gh copilot suggest "list files in src directory"
# Output: Get-ChildItem src\

# No context from previous call
gh copilot suggest "now show me the auth module"
# Output: Get-Content src\auth.js  (ignores "now" — no history)
For long tasks: Claude Code and Gemini CLI both shine

Both maintain full multi-turn context. Claude Code's subagents are powerful for parallel work. Gemini's /chat save / /chat resume and /memory add are great for cross-day continuity. Use stateless Copilot CLI for quick, one-off lookups only.

Section 5

Tool-Specific Prompt Tips

Generic prompting advice ("be specific," "give examples") applies everywhere. But each tool has behaviors and strengths that reward particular prompting patterns — and ignoring those patterns leaves significant quality on the table.

Claude Code Best Practices
  • Be specific about what should change vs what should stay the same — prevents unintended rewrites
  • "Explain your reasoning before writing code" — forces step-by-step thinking and catches wrong approaches early
  • Use CLAUDE.md to set default coding standards — never repeat conventions in prompts
  • Ask it to write tests before the implementation — locks in expected behavior first
  • "What's the simplest change that achieves X?" — prevents over-engineering
  • For risky changes: "what could go wrong with this approach?" before committing
Gemini CLI Best Practices
  • Use @ aggressively — more context = better results with the 1M window
  • /memory add your preferences once; they persist so you never repeat them
  • Start with /plan for complex tasks — review the approach before execution begins
  • Use --model gemini-2.5-pro for architecture decisions; flash for quick lookups
  • Load an entire directory: @src/ what's the overall architecture? — the full picture matters
  • /chat save before ending a long session; resume tomorrow with full context
Copilot CLI Best Practices
  • It excels at shell command translation — lean into that, don't fight it
  • gh copilot explain <command> is excellent for understanding unfamiliar commands
  • Combine with IDE Copilot for a full workflow: CLI for shell tasks, IDE for code analysis
  • Specify command type: -t shell vs -t git vs -t gh for tighter results
  • Paste complete error messages — it suggests the right debugging command sequence
  • Use for GitHub Actions syntax lookups — it knows YAML workflow structure well
BASH — Prompt Pattern Examples
# ── CLAUDE CODE: reasoning before code ───────────────────────
claude "Explain your reasoning about the best approach, then write
        the retry middleware for the Stripe webhook handler.
        Keep the existing error logging pattern unchanged."

# ── CLAUDE CODE: tests first ──────────────────────────────────
claude "Write tests for the payment retry logic BEFORE writing the
        implementation. Make the tests fail first, then fix them."

# ── GEMINI CLI: aggressive @ loading ─────────────────────────
gemini "@src/payments/ @src/webhooks/ @migrations/ \
  What's missing from our error-handling strategy?"

# ── GEMINI CLI: /plan before executing ───────────────────────
gemini
# > /plan refactor the payment module to add idempotency keys
# Review the plan, ask questions, THEN approve execution

# ── GEMINI CLI: model selection ──────────────────────────────
gemini --model gemini-2.5-pro \
  "@src/ Design the retry architecture for webhook failures"

gemini --model gemini-2.5-flash \
  "What flag does grep use for case-insensitive search?"

# ── COPILOT CLI: command-type flag ────────────────────────────
gh copilot suggest -t git "undo last commit but keep changes staged"
gh copilot suggest -t gh "create a PR from current branch to main"
gh copilot suggest -t shell "find all .env files recursively"

# ── COPILOT CLI: explain a command ───────────────────────────
gh copilot explain "git rebase -i HEAD~3"
POWERSHELL — Prompt Pattern Examples
# ── CLAUDE CODE: reasoning before code ───────────────────────
claude "Explain your reasoning about the best approach, then write
        the retry middleware for the Stripe webhook handler.
        Keep the existing error logging pattern unchanged."

# ── CLAUDE CODE: tests first ──────────────────────────────────
claude "Write tests for the payment retry logic BEFORE writing the
        implementation. Make the tests fail first, then fix them."

# ── GEMINI CLI: aggressive @ loading ─────────────────────────
gemini "@src/payments/ @src/webhooks/ @migrations/ What's missing from our error-handling strategy?"

# ── GEMINI CLI: /plan before executing ───────────────────────
# In interactive Gemini session:
# > /plan refactor the payment module to add idempotency keys
# Review plan, then approve

# ── GEMINI CLI: model selection ──────────────────────────────
gemini --model gemini-2.5-pro "@src/ Design the retry architecture for webhook failures"
gemini --model gemini-2.5-flash "What flag does Select-String use for case-insensitive search?"

# ── COPILOT CLI: command-type flag ────────────────────────────
gh copilot suggest -t git "undo last commit but keep changes staged"
gh copilot suggest -t gh "create a PR from current branch to main"
gh copilot suggest -t shell "find all .env files recursively"

# ── COPILOT CLI: explain a command ───────────────────────────
gh copilot explain "git rebase -i HEAD~3"
Section 6

Error Handling Prompts

Pasting an error message is one of the most common real-world prompts you'll use. Each tool handles it through the lens of its core philosophy — analysis, code fix, or shell debugging command.

ERROR (pasted into all three tools)
TypeError: Cannot read properties of undefined (reading 'map')
    at processWebhookEvents (src/webhooks/processor.js:47:28)
    at async handleStripeEvent (src/webhooks/handler.js:23:5)
Claude Code
Reads processor.js:47 and handler.js:23 automatically. Asks: "Is events expected to be an array or can it be null?" Then proposes a targeted fix with a null guard and explains why it can be undefined (Stripe sometimes sends an empty payload on certain event types).
Gemini CLI
Scans @src/webhooks/, finds the error location, and cross-references other callers of processWebhookEvents across the codebase. Suggests the fix plus a broader audit: "2 other callers also skip null-checking — want me to fix those too?"
Copilot CLI
Suggests: node --stack-trace-limit=20 src/webhooks/handler.js and grep -n "map" src/webhooks/processor.js. Useful for finding the exact line fast — but the actual debugging is left to you.
Error handling is where Copilot CLI's shell-first approach shows its limits

Copilot CLI is excellent at "what command do I run to see this error?" but it won't read your source files and diagnose the root cause. For error diagnosis that requires reading code, Claude Code or Gemini CLI are the right tools. Use Copilot CLI to generate the debugging commands, then hand the analysis to one of the other tools.

What Just Happened?

You now have the full prompting picture for all three tools. You can answer:

  • What's the structural difference between CLAUDE.md and copilot-instructions.md?
  • When would you use @src/ vs natural language file references?
  • Why does Gemini CLI sometimes find more issues in a codebase scan than Claude Code?
  • Which tool is appropriate for a long, multi-day refactoring task? Which for a 30-second shell command lookup?
  • How does each tool respond differently to the same error message?

Next module (M04) covers code generation — writing new files, refactoring existing ones, and how each tool handles large, multi-file changes.

Knowledge Check

Test your understanding of prompting and context across all three tools — 6 questions.

Question 1 of 6
Which context file is loaded automatically by the terminal CLI tool (not just an IDE)?
Correct. CLAUDE.md is auto-loaded by Claude Code; GEMINI.md by Gemini CLI. copilot-instructions.md is a GitHub product feature — it affects Copilot in VS Code and on GitHub PRs, but the gh copilot suggest CLI tool does NOT read it. This is a common source of confusion.
Question 2 of 6
You run: gemini "@src/ @tests/ what's not covered by our tests?". What is the @ syntax doing here?
Correct. The @ prefix in Gemini CLI is a context-loading directive. Gemini reads every file in src/ and tests/ and includes their contents in the prompt before generating a response. This is what makes its 1M context window so powerful for codebase-wide analysis.
Question 3 of 6
When you paste the same error message into GitHub Copilot CLI, what kind of response should you expect?
Correct. Copilot CLI is shell-command-first. When given an error, it suggests commands like node --stack-trace-limit=20 or grep -n "map" file.js. It doesn't read your source files and diagnose root causes — that's the job of Claude Code or Gemini CLI.
Question 4 of 6
What does Gemini CLI's /memory add command do that running gemini fresh each time does NOT?
Correct. /memory add "use pydantic v2" stores that fact in Gemini's persistent memory, which is automatically included in every future session. Unlike GEMINI.md (which is project-specific), memory notes travel with your Gemini user profile. They're great for personal preferences like coding style or toolchain choices.
Question 5 of 6
You have CLAUDE.md and you want to start using Gemini CLI on the same project. What's the fastest path to a working GEMINI.md?
Correct. CLAUDE.md and GEMINI.md share the same plain-markdown format. The stack, rules, and commands are ~95% identical. The only section that needs updating is the tool-specific hints at the end — swap "Claude-Specific Hints" for "Gemini-Specific Hints" and adjust the model names and tool-specific commands.
Question 6 of 6
Which prompt pattern is unique to Claude Code and leverages its architecture in a way neither Gemini CLI nor Copilot CLI supports natively?
Correct. Claude Code's subagent architecture lets you run parallel work within a single session — one subagent writes tests while another writes the implementation, both reporting back to your main context. Gemini CLI has no native subagent model (though it has multi-agent features via API). Copilot CLI is stateless and can't maintain parallel work streams at all. /chat save is a Gemini CLI feature, not Claude Code.