Automated code review is one of the most practical applications of AI in software development. In this guide, you’ll learn how to build an AI-powered code review agent using LangChain4j and Spring Boot that integrates with GitHub to automatically review pull requests.
Why Build an AI Code Review Agent?
Manual code reviews are time-consuming and inconsistent. Studies show that developers spend up to 6 hours per week on code reviews. An AI agent can:
- Catch common bugs and security vulnerabilities instantly
- Enforce coding standards consistently
- Provide educational explanations for junior developers
- Review PRs in seconds, not hours
Architecture Overview
1
2
3
4
5
| GitHub Webhook → Spring Boot API → LangChain4j Agent → LLM (GPT-4 / Claude)
↓
Structured Analysis
↓
GitHub PR Comment
|
The agent receives a GitHub webhook when a pull request is opened or updated, analyzes the diff using an LLM, and posts review comments back to the PR.
Prerequisites
- Java 21+
- Spring Boot 3.2+
- A LangChain4j dependency
- GitHub personal access token
- OpenAI or Anthropic API key
Step 1: Project Setup
Create a new Spring Boot project and add the LangChain4j dependency:
1
2
3
4
5
6
7
8
9
10
| <dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-open-ai-spring-boot-starter</artifactId>
<version>0.36.2</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j</artifactId>
<version>0.36.2</version>
</dependency>
|
LangChain4j’s @AiService annotation makes it incredibly simple to define an AI-powered interface:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| @AiService
public interface CodeReviewService {
@SystemMessage("""
You are an expert Java code reviewer. Analyze the provided code diff and:
1. Identify bugs, security vulnerabilities, and performance issues
2. Check for proper error handling
3. Verify thread safety
4. Suggest improvements with specific code examples
5. Rate severity: CRITICAL, WARNING, or SUGGESTION
Be specific. Reference exact line numbers and provide fix suggestions.
""")
String reviewPullRequest(
@UserMessage String diffContent,
@UserMessage String context
);
}
|
Step 3: GitHub Integration
Use the GitHub API to fetch pull request diffs:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| @Service
public class GitHubService {
private final GitHubClient gitHubClient;
public PullRequestDiff getDiff(String repoOwner, String repoName, long prNumber) {
String url = "/repos/%s/%s/pulls/%d".formatted(repoOwner, repoName, prNumber);
return gitHubClient.get(url, PullRequestDiff.class);
}
public void postReviewComment(String repoOwner, String repoName,
long prNumber, String comment) {
String url = "/repos/%s/%s/pulls/%d/comments".formatted(
repoOwner, repoName, prNumber);
gitHubClient.post(url, new CommentRequest(comment));
}
}
|
Step 4: Build the Webhook Endpoint
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
| @RestController
@RequestMapping("/api/webhooks/github")
public class GitHubWebhookController {
private final CodeReviewService reviewService;
private final GitHubService gitHubService;
@PostMapping
public ResponseEntity<Void> handleWebhook(
@RequestBody GitHubWebhookEvent event,
@RequestHeader("X-GitHub-Event") String eventType) {
if (!"pull_request".equals(eventType)) {
return ResponseEntity.ok().build();
}
if (!"opened".equals(event.getAction()) &&
!"synchronize".equals(event.getAction())) {
return ResponseEntity.ok().build();
}
// Fetch the diff
PullRequestDiff diff = gitHubService.getDiff(
event.getRepo().getOwner(),
event.getRepo().getName(),
event.getPullRequest().getNumber()
);
// Run AI review
String review = reviewService.reviewPullRequest(
diff.getContent(),
buildContext(event)
);
// Post comments back
gitHubService.postReviewComment(
event.getRepo().getOwner(),
event.getRepo().getName(),
event.getPullRequest().getNumber(),
review
);
return ResponseEntity.ok().build();
}
}
|
Step 5: Java-Specific Review Rules
For Java projects, enhance the system prompt with specific rules:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| @SystemMessage("""
You are reviewing Java/Spring Boot code. Pay special attention to:
Security:
- SQL injection (especially MyBatis ${} vs #{})
- Improper input validation
- Sensitive data exposure in logs
Spring Boot:
- Missing @Transactional on write operations
- Incorrect transaction propagation
- Bean scope issues (singleton vs prototype)
- Missing @Valid on request DTOs
Concurrency:
- Race conditions in synchronized blocks
- Improper use of CompletableFuture
- Thread pool configuration issues
Performance:
- N+1 query problems (Hibernate/MyBatis)
- Missing pagination
- Inefficient collection operations
- Memory leaks (unclosed resources)
""")
|
Step 6: Rate Limiting and Cost Control
LLM API calls can get expensive. Implement rate limiting:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| @Configuration
public class RateLimitConfig {
@Bean
public Bucket reviewBucket() {
return Bucket.builder()
.addLimit(Bandwidth.classic(50, Refill.intervally(50,
Duration.ofHours(1))))
.build();
}
}
// In your service
public Optional<String> reviewWithLimit(String diff) {
if (reviewBucket.tryConsume(1)) {
return Optional.of(reviewService.reviewPullRequest(diff, ""));
}
return Optional.empty();
}
|
Deployment
Deploy as a Spring Boot application. For GitHub integration, use ngrok for local testing or deploy to a cloud platform.
Key configuration:
1
2
3
4
5
6
7
8
9
10
| langchain4j:
open-ai:
chat-model:
model-name: gpt-4o
temperature: 0.1
timeout: 60s
github:
webhook-secret: ${GITHUB_WEBHOOK_SECRET}
token: ${GITHUB_TOKEN}
|
Results and Next Steps
After deploying, expect the agent to catch common issues like:
- Missing null checks
- SQL injection via MyBatis string interpolation
- Thread safety issues in concurrent code
- Improper exception handling
Next improvements:
- Add file-level review for context awareness
- Support for multiple LLM providers (Claude, Gemini)
- Custom rule configuration per repository
- Review history and trend analysis
Conclusion
Building an AI code review agent with LangChain4j takes surprisingly few lines of code. The combination of LangChain4j’s @AiService and Spring Boot’s dependency injection makes it easy to create production-ready AI tools.
The full source code is available on GitHub.
Have questions? Leave a comment below or reach out on Twitter @javadevai.