karasu 每週更新:調校 AI 程式碼審查帶來的經驗
Rate limits, skipped steps, and hooks: what tuning AI code review for agent PRs taught me (karasu weekly)
karasu 本週更新記錄了為 Agent PR 調校 AI 程式碼審查的經驗:反覆審查會消耗配額並觸發速率限制,書面流程亦未能確保執行。最近 60 個已合併 PR 中,37 個經 CodeRabbit 審查,共進行 80 次審查,其中 43 次為重審,並在 5 個 PR 提出 10 項新發現。
karasu is a text modeling language for system architecture, inspired by the C4 model.
You describe your system in .krs files and karasu draws the views: system, deployment, and team structure.
I haven't written its code by hand; everything goes through Claude Code.
This is the third weekly update.
It covers changes merged from October 18 to 24.
This time I start with what I learned building with agents, then go through what shipped.
This week in numbers: 50 PRs merged (11 of them Dependabot) and 6 decisions recorded as ADRs.
No release went out this week.
The unreleased changes, including both highlights below, are due in today's monthly release (see "Coming next").
Lessons from building with agents this week
CodeRabbit's review works where I can't follow the details.
CodeRabbit reviews karasu's PRs.
In one earlier PR, it pointed out a case in edges between cards in the same row: the two points of the route around a card sat at the same height.
The route check treated a corridor of zero height as invalid and threw away the clear route.
So the straight route through the cards stayed.
karasu's layout logic is complex enough that I had found it hard to review in detail.
Findings like this, ones I would never have thought of, help a lot.
But a re-review on every fix uses up the quota.
Each time the agent fixes a finding and pushes, CodeRabbit reviews again.
Repeat that and you hit the rate limit, and the PR waits.
On one PR, CodeRabbit reviewed six times.
Two would have been enough: the first review and one round of fixes. Three of the extra runs found one class of problem one instance at a time.
The quota then was 2 reviews an hour, and each wait was 38 to 39 minutes.
After four pushes in a row, CodeRabbit paused automatic reviews, and from then on each one had to be requested by hand.
Dropping re-reviews isn't the answer either.
I counted the 37 CodeRabbit-reviewed PRs among the last 60 merged.
They took 80 reviews, 43 of them re-reviews.
Re-reviews raised 10 new findings on 5 PRs, all in files that the fix commits touched.
So I cut problems down before the web review.
This is the order I follow now.
- Set a risk tier from the paths a change touches, and review deeper where the tier is higher (the design is merged; implementation is next). Changes to ADRs or tests alone merge automatically after approval; changes to workflows, releases, or dependencies get a human reading the diff.
- Before taking a PR out of draft, run the
/engineering:code-reviewskill locally. - Then run the CodeRabbit CLI once. The CLI's quota (10 an hour) is separate from PR reviews.
- If that comes back clean, mark the PR ready and send it to the web review.
Written steps weren't followed.
The step to run the CLI used to live only in a local memory note of the agent.
Of about 290 sessions since October 1 that created or readied a PR, one ran the CLI.
Even after I added the step to the procedure, a session the next day readied a PR without the local review.
The step that hands a readied PR over to working through CodeRabbit's findings ran in about 7 of about 40 sessions.
Most of those times, I typed it myself.
So the steps are becoming Claude Code hooks.
A hook that hands over to that step right after gh pr ready is merged, and a hook that refuses gh pr ready before the local review is in a PR now.
The trial and error turned up holes in the process.
The main checkout had a Stop hook that reported uncommitted changes when a session ended.
It was meant to prevent commits made straight onto main.
It never blocked such a commit; it only reported at the end.
On October 24, it kept a session from exiting over changes I had left behind by hand.
I dropped the Stop hook and made lefthook's pre-commit refuse commits on main.
Because it is a Git hook, it applies to whoever commits.
The ADR also records what still gets through, such as cherry-pick and --no-verify.
In another project, I'm trying automatic merges decided by a change's impact.
It started with How the Claude Code team does code review.
The Claude Code team describes how they review code there, and their way of trusting agents to land changes on main influenced me strongly.
I'm trying it in a private project.
The idea matches karasu's risk tiers and goes one step further.
- The tier comes from the paths a change touches, not from its author. Docs alone skip the AI review; ordinary changes go through the AI review, the checks, and the end-to-end tests. Touching migrations, authentication, outbound sends, or the gate itself adds a human approval.
- Approval works only from a human's terminal; the agent can't approve.
- An unresolved finding from the AI review blocks the merge. Reviews stop at three rounds, and from the second round on they look only at what changed since the last one.
- An eval built from past fixes measures how many of 19 bugs the reviewer finds. Revising the review guidelines took it from 5 to 7. The number is generous, since I revised and measured on the same 19 cases.
- The AI review also found holes in the gate itself. A change could rewrite the rules that judge it and rate itself low. The gate now judges with the rules from the version on main.
It's still being built, and no change has gone through it yet.
I'll report once it runs.
Hand over the whole import graph, not just the open file
Last week I fixed karasu serve from npm, which hadn't worked at all.
Even so, serve in 0.9.0 couldn't draw a model that imports other files.
It put only the opened file into the browser's in-memory file system, renamed to /serve/index.krs.
Every import reported "File not found".
The design compared three options.
-
A: hand over the whole served directory. A new
GET /api/projecton the server returns every.krsand.krs.styleunder it in one response. - B: read files one at a time over HTTP. Two new endpoints that take a path, and one round trip per file on every compile.
- C: walk the imports on the server and return only the files needed. It would add a new public helper to core to save a few tens of KB.
The cost of A is sending the whole directory.
Measured on the entire karasu repository, that came to 108 files and 164 KB, so I went with A.
The app places the files it receives at their real paths and fetches them again whenever a file changes.
Imports now resolve by the same rules as karasu render, and saving an imported file or a style sheet redraws the preview.
When only an imported file changes, the view you drilled into stays where it was.
GET /api/project takes no path from the request and doesn't follow symbolic links.
Nothing outside the served directory comes back.
Along the way, a file in a subdirectory (/services/order) can now be opened; before, it couldn't be opened at all.
The nightly end-to-end test for serve got a fix too.
It had been serving the regular app build instead of the serve build that the npm package actually ships.
It's the same lesson as last week, that only a test running the packaged artifact catches this kind of bug, and the test now runs the shipped build.
Share is back in serve.
Share links point at the public app (karasu.kompiro.dev), so whoever receives one can open the diagram without running karasu.
One viewer for the app and the editor, reading unsaved buffers first
The Visual Studio Code extension's preview used to be a webview written by hand for the extension.
Every feature added to the app's preview had to be ported to Visual Studio Code separately.
Now the webview runs the app's viewer as it is.
The work came in three PRs.
- Add the seams on the app side. A host can now drive the viewer: tell it where to read files, get notified of jumps, and switch the theme and language.
- Replace the Visual Studio Code preview. The hand-written webview is gone, and the webview runs the app's viewer. Pan and zoom, the CRUD view, facets, and edge hover with the detail panel now work in Visual Studio Code without a port.
- Write preview edits back to the editor. Picking an edge direction from the right-click menu puts the change into the editor's buffer, unsaved. The editor's undo takes it back.
The viewer asks the extension for every file it reads.
The extension reads the open editor buffer first and falls back to the disk.
So unsaved edits show up in the preview as you type.
That holds for imported files as well as the open one.
The old preview read from the disk, so unsaved edits never reached the diagram.
I found this by reading the code during the design survey and haven't reproduced it in Visual Studio Code.
On a write, the extension compares the buffer with the text the viewer last read.
If you typed something in between and the text changed, nothing is written.
The check keeps a write from overwriting your own edit.
Jumping to a node defined in an imported file now opens the right file, too.
Other changes this week
karasu fmt no longer moves comments to the end of the file.
karasu fmt and format-on-save printed every comment written above or beside a property line at the end of the file.
Property lines have no position in the AST, and every block kind had the same problem: edges, deploy, organization, and more.
Comments now stay next to the line they annotate.
All 16 new tests fail against the formatter on main before the fix.
The two bugs last week's e2e tests found are fixed.
Last week's post listed them as not yet fixed.
The first: shortcuts such as Ctrl/Cmd+B fired while you typed in the editor.
In Chromium, Monaco takes input through a div with the EditContext API attached.
That element now counts as a text input.
The second: reloading while the deployment view or the matrix was open dropped you back on the system view.
Lanes stay inside a drill-down frame.
In a drill-down view, the lanes for edges running beside the cards went onto or past the frame's sides.
Across 4 models and 1,542 views, vertical runs on or outside the frame went from 3,100 to 31.
The canvas grew by 1.5% in exchange.
One view got more crossings (TwentyServer in the Twenty model, +2,018), and a separate Issue tracks it.
translate --from db handles migration history.
It now replays migrations, from drizzle and others, in order, so dropped tables and temporary tables from rebuilds no longer remain.
That fix opened a hole of its own, though.
A ) inside a string literal ended the CREATE TABLE body early, so a value such as DEFAULT ') DROP TABLE a' replayed a DROP TABLE.
Another PR closed it before any release.
Small fixes.
Edges tagged [inferred] were drawn in the same color as untagged edges, against the spec. I measured three color options and switched to one that stands apart.
The .krs.style lexer silently dropped every non-ASCII character, so a Japanese selector such as #注文 had no effect.
179 relative links in the reference docs bundled with the skills broke once installed. They are now rewritten when the files are copied.
Coming next
- Today, October 25, is the last Sunday of the month, when the monthly release train leaves. 16 unreleased changesets, including both highlights, are due on npm and the Visual Studio Code Marketplace.
- The implementation of review depth by risk tier is still ahead (its Issue is open).
- An Issue is open to make
/coderabbit-convergefix every instance of a finding's class before pushing.
- Site: karasu.kompiro.dev
- Source: github.com/kompiro/karasu
來源:DEV Community · dev.to