An agentic code generation and review pipeline built with Quarkus and LangChain4j. A plain-text spec goes in — reviewed, security-checked Java code comes out.
Local LLM. Five agents. Two self-correcting loops. Your code never leaves your machine.
The pipeline chains five specialized agents in a fixed sequence:
| Agent | Role | Scope key |
|---|---|---|
Coder |
Writes initial code from the spec | writes code |
Reviewer |
Checks quality checklist — APPROVED or FAILED: <reason> |
writes review_status |
Editor |
Rewrites code on failure, returns to Reviewer | writes code |
SecurityReviewer |
OWASP-style security pass | writes security_status |
SecurityEditor |
Patches security issues, returns to SecurityReviewer | writes code |
Review loop (Reviewer ↔ Editor) runs up to 3 iterations until APPROVED.
Security loop (SecurityEditor ↔ SecurityReviewer) runs until APPROVED.
All agents communicate exclusively through a shared agentic scope — a key/value store. No agent holds a reference to any other agent.
| Requirement | Version |
|---|---|
| Java | 25 |
| Maven | via ./mvnw wrapper |
| Ollama | latest — ollama.ai |
| Model | qwen2.5-coder:3b (default) |
Pull the model before starting:
ollama pull qwen2.5-coder:3b# Start with Ollama (default)
./mvnw quarkus:dev
# Start with an OpenAI-compatible endpoint (e.g. LM Studio)
./mvnw quarkus:dev -PopenaiOr use Docker Compose — see Docker below.
Open http://localhost:8090, enter a spec such as:
Write a Java method that validates an email address
The status log shows each agent as it runs:
› Coder is working...
› Coder finished: public static boolean isValidEmail(String email) {...
› Reviewer is working...
› Reviewer finished: FAILED: No Javadoc, missing null check on input...
› Editor is working...
› Editor finished: /** Validates whether the given string is a valid emai...
› Reviewer is working...
› Reviewer finished: APPROVED
› SecurityReviewer is working...
› SecurityReviewer finished: APPROVED
LLM provider is selected via application.properties or Maven profile. No code changes required to switch.
quarkus.langchain4j.chat-model.provider=ollama
quarkus.langchain4j.ollama.base-url=http://localhost:11434
quarkus.langchain4j.ollama.chat-model.model-id=qwen2.5-coder:3b
quarkus.langchain4j.ollama.timeout=PT300S%openai.quarkus.langchain4j.openai.base-url=http://localhost:1234/v1
%openai.quarkus.langchain4j.openai.api-key=lm-studio
%openai.quarkus.langchain4j.openai.chat-model.model-id=local-modelOverride via environment variables — see .env.template.
| URL | Description |
|---|---|
http://localhost:8090/ |
Web UI |
ws://localhost:8090/coding |
WebSocket — send spec as plain text, receive JSON messages |
http://localhost:8090/topology |
Topology Report — HTML execution trace of the last pipeline run |
{ "type": "connected", "content": "Pipeline ready." }
{ "type": "status", "content": "Coder is working..." }
{ "type": "result", "content": "<generated code>" }
{ "type": "error", "content": "<error message>" }After each pipeline run, GET /topology returns an HTML report of the full execution trace — which agents ran, how many loop iterations occurred, and how long each step took.
Useful for debugging slow pipelines and for auditing what the agents actually did — relevant when AI-generated code goes into a team review workflow.
src/main/java/de/markserver/agentic/coding/
├── boundary/
│ ├── CodingWebSocket.java @WebSocket(path="/coding")
│ └── TopologyResource.java GET /topology
└── control/
├── CodingAgents.java 5 agent interfaces
├── CodingPipeline.java pipeline builder (@ApplicationScoped)
└── WebSocketAgentListener.java AgentListener → WebSocket streaming
src/main/resources/
├── application.properties
└── prompts/ externalized prompt templates
A pre-built image is published to the GitHub Container Registry on every push to main — built with Quarkus Jib, no Docker daemon required in CI.
docker pull ghcr.io/mgoericke/agentic-coding-assistant:latestPulls qwen2.5-coder:3b automatically on first run (~2 GB).
docker compose upWorks with LM Studio, the OpenAI API, or any compatible endpoint.
# LM Studio running on your host machine (default)
docker compose -f docker-compose.openai.yml up
# OpenAI API
OPENAI_BASE_URL=https://api.openai.com/v1 \
OPENAI_API_KEY=sk-... \
OPENAI_MODEL=gpt-4o \
docker compose -f docker-compose.openai.yml up./mvnw package -Dquarkus.container-image.build=true<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-agentic</artifactId>
<version>1.13.1-beta23</version>
</dependency>
<dependency>
<groupId>io.quarkiverse.langchain4j</groupId>
<artifactId>quarkus-langchain4j-ollama</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-websockets-next</artifactId>
</dependency>langchain4j-agentic provides the Sequence, Loop, Parallel, and Conditional pipeline primitives. Agents and pipelines are built programmatically per request — no hidden CDI wiring.
# Unit tests
./mvnw test
# Integration tests
./mvnw verify -DskipITs=false- Test coverage —
@QuarkusTestsmoke tests for WebSocket and/topologyendpoint - Feedback loop — send corrections back into a second pipeline run
- TestWriter agent — generate unit tests as a sixth pipeline step
- Picocli CLI boundary — run the same pipeline from terminal or CI
- Human in the Loop — pause after first Reviewer pass for manual approval
- Domain-specific skills — swap agent prompts for document review, PR summaries, or requirements analysis
| Runtime | Quarkus 3.35.1 |
| Language | Java 25 |
| Agentic pipeline | langchain4j-agentic 1.13.1-beta23 |
| LLM providers | Ollama · OpenAI-compatible (LM Studio) |
| WebSocket | quarkus-websockets-next |
| REST | quarkus-rest-jackson |

