Give your agents a `check` command
A simple idea can elevate your developer productivity significantly when using agents. In my previous thought piece, I discussed how agents waste time figuring out relevant tools to check their work. This is especially bad if your project uses some non-standard tools, frameworks or has complex build steps. The agent will waste a lot of time trying to figure out how to check its work, and it may even fail to do so.
For example, my side project https://umka.day has a complex build process envolving WASM compilation. To make sure the main app passes typecheck the agent needs to:
- Figure out to run Rust -> WASM compilation
- Copy generated WASM files to the right place
- Run the main app typecheck command
Even if you have scripts to automate these steps the agent might forget to run them and be stuck in a frustration loop trying to understand why newly added methods are missing (because of the stale TypeScript definition not being updated). I’ve seen agents trying to analyze 10mg WASM glue code and it’s just a waste of time.
The biggest productivity leap happened when I added a check command to my project. This command runs all the necessary steps to check the work of the agent and it is the only command the agent needs to know about. The agent can simply run check after making changes.
This particular project uses a combination of mise and Bazel
[tasks.check]
description = "Build server and check TypeScript (parallel)"
depends = [
"proto",
"wasm",
"check:server", # uses Bazel
"check:ts",
"check:e2e",
"check:landing",
"check:test",
"check:lint",
"telemetry:schema",
"bundle"
]
⏺ Build error in hotkeys.ts. Let me see the actual error:
⏺ Bash(mise run check 2>&1 | grep -A 5 "hotkeys")
⎿ [//:check:ts] web/app/src/hotkeys.ts(1,23): error TS2307: Cannot find module 'hotkeys-js' or its corresponding type declarations.
[//:check:server] WARNING: Build option --compilation_mode has changed, discarding analysis cache (this can be expensive, see https://bazel.build/advanced/performance/iteration-speed).
[//:bundle] Rsbuild v1.7.3
… +31 lines (ctrl+o to expand)
⎿ (timeout 5m)
The actual choice of tools and commands is not that important. The important part is that the agent only needs to know about one command and this command then can be arbitrarily complex. The most challenging part if to keep this command fast enough so that the agent can iterate quickly. In my case, the check command takes around 30 seconds to run because I leverage a lot of parallelism and agressive caching.
For large codebases you might need to encorporate more complex logic into the check. For example, the combination of Bazel, bazel-diff and remote builds works really well. For small and medium sized codebases tools like mise offer a good balance of simplicity and performance but still require some setup and maintaince to keep the check command fast, e.g. setting up inputs, outputs and dependencies for your tasks so mise knows how to cache and when to rebuild.