What you’ll be able to do
- Choose Grep for searching code content and Glob for finding files by name or extension pattern
- Use Edit for targeted changes, and fall back to Read + Write when Edit can’t find unique anchor text
- Build codebase understanding incrementally: Grep for entry points, then Read to follow imports and trace flows
- Trace a function through wrapper modules by finding every exported name first, then searching for each one
What you need to know
Six tools, each with a clear job
Claude Code and agents built on the Agent SDK come with built-in tools for working in a codebase. Exam questions about them are usually selection questions: which tool fits this need.
- Grep searches file contents for a pattern: a function name, an error message, an import statement. Use it for "where is this text in the code?"
- Glob matches file paths against a pattern such as
**/*.test.tsxorsrc/api/**/*.ts. Use it for "which files have this name or extension?" - Read loads a file's full contents.
- Write writes a file's full contents, creating or replacing it.
- Edit makes a targeted change by finding a piece of existing text and replacing it. The text must match exactly one place in the file.
- Bash runs shell commands, for example the test suite, a build, or a script. Use it for work the file tools do not cover, such as running the tests after a change.
Mixing up Grep and Glob is the classic mistake. Grepping for "test" to find test files returns every file that mentions the word. Globbing **/*.test.tsx returns exactly the test files. And Glob can't tell you who calls parseConfig, because that information is inside files, not in their names.
Edit needs a unique anchor, and Read + Write is the fallback
Edit is the right tool for a targeted change: it touches only the matched text and leaves the rest of the file as it was. It relies on the anchor text appearing exactly once. In files with repeated blocks, such as several identical config stanzas or duplicated handlers, the anchor can match more than once and Edit fails.
Retrying the same Edit fails the same way. The reliable fallback is Read + Write: read the full file, make the change with the whole content in view, and write the file back. It is a heavier operation, so use it when Edit can't find a unique match, not as the default for every small change.
Read(file) # load the whole file
change only the payments block’s timeout, with full context
Write(file, updated_content)
Explore incrementally, not all at once
Reading every file in an unfamiliar codebase before starting fills the context with code that mostly doesn't matter, and the details that do matter get lost among it. A better approach builds understanding step by step:
- Grep for entry points: the route that handles the failing request, the function named in the error, the place a config key is read.
- Read those files and follow their imports to the modules they actually depend on.
- Trace the flow one hop at a time, reading new files only when the current path leads there.
Each step is chosen based on what the previous one found, so the agent reads the files on the relevant path and skips the rest.
Trace through wrapper modules by name
Codebases often wrap functions: a utility formatCurrency is re-exported by a money module as formatAmount, and a UI helper wraps that again as displayPrice. Grepping for formatCurrency finds the definition and the wrapper, but not the dozens of callers that only use the wrapped names.
To find every real use, first identify all the names it is exported under: read the wrapper modules and note each export and alias. Then Grep for each of those names across the codebase. Only the full set of names gives you the full set of callers. A broader single pattern, a case-insensitive search, or a Glob for files with "currency" in the path won't find callers that use a different name.
Key concept
Grep for contents, Glob for paths, Edit for targeted changes with a unique anchor, Read + Write when the anchor isn’t unique. Understand code by starting from Grep hits and following imports, and trace wrapped functions by searching for every exported name.
When a scenario describes an agent with an overflowing context, missed callers, or a failing edit loop, check first whether it picked the right built-in tool for the job.
Practice scenario
getUserProfile function is used before it is deprecated. It starts by reading all 600 files in the repository, runs low on context halfway through, and reports 4 callers. A teammate knows there are more, because services/users.ts re-exports it as fetchProfile and loadUser. A later attempt to update an identical deprecation comment in a file that contains it twice fails repeatedly with Edit.Work it through, then open this
Start with Grep for getUserProfile to find the definition and any wrappers, then Read services/users.ts to collect every exported alias (fetchProfile, loadUser). Then Grep for each name across the codebase. That finds the full set of callers without reading 600 files. For the comment, Edit can’t succeed while the anchor text appears twice. Read the file, make the intended change with full context, and Write it back.
Build exercise — Trace a function the incremental way
Intermediate · 25 min
What you’ll learn
- Matching Grep and Glob to content and path questions
- Tracing a wrapped function to all of its callers
- Falling back from Edit to Read + Write
-
In a real repository, use Glob to list all test files by pattern, then use Grep to find every file that imports one specific module.
- Why: It makes the content-versus-path split concrete. Each tool answers only one kind of question.
- You should see: Glob returning only files that match the name pattern, and Grep returning only files whose contents mention the import.
-
Pick a function that is re-exported or wrapped. Read the wrapper modules to list every exported name, then Grep for each name and compare the count with a search for the original name alone.
- Why: Callers using an alias are invisible to a search for the original name.
- You should see: More callers from the full set of names than from the single original name.
-
Create a file with the same line in two places and try to Edit that line. When it fails, Read the file and Write the corrected version.
- Why: Edit’s unique-match requirement is easy to forget until it blocks you, and Read + Write is the reliable fallback.
- You should see: Edit refusing the ambiguous anchor, and Read + Write applying the change exactly where you intended.
Exam traps
Using Grep to find files by name, or Glob to search inside files
Grep searches contents. Glob matches paths. Each tool answers a different question.
Reading every file upfront to understand a codebase
It wastes context on irrelevant code. Start from Grep hits and follow imports with Read.
Retrying Edit with the same non-unique anchor text
It will fail the same way. Fall back to Read + Write.
Searching only for a function’s original name when wrapper modules re-export it under other names
Collect every exported name from the wrappers first, then search for each one.
Rewriting a whole file with Write when a targeted Edit with a unique anchor would do
Edit is the tool for targeted changes. Read + Write is the fallback for when Edit can’t find a unique match.
Sources
- Claude Developer Platform Docs
- Anthropic, Claude Certified Architect – Foundations Exam Guide v1.0 (July 2026)