{
    "componentChunkName": "component---src-templates-blog-post-js",
    "path": "/i-hired-gpt-3-as-my-on-call-intern/",
    "result": {"data":{"site":{"siteMetadata":{"title":"catch { snail }","author":"Andrew"}},"markdownRemark":{"id":"a7c7b180-3bdf-5e61-8a69-8a599112637a","excerpt":"This blog has been two blogs wearing a trenchcoat: infrastructure posts and GPT posts, politely ignoring each other. This summer they finally met, because I got…","html":"<p>This blog has been two blogs wearing a trenchcoat: infrastructure posts and GPT posts, politely ignoring each other. This summer they finally met, because I got paged at 3:12am, spent forty minutes spelunking through Loki, and discovered the root cause was — again — the same Redis pod OOMing. Forty minutes, for a diagnosis that fits in a sentence.</p>\n<p>A sentence, you say. We have a machine for sentences now.</p>\n<h2 id=\"what-it-is-and-deliberately-isnt\" style=\"position:relative;\"><a href=\"#what-it-is-and-deliberately-isnt\" aria-label=\"what it is and deliberately isnt permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What it is (and deliberately isn’t)</h2>\n<p>The <a href=\"/the-rematch-my-fine-tuned-gpt-2-vs-a-frozen-giant-with-five-examples\">April post</a> already litigated the tempting version — the closed loop where the model fixes things itself — and the verdict stands: not unattended, not on a box I like. A system that invents flags does not get <code class=\"language-text\">kubectl</code>.</p>\n<p>But there’s a humbler job that’s still most of the pain: <strong>translation</strong>. When an alert fires, the on-call intern doesn’t fix anything. The intern gathers context, forms a hypothesis, and hands the human a briefing. So:</p>\n<p><strong>Alertmanager webhook → context gatherer → davinci → Slack message.</strong></p>\n<p>The Slack message has three parts: a one-sentence hypothesis, the evidence, and a suggested <em>first command</em> — the <code class=\"language-text\">kubectl describe</code> or LogQL query I’d probably start with anyway. It proposes; I dispose. The plan is still the product.</p>\n<h2 id=\"the-keyhole-problem-industrial-edition\" style=\"position:relative;\"><a href=\"#the-keyhole-problem-industrial-edition\" aria-label=\"the keyhole problem industrial edition permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The keyhole problem, industrial edition</h2>\n<p>The hard engineering isn’t the model call — it’s that an incident produces megabytes of context and the <a href=\"/gpt3-rematch\">keyhole</a> is still 2048 tokens. Commit diffs were easy; logs are a firehose of repetition. So most of the code is what I’ve started calling <strong>log distillation</strong>:</p>\n<ul>\n<li>Pull the alert’s labels, the pod’s k8s events, the last <code class=\"language-text\">git log</code> entries touching those manifests, and a Loki query for the affected pod.</li>\n<li>Collapse duplicate lines into <code class=\"language-text\">[x347] connection refused ...</code> — log spam compresses beautifully, because spam is the point of spam.</li>\n<li>Keep the window around the <em>first</em> error, not the last. The end of an incident log is all symptoms; patient zero is at the beginning.</li>\n<li>Budget: ~600 tokens of distilled logs, ~200 of events and deploy history, ~900 of few-shot examples (three real past incidents with the briefings I <em>wish</em> I’d been handed), leaving room for the answer. Temperature 0 — I want the boring completion, this is not poetry night.</li>\n</ul>\n<p>The prompt is a crime-scene summary, not the crime scene. Deciding what makes the summary turned out to be 90% of the project, and honestly, building the distiller taught me more about my own logs than the model did.</p>\n<h2 id=\"the-lie-detector\" style=\"position:relative;\"><a href=\"#the-lie-detector\" aria-label=\"the lie detector permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The lie detector</h2>\n<p>Now the part I’m actually proud of, because the obvious failure mode here is dangerous: a fluent, confident, <em>wrong</em> briefing at 3am is worse than no briefing — I’ll trust it precisely because I’m too tired not to.</p>\n<p>The fix exploits something nice: <strong>the model may invent explanations, but the logs are right there.</strong> The prompt requires the hypothesis to cite two verbatim log lines as evidence, and then the <em>script</em> — dumb, deterministic Python — checks that those exact lines exist in the real distilled logs before posting anything.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">for</span> quote <span class=\"token keyword\">in</span> extract_quotes<span class=\"token punctuation\">(</span>completion<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">if</span> quote<span class=\"token punctuation\">.</span>strip<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">not</span> <span class=\"token keyword\">in</span> distilled_logs<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> post_slack<span class=\"token punctuation\">(</span><span class=\"token string\">\"⚠️ no confident hypothesis (evidence check failed)\"</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>If the model quotes a log line that doesn’t exist, it invented its evidence, and its conclusion is presumptively garbage — discarded, no briefing, just an honest shrug. It’s <code class=\"language-text\">terraform plan</code> for prose: <a href=\"/terraform-destroy-ritual\">beliefs don’t ship until they’ve met evidence</a>, and crucially, the <em>verifier isn’t the model</em>. Generation is allowed to be creative; verification is grep. Never ask the suspect to also be the jury.</p>\n<h2 id=\"six-weeks-of-production-numbers\" style=\"position:relative;\"><a href=\"#six-weeks-of-production-numbers\" aria-label=\"six weeks of production numbers permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Six weeks of production numbers</h2>\n<p>47 alerts since mid-July (a couple were self-inflicted, see: quarterly destroy ritual). Grading each briefing after the fact:</p>\n<ul>\n<li><strong>31 correct or usefully close</strong> — the hypothesis was right, or wrong in a way that still pointed at the right pod.</li>\n<li><strong>9 confidently wrong</strong> — but because the evidence quotes were real, I could see <em>why</em> it was wrong in seconds. A briefing with receipts fails gracefully; you audit the receipts, not the prose.</li>\n<li><strong>7 discarded by the evidence check.</strong> These are the wins nobody sees: seven fluent hallucinated briefings that never reached my phone. The lie detector’s catch rate is the whole reason I trust the other forty.</li>\n</ul>\n<p>Best moment: a cascade of timeout alerts where the intern’s briefing led with a deploy from six hours earlier — it had noticed the git timestamp in the context block sat just before the first error, a correlation I’d missed because six hours “felt” too far away. Statistical models don’t have feelings about time. Point, intern.</p>\n<p>Worst moment: it diagnosed a disk-pressure alert as a Redis memory issue because two of my three few-shot examples were Redis incidents. My examples had taught it that everything is Redis. Few-shot bias is real: the intern is a mirror, and I’d shown it a very Redis-shaped mirror.</p>\n<p>Cost: about $0.14 of davinci per incident. Cheapest coworker I’ve ever had, and it never asks to reschedule the retro.</p>\n<h2 id=\"why-i-didnt-fine-tune-although-now-i-could\" style=\"position:relative;\"><a href=\"#why-i-didnt-fine-tune-although-now-i-could\" aria-label=\"why i didnt fine tune although now i could permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Why I didn’t fine-tune (although now I could)</h2>\n<p>OpenAI shipped a fine-tuning API this summer, so the <a href=\"/gpt3-rematch\">rematch question</a> is live again — and I declined, by my own rulebook. Fine-tuning owns <em>context that never fits through the keyhole</em>, stable distributions like two years of my commit voice. But incidents are the opposite: each one’s crucial context is <em>fresh</em> — today’s logs, this morning’s deploy — and worthless tomorrow. There’s no stable distribution to bake into weights; there’s only the keyhole, refilled per incident. Right tool, and for once I picked it by theory instead of by vibes.</p>\n<h2 id=\"coda\" style=\"position:relative;\"><a href=\"#coda\" aria-label=\"coda permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Coda</h2>\n<p>GitHub spent the summer previewing Copilot — an autocomplete with hands is real now, it lives in editors, and yes, there’s a waitlist, because in this field even the future queues. Meanwhile my little intern suggests, cites, and gets fact-checked by twelve lines of Python.</p>\n<p>I’ve stopped thinking the interesting question is “what can the model do.” The interesting question is <strong>what shape of harness makes a confident liar useful</strong> — distill what goes in, verify what comes out, keep the hands human. That harness cost me a summer of evenings and it’s mostly string handling. Somebody’s going to get very rich selling harnesses.</p>\n<p>Next: GitOps, for real this time. The robots that apply commits have waited three posts, and now they have a coworker who reads logs.</p>","frontmatter":{"title":"I hired GPT-3 as my on-call intern","date":"September 19, 2021","description":"Wiring davinci between Alertmanager and Slack — six weeks of a language model reading my logs at 3am, with a built-in lie detector"}}},"pageContext":{"slug":"/i-hired-gpt-3-as-my-on-call-intern/","previous":{"fields":{"slug":"/the-rematch-my-fine-tuned-gpt-2-vs-a-frozen-giant-with-five-examples/"},"frontmatter":{"title":"The rematch: my fine-tuned GPT-2 vs. a frozen giant with five examples"}},"next":{"fields":{"slug":"/odd-bot-out-a-party-game-where-gpt-3-hides-among-your-relatives/"},"frontmatter":{"title":"Odd Bot Out: a party game where GPT-3 hides among your relatives"}}}},
    "staticQueryHashes": ["3435731857","426816048","63159454"]}