<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Charlie Li</title>
    <description>The latest articles on DEV Community by Charlie Li (@_2b847605e5fbe8a8c9e26).</description>
    <link>https://dev.to/_2b847605e5fbe8a8c9e26</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3880125%2F3b88324b-7264-4bb9-8920-9a079c64b096.jpg</url>
      <title>DEV Community: Charlie Li</title>
      <link>https://dev.to/_2b847605e5fbe8a8c9e26</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_2b847605e5fbe8a8c9e26"/>
    <language>en</language>
    <item>
      <title>I Replaced Our $300/month Code Review Tool with a 50-Line GitHub Action</title>
      <dc:creator>Charlie Li</dc:creator>
      <pubDate>Wed, 15 Apr 2026 09:17:16 +0000</pubDate>
      <link>https://dev.to/_2b847605e5fbe8a8c9e26/i-replaced-our-300month-code-review-tool-with-a-50-line-github-action-g39</link>
      <guid>https://dev.to/_2b847605e5fbe8a8c9e26/i-replaced-our-300month-code-review-tool-with-a-50-line-github-action-g39</guid>
      <description>&lt;p&gt;Last month, our 8-person team was paying &lt;strong&gt;$288/month&lt;/strong&gt; for CodeRabbit ($19/seat × 8 devs × 2 repos).&lt;/p&gt;

&lt;p&gt;The reviews were good. But $3,456/year for "this function is too long" and "consider adding error handling"? I started wondering what we were actually paying for.&lt;/p&gt;

&lt;p&gt;So I built a replacement using &lt;strong&gt;GitHub Actions + OpenAI API&lt;/strong&gt;. Total cost: &lt;strong&gt;$4.20 last month&lt;/strong&gt;. It catches real bugs, not just style nits.&lt;/p&gt;

&lt;p&gt;Here's the exact setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 50-Line Config
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;.github/workflows/ai-review.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AI Code Review&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;opened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;synchronize&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;reopened&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
  &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ai-review&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.event.pull_request.draft == &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get changed files&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;diff&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;git diff origin/${{ github.event.pull_request.base.ref }}...HEAD \&lt;/span&gt;
            &lt;span class="s"&gt;--name-only --diff-filter=ACMR \&lt;/span&gt;
            &lt;span class="s"&gt;-- '*.ts' '*.tsx' '*.js' '*.jsx' '*.py' '*.go' '*.rs' \&lt;/span&gt;
            &lt;span class="s"&gt;| head -20 &amp;gt; changed_files.txt&lt;/span&gt;
          &lt;span class="s"&gt;echo "count=$(wc -l &amp;lt; changed_files.txt)" &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get diff content&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.diff.outputs.count &amp;gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;git diff origin/${{ github.event.pull_request.base.ref }}...HEAD \&lt;/span&gt;
            &lt;span class="s"&gt;-- $(cat changed_files.txt | tr '\n' ' ') &amp;gt; pr_diff.txt&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AI Review&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.diff.outputs.count &amp;gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.OPENAI_API_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;PR_TITLE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.pull_request.title }}&lt;/span&gt;
          &lt;span class="na"&gt;PR_BODY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.pull_request.body }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;DIFF=$(head -c 30000 pr_diff.txt)&lt;/span&gt;
          &lt;span class="s"&gt;RESPONSE=$(curl -s https://api.openai.com/v1/chat/completions \&lt;/span&gt;
            &lt;span class="s"&gt;-H "Authorization: Bearer $OPENAI_API_KEY" \&lt;/span&gt;
            &lt;span class="s"&gt;-H "Content-Type: application/json" \&lt;/span&gt;
            &lt;span class="s"&gt;-d "$(jq -n \&lt;/span&gt;
              &lt;span class="s"&gt;--arg diff "$DIFF" \&lt;/span&gt;
              &lt;span class="s"&gt;--arg title "$PR_TITLE" \&lt;/span&gt;
              &lt;span class="s"&gt;--arg body "$PR_BODY" \&lt;/span&gt;
              &lt;span class="s"&gt;'{&lt;/span&gt;
                &lt;span class="s"&gt;model: "gpt-4o-mini",&lt;/span&gt;
                &lt;span class="s"&gt;messages: [{&lt;/span&gt;
                  &lt;span class="s"&gt;role: "system",&lt;/span&gt;
                  &lt;span class="s"&gt;content: "You are a senior engineer doing code review. Be concise. Focus on: bugs, security issues, performance problems, and logic errors. Skip style/formatting. For each issue, cite the exact file and line. If the code is fine, say so briefly."&lt;/span&gt;
                &lt;span class="s"&gt;}, {&lt;/span&gt;
                  &lt;span class="s"&gt;role: "user",&lt;/span&gt;
                  &lt;span class="s"&gt;content: "PR: \($title)\n\nDescription: \($body)\n\nDiff:\n\($diff)"&lt;/span&gt;
                &lt;span class="s"&gt;}],&lt;/span&gt;
                &lt;span class="s"&gt;max_tokens: 1500,&lt;/span&gt;
                &lt;span class="s"&gt;temperature: 0.1&lt;/span&gt;
              &lt;span class="s"&gt;}')" )&lt;/span&gt;
          &lt;span class="s"&gt;echo "$RESPONSE" | jq -r '.choices[0].message.content' &amp;gt; review.md&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Post Review Comment&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.diff.outputs.count &amp;gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;GH_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;REVIEW=$(cat review.md)&lt;/span&gt;
          &lt;span class="s"&gt;gh pr comment ${{ github.event.pull_request.number }} \&lt;/span&gt;
            &lt;span class="s"&gt;--body "## 🤖 AI Code Review&lt;/span&gt;

          &lt;span class="s"&gt;$REVIEW&lt;/span&gt;

          &lt;span class="s"&gt;---&lt;/span&gt;
          &lt;span class="s"&gt;*Powered by GPT-4o-mini · [How this works](https://1611833802030.gumroad.com/l/ai-code-review-guide)*"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Push this file, and every PR gets an AI review.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Actually Catches
&lt;/h2&gt;

&lt;p&gt;After 3 weeks and ~120 PRs, here's what surprised me:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real bugs it caught:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;code&gt;Promise.all&lt;/code&gt; that silently swallowed rejections (would have caused data loss)&lt;/li&gt;
&lt;li&gt;An SQL query with string interpolation instead of parameterized queries (SQL injection)&lt;/li&gt;
&lt;li&gt;A race condition in a cache invalidation handler&lt;/li&gt;
&lt;li&gt;An off-by-one error in a pagination endpoint (returning 11 items for &lt;code&gt;?limit=10&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What it (correctly) ignores:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Variable naming preferences&lt;/li&gt;
&lt;li&gt;Import ordering&lt;/li&gt;
&lt;li&gt;"Consider using optional chaining" type suggestions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key is the system prompt. Notice: &lt;strong&gt;"Skip style/formatting"&lt;/strong&gt;. This one instruction eliminates 80% of the noise that makes commercial tools annoying.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Breakdown
&lt;/h2&gt;

&lt;p&gt;Here's our actual usage for March 2026:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PRs reviewed&lt;/td&gt;
&lt;td&gt;124&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Avg tokens/review&lt;/td&gt;
&lt;td&gt;~3,200 input + ~800 output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model&lt;/td&gt;
&lt;td&gt;GPT-4o-mini&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost per review&lt;/td&gt;
&lt;td&gt;~$0.034&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Monthly total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$4.20&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For comparison:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CodeRabbit: $19/seat/month → $152/month (8 devs)&lt;/li&gt;
&lt;li&gt;Bito: $15/seat/month → $120/month&lt;/li&gt;
&lt;li&gt;Greptile: $24/seat/month → $192/month&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;This setup: $4.20/month&lt;/strong&gt; (flat, not per-seat)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's a &lt;strong&gt;97% reduction&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  5 Optimizations That Actually Matter
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Filter files aggressively
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;--diff-filter=ACMR&lt;/code&gt; flag already skips deleted files. But also skip files that don't need review:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;-- '*.ts' '*.tsx' '*.js' '*.jsx' '*.py' '*.go' '*.rs'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This skips &lt;code&gt;.md&lt;/code&gt;, &lt;code&gt;.json&lt;/code&gt;, &lt;code&gt;.yaml&lt;/code&gt;, config files, and lock files. Saves ~40% on tokens.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Cap the diff size
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;DIFF&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 30000 pr_diff.txt&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;30KB covers most PRs. For mega-PRs (1000+ lines), you'd need a chunking strategy — but honestly, mega-PRs are a process problem, not a tooling problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Use GPT-4o-mini, not GPT-4o
&lt;/h3&gt;

&lt;p&gt;For code review, &lt;code&gt;gpt-4o-mini&lt;/code&gt; catches 90%+ of what &lt;code&gt;gpt-4o&lt;/code&gt; catches, at &lt;strong&gt;1/15th the cost&lt;/strong&gt;. The quality difference is mostly in nuanced architectural suggestions — not in bug detection.&lt;/p&gt;

&lt;p&gt;Save &lt;code&gt;gpt-4o&lt;/code&gt; for security-critical repos.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Set temperature to 0.1
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"temperature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Low temperature = consistent, deterministic reviews. You don't want creative writing in code review.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Skip draft PRs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.event.pull_request.draft == &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't waste API calls on work-in-progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Doesn't Do (And Whether You Should Care)
&lt;/h2&gt;

&lt;p&gt;Honest limitations:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Commercial Tools&lt;/th&gt;
&lt;th&gt;This Setup&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Inline comments on specific lines&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌ (PR-level comment)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auto-fix PRs&lt;/td&gt;
&lt;td&gt;Some&lt;/td&gt;
&lt;td&gt;❌ (but achievable*)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning from your codebase&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dashboard / analytics&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SOC 2 / enterprise compliance&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;*Auto-fix is doable — you generate a patch and create a PR. I cover this in &lt;a href="https://1611833802030.gumroad.com/l/ai-code-review-guide" rel="noopener noreferrer"&gt;the full guide&lt;/a&gt; (Chapter 6).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My take:&lt;/strong&gt; If you're a 5-50 person team, the basic setup above covers 80% of the value. Inline comments are nice but not essential. If you're 100+ engineers with compliance requirements, CodeRabbit is probably worth it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Switching to Claude (Alternative)
&lt;/h2&gt;

&lt;p&gt;Prefer Anthropic? Swap the API call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;RESPONSE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.anthropic.com/v1/messages &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: &lt;/span&gt;&lt;span class="nv"&gt;$ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"anthropic-version: 2023-06-01"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;jq &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--arg&lt;/span&gt; diff &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DIFF&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--arg&lt;/span&gt; title &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PR_TITLE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s1"&gt;'{
      model: "claude-sonnet-4-5-20250514",
      max_tokens: 1500,
      system: "You are a senior engineer doing code review. Be concise. Focus on bugs, security issues, performance problems, and logic errors. Skip style/formatting.",
      messages: [{
        role: "user",
        content: "PR: \($title)\n\nDiff:\n\($diff)"
      }]
    }'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RESPONSE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.content[0].text'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; review.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude tends to be more thorough on security issues. GPT-4o-mini is faster and cheaper for general review.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;3 weeks in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;$4.20/month&lt;/strong&gt; vs $288/month (saved $283.80)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2 real bugs caught&lt;/strong&gt; that humans missed (the SQL injection alone justified the effort)&lt;/li&gt;
&lt;li&gt;Review comments dropped from an average of 12 (CodeRabbit, mostly noise) to 3-4 (focused, actionable)&lt;/li&gt;
&lt;li&gt;Setup time: &lt;strong&gt;5 minutes&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest win wasn't cost — it was &lt;strong&gt;signal-to-noise ratio&lt;/strong&gt;. When every AI comment is worth reading, developers actually read them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Want the Full Playbook?
&lt;/h2&gt;

&lt;p&gt;This article covers the basics. The complete 208-page guide includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Auto-fix PRs&lt;/strong&gt; — AI generates patches, not just suggestions (Chapter 6)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security automation&lt;/strong&gt; — OWASP Top 10 scanning on every PR (Chapter 5)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team standards as code&lt;/strong&gt; — &lt;code&gt;.review-rules.yml&lt;/code&gt; that AI enforces (Chapter 7)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-repo &amp;amp; monorepo&lt;/strong&gt; strategies (Chapter 8)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost optimization&lt;/strong&gt; — caching, batching, incremental review (Chapter 9)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ROI templates&lt;/strong&gt; for convincing your manager (real case: 1,018% ROI)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📘 &lt;a href="https://1611833802030.gumroad.com/l/ai-code-review-guide" rel="noopener noreferrer"&gt;&lt;strong&gt;AI Code Review: The Practical Guide — $9.99 on Gumroad&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;New to AI code review? Start with the &lt;a href="https://1611833802030.gumroad.com/l/pbuhwx" rel="noopener noreferrer"&gt;&lt;strong&gt;free cheat sheet&lt;/strong&gt;&lt;/a&gt; — one-page config + prompt templates.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>github</category>
      <category>codereview</category>
      <category>devops</category>
    </item>
    <item>
      <title>I Replaced Our $600/Month Code Review Tool with 30 Lines of YAML (Here's How)</title>
      <dc:creator>Charlie Li</dc:creator>
      <pubDate>Wed, 15 Apr 2026 09:16:22 +0000</pubDate>
      <link>https://dev.to/_2b847605e5fbe8a8c9e26/i-replaced-our-600month-code-review-tool-with-30-lines-of-yaml-heres-how-51c4</link>
      <guid>https://dev.to/_2b847605e5fbe8a8c9e26/i-replaced-our-600month-code-review-tool-with-30-lines-of-yaml-heres-how-51c4</guid>
      <description>&lt;p&gt;Last month, our team was paying &lt;strong&gt;$600/month&lt;/strong&gt; for an AI code review tool. 10 developers × $60/seat.&lt;/p&gt;

&lt;p&gt;The tool was fine. But I started wondering: these tools just call OpenAI's API and post comments on PRs. The API costs ~$0.02 per review. We were paying $60/seat for a glorified API wrapper.&lt;/p&gt;

&lt;p&gt;So I built our own. &lt;strong&gt;It took 5 minutes. It costs ~$8/month for the entire team.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's the exact setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 30-Line Workflow
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;.github/workflows/ai-review.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AI Code Review&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;opened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;synchronize&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;review&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
      &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get changed code&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;diff&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;DIFF=$(git diff origin/${{ github.base_ref }}...HEAD -- \&lt;/span&gt;
            &lt;span class="s"&gt;'*.py' '*.js' '*.ts' '*.go' '*.java' '*.rs' \&lt;/span&gt;
            &lt;span class="s"&gt;':!*.min.js' ':!*lock*' ':!*.generated.*')&lt;/span&gt;
          &lt;span class="s"&gt;# Truncate to avoid token limits&lt;/span&gt;
          &lt;span class="s"&gt;echo "diff&amp;lt;&amp;lt;EOF" &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;
          &lt;span class="s"&gt;echo "$DIFF" | head -c 12000 &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;
          &lt;span class="s"&gt;echo "EOF" &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AI Review&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.OPENAI_API_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;GH_TOKEN&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;REVIEW=$(curl -s https://api.openai.com/v1/chat/completions \&lt;/span&gt;
            &lt;span class="s"&gt;-H "Authorization: Bearer $OPENAI_API_KEY" \&lt;/span&gt;
            &lt;span class="s"&gt;-H "Content-Type: application/json" \&lt;/span&gt;
            &lt;span class="s"&gt;-d "{&lt;/span&gt;
              &lt;span class="s"&gt;\"model\": \"gpt-4o-mini\",&lt;/span&gt;
              &lt;span class="s"&gt;\"messages\": [{&lt;/span&gt;
                &lt;span class="s"&gt;\"role\": \"system\",&lt;/span&gt;
                &lt;span class="s"&gt;\"content\": \"You are a senior code reviewer. Review for: 1) Bugs and logic errors 2) Security vulnerabilities (OWASP Top 10) 3) Performance issues 4) Code style violations. Be specific with line numbers. Use GitHub markdown.\"&lt;/span&gt;
              &lt;span class="s"&gt;},{&lt;/span&gt;
                &lt;span class="s"&gt;\"role\": \"user\",&lt;/span&gt;
                &lt;span class="s"&gt;\"content\": $(echo '${{ steps.diff.outputs.diff }}' | jq -Rs .)&lt;/span&gt;
              &lt;span class="s"&gt;}],&lt;/span&gt;
              &lt;span class="s"&gt;\"max_tokens\": 2000&lt;/span&gt;
            &lt;span class="s"&gt;}" | jq -r '.choices[0].message.content')&lt;/span&gt;

          &lt;span class="s"&gt;gh pr comment ${{ github.event.pull_request.number }} \&lt;/span&gt;
            &lt;span class="s"&gt;--body "## 🤖 AI Code Review&lt;/span&gt;

          &lt;span class="s"&gt;$REVIEW&lt;/span&gt;

          &lt;span class="s"&gt;---&lt;/span&gt;
          &lt;span class="s"&gt;*Powered by gpt-4o-mini · [How this works](https://1611833802030.gumroad.com/l/ai-code-review-cheat-sheet)*"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Every PR now gets an AI review automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Actually Catches
&lt;/h2&gt;

&lt;p&gt;After 3 months and ~400 PRs, here's what our AI reviewer found that humans missed:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue Type&lt;/th&gt;
&lt;th&gt;Caught&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SQL Injection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Raw string interpolation in queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Missing null checks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;47&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;user.profile.name&lt;/code&gt; without optional chaining&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;N+1 queries&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Loop inside a loop hitting the database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hardcoded secrets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;API keys in test files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Race conditions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Concurrent map access in Go&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The AI doesn't replace human reviewers. But it catches the "obvious" stuff that humans skim over when they're reviewing 15 PRs before lunch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Breakdown: DIY vs. Commercial Tools
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;th&gt;10-Dev Team Cost&lt;/th&gt;
&lt;th&gt;Per-Review Cost&lt;/th&gt;
&lt;th&gt;Setup Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;This workflow&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~$8/mo&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0.02&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5 minutes&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeRabbit&lt;/td&gt;
&lt;td&gt;$600/mo&lt;/td&gt;
&lt;td&gt;Included&lt;/td&gt;
&lt;td&gt;10 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bito&lt;/td&gt;
&lt;td&gt;$400/mo&lt;/td&gt;
&lt;td&gt;Included&lt;/td&gt;
&lt;td&gt;15 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greptile&lt;/td&gt;
&lt;td&gt;$500/mo&lt;/td&gt;
&lt;td&gt;Included&lt;/td&gt;
&lt;td&gt;20 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sourcery&lt;/td&gt;
&lt;td&gt;$480/mo&lt;/td&gt;
&lt;td&gt;Included&lt;/td&gt;
&lt;td&gt;10 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Why is it so cheap?&lt;/strong&gt; GPT-4o-mini costs $0.15/1M input tokens. A typical PR diff is ~2,000 tokens. That's $0.0003 for the input + ~$0.006 for the output. Under $0.01 per review.&lt;/p&gt;

&lt;p&gt;Even if you review 50 PRs/day, that's $15/month. Not $600.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 Upgrades Worth Adding
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Security-Focused Prompt
&lt;/h3&gt;

&lt;p&gt;Replace the system message for repos that handle user data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Focus exclusively on security:
- SQL injection (parameterized queries?)
- XSS (output encoding?)
- Authentication bypass
- Hardcoded credentials
- Insecure deserialization
- SSRF potential
Flag severity as 🔴 Critical / 🟡 Warning / 🟢 Info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Skip Bot-Generated Code
&lt;/h3&gt;

&lt;p&gt;Add a path filter to avoid reviewing auto-generated files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get changed code&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;DIFF=$(git diff origin/${{ github.base_ref }}...HEAD -- \&lt;/span&gt;
            &lt;span class="s"&gt;'*.py' '*.js' '*.ts' \&lt;/span&gt;
            &lt;span class="s"&gt;':!*.generated.*' ':!*.min.*' ':!*lock*' \&lt;/span&gt;
            &lt;span class="s"&gt;':!*migration*' ':!*__snapshots__*' \&lt;/span&gt;
            &lt;span class="s"&gt;':!vendor/*' ':!node_modules/*')&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Use Claude for Complex Reviews
&lt;/h3&gt;

&lt;p&gt;For architecture reviews or large PRs, Claude Sonnet gives more nuanced feedback:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.anthropic.com/v1/messages &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: &lt;/span&gt;&lt;span class="nv"&gt;$ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"anthropic-version: 2023-06-01"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"content-type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"{
    &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;model&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;claude-sonnet-4-20250514&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,
    &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;max_tokens&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: 2000,
    &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;messages&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: [{
      &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;role&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;,
      &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Review this code diff for architectural concerns, not just bugs:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="nv"&gt;$DIFF&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;
    }]
  }"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common Pitfalls
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;"The diff is too big"&lt;/strong&gt; — Truncate to 12K chars (line 14 above). For bigger PRs, split by file and review each separately. The full guide covers a chunking strategy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Reviews are too generic"&lt;/strong&gt; — Add your team's coding standards to the system prompt. "We use Python 3.12+, prefer dataclasses over dicts, and require type hints on all public functions."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"It comments on every PR including dependabot"&lt;/strong&gt; — Add a condition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.actor != 'dependabot[bot]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;"Rate limiting"&lt;/strong&gt; — OpenAI's rate limits are generous (500 RPM for gpt-4o-mini). If you hit them, add a retry with exponential backoff.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want the Full Playbook?
&lt;/h2&gt;

&lt;p&gt;This article covers the basics. I wrote a &lt;strong&gt;208-page guide&lt;/strong&gt; that goes deep into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔧 &lt;strong&gt;Auto-fix PRs&lt;/strong&gt; — AI doesn't just find bugs, it opens fix PRs automatically&lt;/li&gt;
&lt;li&gt;🔒 &lt;strong&gt;Security automation&lt;/strong&gt; — OWASP Top 10 scanning on every commit&lt;/li&gt;
&lt;li&gt;🏢 &lt;strong&gt;Multi-repo strategies&lt;/strong&gt; — monorepo and cross-repo review patterns&lt;/li&gt;
&lt;li&gt;💰 &lt;strong&gt;Cost optimization&lt;/strong&gt; — from $0.02/review down to $0.005/review&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;ROI quantification&lt;/strong&gt; — prove the value to your manager (real case: 1,018% ROI)&lt;/li&gt;
&lt;li&gt;👥 &lt;strong&gt;Team standards as code&lt;/strong&gt; — encode your style guide into AI rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://1611833802030.gumroad.com/l/ai-code-review-cheat-sheet" rel="noopener noreferrer"&gt;📥 Grab the free cheat sheet first&lt;/a&gt;&lt;/strong&gt; — it's a one-page PDF with the workflow above plus model selection guide and cost calculator.&lt;/p&gt;

&lt;p&gt;If you want everything: &lt;strong&gt;&lt;a href="https://1611833802030.gumroad.com/l/ai-code-review-guide" rel="noopener noreferrer"&gt;AI Code Review: The Practical Guide — $9.99&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




</description>
      <category>ai</category>
      <category>codereview</category>
      <category>githubactions</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
