The code and data behind xeiaso.net
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(blog): add reviewbot post (#1107)

* feat(blog): add first reviewbot draft

Signed-off-by: Xe Iaso <me@xeiaso.net>

* feat(blog/reviewbot): finish prose

Signed-off-by: Xe Iaso <me@xeiaso.net>

---------

Signed-off-by: Xe Iaso <me@xeiaso.net>

authored by

Xe Iaso and committed by
GitHub
bbec4739 fc0df877

+154
+154
lume/src/blog/2026/reviewbot.mdx
··· 1 + --- 2 + title: "I made a simple agent for PR reviews. Don't use it." 3 + desc: "Reviewbot is eternal, yet also very cooked." 4 + date: 2026-01-11 5 + # hero: 6 + # ai: "" 7 + # file: "" 8 + # prompt: "" 9 + # social: false 10 + --- 11 + 12 + My coworkers really like AI-powered code review tools and it seems that every time I make a pull request in one of their repos I learn about yet another AI code review SaaS product. Given that there are so many of them, I decided to see how easy it would be to develop my own AI-powered code review bot that targets GitHub repositories. I managed to hack out the core of it in a single afternoon using a model that runs on my desk. I've ended up with a little tool I call [reviewbot](https://github.com/Xe/x/tree/master/cmd/reviewbot) that takes GitHub pull request information and submits code reviews in response. 13 + 14 + reviewbot is powered by a [DGX Spark](/blog/2025/dgx-spark-first-look/), [llama.cpp](https://github.com/ggml-org/llama.cpp), and OpenAI's [GPT-OSS 120b](https://openai.com/index/introducing-gpt-oss/). The AI model runs on my desk with a machine that pulls less power doing AI inference than my gaming tower pulls running fairly lightweight 3D games. In testing I've found that nearly all runs of reviewbot take less than two minutes, even at a rate of only 60 tokens per second generated by the DGX Spark. 15 + 16 + reviewbot is about 350 lines of Go that just feeds pull request information into the context window of the model and provides a few tools for actions like "leave pull request review" and "read contents of file". I'm considering adding other actions like "read messages in thread" or "read contents of issue", but I haven't needed them yet. 17 + 18 + To make my life easier, I distribute it as [a Docker image](https://github.com/Xe/x/pkgs/container/x%2Freviewbot) that [gets run in GitHub Actions](https://github.com/Xe/x/blob/master/cmd/reviewbot/actions/reviewbot-manually-invoked.yaml) whenever a pull review comment includes the magic phrase `/reviewbot`. 19 + 20 + The main reason I made reviewbot is that I couldn't find anything like it that let you specify the combination of: 21 + 22 + - Your own AI model name 23 + - Your own AI model provider URL 24 + - Your own AI model provider API token 25 + 26 + I'm fairly sure that there are thousands of similar AI-powered tools on the market that I can't find because Google is a broken tool, but this one is mine. 27 + 28 + ## How it works 29 + 30 + When reviewbot reviews a pull request, it assembles an AI model prompt like this: 31 + 32 + ```text 33 + Pull request info: 34 + 35 + <pr> 36 + <title>Pull request title</title> 37 + <author>GitHub username of pull request author</author> 38 + <body> 39 + Text body of the pull request 40 + </body> 41 + </pr> 42 + 43 + Commits: 44 + 45 + <commits> 46 + <commit> 47 + <author>Xe</author> 48 + <message> 49 + chore: minor formatting and cleanup fixes 50 + 51 + - Format .mcp.json with prettier 52 + - Minor whitespace cleanup 53 + 54 + Assisted-by: GLM 4.7 via Claude Code 55 + Reviewbot-request: yes 56 + Signed-off-by: Xe Iaso <me@xeiaso.net> 57 + </message> 58 + </commit> 59 + </commits> 60 + 61 + Files changed: 62 + 63 + <files> 64 + <file> 65 + <name>.mcp.json</name> 66 + <status>modified</status> 67 + <patch> 68 + @@ -3,11 +3,8 @@ 69 + "python": { 70 + "type": "stdio", 71 + "command": "go", 72 + - "args": [ 73 + - "run", 74 + - "./cmd/python-wasm-mcp" 75 + - ], 76 + + "args": ["run", "./cmd/python-wasm-mcp"], 77 + "env": {} 78 + } 79 + } 80 + -} 81 + \ No newline at end of file 82 + +} 83 + </patch> 84 + </file> 85 + </files> 86 + 87 + Agent information: 88 + 89 + <agentInfo> 90 + [contents of AGENTS.d in the repository] 91 + </agentInfo> 92 + ``` 93 + 94 + The AI model can return one of three results: 95 + 96 + - Definite approval via the `submit_review` tool that approves the changes with a summary of the changes made to the code. 97 + - Definite rejection via the `submit_review` tool that rejects the changes with a summary of the reason why they're being rejected. 98 + - Comments without approving or rejecting the code. 99 + 100 + The core of reviewbot is the "AI agent loop", or a loop that works like this: 101 + 102 + - Collect information to feed into the AI model 103 + - Submit information to AI model 104 + - If the AI model runs the `submit_review` tool, publish the results and exit. 105 + - If the AI model runs any other tool, collect the information it's requesting and add it to the list of things to submit to the AI model in the next loop. 106 + - If the AI model just returns text at any point, treat that as a noncommittal comment about the changes. 107 + 108 + ## Don't use reviewbot 109 + 110 + reviewbot is a hack that probably works well enough for me. It has a number of limitations including but not limited to: 111 + 112 + - It does not work with closed source repositories due to the [gitfs](https://pkg.go.dev/rsc.io/gitfs) library not supporting cloning repositories that require authentication. Could probably fix that with some elbow grease if I'm paid enough to do so. 113 + - A fair number of test invocations had the agent rely on unpopulated fields from the GitHub API, which caused crashes. I am certain that I will only find more such examples and need to issue patches for them. 114 + - reviewbot is like 300 lines of Go hacked up by hand in an afternoon. If you really need something like this, you can likely write one yourself with little effort. 115 + 116 + ## Frequently asked questions 117 + 118 + When such an innovation as reviewbot comes to pass, people naturally have questions. In order to give you the best reading experience, I asked my friends, patrons, and loved ones for their questions about reviewbot. Here are some answers that may or may not help: 119 + 120 + ### Does the world really need another AI agent? 121 + 122 + Probably not! This is something I made out of curiosity, not something I made for you to actually use. It was a lot easier to make than I expected and is surprisingly useful for how little effort was put into it. 123 + 124 + ### Is there a theme of FAQ questions that you're looking for? 125 + 126 + Nope. Pure chaos. Let it all happen in a glorious way. 127 + 128 + ### Where do we go when we die? 129 + 130 + How the fuck should I know? I don't even know if chairs exist. 131 + 132 + ### Has anyone ever really been far even as decided to use even go want to do look more like? 133 + 134 + At least half as much I have wanted to use go wish for that. It's just common sense, really. 135 + 136 + ### If you have a pile of sand and take away one grain at a time, when does it stop being a pile? 137 + 138 + When the wind can blow all the sand away. 139 + 140 + ### How often does it require oatmeal? 141 + 142 + Three times daily or the netherbeast will emerge and doom all of society. We don't really want that to happen so we make sure to feed reviewbot its oatmeal. 143 + 144 + ### How many pancakes does it take to shingle a dog house? 145 + 146 + At least twelve. Not sure because I ran out of pancakes. 147 + 148 + ### Will this crush my enemies, have them fall at my feet, their horses and goods taken? 149 + 150 + Only if you add that functionality in a pull request. reviewbot can do anything as long as its code is extended to do that thing. 151 + 152 + ### Why should I use reviewbot? 153 + 154 + Frankly, you shouldn't.