跳到主内容
精选85GitHub 博客(RSS)技巧与观点

用堆叠式 PR 把巨型 AI 生成代码拆成可审查的栈

Turn one giant AI-generated pull request to a reviewable stack

原文
推荐理由

做 AI 编码代理落地或管理大型代码库的同学必看,这套堆叠 PR 的拆解思路和 gh-stack 用法可以直接照搬,能显著缓解 AI 生成代码的审查难题。

Think about the last big feature you shipped. Be honest. Did you cram it into one giant pull request, or did you split it into smaller scoped pull requests? For years, you have silently had to decide between watching a pull request grow so large that reviewing it becomes a nightmare or breaking it into a chain of smaller pull requests that you have to babysit, sync by hand, and untangle conflicts every time a change is introduced below.

Both options have trade-offs. One is hard to review, while the other is hard to maintain. Your decision that day leans towards the less painful option.

Now add coding agents. They are incredibly productive and are projected to drive a 50% productivity gain across every SDLC stage by 2028, according to Gartner. But, they can’t take away the choice of how you structure your pull requests. They amplify the need to make it.

In this post, follow along with an example of how you can use stacked pull requests to simplify reviews.

A closer look: Adding product search to a shopping assistant

Let’s say you issue a prompt to add product search to a shopping assistant, walk away and minutes later, literally, you come back to review, steer, and approve. But look closely at what tends to land in that single pull request:

  • A new data model and its seed data
  • An API route and its validation
  • The client wiring and the UI and the empty/fallback/error states

…all of this and more in one ginormous 1,000+ line diff.

For agents largely trained on how code has traditionally been written over the years, this pattern is their default way of shipping. Let’s play this out.

You want to add product search on as existing web application and your starting state is:

  • A mock AI Assistant showing responses from a random-line generator
  • Inconsistent product data hardcoded and scattered across components
  • No catalog module, no API, no data layer—no nothing

An issue is opened to implement the feature, and a typical flow would be to create a feature branch, assign it to a coding agent (or multiple custom agents), get a first draft of the whole implementation code and updated tests…

…you read the code (well, you maybe read the code). Then, you still need to manually verify feature behavior and make any necessary updates, push and open a pull request with its long-yet-shallow AI generated description, ensure CI checks are green, and self-review diff then request reviewers. You get started…

<reviewer's hat>

Reviewer: 1,721 lines changed!! This description isn’t very helpful. I’ll review this later.

</reviewer's hat>

And what follows is familiar:

  • The large pull request becomes hard to review—so it just…sits there.
  • Reviewers lose context and the feedback quality drops.
  • It becomes even slower to merge.

This kicks off a manual, messy, time-consuming process that’s prone to conflicts before the feature lands, and it eventually lands under-reviewed.

GitHub stacked pull requests

Stacked pull requests introduce a different and better structure of delivery. The principle is simple: decomposition. Instead of shooting for a single pull request that addresses the issue in its entirety, you break down the feature into logical layers and identify the dependency chain to arrive at your desired goal. This gives you, and your agents, a native way to decompose work that otherwise lands in a giant pull request into a chain of small, focused and independently reviewable layers.

That large pull request that’s hard to review becomes a stack of smaller, logically ordered pull requests, each scoped to a single concern, small enough to hold in a reviewer’s head and with just enough context naturally flowing from the previously reviewed pull request.

Let’s make it happen.

The stack structure

Let’s look at the steps involved when decomposing the problem and arranging the layered stack.

First, and importantly, set the stack base. This matters because CI checks and merge rules throughout the stack management lifecycle get evaluated against the stack base.

Then, identify the core foundational unit of work and put it closer to the base (lowest in the stack), and layer dependent work above it.

Stack Layer (L#)/BranchWhat to shipDepends on
L1 (feat/catalog-data)A typed catalog with seed data, validation, and a data access modulemain (stack base)
L2 (feat/search-api)Validated /api/products/search endpointfeat/catalog-data
L3 (feat/chat-grounding)Chat calls the API and answers from real product datafeat/search-api
L4 (feat/grounded-ui)Product citation cards + statefeat/chat-grounding

Now the independent concerns are clear: data, API, wiring, UX, making it possible to allocate different reviewer audiences for each. Data is reviewed by a data owner, UX by a UI owner.

GitHub’s native support for stacked pull requests can be launched from the pull request UI and extends seamlessly to the terminal with the gh stack CLI.

Install the stacked pull requests CLI extension

Run the following:

gh extension install github/gh-stack

In ancient times, you’d be set to start working. Not today though. There are agents working alongside you. These agents need to learn how stacks work and how to create and manage them on your behalf. The gh-stack skills teaches them this.

gh skill install github/gh-stack

Or, if you prefer:

npx skills add github/gh-stack

For the specific feature from the above example, your development workflow has custom agents, each with defined work streams and that follow a strict scoping discipline to achieve the goal of small, single-scoped pull requests.

Layer/branchAgent
L1 (feat/catalog-data)Data modeler agent
L2 ( feat/search-api)Backend agent
L3 ( feat/chat-grounding)Frontend agent
L4 ( feat/grounded-ui)Frontend agent

The last piece of the setup is to confirm CI exists. As mentioned earlier, each pull request will be evaluated against the stack base, and these checks will run for every layer.

Now the work begins.

Layer one: Data catalog foundation

Most agent workflows today are automated and execute autonomously in loops, but for the sake of illustration, we’ll cover each step at a time.

At this point, all agents are familiar with how stacked pull requests work, so a typical workflow at this stage would be:

  • Invoking the Data Modeler agent with an appropriate prompt
  • The agent initializes a new stack and sets the first branch—feat/catalog-data with main as its base using gh init stack
  • Checks out, works and runs validation
  • (All checks == green) ? commit the layer : Iterate

Reviewer’s note for the future: Are the types correct? Is the data validated? Is the query helper safe? Period.

Layer two: Product search API

Follow a flow similar to:

  • Invoking the Backend agent with an appropriate prompt
  • The agent adds the next layer feat/search-api on top of layer one, its base: feat/catalog-data, to import the completed data access module with gh stack add
  • Checks out, works and runs validation
  • Developer tests the API manually
  • (API works && All checks == green) ? commit the layer : Iterate

Reviewer’s note for the future: Is input validated? Is the response contract stable? Are error/empty states handled here or pushed downstream? Period.

Layer three: Wire chat to the API

In this next layer, you:

  • Invoke the Frontend agent with an appropriate prompt
  • The agent adds the next layer feat/chat-grounding on top of layer two. Its base: feat/search-api, which will branch off with both the data access module and validated API.
  • Checks out, works and runs browser tests with Playwright
  • (All checks == green) ? commit the layer : Iterate

Reviewer’s note for the future: Is every answer tracing back to a real API response? What happens when the API fails or returns nothing? Period.

Layer four: Grounded UI and citations

更进一步:量化金融体系

看懂新闻只是起点——沿量化金融路径,把它变成能交付的工程能力

进入量化体系 →

相似阅读

另一事件,读法相近