Stop Building Chatbots. Build Agents That Open PRs. A developer argues that AI agents should output reviewable artifacts like pull requests instead of chat replies, because PRs provide a diff, CI gates, and a reject button that chat messages lack. The post uses the author's own blog bot as an example, which opens a PR against a repo when mentioned in Slack. Stop Building Chatbots. Build Agents That Open PRs. A chat reply evaporates. You read it, you nod, you scroll, and ten minutes later it's gone, buried in a thread you'll never open again. A pull request sits in GitHub with your name on it until you deal with it. You can reject it with one click. You can tag the person who actually owns the code. It has a diff. It has a status check. It either passes the gate or it doesn't. That difference is the whole argument. The unit of useful agent work is a reviewable artifact — a PR, a draft, a diff — not a chat reply. If the output is a chat paragraph, I still have the job. If the output is a PR with passing checks, now I have a decision to make. I keep watching teams pour months into the first thing and wonder why nobody's life got better. The chat reply is a dead end The common chatbot flow is stupidly familiar. You ask it something. It thinks. It streams back prose. You copy the part you wanted, paste it somewhere it actually matters, fix the three things it got wrong, and move on. The agent did real work and then handed it to you in the one format that guarantees you have to do the work again. The chat reply has no home. It doesn't live in the system where the work lives. It can't be checked by CI. It can't be diffed against what was there before. It can't be approved by a second person. It expires the instant the conversation scrolls. You are the storage layer, the validation layer, and the merge button, and you're doing all three by hand, from memory, in a text box. It demos beautifully and then makes you do the integration work by hand. The chat reply feels like magic for the first ten seconds, then quietly offloads every hard part — verification, integration, accountability — back onto you. What a reviewable artifact gives you Swap the output. You can keep the model boring. The important change is giving it a repo checkout, a branch, and a gate — so the thing that comes out the end is a pull request instead of a paragraph. A PR gives me the boring machinery chat never gets near: A place to live. The work lands in the repo, the doc, the ticket — where the real artifact already lives. No copy-paste, no re-typing. The agent did the integration, not just the thinking. A diff. I see exactly what changed. Not a description of what changed, told to me in friendly prose. The actual lines. Red and green. A gate. CI runs. Tests run. A linter runs. A validation script runs. The artifact has to clear a bar before a human ever looks, and the agent is the one who has to satisfy it. A review surface. It sits in a queue. I can look now or tomorrow. I can hand it to someone else. I can leave a comment and ask for a change. The decision is deferred to me by design. A reject button. This is the one that matters most. The default action is not merged . Nothing ships because a model felt confident. It ships because a human with a name and a reputation said yes. That last point is the whole reframing of the spark, the bellows, and the quench /blog/spark-bellows-quench . The agent runs the bellows: the mechanical middle, the rough draft, the scaffolding. You keep the quench — hitting merge, putting your name on it, standing behind it. A chat reply collapses all three into one ambiguous blob in a window. A PR keeps the boundary crisp. The machine opens it. You close it. The worked example: this post is a pull request My blog bot works this way. It's an agent I @ -mention in Slack. I gave it one line: opinionated post: "Stop building chatbots — build agents that open PRs." The unit of useful agent work is a reviewable artifact PR, draft, diff , not a chat reply. Use my blog bot as the worked example. Strong POV, my voice. Notice what it did not do. It did not reply in the thread with 1,700 words of markdown for me to admire and then paste into my repo by hand. It did not hand me a chat message. It opened a pull request against my portfolio repo. Between that Slack message and the PR, the agent ran the boring pipeline I never want sprayed into Slack: Slack mention → reset repo to latest main → survey recent posts calibrate voice → draft page.mdx + metadata.json → scan voice banned-phrase gate, mirrors CI → generate + upload images to the CDN → boot the site locally, render /blog/