Google CloudProfessional Agentic Architect2026-092.1 Using coding agents effectively
Refactor and optimize with repository evidence
Completed by the knowledge check
Learning objective
Use a coding agent to refactor and optimize an application without guessing at its architecture or claiming unmeasured gains. Preserve required behavior, measure the target resource, and produce a focused diff that a human can review. This lesson does not cover sandbox selection, access controls, or vulnerability patching.
Core idea
Treat agent-assisted improvement as an evidence loop:
- Map the relevant repository context.
- Baseline behavior and performance before editing.
- Change the smallest coherent design surface.
- Verify correctness and measure the same workload again.
- Review the diff, evidence, and trade-offs.
The agent proposes and executes work inside this loop. Repository conventions, tests, profiles, benchmarks, and the final diff constrain its choices. None is sufficient alone: context does not prove behavior, tests do not locate a bottleneck, a profile does not prove an improvement, and a benchmark does not show whether the code remains correct.
How it works
Map the change surface
Give the agent a measurable objective and an explicit scope. Then have it read the repository before editing:
- project instructions and architecture records;
- build manifests, dependency locks, and supported runtime versions;
- public interfaces, callers, data flows, and error-handling conventions;
- nearby implementations and tests;
- version-control history when it explains a constraint.
This is repository context, not the largest possible prompt. Select files and history that can change the decision, and summarize the discovered invariants. For example, “preserve ordering, error types, and the public interface” is more useful than a directory dump. Gemini CLI supports hierarchical project instructions in GEMINI.md files, including more specific context discovered for subdirectories (Provide context with GEMINI.md files). Those instructions guide the agent, but source code and executable checks still provide the evidence for a particular change.
Establish correctness and performance baselines
For a refactor, identify the observable contract and run the relevant tests before changing code. If a required behavior lacks coverage, confirm it from repository evidence and add a characterization test. Do not rewrite an assertion merely to make an agent’s new output pass.
For an optimization, define the workload, metric, environment, and acceptance threshold. Record a repeatable baseline such as latency, throughput, CPU time, or allocations. Then profile the representative workload to find where the resource is spent. CPU, heap, and tracing data answer different questions; Go’s diagnostics guide, for example, distinguishes profiling of expensive code from tracing latency across a request (Diagnostics).
Use representative inputs. A fast microbenchmark of a rare path can improve while application performance remains unchanged. The Go profile-guided optimization guide warns that an unrepresentative profile produces little or no production benefit and that representative benchmarks can be difficult to maintain (Profile-guided optimization).
Make and verify one coherent change
Ask the agent to state its hypothesis before editing: “Parsing the same policy for every item dominates CPU time; parse once per request.” Implement only the change needed to test that hypothesis. Preserve interfaces unless the objective requires an intentional contract change.
Run verification in layers:
- Run the focused tests for fast feedback.
- Rerun the same benchmark under comparable conditions.
- Re-profile when the result must be attributed to the intended hotspot.
- Run the broader test suite and required build, lint, and type checks.
- Inspect repository status plus both working-tree and staged diffs.
Report baseline and result with units and workload details. A single faster run is weak evidence; use the repository’s benchmark framework and repeated A/B comparison. Go’s testing package, for example, provides benchmarks and points to benchstat for statistically robust comparisons (Package testing).
The final check must include untracked and staged files. A plain git diff compares the working tree with the index, while git diff --staged compares the index with HEAD; git status also reports untracked paths (git diff, git status).
Key distinctions and trade-offs
Refactor versus optimization: A refactor improves internal structure while preserving observable behavior. An optimization targets a measured resource or performance outcome. One edit can do both, but evaluate correctness and performance separately.
Test versus benchmark versus profile: A test checks expected behavior. A benchmark compares a metric for a controlled workload. A profile attributes resource use across code paths. Passing tests do not prove a speedup, and a better benchmark does not prove semantic equivalence.
Small diff versus smallest line count: A reviewable diff is one self-contained change with its related tests and measurement evidence. It is not necessarily the fewest edited lines. A shared abstraction might require several files but be safer than duplicating a shortcut. Google engineering guidance recommends separating substantial refactors from feature or bug changes and keeping related tests with the change (Small CLs).
Focused checks versus full regression: Focused checks shorten the agent’s feedback loop. Broader checks catch effects outside the inspected module. Use both in that order; do not mistake a targeted pass for repository-wide safety.
Architecture / decision scenario
A pricing service misses its CPU budget during a promotion workload. A coding agent reads the service instructions, request handler, pricing rules, cache conventions, callers, and tests. The public response, rounding rule, error types, and rule-refresh behavior become explicit invariants.
The baseline benchmark records requests per second and allocations for a fixed data set. A CPU profile shows repeated parsing of the same immutable rule set on the hot path. The agent proposes parsing once when a versioned rule set loads, then reusing the parsed form until that version changes.
Before editing, the agent adds missing characterization tests for rounding, invalid rules, and refresh behavior. It then extracts parsing from request evaluation without changing the public interface. The focused tests pass, the same benchmark shows the required improvement, and a second profile confirms that parsing no longer dominates the hot path. The full suite and static checks also pass.
The final diff contains the refactor, cache invalidation, related tests, and benchmark code. It excludes a dependency upgrade and unrelated formatting. The change description states the hypothesis, baseline, result, workload, commands, and residual risk. A reviewer can evaluate semantics and performance instead of trusting “optimized” code.
Common exam traps
- Asking an agent to “make it faster” without naming a workload, metric, or threshold.
- Loading many repository files while missing the relevant instructions, callers, tests, or supported versions.
- Treating passing tests as proof of performance or a profiler’s hot function as proof that a proposed rewrite is faster.
- Changing tests to accept new output when a refactor is supposed to preserve behavior.
- Optimizing a microbenchmark that does not represent the production path.
- Mixing a refactor, dependency upgrades, formatting, and behavior changes into one difficult-to-review diff.
- Reporting percentage improvement without the baseline, units, workload, and measurement conditions.
What to remember
- Map repository constraints before editing.
- Preserve behavior with tests and prove performance with comparable measurements.
- Use profiles to locate cost, not to claim the final improvement.
- Make one coherent change and run focused checks before broader regression checks.
- Hand reviewers a focused diff plus the hypothesis, commands, and evidence.
Knowledge check
A coding agent rewrites a function identified by a CPU profile. Behavior tests pass, and the agent claims a speedup. What evidence is still needed to support that claim?
A behavior-preserving refactor changes an edge-case output that has no test. Callers and documentation establish the original behavior. What should the agent do?
Before handoff, the agent reports that git diff is empty and declares the change set reviewed. Which inspection completes the review?
git diff HEAD~1 for the last commitgit diff after saving all open filesgit diff only compares the working tree with the index. Staged changes need git diff --staged , and git status lists untracked files that neither diff shows.References
- Gemini CLI, Provide context with
GEMINI.mdfiles - The Go Programming Language, Diagnostics
- The Go Programming Language, Profile-guided optimization
- The Go Programming Language, Package
testing - Git,
git diffdocumentation - Git,
git statusdocumentation - Google Engineering Practices, Small CLs