<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[The Build Log]]></title><description><![CDATA[A running log of AI systems I'm building — RAG pipelines, agentic tools, and the engineering decisions behind them — plus the occasional opinion on where this s]]></description><link>https://kkhandelwal.me</link><generator>RSS for Node</generator><lastBuildDate>Wed, 09 Sep 2026 10:00:20 GMT</lastBuildDate><atom:link href="https://kkhandelwal.me/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[I Built an AI That Turns GitHub Issues Into Pull Requests — No Local Setup Required]]></title><description><![CDATA[Every developer knows the drill. A bug gets filed. You clone the repo (if you haven't already), pull the latest changes, spend 10-15 minutes just understanding where the problem lives, write a fix, wr]]></description><link>https://kkhandelwal.me/i-built-an-ai-that-turns-github-issues-into-pull-requests-no-local-setup-required</link><guid isPermaLink="true">https://kkhandelwal.me/i-built-an-ai-that-turns-github-issues-into-pull-requests-no-local-setup-required</guid><category><![CDATA[AI]]></category><category><![CDATA[agentic AI]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[architecture]]></category><category><![CDATA[Python]]></category><category><![CDATA[Sandbox]]></category><dc:creator><![CDATA[Krishna Khandelwal]]></dc:creator><pubDate>Sun, 09 Aug 2026 12:37:25 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a115978e6fc7fbb6d09255f/2f370254-a9f4-4383-a6db-869419d81440.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every developer knows the drill. A bug gets filed. You clone the repo (if you haven't already), pull the latest changes, spend 10-15 minutes just understanding <em>where</em> the problem lives, write a fix, write tests, run them, iterate, and finally open a PR. For a small-to-medium issue, this routinely eats <strong>45 minutes to an hour</strong> — and that's before code review even starts.</p>
<p>Multiply that across a backlog of 50 "good first issue" tickets and you're looking at entire engineering-days spent on work that's often mechanical: locate → understand → patch → verify → submit.</p>
<p>I wanted to see how much of that loop could be automated — not with a single LLM call and a prayer, but with a system that actually mirrors how an experienced engineer works through an issue.</p>
<blockquote>
<p>💡 <strong>Prefer hands-on testing?</strong> Scroll to the bottom of this post for an interactive live demo and repository links!</p>
</blockquote>
<hr />
<h2>What I Built</h2>
<p><strong>resolvo</strong> takes two inputs — a GitHub issue and a repository URL — and returns a pull request with passing tests. No local clone. No manual setup. Everything runs remotely, and you get an SSE-streamed view of progress in real time.</p>
<p>The measured result: <strong>turnaround time on lightweight-to-medium issues drops by roughly 85%.</strong></p>
<h3>Core Features</h3>
<p><strong>Zero local footprint</strong> — the entire fix-and-verify loop happens in a remote sandbox. Your machine never touches the repo.</p>
<p><strong>Smart triage</strong> — not every issue needs the same amount of machinery. The system classifies each issue by complexity and routes it down a lighter or heavier path accordingly, so simple fixes don't pay the cost of an exhaustive analysis.</p>
<p><strong>Real understanding, not pattern-matching</strong> — before writing a single line of code, the system builds an actual map of the codebase: which functions call which, which files depend on which, and where the relevant logic actually lives. This is what separates a fix that compiles from a fix that's <em>correct</em>.</p>
<p><strong>Tests are generated and run, not assumed</strong> — every fix is verified in an isolated sandbox before it ever reaches a PR. If tests fail, the system iterates on its own fix.</p>
<p><strong>Built-in code review</strong> — a review pass checks the diff for quality issues before the PR goes out, and can request changes just like a human reviewer would, triggering another round of fixes.</p>
<p><strong>Human-in-the-loop where it matters</strong> — for anything flagged as high-risk or high-complexity, the system stops and hands off for human review rather than merging blind.</p>
<p><strong>Live progress, not a black box</strong> — you see each stage as it happens, not just a final "done."</p>
<hr />
<h2>Architecture Decisions Worth Highlighting</h2>
<h3>1. Not every issue deserves the same treatment</h3>
<p>One of the earliest lessons: treating a one-line typo fix and a cross-module refactor with the same pipeline is wasteful and slow. The system makes an early, fast classification pass and picks one of three paths — a <strong>fast track</strong> for trivial changes, a <strong>standard path</strong> for typical fixes with full test coverage, and a <strong>critical path</strong> for anything that always requires a human to sign off before merging. This routing decision alone is a major contributor to the speed gains on lightweight and medium-weight issues — they simply skip stages that heavier issues need.</p>
<h3>2. Understanding before editing</h3>
<p>Rather than asking a model to guess at a fix from a raw diff view, the system first constructs a structural understanding of the target repository — how files relate to each other, what depends on what. This map is what the planning stage draws from when deciding exactly which files need to change and why, before any code is written.</p>
<h3>3. Multiple signals for finding the right code</h3>
<p>Locating the <em>actual</em> file(s) relevant to a fix is often the hardest part of debugging — harder than writing the fix itself. Rather than relying on a single retrieval strategy, the planning stage combines several independent signals (keyword-based search, semantic re-ranking, symbol name matching, and dependency-aware expansion) and merges them into a single ranked shortlist. Diversity of signal beats depth of any one signal.</p>
<h3>4. Verification is not optional</h3>
<p>A generated diff isn't trusted until it's been tested in a live, isolated environment. This closes the loop that a lot of "AI writes code" demos skip — a fix that looks plausible but doesn't actually pass tests is worse than no fix at all.</p>
<h3>5. Review as a built-in gate, not an afterthought</h3>
<p>Before a PR reaches a human, it goes through an automated review pass that can reject the change and send it back for another iteration — with the feedback carried forward so the next attempt actually addresses what was flagged, rather than starting from scratch.</p>
<hr />
<h2>Why This Matters for Lightweight and Medium Issues</h2>
<p>The 85% turnaround improvement isn't evenly distributed — it's heavily concentrated in the issue categories that make up the bulk of most backlogs:</p>
<p><strong>Lightweight issues</strong> (typos, small logic bugs, minor config changes) skip the heaviest analysis stages entirely and move through a fast, lightly-reviewed path — these go from "sit in the backlog for days" to "resolved in minutes."</p>
<p><strong>Medium issues</strong> (a bug that touches 2-3 files, a small feature with defined scope) benefit most from the automated retrieval-and-planning stage — the part of the work that normally costs a human the most <em>thinking</em> time before they write a single line of code.</p>
<p><strong>Critical/complex issues</strong> still get a human in the loop by design — this system isn't trying to replace judgment on high-stakes changes, just remove the grunt work leading up to that judgment call.</p>
<p>The net effect: engineers spend their time on the 10-20% of issues that genuinely need human judgment, while the mechanical majority resolve themselves.</p>
<hr />
<h2>What's Next</h2>
<p>I'm continuing to refine the classification thresholds and expanding language support beyond the current scope. If there's interest, I'll follow up with a deeper post on the evaluation methodology — how "success" is measured across issue types, and where the system still needs a human's help.</p>
<hr />
<p>Have you tried automating parts of your issue-resolution workflow? I'd be curious to hear what's worked (or hasn't) for your team.</p>
<hr />
<h2>🚀 Live Demo &amp; Repository</h2>
<p>Ready to see how <strong>resolvo</strong> converts a GitHub issue into a tested PR in real time?</p>
<ul>
<li><p>👉 <a href="https://resolvo.kkhandelwal.me"><strong>Launch the Interactive Live Demo</strong></a> <em>(No local setup required)</em></p>
</li>
<li><p>⭐ <a href="https://github.com/KKhandelwal1733/resolvo"><strong>Check out the Code on GitHub</strong></a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[From Noisy Retrieval to Precision: Building a Production RAG Pipeline for Indian Tax Law]]></title><description><![CDATA[Background
Indian tax law — GST, Income Tax, circulars, notifications — is dense, cross-referential, and unforgiving of ambiguity. A chatbot that retrieves the wrong section confidently is worse than ]]></description><link>https://kkhandelwal.me/from-noisy-retrieval-to-precision-building-a-production-rag-pipeline-for-indian-tax-law</link><guid isPermaLink="true">https://kkhandelwal.me/from-noisy-retrieval-to-precision-building-a-production-rag-pipeline-for-indian-tax-law</guid><category><![CDATA[Retrieval-Augmented Generation]]></category><category><![CDATA[RAG ]]></category><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[#anthropic]]></category><category><![CDATA[architecture]]></category><category><![CDATA[Machine Learning]]></category><dc:creator><![CDATA[Krishna Khandelwal]]></dc:creator><pubDate>Wed, 10 Jun 2026 12:36:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a115978e6fc7fbb6d09255f/bc0e56de-8d4d-48b1-82c7-a0de58343f57.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>Background</h2>
<p>Indian tax law — GST, Income Tax, circulars, notifications — is dense, cross-referential, and unforgiving of ambiguity. A chatbot that retrieves the wrong section confidently is worse than one that admits it doesn't know. Getting retrieval right is not optional; it's the whole game.</p>
<p>This post documents the full journey of building a production RAG pipeline for a tax Q&amp;A system: data collection, chunking, vector ingestion, hybrid search, reranking, and finally the technique that made the biggest difference — <strong>contextual chunking</strong>.</p>
<hr />
<h2>Stage 1: Data Collection and Corpus Preparation</h2>
<p>The first step was sourcing and cleaning the raw corpus: GST acts, Income Tax Act sections, CBDT/CBIC circulars, notifications, and FAQs. Each document was parsed and enriched with structured metadata before storage:</p>
<ul>
<li><p><code>source</code> — act name, circular number, or notification reference</p>
</li>
<li><p><code>section</code> / <code>chapter</code> — structural position within the document</p>
</li>
<li><p><code>effective_date</code> — relevant for time-bound provisions</p>
</li>
<li><p><code>document_type</code> — act | circular | notification | FAQ<br />Metadata isn't decoration — it becomes a filter layer during retrieval, letting you scope searches to a specific document type or date range.</p>
</li>
</ul>
<hr />
<h2>Stage 2: Chunking Strategy (v1 — Naive Overlap)</h2>
<p>Standard recursive character splitting with overlap. Chunks of ~400–500 tokens with a 50-token overlap, metadata injected into each chunk's payload.</p>
<p>The intuition behind overlap is sound: if a concept spans a chunk boundary, the overlap ensures neither chunk loses it entirely. In practice, for dense legal text, this assumption breaks. A 50-token overlap cannot carry the subject of a section header that appeared 300 tokens ago.</p>
<p>Ingested into a Qdrant vector store using <code>BAAI/bge-m3</code> embeddings (dense-only, 1024 dimensions).</p>
<hr />
<h2>Stage 3: Baseline Evaluation</h2>
<p>A hand-labelled evaluation set of <strong>100 question–answer pairs</strong> was prepared, covering a representative spread of GST and Income Tax queries — section lookups, rate queries, exemption conditions, filing deadlines, and cross-act references.</p>
<p><strong>Baseline retrieval metrics (naive chunks + semantic search only):</strong></p>
<table>
<thead>
<tr>
<th>Metric</th>
<th>Score</th>
</tr>
</thead>
<tbody><tr>
<td>Faithfulness</td>
<td>0.9360</td>
</tr>
<tr>
<td>Context Precision</td>
<td>0.2305</td>
</tr>
<tr>
<td>Context Recall</td>
<td>0.149</td>
</tr>
<tr>
<td>Answer Correctness</td>
<td>0.258</td>
</tr>
</tbody></table>
<p>The numbers confirmed what manual inspection already showed: chunks were being retrieved that were <em>semantically adjacent</em> to the query but not actually answering it. The model was picking up on tax-domain vocabulary without landing on the right provision.</p>
<hr />
<h2>Stage 4: Hybrid Search — Semantic + BM25</h2>
<p>The first major improvement came from combining <strong>dense vector search</strong> with <strong>BM25 lexical matching</strong>.</p>
<h3>Why BM25 matters for legal text</h3>
<p>Embedding models are excellent at capturing semantic meaning — "what is the GST rate on this type of service" maps well to the right embedding neighbourhood. But legal text is full of terms that need exact matching: section numbers (<code>Section 80C</code>), notification references (<code>Circular No. 183/15/2022</code>), HSN codes, specific defined terms. An embedding model might correctly associate <code>80C</code> with deductions but miss the specific sub-section being asked about. BM25 catches these exact-match signals.</p>
<p>BM25 builds on TF-IDF (Term Frequency-Inverse Document Frequency) — measuring how significant a term is relative to the full corpus — and refines it with document-length normalisation and term saturation to prevent common words from dominating results.</p>
<h3>Reciprocal Rank Fusion (RRF)</h3>
<p>Results from semantic search and BM25 are merged using <strong>Reciprocal Rank Fusion</strong>. RRF assigns each chunk a score based on its rank in each list (not its raw similarity score), then sums these across both lists. This avoids the score-scale mismatch between cosine similarity and BM25 scores, producing a stable combined ranking.</p>
<p><strong>Metrics after hybrid search + RRF:</strong></p>
<table>
<thead>
<tr>
<th>Metric</th>
<th>Baseline</th>
<th>Hybrid Search</th>
</tr>
</thead>
<tbody><tr>
<td>Faithfulness</td>
<td>0.9360</td>
<td>0.9234</td>
</tr>
<tr>
<td>Context Precision</td>
<td>0.2305</td>
<td>0.3510</td>
</tr>
<tr>
<td>Context Recall</td>
<td>0.149</td>
<td>0.213</td>
</tr>
<tr>
<td>Answer Correctness</td>
<td>0.258</td>
<td>0.3111</td>
</tr>
</tbody></table>
<hr />
<h2>Stage 5: Reranking</h2>
<p>After fusion, the top-K candidates are re-scored by a <strong>cross-encoder reranker</strong>. Unlike bi-encoder embeddings (which encode query and document independently), a cross-encoder takes the (query, chunk) pair jointly and produces a relevance score with full attention across both.</p>
<p>This is significantly more compute-intensive — you cannot precompute cross-encoder scores at index time — but since it only runs on the top-K candidates (typically 20–50), the latency overhead is manageable.</p>
<p>For a tax domain, reranking provides a meaningful signal: a chunk about GST input tax credit and a chunk about income tax deductions may embed similarly against a generic "tax credit" query, but a cross-encoder can distinguish the domain mismatch.</p>
<p><strong>Metrics after hybrid search + reranking:</strong></p>
<table>
<thead>
<tr>
<th>Metric</th>
<th>Baseline</th>
<th>Hybrid</th>
<th>Hybrid + Rerank</th>
</tr>
</thead>
<tbody><tr>
<td>Faithfulness</td>
<td>0.8560</td>
<td>0.9234</td>
<td>0.9364</td>
</tr>
<tr>
<td>Context Precision</td>
<td>0.2305</td>
<td>0.3510</td>
<td>0.4108</td>
</tr>
<tr>
<td>Context Recall</td>
<td>0.149</td>
<td>0.213</td>
<td>0.4494</td>
</tr>
<tr>
<td>Answer Correctness</td>
<td>0.258</td>
<td>0.3111</td>
<td>0.4566</td>
</tr>
</tbody></table>
<hr />
<h2>Stage 6: Contextual Chunking — The Game Changer</h2>
<p>Even with hybrid search and reranking, a root cause remained unaddressed: <strong>chunks were stripped of the context they needed to be interpretable</strong>.</p>
<p>Consider a chunk extracted from the GST Act:</p>
<blockquote>
<p><em>"The registered person shall not be allowed to take input tax credit in respect of any supply of goods or services or both after the due date..."</em></p>
</blockquote>
<p>This is a perfectly valid sentence. But without knowing which section it comes from, which financial year's amendment applies, or what "registered person" refers to in context — it's ambiguous. A retrieval system can fetch it, but an LLM generating an answer from it may fill in the wrong context.</p>
<h3>The Contextual Chunking Approach</h3>
<p>Contextual chunking, introduced by Anthropic, prepends a short LLM-generated context summary to each chunk <em>before</em> embedding it and building the BM25 index. The context is generated by passing the full source document alongside the target chunk to the model with this prompt structure:</p>
<pre><code class="language-plaintext">&lt;document&gt;
{{Context}}
&lt;/document&gt;
 
&lt;chunk&gt;
{{CHUNK_CONTENT}}
&lt;/chunk&gt;
 
Give a short, succinct context (50–100 tokens) that situates this chunk within 
the overall document to improve search retrieval. Respond only with the context.
</code></pre>
<p>The output for the chunk above might become:</p>
<blockquote>
<p><em>"This chunk is from Section 16(4) of the CGST Act 2017, which sets the time limit for claiming input tax credit by a registered taxpayer. The company's revenue grew by 3% over the previous quarter."</em></p>
</blockquote>
<p>This 50–100 token prefix — added to both the embedding and the BM25 index — dramatically increases the chunk's specificity. Retrieval now benefits from the document-level signal without requiring the entire document to be embedded.</p>
<blockquote>
<p><strong>Note on cost:</strong> Generating context for every chunk at indexing time does incur LLM API costs. For large corpora, prompt caching (available on the Claude API) can reduce this significantly — up to 90% cost reduction on repeated document prefixes.</p>
</blockquote>
<h3>Why Other Approaches Underperform</h3>
<p>Generic document summaries appended to chunks provide marginal gains — a summary of the entire GST Act tells you very little about which specific provision a chunk belongs to. Hypothetical Document Embedding (HyDE) and summary-based indexing have also been benchmarked and show lower performance than chunk-specific contextualisation for retrieval tasks.</p>
<p><strong>Metrics after contextual chunking:</strong></p>
<table>
<thead>
<tr>
<th>Metric</th>
<th>Baseline</th>
<th>Hybrid + Rerank</th>
<th>Contextual + Hybrid + Rerank</th>
</tr>
</thead>
<tbody><tr>
<td>Faithfulness</td>
<td>0.8560</td>
<td>0.9234</td>
<td>0.9364</td>
</tr>
<tr>
<td>Context Precision</td>
<td>0.2305</td>
<td>0.3510</td>
<td>0.4108</td>
</tr>
<tr>
<td>Context Recall</td>
<td>0.149</td>
<td>0.213</td>
<td>0.4494</td>
</tr>
<tr>
<td>Answer Correctness</td>
<td>0.258</td>
<td>0.3111</td>
<td>0.4566</td>
</tr>
</tbody></table>
<p>Anthropic's benchmarks on their datasets show contextual retrieval reducing failed retrievals by <strong>49%</strong> over standard embedding-only RAG, and by <strong>67%</strong> when combined with reranking. Results in domain-specific corpora like legal/tax text tend to be on the higher end of this range due to how heavily context-dependent the language is.</p>
<hr />
<h2>Full Pipeline Architecture</h2>
<pre><code class="language-plaintext">Raw Documents (GST Act, IT Act, Circulars, Notifications)
         │
         ▼
   Metadata Extraction
   (source, section, effective_date, doc_type)
         │
         ▼
   Recursive Text Chunking (~400-500 tokens)
         │
         ▼
   Contextual Prefix Generation (LLM, per chunk)
         │
   ┌─────────────────┐
   ▼                          ▼
  Dense Embedding         BM25 Index
  (bge-m3, 1024d)     (contextual chunks)
  → Qdrant                 │
     │                      │
     └──────┬───────┘
                   ▼
         Reciprocal Rank Fusion
                  │
                  ▼
           Cross-Encoder Reranker
                  │
                  ▼
            Top-K Chunks → LLM → Answer
</code></pre>
<hr />
<h2>Key Takeaways</h2>
<p><strong>Overlap alone doesn't solve context loss.</strong> For technical/legal text where document structure carries meaning, naive overlap is insufficient. Context needs to be explicitly injected.</p>
<p><strong>BM25 is not obsolete.</strong> Lexical matching remains essential for identifier-heavy domains — section numbers, notification codes, HSN codes. Pure semantic search misses these.</p>
<p><strong>Reranking is the cheapest meaningful improvement.</strong> Cross-encoder reranking on top-K candidates adds latency (100–300ms typically) but no indexing cost, and the quality gain is significant.</p>
<p><strong>Contextual chunking compounds with everything else.</strong> It improves both the embedding quality and the BM25 index simultaneously, so every downstream step benefits.</p>
<p><strong>Evaluation set quality is everything.</strong> 100 hand-labelled Q&amp;A pairs covering the actual distribution of user queries is worth more than automated generation at 10x the size. Garbage evals produce misleading metrics.</p>
<hr />
<h2>References</h2>
<ul>
<li><p><a href="https://www.anthropic.com/engineering/contextual-retrieval">Contextual Retrieval — Anthropic Engineering Blog</a></p>
</li>
<li><p><a href="https://huggingface.co/BAAI/bge-m3">BAAI/bge-m3 — FlagEmbedding</a></p>
</li>
<li><p><a href="https://docs.ragas.io">RAGAS — RAG Evaluation Framework</a></p>
</li>
<li><p><a href="https://qdrant.tech/documentation/">Qdrant Vector Database</a></p>
</li>
<li><p><a href="https://dl.acm.org/doi/10.1145/1571941.1572114">Reciprocal Rank Fusion (Cormack et al., 2009)</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[What I Learnt This Week: Deconstructing AI Logic, Tokens, and the Hidden Traps]]></title><description><![CDATA[Hey everyone! Welcome to my very first tech blog post. 👋
Lately, I’ve been diving deep into how Large Language Models (LLMs) actually work under the hood. Like most people, I used to treat AI like a ]]></description><link>https://kkhandelwal.me/what-i-learnt-this-week-deconstructing-ai-logic-tokens-and-the-hidden-traps</link><guid isPermaLink="true">https://kkhandelwal.me/what-i-learnt-this-week-deconstructing-ai-logic-tokens-and-the-hidden-traps</guid><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[Beginner Developers]]></category><category><![CDATA[#PromptEngineering]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[techblog]]></category><dc:creator><![CDATA[Krishna Khandelwal]]></dc:creator><pubDate>Sat, 23 May 2026 16:27:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a115978e6fc7fbb6d09255f/e3b4e331-5001-494a-a781-fac422a46cfd.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey everyone! Welcome to my very first tech blog post. 👋</p>
<p>Lately, I’ve been diving deep into how Large Language Models (LLMs) actually work under the hood. Like most people, I used to treat AI like a black box—you type a prompt, magic happens, and a polished answer pops out.</p>
<p>But this week, I dug into the mechanics behind the screen and discovered three fascinating insights (and one major training trap) that completely changed how I think about prompting and training AI. If you're a beginner like me, let's break them down together!</p>
<hr />
<h2>1. Why "Give Me the Answer Only" Actually Breaks the AI 🧠</h2>
<p>When I’m in a rush, my natural instinct is to prompt an LLM with something like: <em>"Just give me the final answer, skip the explanation."</em> Turns out, this is a terrible idea for complex logic or math.</p>
<p>I learned that the intermediate, step-by-step reasoning steps a model outputs (often called <strong>Chain-of-Thought</strong>) aren't just there to look pretty for us humans—<strong>they are literally generated for the model itself.</strong> LLMs predict text sequentially, token by token. Each new word it writes relies heavily on the context of the words it <em>just</em> wrote. When you force a model to skip its thinking process and jump straight to the conclusion, you rob it of its working memory.</p>
<blockquote>
<p><strong>💡 Lesson #1:</strong> If you want accurate results for tricky problems, always let the model think out loud!</p>
</blockquote>
<hr />
<h2>2. The Counting Blind Spot: Why AI Fails at Basic Spelling &amp; Counting 🔢</h2>
<p>Have you ever asked an AI to count how many times a specific letter appears in a long word, only for it to confidently give you the wrong number? I always found this completely baffling. It's a supercomputer, right? Why can't it count to 4?</p>
<p>Here is the secret: <strong>AI does not see raw text character-by-character.</strong> Instead, before your text even hits the AI's "brain," a preprocessing step cuts words up into semantic chunks called <strong>Tokens</strong>.</p>
<p>Because the model only processes these pre-packaged token IDs, it doesn't intuitively "see" the individual letters inside them. It’s like trying to count the syllables in a word without being allowed to look at the alphabet.</p>
<h3>The Fix: Execution Over Prediction</h3>
<p>This is why using tools changes everything. When you tell an LLM to <strong>"use code"</strong> (like an integrated Python interpreter) to solve a problem, it stops guessing the next word based on mathematical probability. Instead, it generates a literal, deterministic script and executes it.</p>
<ul>
<li><p><strong>Prediction:</strong> "I guess the word <em>strawberry</em> has 2 'r's based on common speech patterns." ❌</p>
</li>
<li><p><strong>Execution:</strong> <code>print("strawberry".count("r"))</code> -&gt; <code>3</code> ✅</p>
</li>
</ul>
<hr />
<h2>3. Training the Unquantifiable: How We Teach AI to Tell Jokes 🎭</h2>
<p>How do you train an AI to do something completely subjective, like writing a funny joke, maintaining a helpful tone, or summarizing an essay well? There is no absolute mathematical "right answer" to check against a key.</p>
<p>I looked into how engineers solve this at scale, and it comes down to an awesome process called <strong>RLHF (Reinforcement Learning from Human Feedback)</strong>:</p>
<ol>
<li><p><strong>Human Scoring:</strong> Humans are given multiple variations of an AI response to a single prompt and rank them from best to worst.</p>
</li>
<li><p><strong>The Reward Model:</strong> That ranking data is fed into a separate "referee" neural network to teach it what a "good" human response looks like.</p>
</li>
<li><p><strong>The Loop:</strong> The main AI generates text, the referee network scores it, and the main AI adjusts its internal parameters to chase higher scores.</p>
</li>
</ol>
<hr />
<h2>4. The Over-Training Trap 🛑</h2>
<p>You would think that leaving a model in this reinforcement loop longer would make it smarter and smarter, right? This was my absolute favorite finding this week: <strong>it doesn't!</strong></p>
<p>I learned about a fascinating concept where response quality behaves like an inverted U-curve relative to training time.</p>
<p>If you let the training loop run too long without intervention, the quality drops off a cliff. The AI starts "gaming the system." It figures out exactly what quirks or phrases the referee network scores highly, and it begins outputting overly long, repetitive, or incredibly sycophantic ("brown-nosed") answers. They score perfectly on paper but read horribly to a real human.</p>
<p>Knowing exactly when to hit the brakes on training is a literal science!</p>
<hr />
<h2>Wrapping Up 🚀</h2>
<p>Writing this all out helped me realize that prompt engineering isn't just about finding "magic words"—it’s about understanding the underlying architecture of the machine you are collaborating with.</p>
<p>If you're also experimenting with AI tools, try letting them write out their reasoning next time or explicitly ask them to use a code block for calculation, and watch your results drastically improve.</p>
<p><em>What did you learn in your tech journey this week? Let me know in the comments below, and don't forget to follow along for more beginner-friendly tech roundups!</em></p>
]]></content:encoded></item></channel></rss>