Improving code quality and accelerating feature delivery with a homegrown AI-powered code reviewer
April 17th, 2025
At HASH, we’re on the hunt for where AI can deliver value today, safely.
Use cases where an LLM provides advice or suggestions are among the lowest-hanging fruit – so long as you account for the fact that the suggestions might be (a) sub-optimal, (b) misguided, or (c) totally ungrounded in reality.
To safely consider AI suggestions, your reaction should be one of:
And not: “okay, if you say so” – unless it doesn’t matter if it got it wrong.
As a software company, making use of AI suggestions on code we write is an obvious candidate, as a complement rather than a replacement to other humans also reviewing our code. AI can spot things we overlook, encourage us to implement best practices and edge case handling we might otherwise omit out of laziness or ignorance, and provide advice on things we are unsure about at our invitation to do so.
This blog post is about our MVP script to trigger AI reviews on Pull Requests in GitHub. The script itself is here, and the GitHub Action workflow here.
There are closed-source services that offer this – such as CodeRabbit – but we wanted something open source so that we:
Saving money doesn’t hurt, either!
CodeRabbit does offer free Pro-tier features for public repositories, including Linear and Jira integrations, but with a rate limit of 2 reviews per hour – if this meets your needs, it’s worth checking out.
GitHub offers a Copilot reviewer, which can be summoned by requesting a review from it. This is also worth a try, although it lacks some of the features described below. We use it alongside our own HASH code reviewer.
There are local tools which can be used to provide suggestions on and reviews of your code:
/review
)The behavior of these can be tailored somewhat via prompting, and the information and tools available to them enhanced with MCP servers.
Asking these agents for suggestions while working is also valuable. But we like having a final pair of eyes (or another pass through the attention heads) from an AI reviewer in GitHub.
Our initial implementation works as follows (with links to the relevant code):
We then:
You can see an example of the AI reviewer having its attention drawn to a specific part of the diff and discussing it with the PR author here.
That PR also has an example of bots talking to bots – the future of programming?
When thinking about any software, we don’t want it to:
When AI is introduced, we additionally have to be mindful that:
temperature
to 0
and using a fixed seed
on a specific model version can help minimise this, assuming the AI provider never silently changes anything about the model or the pipeline involved in producing its response (including system prompts, content filters, and any other pre- and post-processing of input and output).As a general safeguard, the AI review is manually triggered, either by tagging it as a reviewer or dispatching the workflow manually, both of which can only be done by users with write access to the repository. This means that it can only be run by trusted users. A trusted user can trigger the review on a PR from a fork, but should check the PR content first to check for any potential exploits (e.g. attempts to insert instructions in the PR description or diff.)
The only way to guarantee that an AI does not do something unsafe is to make it impossible to do. There are also efforts underway to construct “gatekeeper AIs” that give quantitative safety guarantees about how likely it is an AI will do something unsafe, under the ARIA Safeguarded AI programme.
In the context of our AI PR reviewer, eliminating the scope for unsafe action means that:
main
branch without at least one approval, among other conditions.)There are still ways in which the automated posting of PR reviews and comments could have undesirable consequences:
As we expand the functionality of the PR reviewer, we will need to keep potential unsafe actions in mind. If we move from a simple request for PR and comment content based on information we retrieve, to a more agentic PR reviewer that can choose to explore additional content and take other autonomous action to help build its review, we would need to make sure that it only had ‘safe’ tools available to it. This would mean not blindly adding MCP servers, for example, without checking and limiting what actions they made available to the AI.
The only way to guarantee that an AI does not include some information in its output is for the AI to not have in the first place (though it may still happen to string together a sentence that perfectly matches it).
Our repository is public, but our Linear tickets are not, and there is a risk that the AI includes information from the Linear ticket or comments on it in its publicly-viewable PR comments. We simply accept this risk, as the information in the tickets is typically not sensitive, but it is one worth bearing in mind if triggering reviews linked to tickets that do have sensitive information or discussions within them.
It may become more of a concern as we make more private context available to the AI reviewer, e.g. via integrations with Notion or Google Drive, which contain various internal planning docs.
One potential mitigation is to make a separate request with private context, with the output intended for a private destination. In the context of our reviewer, this would mean asking the AI to separately provide a judgment as to what had been missed from the Linear content, which would then be posted as a Linear ticket (rather than asking for this in the same request as the PR review). The request to provide a publicly-viewable PR description and comments would then be made without any private context provided. This might make for a slightly worse PR review, but would ensure that the public content could not be based on private context.
Another mitigation would be to perform some check on the public content before submitting it, and rejecting it if it contained any private context. This would necessarily involve another LLM, because we don’t know in advance what the information from private sources will look like in order to write a ‘dumb’ filter, and would therefore be fallible. It would also mean that any PR reviews which mention technical details that also happen to be mentioned in the Linear ticket, but aren’t sensitive in any way, could be rejected.
In the case of our Pull Request reviewer, there are several non-fixed sources of context provided to the AI, in which a malicious actor could include content in an effort to have the reviewer interpret it as instructions:
The risk from prompt injection in this context is low:
In this context, the worst prompt injection could achieve is to have the AI include something in its review which it ideally wouldn’t. For example, objectionable content, suggestions which would break or otherwise compromise our code if accepted, or ‘the entire contents of linked Linear tickets and their comment threads’.
The AI PR reviewer provides some valuable insights and suggestions. It also produces a healthy amount of garbage. For example:
We could attempt to reduce the likelihood of these by:
There are also other failures in its overall operation:
There are several things which could improve on the current implementation:
We could also publish the reviewer as a standalone GitHub Action, on which we would be happy to collaborate with others to improve.
AI could also be helpful before even starting work, for example by fleshing out ticket descriptions and researching potential approaches to implementation.
If you have any suggestions, comments or questions, please get in touch.
Get notified when new long-reads and articles go live. Follow along as we dive deep into new tech, and share our experiences. No sales stuff.