iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🪓

Changing How I Structure PRs Made My AI Significantly Smarter

に公開

"This PR has +1,200 lines—can you review it by the end of the day?"

I froze upon seeing the Slack notification.

I opened the diff. 32 files. 1,247 lines changed. One commit. The message: "feat: implement user dashboard."

—I scrolled, and scrolled, and it never seemed to end.

Introduction

Now that AI-powered coding agents have become the norm, the "speed of generation" for code has skyrocketed. However, code review processes are starting to collapse at the same rate.

Recently, the "GitHub Lines Viewed" extension—a tool to help maintain sanity by showing a progress bar when reviewing massive AI-generated PRs—was trending on Hacker News.

Perhaps many people are thinking, "Since AI writes so much code, we need to streamline the review process too."

But I realized something else. The problem isn't the review process itself. The way we cut PRs is broken. And once I fixed that, even the quality of the AI's output improved.

Why AI PRs Bloat

The cause is simple. When you instruct an AI agent to "build a dashboard feature," the AI dutifully tries to do it all at once.

API routes, components, state management, tests, styling—while a human would naturally break this down into "API first," then "UI next," the AI delivers the entire thing as one monolithic piece.

In my team, the same thing started happening after we introduced Claude Code.

# A list of PRs from the other day
PR #142: feat: implement notification system (+2,834 lines)
PR #143: fix: typo in README (+1 line)
PR #144: feat: add analytics dashboard (+1,891 lines)

A one-line fix and a 2,000-line feature addition appear as equal "1 PR" items. Reviewers approve PR #143 in seconds, while PR #142 and #144 remain unreviewed for three days, ignored with a "I'll look at it later."

Specifically, here is what makes this painful:

// Part of the diff from PR #142 (Notification System)
// File: src/notifications/NotificationProvider.tsx
export const NotificationProvider: React.FC<Props> = ({ children }) => {
  const [notifications, setNotifications] = useState<Notification[]>([]);
  const ws = useRef<WebSocket | null>(null);

  useEffect(() => {
    ws.current = new WebSocket(process.env.NEXT_PUBLIC_WS_URL!);
    ws.current.onmessage = (event) => {
      const data = JSON.parse(event.data);
      setNotifications(prev => [...prev, data]);
    };
    return () => ws.current?.close();
  }, []);
  // ... continues for another 200 lines

WebSocket connections, state management, UI components, toast notifications, read receipts—everything is packed into a single PR. A reviewer has to judge whether the "WebSocket connection logic is correct" and whether the "toast animation is appropriate" simultaneously. The cognitive load is simply too high.

Public Sentiment

There are broadly two schools of thought on this issue.

The "Review Tool" camp argues: "Code written by AI should be reviewed by AI. You need an LLM-based review bot." Indeed, tools like GitHub Copilot PR Review and CodeRabbit are spreading rapidly.

The "Human Must Read Everything" camp argues: "Whether it's auto-generated or hand-written, a human should read every line before merging. That is a professional's responsibility."

—Honestly, both sound logical, but neither resonated with me.

AI reviews are convenient, but they cannot make context-dependent judgments like, "Is this WebSocket connection okay given our infrastructure configuration?" On the other hand, having a human meticulously read 2,000 lines every time is not sustainable in reality.

Both approaches assume that "massive PRs will inevitably be sent your way." But isn't that premise itself flawed?

Designing PR Granularity as a Human

What I tried was to design "how to cut the PRs" first, before instructing the AI on "what to build."

Specifically, I do it like this:

# Implementation Plan for Notification System

## PR 1: WebSocket connection foundation (Guide: under 200 lines)
- Set up WebSocket client
- Handling connection, disconnection, and reconnection
- Tests

## PR 2: Notification data model and store (Guide: under 150 lines)
- Type definitions for notifications
- State management (zustand or context)
- Tests

## PR 3: Notification UI components (Guide: under 250 lines)
- Toast display
- Notification list panel
- Toggle read/unread status

## PR 4: Integration and integration tests (Guide: under 200 lines)
- Integration of PR 1-3
- E2E tests

I create this before passing it to Claude Code. Then, I assign tasks on a per-PR basis.

# Bad example
claude "Implement the notification system"

# Good example
claude "Implement the WebSocket connection foundation. Limit the scope to the range of PR 1 in this document."

The key is to explicitly state constraints like "Guide: under 200 lines." When given constraints, AI surprisingly adheres to the scope. Conversely, without constraints, it tends to expand indefinitely with "while I'm at it, I'll add this too."

Even in agentic skills frameworks like obra/superpowers, there is a design philosophy of breaking down tasks into small units of skills. Instead of throwing a massive task at an AI agent, you structure it as a combination of skills (= small responsibilities). The same logic applies to PR granularity design.

Realization—The Quality of AI Output Improved

The interesting part was that after I started designing PR granularity as a human, not only did the review process become easier, but the quality of the AI's output itself improved.

The reason is likely simple: AI performs more accurately when the scope is narrow.

If you ask it to "build the entire notification system," the AI tries to ensure overall consistency, leading to half-baked implementations here and there. Even if there's a subtle bug in the WebSocket connection logic, you might not notice it while focusing on the UI-side implementation.

However, if you say "Build only the WebSocket connection foundation, including handling for connection, disconnection, reconnection, and tests," the AI focuses on that narrow scope. It meticulously picks up edge cases. Test coverage naturally becomes higher as well.

In other words, this means:

PR granularity design is not just for the reviewer, but also for the AI.

Constraints are not the enemy of AI. Constraints are AI's focus.

This was also touched upon in an article that was trending on Zenn: "Working with 3 AI agents for a week using Agent Teams + Skills." When coordinating multiple agents, clearly defining the scope for each agent determines the overall quality. Dividing responsibilities yields better results than having one agent do everything. The same applies to PRs.

Conclusion

In an era where AI writes code, what humans should do is not "speed up reviews."

It is to design "what makes up a single PR."

Adding review tools is fine. AI review bots are also convenient. But before that, if a PR exceeds 1,000 lines, something is already broken.

PR granularity is the granularity of instructions to the AI, and the granularity of thought.

Next time, before telling an AI to "build this," take five minutes to pause and write a PR split plan. It will likely change everything—the review, the AI's output, and your team's velocity.

References

Discussion