Cut AI agent token usage by 86–96% on Go codebases. One compact
ARCHITECTURE.mdreplaces reading every source file — agents navigate faster, cost less, hallucinate less.
- Install
- Quick start
- Why it works
- Token savings benchmark
- Commands
- Using with AI agents
- Global flags
- Export formats
- Graph layers
Install script (Linux & macOS):
curl -sS https://raw.githubusercontent.com/kriuchkov/go-build-graph/master/install.sh | shGo install:
go install github.com/kriuchkov/go-build-graph/cmd/go-build-graph@latestBuild from source:
git clone https://github.com/kriuchkov/go-build-graph.git
cd go-build-graph
go build -o go-build-graph ./cmd/go-build-graphDownload binary:
Download the latest release from the Releases page.
# 1. Build the graph (run in your module root)
go-build-graph build --symbols ./...
# 2. Generate ARCHITECTURE.md
go-build-graph report --out ARCHITECTURE.mdCommit ARCHITECTURE.md alongside your code so agents always have an up-to-date map.
An AI agent exploring a codebase reads source files to answer three questions:
- Where is the code? (which package)
- What exists there? (types, interfaces, functions)
- How is it connected? (imports, implements)
Source files bury these answers inside implementation. ARCHITECTURE.md answers only those three questions — nothing else.
| What's in source files | In ARCHITECTURE.md |
|---|---|
| Function bodies | — |
| Parameter types and signatures | — |
| Struct field types | — |
| Constant values | — |
| Comments and docstrings | — |
| External imports | — |
| Test files | — |
| Package names | ✓ |
| Type / interface / func names | ✓ |
| Intra-module import graph | ✓ |
| Interface → implementor map | ✓ |
The agent reads ARCHITECTURE.md first to build a map, then opens only the specific files it needs to edit.
| Project | Non-test .go files |
Source tokens | ARCHITECTURE.md tokens |
Saved |
|---|---|---|---|---|
| go-build-graph (this repo) | 35 | ~17 300 | ~2 400 | 86 % |
| gin v1 | 58 | ~55 000 | ~2 300 | 96 % |
Token estimate: characters ÷ 4 (standard approximation for mixed code/prose). Test files excluded — agents read them when running tests, not when exploring structure.
Run the same measurement on your repo:
# Source tokens (exclude tests and vendor)
find . -name "*.go" -not -path "*/testdata/*" -not -path "*/vendor/*" -not -name "*_test.go" \
| xargs cat | wc -c
# → divide by 4
# ARCHITECTURE.md tokens
wc -c < ARCHITECTURE.md
# → divide by 4go-build-graph build ./... # packages only (layer 1)
go-build-graph build --symbols ./... # + symbols, interfaces (layer 2)
go-build-graph build --calls ./... # + call graph via RTA (layer 3)
go-build-graph build --calls --algo cha ./... # use CHA instead of RTAResults are saved to graph.json.gz. Subsequent runs use a checksum cache — only changed packages are re-analysed.
go-build-graph report # writes ARCHITECTURE.md in current dir
go-build-graph report --out docs/arch.md # custom pathGenerates a standalone markdown file with:
- Package list with interfaces, structs, functions, and intra-module imports
- Interface/implementor table
go-build-graph update-docs # updates ARCHITECTURE.md (default)
go-build-graph update-docs --docs README.md # inject into READMEWrites (or refreshes) a section between HTML comment markers:
<!-- go-build-graph:start -->
## Architecture
...
<!-- go-build-graph:end -->Re-running is idempotent — only touches the file when content changes.
go-build-graph find Store # any symbol named Store
go-build-graph find Store --kind interface # interfaces only
go-build-graph find Store --package myapp/store # only in that package subtree
go-build-graph find Store --json # machine-readable outputgo-build-graph refs pkg:example.com/myapp/store
go-build-graph refs sym:example.com/myapp/store#Store --relation implements
go-build-graph refs sym:example.com/myapp/store#Store --relation calls --incominggo-build-graph context sym:example.com/myapp/store#MemoryStore
go-build-graph context sym:example.com/myapp/store#MemoryStore --jsongo-build-graph export --format dot # GraphViz DOT to stdout
go-build-graph export --format mermaid --out g.mmd # Mermaid to filePipe the DOT output into dot -Tsvg (GraphViz) to render an SVG. Paste the Mermaid output directly into GitHub markdown fences or mermaid.live.
go-build-graph view # write graph.html to current dir
go-build-graph serve # interactive dashboard at http://localhost:8080
go-build-graph serve --addr :9090Use the composite action to regenerate ARCHITECTURE.md automatically on every push:
# .github/workflows/architecture.yml
name: Update architecture docs
on: [push]
jobs:
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: kriuchkov/go-build-graph/action@v1
with:
symbols: 'true'
docs: ARCHITECTURE.md
commit: 'true'Add an AGENTS.md to your repo root:
# Using this codebase
If ARCHITECTURE.md exists, read it first — it has the package map and key interfaces.
## Finding things
go-build-graph find <name> --json
go-build-graph refs <id> --relation implements
go-build-graph context <id> --jsonClaude Code picks up AGENTS.md automatically. The agent reads ARCHITECTURE.md first, then calls go-build-graph to explore relationships before editing.
Add a step to your CI or a git pre-commit hook:
go-build-graph build --symbols ./... && go-build-graph update-docs --docs ARCHITECTURE.md
git add ARCHITECTURE.md| Flag | Default | Description |
|---|---|---|
--module-path |
. |
Path to the Go module root |
--out |
. |
Output directory for graph and report |
--graph |
graph.json.gz |
Path to an existing graph file |
--packages |
./... |
Package patterns to analyse |
--no-cache |
false | Disable incremental cache |
--verbose |
false | Debug logging to stderr |
--json |
false | JSON output for find, refs, context |
| Format | Flag | Renderer |
|---|---|---|
| GraphViz DOT | --format dot |
dot -Tsvg, Graphviz, VS Code extension |
| Mermaid | --format mermaid |
GitHub markdown, mermaid.live, Obsidian |
| Layer | Flag | Content |
|---|---|---|
| 1 | (default) | Package nodes + import edges |
| 2 | --symbols |
+ structs, interfaces, funcs, methods, fields, implements edges |
| 3 | --calls |
+ call graph edges (RTA or CHA) |
