{"slug": "turning-a-generic-llm-into-a-ruby-libgd-expert-one-correction-at-a-time", "title": "Turning a Generic LLM Into a Ruby-LibGD Expert (One Correction at a Time)", "summary": "A developer attempting to use a local LLM to assist with the Ruby-LibGD gem discovered the model repeatedly hallucinated nonexistent methods like colorAllocate() and savePng(), despite being corrected with accurate API details throughout the day. The experiment highlighted how LLMs balance pretrained patterns against in-context corrections, often reverting to familiar but incorrect behaviors.", "body_md": "June 2, 2026\n\n*What a day of conversations taught me about context, memory, and the limits of local AI models.*\n\nA few days ago, I started what seemed like a simple experiment.\n\nI wanted a local LLM to help me work on a Ruby gem I’ve been developing: **Ruby-LibGD**, a Ruby binding for the GD Graphics Library.\n\nThe goal wasn’t complicated. I wanted the model to help me create examples, improve documentation, generate tutorials, and eventually contribute code.\n\nWhat followed became an accidental study of how modern LLMs learn—or more accurately, how they *appear* to learn.\n\n### The First Problem: The Model Didn’t Know My Library\n\nThe first requests seemed straightforward:\n\nCould you graph a 2D function using Ruby-LibGD?\n\nThe model answered confidently.\n\nToo confidently.\n\nIt produced code using methods such as:\n\n```\nimage.colorAllocate(...)image.savePng(...)\n```\n\nThe problem?\n\nNeither method exists in Ruby-LibGD.\n\nThe model wasn’t lying. It was doing what LLMs do best: predicting what *looks* plausible.\n\nIts training data likely contained examples from:\n\n- PHP’s GD library\n- Older GD bindings\n- Generic graphics libraries\n- Similar APIs from other languages\n\nThe result was believable code that would never run.\n\n### The Hallucination Trap\n\nWhat fascinated me wasn’t that the model was wrong.\n\nWhat fascinated me was *how* it was wrong.\n\nEach answer was internally consistent.\n\nThe model wasn’t generating random nonsense.\n\nIt was constructing an alternate reality where Ruby-LibGD behaved like other graphics libraries it had seen before.\n\nFor example:\n\n```\nimage.colorAllocate(255, 255, 255)\n```\n\nlooks perfectly reasonable.\n\nSo does:\n\n```\nimage.savePng(\"output.png\")\n```\n\nIf you’ve worked with graphics libraries before, neither raises suspicion.\n\nBut Ruby-LibGD uses:\n\n```\nGD::Color.rgb(255, 255, 255)\n```\n\nand:\n\n```\nimage.save(\"output.png\")\n```\n\nThose details matter.\n\nAnd those details weren’t in the model’s weights.\n\n### Teaching the Model\n\nSo I started correcting it.\n\nNot once.\n\nRepeatedly.\n\nThroughout the day.\n\nI explained:\n\n```\nGD::Color.rgb(r, g, b)GD::Color.rgba(r, g, b, a)\n```\n\nI explained:\n\n```\nimage.save(\"file.png\")\n```\n\ninstead of:\n\n```\nsavePng()\n```\n\nI provided actual code.\n\nActual examples.\n\nActual API usage.\n\nActual Dockerfiles.\n\nActual constructors.\n\nFor example:\n\n```\nHist2D.new(  x: x_data,  y: y_data,  width: 500,  height: 500,  bin_step: 0.5).render(\"weather_hist2d.png\")\n```\n\nI corrected installation instructions:\n\n```\ngem install ruby-libgd\n```\n\nand usage:\n\n```\nrequire 'gd'\n```\n\nEvery correction pushed the model closer to reality.\n\n### The Surprising Part\n\nIt still kept making the same mistakes.\n\nOver.\n\nAnd over.\n\nAnd over.\n\nI corrected colorAllocate().\n\nThe model used it again.\n\nI corrected savePng().\n\nThe model used it again.\n\nI explained that Hist2D renders directly to a file.\n\nThe model tried to draw it on a GD::Image anyway.\n\nAt first, this felt frustrating.\n\nThen I realized something important.\n\nThe model wasn’t ignoring me.\n\nThe model was balancing two competing sources of truth:\n\n### Source #1: Pretraining\n\nYears of accumulated patterns from its training data.\n\n### Source #2: Context\n\nThe information I was feeding it during the conversation.\n\nWhen those sources disagreed, the model didn’t always choose context.\n\nSometimes it reverted to what it had seen millions of times during training.\n\n### Context Is Not Training\n\nThis is where I think many developers misunderstand LLMs.\n\nPeople often say:\n\n“I gave it the documentation.”\n\nor\n\n“I uploaded the examples.”\n\nas if that should instantly solve everything.\n\nBut context isn’t training.\n\nUploading documentation doesn’t rewrite model weights.\n\nThe model is constantly negotiating between:\n\n- what it learned during training\n- what you’re telling it right now\n\nSometimes the documentation wins.\n\nSometimes the training wins.\n\nAnd sometimes you get a strange hybrid of both.\n\nThat’s exactly what I was seeing.\n\n### Building a Temporary Expert\n\nAs the day progressed, something interesting happened.\n\nThe answers started changing.\n\nNot perfectly.\n\nBut noticeably.\n\nThe model began referencing actual Ruby-LibGD concepts.\n\nIt started using:\n\n```\nrequire 'gd'\n```\n\ninstead of inventing package names.\n\nIt started referencing:\n\n```\nHist2D.new(...)\n```\n\nand:\n\n```\nPlot.new(...)\n```\n\nIt began recognizing conventions specific to the library.\n\nThe model wasn’t becoming permanently smarter.\n\nIts weights were unchanged.\n\nBut within the conversation, it was gradually becoming a temporary Ruby-LibGD specialist.\n\nA kind of expert assembled from:\n\n- conversation history\n- examples\n- corrections\n- documentation\n- repeated reinforcement\n\n### What This Taught Me About Local Models\n\nI’ve spent a lot of time experimenting with local models.\n\nOne recurring frustration is that niche projects often don’t exist in their training data.\n\nRuby-LibGD is tiny compared to Rails.\n\nA local model might know everything about Rails.\n\nIt might know almost nothing about Ruby-LibGD.\n\nThat doesn’t make the model useless.\n\nIt changes the role of the developer.\n\nInstead of simply asking questions, you become a teacher.\n\nYou build the expertise layer yourself.\n\nYou provide:\n\n- documentation\n- examples\n- conventions\n- corrections\n- project-specific knowledge\n\nIn other words, you’re constructing a temporary knowledge system around the model.\n\n### The Bigger Lesson\n\nBy the end of the day, I realized I wasn’t really teaching Ruby-LibGD.\n\nI was observing the boundary between memory and context.\n\nWatching a model repeatedly make the same mistake, then slowly reduce that mistake over time, is one of the clearest demonstrations of how LLMs actually work.\n\nThe model didn’t suddenly learn.\n\nIt didn’t retrain itself.\n\nIt didn’t gain permanent knowledge.\n\nInstead, it continuously negotiated between:\n\n- prior knowledge\n- immediate evidence\n\nAnd every correction shifted that balance a little further.\n\n### Final Thoughts\n\nWhen people talk about AI assistants, they often imagine a system that either knows something or doesn’t.\n\nReality is much messier.\n\nKnowledge exists on a spectrum.\n\nA model can be:\n\n- completely unaware of a library,\n- vaguely familiar with it,\n- partially grounded by documentation,\n- or temporarily transformed into a domain expert through context.\n\nMy day with Ruby-LibGD showed me that the most interesting part isn’t the hallucinations.\n\nIt’s the process of watching a model slowly converge toward reality as you feed it better information.\n\nNot because its brain changes.\n\nBecause *its world changes*.\n\nAnd for anyone building niche software, maintaining legacy systems, or working on specialized libraries, that distinction matters more than any benchmark score ever will.", "url": "https://wpnews.pro/news/turning-a-generic-llm-into-a-ruby-libgd-expert-one-correction-at-a-time", "canonical_source": "https://rubystacknews.com/2026/06/02/turning-a-generic-llm-into-a-ruby-libgd-expert-one-correction-at-a-time/", "published_at": "2026-06-03 02:49:16+00:00", "updated_at": "2026-06-18 11:55:37.648560+00:00", "lang": "en", "topics": ["large-language-models", "developer-tools"], "entities": ["Ruby-LibGD", "GD Graphics Library", "LLM", "Hist2D", "GD::Color", "GD::Image"], "alternates": {"html": "https://wpnews.pro/news/turning-a-generic-llm-into-a-ruby-libgd-expert-one-correction-at-a-time", "markdown": "https://wpnews.pro/news/turning-a-generic-llm-into-a-ruby-libgd-expert-one-correction-at-a-time.md", "text": "https://wpnews.pro/news/turning-a-generic-llm-into-a-ruby-libgd-expert-one-correction-at-a-time.txt", "jsonld": "https://wpnews.pro/news/turning-a-generic-llm-into-a-ruby-libgd-expert-one-correction-at-a-time.jsonld"}}