Gemini CLI is a terminal coding agent from Google. You start it in a Go module with gemini. Give it a focused GEMINI.md and a test-driven loop, and it can make refactors, add tests, and fix concurrency issues while you keep control of interfaces and dependencies. See Gemini CLI for an overview.
What makes Gemini CLI a good fit for Go code
Go’s toolchain is predictable: go build, go test, go vet, and gofmt produce quick feedback. That makes it a good fit for an agent because the agent can verify its own work without guessing. The module system gives clear boundaries, and idiomatic Go favors small interfaces, explicit errors, and table-driven tests. Gemini CLI can read and edit multiple files in a package, update a test next to a function, and run the exact go test command you prefer. It is not a replacement for a Go programmer: you still decide interface boundaries, concurrency policy, and dependency choices. The value is that it reduces the tedious parts—adding fields, threading context, renaming, scaffolding tests—while following the rules you set in GEMINI.md. For a step-by-step walkthrough, read how to use Gemini CLI.
Give the agent a Go rulebook
Create GEMINI.md in the repository root before asking for substantial changes. Keep it short and Go-specific. Tell the agent how to compile, test, and lint, where packages live, and what to avoid. A realistic file for a module with cmd/ and internal/ may look like this:
# Gemini CLI instructions
## Build and verification
- Run `go build ./...` after every change.
- Run `go test ./...` after every behavior change.
- Run `go vet ./...` and `gofmt -l .`; fix all findings.
## Go rules
- Do not add a dependency unless the user asks or the module already uses it.
- Keep changes within the package that owns the behavior.
- Prefer table-driven tests with the standard `testing` package.
- Functions that wait or block must accept `context.Context` first.
- Do not introduce global mutable state.
- Use interfaces at the method that consumes them, not at the producer.
## Layout
- Main programs under `cmd/`.
- Reusable packages under `internal/`.
- Tests next to the code they test.
If your module has generated files, list them explicitly so the agent does not edit generated code.
Work in small, test-backed turns
Work with the agent in short turns. First describe the outcome and the files involved. Then let the agent propose a plan, make the smallest edit, run the Go toolchain, and show the diff. Review the diff before asking for the next change. For larger work, branch or use a git worktree so you can discard a bad attempt.
| Go task | Good prompt |
|---|---|
| Add timeout to a client | Add a Timeout field to Client and thread it through Do using context.WithTimeout; update existing tests. |
| Refactor to an interface | Change the Store struct to a Store interface with Get and Put; update callers and mocks. |
| Fix goroutine cancellation | Find goroutines in pkg/worker that cannot be stopped and add context cancellation without changing the public API. |
| Add table-driven tests | Write table-driven tests for ParseConfig covering empty input, missing fields, and valid config. |
| Clean up Go style | Run gofmt, go vet, and go test ./...; fix all reported issues and show the diff. |
After each turn, run gofmt -l ., go vet ./..., and go test ./... yourself. If the agent fixed a race, add -race. Do not accept a diff that silently adds a dependency or reshapes an interface beyond the requested change.
Go traps to expect when delegating
Gemini CLI is reliable for mechanical, locally visible work: adding methods to a struct, updating format strings, converting a function to accept an interface, adding json or db tags, and writing table tests. It also handles module-level refactors when you constrain the package list.
Watch it closely on concurrency. Go code often looks correct under go test but leaks goroutines or sends on a closed channel under load. Always review any code that starts a goroutine, uses sync.WaitGroup, sync.Once, or context.WithCancel. Check that cancellation paths actually return and that no goroutine writes to the same map without a mutex. The agent may pass a pointer to a loop variable and not notice, or it may add go keywords without adding a defer/cancel. Another Go-specific trap is dependency creep: the agent may import a third-party package when a few lines of standard library would do. Review go.mod before committing. Interfaces also need a human decision: if you ask it to make code testable, it may introduce a broad interface that creates more indirection than the codebase wants. Keep interfaces small and defined at the consumer.
Go verification beyond go test
Treat the agent’s own test run as a first pass, not proof. For Go, verification should include formatting, static analysis, and race detection. After the agent finishes a task, run:
gofmt -l .
go vet ./...
go test ./...
go test -race ./...
Use go test -count=1 ./... when you want to bypass the test cache. For table-driven tests, check that the agent used subtests with t.Run and included explicit input, want, and wantErr fields. That makes failures easy to read. If the agent changes concurrency behavior, run the race detector on the affected package and add a slow test that stresses cancellation paths. If the agent adds //go:build tags or modifies generated files, verify them manually.
Parallel agents with AgentVera
On larger Go projects, running multiple Gemini CLI instances in parallel can speed up independent changes, but you need isolation. AgentVera runs real CLI agents in separate git worktrees so parallel edits do not overwrite each other. It also adds automatic code review from a second model with findings linked to file:line, which is especially useful for spotting Go concurrency mistakes such as a missing defer or a shared map access. Checkpoints let you undo an agent turn if a refactor breaks go test -race, and token budgets keep one agent from consuming the entire day’s limit while preserving its conversation.
Keep the loop tight
Start with a focused GEMINI.md and small, test-backed prompts. For every change, inspect the diff, run gofmt, go vet, and go test -race, and watch goroutine and dependency changes closely. When you need more throughput, isolate parallel agents with worktrees and a review pass. That is the practical way to make Gemini CLI a useful member of a Go team.