Skip to content
JavaAgentic

Type at least two characters. Try “RAG”, “pgvector” or “tool calling”.

Building Autonomous Coding Agents

Design autonomous coding agents in Java: code generation with verification, review agents that bias for precision, refactoring and test-generation agents — with the guardrails they need.

Advanced4 min readUpdated
On this page

Coding agents are among the most useful and most dangerous agents to build — useful because code has objective verification (it compiles or it does not), dangerous because a coding agent with real access can do real damage. This tutorial covers the main types and the guardrails each needs.

Key Takeaways

  • Coding agents have objective feedback — compile and test results — so let them verify.
  • Review agents must bias for precision; false positives get them muted.
  • Sandbox generated code; never run it against production.
  • Human approval before any change is merged or deployed. No exceptions.

The verify-and-revise loop

The single most important design idea: a coding agent should run its output and revise based on real feedback, not guess.

Generate, compile, test, revise
public GeneratedCode generate(String task) {
    String code = generator.write(task);
 
    for (int attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
        // Objective feedback — the whole reason coding agents can be reliable.
        CompileResult compile = sandbox.compile(code);
        if (!compile.success()) {
            code = generator.fix(code, compile.errors());
            continue;
        }
        TestResult tests = sandbox.runTests(code);
        if (tests.allPassed()) {
            return new GeneratedCode(code, tests);
        }
        code = generator.fix(code, tests.failures());
    }
    // Never present unverified code as done.
    return GeneratedCode.needsHumanReview(code);
}

The review agent

The DevAgentic project builds one in full. The core discipline is precision over recall:

A precision-biased reviewer
private static final String SYSTEM = """
        Review this Java diff for correctness and security bugs only.
        Report only issues you can point at a specific line for.
 
        Do NOT report style, formatting, or preferences without a defect.
        An empty findings list is a good review. Reviewers who always find
        something get ignored.
        """;

The test-generation agent

Good at breadth — the edge cases humans skip — but weak at knowing what matters:

@Tool("Generate JUnit 5 tests for the given class. Cover edge cases, boundaries and null handling.")
String generateTests(String className, String sourceCode) {
    // Produce tests, then run them so you do not hand back tests that fail to
    // compile or that assert nonsense.
    String tests = testWriter.write(className, sourceCode);
    var result = sandbox.compileAndRun(sourceCode, tests);
    return result.compiles() ? tests : testWriter.fix(tests, result.errors());
}

The refactoring agent

Refactoring has a clear safety net — the tests must still pass:

public RefactorResult refactor(String code, String goal) {
    TestResult before = sandbox.runTests(code);
    if (!before.allPassed()) {
        return RefactorResult.blocked("existing tests fail; fix them first");
    }
 
    String refactored = refactorer.apply(code, goal);
    TestResult after = sandbox.runTests(refactored);
 
    // Behaviour must be preserved — that is what makes it a refactor.
    return after.equals(before)
            ? RefactorResult.success(refactored)
            : RefactorResult.rejected("tests changed; not a safe refactor");
}

Guardrails: the non-negotiables

A coding agent's guardrails: sandboxed execution, scoped access, and human approval before any real change.
  • Sandbox everything. Generated code runs in an isolated environment — a container, never your build server or production.
  • Scope access. The agent touches only the files and commands the task needs. No blanket shell access to your infrastructure.
  • Human approval to merge or deploy. The agent proposes; a person disposes. See human-in-the-loop systems.
  • Log every action for audit and debugging.

What coding agents are good and bad at

Good at: boilerplate, test breadth, mechanical refactors, catching concrete bugs in review, translating between well-specified formats.

Bad at: architectural judgement, knowing what behaviour is intended, understanding business context, and any task where "looks plausible" and "is correct" diverge — which is exactly why the verify loop and human approval matter.

Next

Frequently Asked Questions

How do coding agents verify their own output?
By running it. A code-generation agent that can compile the code and run tests as tools gets objective feedback — did it compile, did the tests pass — instead of guessing. This verify-and-revise loop is what separates a coding agent that produces plausible-looking code from one that produces code that actually works.
Can an AI review bot replace human code review?
No, and it should not try to. A review agent is best as a first pass that catches concrete correctness and security issues, leaving judgement, design and context to humans. Bias it hard toward precision — false positives train reviewers to ignore it, which destroys its value faster than missing issues does.
What guardrails does a coding agent need?
Run generated code in a sandbox, never against production; require human approval before changes are merged or deployed; scope file and command access to what the task needs; and log every action. A coding agent with unrestricted shell access to your infrastructure is a serious risk regardless of its intentions.
Are test-generation agents actually useful?
Yes, with supervision. They are good at generating the tedious breadth of tests — edge cases, boundary values, null handling — that humans skip. They are weaker at knowing what behaviour actually matters, so treat generated tests as a draft a human reviews, and be wary of tests that merely assert current behaviour rather than intended behaviour.

Related tutorials