<?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[Tsx watch]]></title><description><![CDATA[I'll document some tutorials that are self-tweaked, AI-generated, and experience seasoned]]></description><link>https://blog.astrobot.tech</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1767286427687/7fe3505a-f1d9-48e6-a7ee-9749d7314a6e.png</url><title>Tsx watch</title><link>https://blog.astrobot.tech</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 30 Apr 2026 20:42:51 GMT</lastBuildDate><atom:link href="https://blog.astrobot.tech/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Recursive Language Models (RLMs)]]></title><description><![CDATA[Paper: Zhang, Kraska & Khattab — MIT CSAIL, January 2026Code: github.com/alexzhang13/rlm
TLDR;

From first principles — before RLMs, performance degradation over large contexts was a known issue. RLM ]]></description><link>https://blog.astrobot.tech/recursive-language-models-rlms</link><guid isPermaLink="true">https://blog.astrobot.tech/recursive-language-models-rlms</guid><dc:creator><![CDATA[Aditya Raj]]></dc:creator><pubDate>Mon, 30 Mar 2026 19:51:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/f1b23c18-2eeb-4f58-9c53-ef3cfea75da9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Paper:</strong> Zhang, Kraska &amp; Khattab — MIT CSAIL, January 2026<br /><strong>Code:</strong> <a href="https://github.com/alexzhang13/rlm">github.com/alexzhang13/rlm</a></p>
<h2>TLDR;</h2>
<blockquote>
<p>From first principles — before RLMs, performance degradation over large contexts was a known issue. RLM addressed this by saying: "I will write code to split the large context into meaningful chunks, and for each chunk I will call an LLM. That sub-LLM call can itself further split and call recursively."</p>
</blockquote>
<img src="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/0c42dafa-a9bf-4d7d-b71f-a5d3c69c5934.png" alt="" style="display:block;margin:0 auto" />

<p>Your one-line summary is actually the cleanest way to state the paper's core idea:</p>
<blockquote>
<p>"I will write code to split the large context into meaningful chunks, call an LLM on each chunk, and that sub-LLM can itself split and call further."</p>
</blockquote>
<p>The three eras the paper is responding to are exactly:</p>
<p><strong>Era 1 — Vanilla LLM:</strong> Just stuff everything into the window. Works until the context gets long, then quality collapses — the paper calls this <em>context rot</em>. The model attends poorly to tokens far back in the sequence.</p>
<p><strong>Era 2 — Compaction/summary agents:</strong> Split and summarise as you go. Slightly better, but <em>lossy</em> — once you summarise chunk 1, those details are gone forever. Fails for tasks that need every part of the document.</p>
<p><strong>Era 3 — RLM:</strong> Don't put the context in the window at all. Store it as a variable in the REPL. The root LLM writes code to <em>selectively inspect</em> only what it needs, calls sub-LLMs on those pieces, and those sub-LLMs can do the exact same thing again. Nothing is discarded — everything remains accessible in the REPL variable at all times.</p>
<p>The elegant thing is that the recursion is not designed by a human — the <em>model itself</em> decides how to split, how deep to go, and when a chunk is small enough to answer directly. That's what makes it general purpose rather than task-specific.</p>
<hr />
<h2>The Problem: Context Rot</h2>
<p>Frontier LLMs have a fixed context window. When you stuff a very long prompt into it, quality degrades steeply — the model attends poorly to tokens far back in the sequence. The paper calls this <strong>context rot</strong>.</p>
<p>The two approaches before RLMs both fell short:</p>
<table>
<thead>
<tr>
<th>Approach</th>
<th>What it does</th>
<th>Limitation</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Vanilla LLM</strong></td>
<td>Feed the entire prompt directly into the window</td>
<td>Window fills up; context rot kicks in</td>
</tr>
<tr>
<td><strong>Compaction / summary agents</strong></td>
<td>Summarise chunks as context fills</td>
<td>Lossy — early details are permanently discarded</td>
</tr>
</tbody></table>
<p>Neither approach works for tasks that need <strong>dense access throughout</strong> the full document — things like aggregating every line of a dataset, understanding an entire codebase, or reasoning across millions of tokens.</p>
<hr />
<h2>The RLM Idea — From First Principles</h2>
<p>The core insight is simple:</p>
<blockquote>
<p><strong>Don't put the large context into the LLM's attention window at all. Store it as a variable in an external environment. Let the LLM write code to split it into meaningful chunks, then call itself on each chunk. Each sub-call can itself split and call further.</strong></p>
</blockquote>
<p>This is the recursive part — the same model appears at every level of the tree, calling itself until chunks are small enough to answer directly.</p>
<img src="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/1b794245-570f-4173-b5c0-b9ca7cf90cd5.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>How It Works</h2>
<h3>1. The REPL Environment</h3>
<p>When an RLM receives a long prompt <code>P</code>, it does <strong>not</strong> feed <code>P</code> to the LLM. Instead:</p>
<pre><code class="language-python">state["context"] = P          # stored as a variable
hist = [Metadata(state)]      # only length, prefix, structure given to LLM
</code></pre>
<p>The LLM never sees the full text. It only knows the context exists as a variable. To read it, the model must <strong>write code</strong>:</p>
<pre><code class="language-python">chunk = context[:50000]
result = llm_query(f"Summarise this: {chunk}")
</code></pre>
<p>The REPL executes that code and returns only a short truncated <code>stdout</code> back to the model — forcing it to use variables and sub-calls to manage long content rather than printing everything into its window.</p>
<h3>2. The <code>llm_query()</code> Function</h3>
<p>The REPL is initialised with two things:</p>
<ul>
<li><p><code>context</code> — the full prompt as a string variable</p>
</li>
<li><p><code>llm_query()</code> — a function that is itself a sub-RLM call</p>
</li>
</ul>
<p>This means the model can write loops like:</p>
<pre><code class="language-python">chunks = [context[i:i+50000] for i in range(0, len(context), 50000)]
results = [llm_query(f"Answer this about the chunk: {c}") for c in chunks]
final = llm_query(f"Combine these: {results}")
</code></pre>
<p>Each <code>llm_query()</code> call is a full RLM invocation — same loop, same REPL, same ability to recurse further.</p>
<h3>3. The RLM Loop (Algorithm 1)</h3>
<pre><code class="language-python">state ← InitREPL(prompt=P)
state ← AddFunction(state, sub_RLM)   # inject itself as callable
hist  ← [Metadata(state)]

while True:
    code         ← LLM(hist)              # model writes code
    state, stdout ← REPL(state, code)     # code runs, may call sub_RLM
    hist         ← hist + code + Metadata(stdout)
    if state["Final"] is set:
        return state["Final"]
</code></pre>
<img src="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/a5e98d77-f1f6-4f4b-b277-6d3f8ff6e99a.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>The Recursion Tree</h2>
<p>For a 10,000-page document:</p>
<img src="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/6d6e1b63-11d7-4f0b-87fe-1b5d9f87ccd9.png" alt="" style="display:block;margin:0 auto" />

<pre><code class="language-plaintext">Root LLM  (10,000 pages — too large)
├── Sub-LLM 1  (100 pages — still too large → splits again)
│   ├── Sub-Sub-LLM 1.1  (10 pages — fits → answer)
│   ├── Sub-Sub-LLM 1.2  (10 pages — fits → answer)
│   └── ...merge → section 1 summary
├── Sub-LLM 2  (100 pages — fits → answer directly)
├── ...
└── Sub-LLM N  (100 pages — fits → answer directly)
         ↓
Root merges all results → FINAL answer
</code></pre>
<p>The split is not uniform — the root LLM uses code (regex, keyword search, structural markers) to <strong>intelligently decide</strong> how to slice the context. It might fetch only documents containing a keyword, or split by Markdown headers, or chunk by newlines.</p>
<hr />
<h2>When Does It Stop Splitting?</h2>
<p>Two stopping conditions:</p>
<p><strong>1. Natural base case</strong> — the chunk fits comfortably in the sub-LLM's context window. The model answers directly. No further splitting needed.</p>
<p><strong>2. Hard depth limit</strong> — a maximum recursion depth is enforced as a safety guardrail. In the paper's experiments, depth was set to <strong>1</strong>: sub-LLMs could not split further and were treated as plain LLM calls.</p>
<p>There is no explicit "is this small enough?" check baked into the system — the <strong>model itself</strong> learns to judge this through prompting or fine-tuning. This is why weaker models like Qwen3-8B struggled as RLMs without fine-tuning: they didn't reliably know when to stop splitting vs when to just answer.</p>
<hr />
<h2>Key Design Choices vs Naive Approaches</h2>
<p>The paper contrasts RLMs with a "similar-looking" Algorithm 2 that is far less expressive:</p>
<table>
<thead>
<tr>
<th></th>
<th>RLM (Algorithm 1)</th>
<th>Naive agent (Algorithm 2)</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Where does</strong> <code>P</code> <strong>live?</strong></td>
<td>REPL variable — never in LLM window</td>
<td>Directly in <code>hist</code> — window fills immediately</td>
</tr>
<tr>
<td><strong>How are outputs generated?</strong></td>
<td>Via REPL variables — unbounded length</td>
<td>LLM generates directly — bounded by window</td>
</tr>
<tr>
<td><strong>Sub-calls</strong></td>
<td>Programmatic — inside loops, Ω(</td>
<td>P</td>
</tr>
</tbody></table>
<hr />
<h2>Results</h2>
<p>RLMs were evaluated on four tasks of increasing complexity:</p>
<table>
<thead>
<tr>
<th>Task</th>
<th>Complexity</th>
<th>RLM (GPT-5)</th>
<th>Base GPT-5</th>
</tr>
</thead>
<tbody><tr>
<td>S-NIAH (needle-in-haystack)</td>
<td>O(1)</td>
<td>Strong</td>
<td>Strong (within window)</td>
</tr>
<tr>
<td>BrowseComp+ 1K docs</td>
<td>Linear</td>
<td><strong>91.3%</strong></td>
<td>0% (can't fit in window)</td>
</tr>
<tr>
<td>OOLONG</td>
<td>Linear</td>
<td><strong>56.5%</strong></td>
<td>44.0%</td>
</tr>
<tr>
<td>OOLONG-Pairs</td>
<td>Quadratic</td>
<td><strong>58.0%</strong></td>
<td>0.1%</td>
</tr>
</tbody></table>
<p>Key findings:</p>
<ul>
<li><p>RLMs handle inputs <strong>up to 2 orders of magnitude beyond</strong> the model's context window</p>
</li>
<li><p>On information-dense tasks, RLMs outperform all baselines by <strong>double-digit percentages</strong></p>
</li>
<li><p>Median inference cost is <strong>comparable to or cheaper than</strong> a base model call</p>
</li>
<li><p>A fine-tuned 8B model (RLM-Qwen3-8B) outperformed base Qwen3-8B by <strong>28.3% on average</strong></p>
</li>
</ul>
<hr />
<h2>Emergent Patterns in RLM Trajectories</h2>
<p>Even without task-specific training, RLMs develop consistent strategies:</p>
<ul>
<li><p><strong>Regex filtering</strong> — use code to search for keywords before calling sub-LLMs, avoiding unnecessary processing</p>
</li>
<li><p><strong>Batch chunking</strong> — split by newlines, headers, or fixed character counts and process in parallel</p>
</li>
<li><p><strong>Variable stitching</strong> — for long-output tasks, store sub-call results in variables and concatenate into a final answer</p>
</li>
</ul>
<hr />
<h2>Limitations</h2>
<ul>
<li><p>Sub-calls are currently <strong>synchronous and blocking</strong> — async calls would dramatically reduce runtime</p>
</li>
<li><p>Max recursion depth of 1 was used — <strong>deeper recursion</strong> is unexplored</p>
</li>
<li><p>Models without strong <strong>coding capabilities</strong> struggle as RLMs</p>
</li>
<li><p>Thinking models can <strong>run out of output tokens</strong> mid-trajectory if reasoning tokens are too long</p>
</li>
</ul>
<hr />
<h2>One-Line Summary</h2>
<blockquote>
<p>An RLM stores the prompt as a code variable, writes a program to split it into chunks, calls itself on each chunk, and each sub-call can split further — stopping only when a chunk fits in the context window or the recursion depth limit is hit.</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[What is HyDE]]></title><description><![CDATA[The core question is: what makes zero-shot retrieval fail, and what would fix it?
Let me build up the intuition step by step.The root problem: A user query like "how do I fix a leaky pipe?" and a docu]]></description><link>https://blog.astrobot.tech/what-is-hyde</link><guid isPermaLink="true">https://blog.astrobot.tech/what-is-hyde</guid><category><![CDATA[RAG ]]></category><dc:creator><![CDATA[Aditya Raj]]></dc:creator><pubDate>Tue, 24 Mar 2026 05:18:15 GMT</pubDate><content:encoded><![CDATA[<img src="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/85f49482-a5c4-43eb-a1f8-cda56da57d35.png" alt="" style="display:block;margin:0 auto" />

<h3>The core question is: <strong>what makes zero-shot retrieval fail, and what would fix it?</strong></h3>
<p>Let me build up the intuition step by step.<strong>The root problem:</strong> A user query like <em>"how do I fix a leaky pipe?"</em> and a document containing <em>"plumbing maintenance procedures for residential water systems"</em> might mean the same thing — but their vector representations land in different neighborhoods. Zero-shot retrieval compares <em>short + sparse</em> query embeddings to <em>long + rich</em> document embeddings. That mismatch is structural.</p>
<p>So the question becomes: <strong>how do we close this gap?</strong></p>
<hr />
<p><strong>First principles thinking — three possible strategies:</strong></p>
<ol>
<li><p><strong>Strategy 1 — Bring the document closer to the query.</strong> Summarize or compress documents into query-like representations. (This is what dense retrieval models are trained to do.) But it's hard to do at inference time.</p>
</li>
<li><p><strong>Strategy 2 — Bring the query closer to the document.</strong> Expand the query — add synonyms, related terms, more context. Old-school NLP did this (query expansion). But how do you know <em>what</em> to expand with?</p>
</li>
<li><p><strong>Strategy 3 — Bypass the gap entirely.</strong> What if instead of comparing <em>queries to documents</em>, we compared <em>documents to documents</em>?</p>
</li>
</ol>
<p>That third insight is the key leap. Let's follow it.This is the core idea of <strong>HyDE — Hypothetical Document Embeddings.</strong></p>
<hr />
<h3><strong>The key insight unpacked:</strong></h3>
<p><code>Instead of asking *"find documents similar to this query"*, HyDE asks *"find documents similar to what the answer would look like.</code>"*</p>
<p>The LLM generates a <strong>hypothetical document</strong> — essentially, a plausible answer to the query. It doesn't matter if the answer is factually correct. What matters is that it <strong>lives in the same vector space distribution</strong> as real documents. A hallucinated but plausible paragraph about pipe leaks will structurally resemble a real plumbing article far more than the original query <em>"how do I fix a leaky pipe?"</em> ever could.</p>
<p>Then you embed that hypothetical doc and use it as your search vector.</p>
<img src="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/1e3d1eb9-a9a5-4940-b5bf-610abe5b1bdb.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h3><strong>Why does this work, from first principles?</strong></h3>
<p>Embedding models are trained on documents. Their geometry reflects document-level patterns — vocabulary, phrasing, density, style. A short query is an <em>outlier</em> in that space. A paragraph, even a fabricated one, is a native inhabitant.</p>
<p>You're essentially using the LLM as a <strong>query-to-document translator</strong>, converting a sparse user intent signal into something the embedding space is comfortable navigating.</p>
<hr />
<h3><strong>The beautiful tradeoff:</strong></h3>
<p>HyDE offloads the semantic interpretation burden to the LLM (which is good at understanding intent) and lets the embedding model do what it's good at (comparing document-like things to other document-like things). The two models play to their strengths.</p>
<h2>Final Pipeline</h2>
<img src="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/b155be36-0469-42d9-ba4b-5f7aff9c6647.png" alt="" style="display:block;margin:0 auto" />

<p>So HyDE is actually two separate LLM calls doing two completely different jobs:</p>
<ul>
<li><p><strong>LLM call 1</strong> — be creative, hallucinate freely, just sound like a document</p>
</li>
<li><p><strong>LLM call 2</strong> — be accurate, stick to what the retrieved docs actually say</p>
</li>
</ul>
<p>That separation of concerns is the elegance of it.</p>
<h2>Abstract</h2>
<img src="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/bd2936b4-9c6c-4481-8faf-29af5d38c65a.png" alt="" style="display:block;margin:0 auto" />

<p><strong>Research Paper : Precise Zero-Shot Dense Retrieval without Relevance Label</strong></p>
<p>Ref : <a href="https://arxiv.org/abs/2212.10496">https://arxiv.org/abs/2212.10496</a></p>
]]></content:encoded></item><item><title><![CDATA[Positional Encoding in Transformers]]></title><description><![CDATA[1. Overview
Positional Encoding is a technique used in Transformer architectures to encode the order of tokens in a sequence.
Transformers process tokens in parallel, unlike sequential models such as ]]></description><link>https://blog.astrobot.tech/positional-encoding-in-tranformers</link><guid isPermaLink="true">https://blog.astrobot.tech/positional-encoding-in-tranformers</guid><dc:creator><![CDATA[Aditya Raj]]></dc:creator><pubDate>Wed, 04 Mar 2026 08:47:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/45557b44-6965-40b6-a387-9cbf728a8c2a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>1. Overview</h2>
<p><strong>Positional Encoding</strong> is a technique used in <strong>Transformer architectures</strong> to encode the <strong>order of tokens in a sequence</strong>.</p>
<p>Transformers process tokens <strong>in parallel</strong>, unlike sequential models such as RNNs. Because of this, the model has <strong>no inherent understanding of token order</strong>. Positional encoding injects information about <strong>token positions</strong> into token embeddings before they enter the self-attention layers.</p>
<p>The final representation sent to the transformer is:</p>
<pre><code class="language-plaintext">Input = TokenEmbedding + PositionalEncoding
</code></pre>
<p>This allows the model to learn both:</p>
<ul>
<li><p><strong>semantic meaning</strong> (from embeddings)</p>
</li>
<li><p><strong>sequence order</strong> (from positional encoding)</p>
</li>
</ul>
<hr />
<h1>2. Why This Exists</h1>
<h2>The Core Problem</h2>
<p>Self-attention processes tokens <strong>simultaneously</strong>, not sequentially.</p>
<p>Example sentence:</p>
<pre><code class="language-plaintext">"Nitish killed lion"
"Lion killed Nitish"
</code></pre>
<p>Both sentences contain the same tokens:</p>
<pre><code class="language-plaintext">[Nitish, killed, lion]
</code></pre>
<p>If sent to self-attention simultaneously, the model cannot distinguish <strong>token order</strong>, so both sequences appear identical.</p>
<p>This is a fundamental limitation because <strong>word order determines meaning</strong> in natural language.</p>
<h3>Why Previous Models Didn't Have This Problem</h3>
<table>
<thead>
<tr>
<th>Model</th>
<th>Order Awareness</th>
<th>Reason</th>
</tr>
</thead>
<tbody><tr>
<td>RNN</td>
<td>Yes</td>
<td>Tokens processed sequentially</td>
</tr>
<tr>
<td>LSTM</td>
<td>Yes</td>
<td>Hidden state carries time information</td>
</tr>
<tr>
<td>Transformer</td>
<td>No</td>
<td>Tokens processed in parallel</td>
</tr>
</tbody></table>
<p>Transformers sacrifice <strong>sequential processing</strong> for <strong>parallel efficiency</strong>, so positional information must be explicitly added.</p>
<hr />
<h1>3. First Principles Explanation</h1>
<p>To solve the ordering problem, we must encode <strong>position information</strong> alongside token embeddings.</p>
<h3>Components</h3>
<ol>
<li><p><strong>Token Embedding</strong></p>
</li>
<li><p><strong>Positional Encoding</strong></p>
</li>
<li><p><strong>Self-Attention Layer</strong></p>
</li>
</ol>
<h3>Interaction</h3>
<pre><code class="language-plaintext">Token → Embedding Vector
Position → Positional Encoding Vector

Final Input = Embedding + Positional Encoding
</code></pre>
<p>Each token therefore carries:</p>
<pre><code class="language-plaintext">semantic information + positional information
</code></pre>
<h3>Design Requirements</h3>
<p>A good positional encoding must satisfy:</p>
<ol>
<li><strong>Bounded values</strong></li>
</ol>
<p>Neural networks train best with values in small ranges (e.g. -1 to 1).</p>
<ol>
<li><strong>Continuous values</strong></li>
</ol>
<p>Neural networks prefer <strong>smooth functions</strong>, not discrete jumps.</p>
<ol>
<li><strong>Ability to capture relative positions</strong></li>
</ol>
<p>The model should infer relationships like:</p>
<pre><code class="language-plaintext">distance(token_i, token_j)
</code></pre>
<ol>
<li><strong>Unique representation</strong></li>
</ol>
<p>Each position must have a <strong>distinct encoding</strong>.</p>
<hr />
<h1>4. How It Works</h1>
<h3>Step 1 — Tokenize Sentence</h3>
<p>Example:</p>
<pre><code class="language-plaintext">Sentence: "River Bank"
Tokens: [River, Bank]
</code></pre>
<h3>Step 2 — Convert Tokens to Embeddings</h3>
<p>Example:</p>
<pre><code class="language-plaintext">River → embedding vector (d_model)
Bank  → embedding vector (d_model)
</code></pre>
<p>Example dimension:</p>
<pre><code class="language-plaintext">d_model = 512
</code></pre>
<h3>Step 3 — Generate Positional Encoding</h3>
<p>For position <code>pos</code> and dimension <code>i</code>:</p>
<pre><code class="language-plaintext">PE(pos,2i)   = sin(pos / 10000^(2i/d_model))
PE(pos,2i+1) = cos(pos / 10000^(2i/d_model))
</code></pre>
<p>Key ideas:</p>
<ul>
<li><p><strong>even dimensions → sine</strong></p>
</li>
<li><p><strong>odd dimensions → cosine</strong></p>
</li>
</ul>
<h3>Step 4 — Add Positional Encoding to Embedding</h3>
<pre><code class="language-plaintext">InputVector = Embedding + PositionalEncoding
</code></pre>
<h3>Step 5 — Send to Self-Attention</h3>
<p>The resulting vector contains both:</p>
<pre><code class="language-plaintext">semantic meaning + position
</code></pre>
<p>This vector becomes the input to the transformer encoder.</p>
<hr />
<h1>5. Example</h1>
<h3>Situation</h3>
<p>Sentence:</p>
<pre><code class="language-plaintext">"The lion runs"
</code></pre>
<p>Token positions:</p>
<pre><code class="language-plaintext">The  → position 0
lion → position 1
runs → position 2
</code></pre>
<h3>Implementation Idea</h3>
<p>Compute positional encodings:</p>
<pre><code class="language-plaintext">PE(0)
PE(1)
PE(2)
</code></pre>
<p>Then combine:</p>
<pre><code class="language-plaintext">Embedding(The)  + PE(0)
Embedding(lion) + PE(1)
Embedding(runs) + PE(2)
</code></pre>
<h3>Expected Outcome</h3>
<p>The transformer can now learn relationships such as:</p>
<ul>
<li><p>which word comes first</p>
</li>
<li><p>relative distances between words</p>
</li>
<li><p>syntactic dependencies</p>
</li>
</ul>
<hr />
<h1>Summary</h1>
<ul>
<li><p>Transformers process tokens <strong>in parallel</strong>, losing order information.</p>
</li>
<li><p><strong>Positional encoding</strong> injects token position information.</p>
</li>
<li><p>Encodings are generated using <strong>sine and cosine functions</strong> at multiple frequencies.</p>
</li>
<li><p>Positional vectors have the <strong>same dimension as embeddings</strong>.</p>
</li>
<li><p>Final input to transformers is:</p>
</li>
</ul>
<pre><code class="language-plaintext">embedding + positional_encoding
</code></pre>
]]></content:encoded></item><item><title><![CDATA[How to Create a Custom Solana Token with Metadata (Using Token-2022)? ]]></title><description><![CDATA[If you have your Solana CLI set up and you are ready to launch your own digital asset, the new Token-2022 standard (also known as Token Extensions) is the way to go. It offers built-in metadata suppor]]></description><link>https://blog.astrobot.tech/how-to-create-custom-solana-token</link><guid isPermaLink="true">https://blog.astrobot.tech/how-to-create-custom-solana-token</guid><category><![CDATA[Solana]]></category><category><![CDATA[Web3]]></category><dc:creator><![CDATA[Aditya Raj]]></dc:creator><pubDate>Sun, 01 Mar 2026 07:31:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/752f73f8-2d51-4093-a07f-881905ca27f4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you have your Solana CLI set up and you are ready to launch your own digital asset, the new <strong>Token-2022</strong> standard (also known as Token Extensions) is the way to go. It offers built-in metadata support directly at the mint level, meaning you no longer need to rely on external programs like Metaplex just to give your token a name and a picture.</p>
<p>In this guide, we will walk through the exact terminal commands to create a token—we'll use <strong>Adit Coin (ARDT)</strong> as <strong>Aditya Raj De Token</strong> —mint an initial supply, and link it to its metadata.</p>
<hr />
<h2>Step 1: Create the Token Mint</h2>
<p>The first step is to create the actual token "blueprint" (the Mint). We need to specify that we are using the new Token-2022 program and that we want to enable the metadata extension. We will also set the decimals to <code>9</code> (the standard for most Solana tokens).</p>
<p>Run this command in your terminal:</p>
<pre><code class="language-plaintext">spl-token create-token \
  --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb \
  --enable-metadata \
  --decimals 9
</code></pre>
<p><strong>What happens next:</strong></p>
<p>The CLI will generate a unique address for your token. In our example logs, this returned <code>BTJ4cPPwssx6b7jy9GoUyBeLBxufyCSoUzvuegEUCVx8</code>. Keep track of this address; you will need it for the next steps!</p>
<p>Verify Here: <a href="https://explorer.solana.com/tx/2WF1A4JDkpWWfGKTjrihiLZVe4gTPeTKDAieAX6EnkLnrA8tqr4qu339e2iKn6EG2w2CwfaQjeGVHDLYWHrbZJno?cluster=devnet">https://explorer.solana.com/tx/2WF1A4JDkpWWfGKTjrihiLZVe4gTPeTKDAieAX6EnkLnrA8tqr4qu339e2iKn6EG2w2CwfaQjeGVHDLYWHrbZJno?cluster=devnet</a></p>
<img src="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/e1d51d9f-8c40-4bdc-8257-b928340f56b9.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>Step 2: Create an Associated Token Account (ATA)</h2>
<p>Before you can actually mint (create) any of these new tokens, your wallet needs a specific sub-account designed to hold them. Think of it like opening a specific currency pocket inside your main wallet.</p>
<p>Create the account using your new token address:</p>
<pre><code class="language-plaintext">spl-token create-account BTJ4cPPwssx6b7jy9GoUyBeLBxufyCSoUzvuegEUCVx8
</code></pre>
<p><strong>What happens next:</strong></p>
<p>You will receive an output with your new Associated Token Account address (e.g., <code>HJPewMqabd4gnqmTQwiwNiHCQV14ETjVsn7spTiEpiAN</code>). This is where your newly minted tokens will land.</p>
<p>Verify Here:</p>
<p><a href="https://explorer.solana.com/tx/5WPj1VRJYxSZizsxTotE62SCHiuU3DTnJxLhUnuw3Ln6gMe8nU6ueAqskwgdVdqAzzskRcE23tNAXLvpXi7zhjBD?cluster=devnet">https://explorer.solana.com/tx/5WPj1VRJYxSZizsxTotE62SCHiuU3DTnJxLhUnuw3Ln6gMe8nU6ueAqskwgdVdqAzzskRcE23tNAXLvpXi7zhjBD?cluster=devnet</a></p>
<img src="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/0fec82a5-3468-49f0-9d82-6468f5cf70c2.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>Step 3: Mint Your Tokens</h2>
<p>Now it's time to bring your tokens into existence. You can mint tokens in batches or all at once. Let's mint an initial batch of 100 tokens, and then another 100 just to be sure everything is working.</p>
<p>Bash</p>
<pre><code class="language-plaintext"># First Mint
spl-token mint BTJ4cPPwssx6b7jy9GoUyBeLBxufyCSoUzvuegEUCVx8 100

# Second Mint
spl-token mint BTJ4cPPwssx6b7jy9GoUyBeLBxufyCSoUzvuegEUCVx8 100
</code></pre>
<p>Verify Here:</p>
<p><a href="https://explorer.solana.com/tx/64VJQycoCaMSSeMu63Vubxzp2VMzd3GPD82yTYu4E8ynvtSDYZBodVReQtkiD7H1F715o5N9pnnJHfmieC26yfK?cluster=devnet">https://explorer.solana.com/tx/64VJQycoCaMSSeMu63Vubxzp2VMzd3GPD82yTYu4E8ynvtSDYZBodVReQtkiD7H1F715o5N9pnnJHfmieC26yfK?cluster=devnet</a></p>
<img src="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/7f53c5bc-56a6-4de6-90d9-5670c0e45c09.png" alt="" style="display:block;margin:0 auto" />

<p><strong>What happens next:</strong></p>
<p>You successfully generated 200 Adit Coins! They are now sitting safely inside your Token Account.</p>
<h2>Step 4: Initialize the Metadata</h2>
<p>Right now, the blockchain just sees a string of letters and numbers. Let's give it an identity. We will use the <code>initialize-metadata</code> command to assign a Name, a Ticker Symbol, and a URI (a link to a JSON file hosted on IPFS that contains your token's image and description).</p>
<pre><code class="language-plaintext">spl-token initialize-metadata \
  BTJ4cPPwssx6b7jy9GoUyBeLBxufyCSoUzvuegEUCVx8 \
  "Adit Coin" \
  "ARDT" \
  "https://identical-amaranth-bear.myfilebase.com/ipfs/QmYKcq66TEop68NiD1brpsUZ7uVyXNK4thbX7nD4c4Rxtm"
</code></pre>
<p>Verify Here:</p>
<p><a href="https://explorer.solana.com/tx/48bQmUJiE8iAQ5FuA1LESkbjZMGbVD3zPWo9xjGKv2qcftkDT4fraAQ9G6XwgwiSp2BviGXgpNKLJLPpVkZqaLoE?cluster=devnet">https://explorer.solana.com/tx/48bQmUJiE8iAQ5FuA1LESkbjZMGbVD3zPWo9xjGKv2qcftkDT4fraAQ9G6XwgwiSp2BviGXgpNKLJLPpVkZqaLoE?cluster=devnet</a></p>
<img src="https://cdn.hashnode.com/uploads/covers/65d204e2728da825eb42aafc/37be94ff-6037-402b-ab2f-eb3a9975ae9d.png" alt="" style="display:block;margin:0 auto" />

<p><strong>What happens next:</strong></p>
<p>Your token is now fully registered with its on-chain identity! If you look up your token address on an explorer like SolanaFM or Solscan, you will see "Adit Coin", the symbol "ARDT", and the logo pulling from your IPFS link.</p>
<hr />
<p><strong>Thanks for following along!</strong> 🚀</p>
<p>Building and learning in public is a huge part of the journey. Whether you want to collaborate on the next hackathon, discuss Web3 and AI projects, or just talk tech, my inbox is always open.</p>
<p>Let's connect: <a href="https://linkedin.com/">LinkedIn</a> | <a href="https://github.com/">GitHub</a></p>
]]></content:encoded></item><item><title><![CDATA[Installing Solana CLI in an Easy Way]]></title><description><![CDATA[Setting up the Solana CLI manually on Windows by grabbing the binaries straight from GitHub is a great way to have full control over your development environment. It sounds like you had a few autocorr]]></description><link>https://blog.astrobot.tech/installing-solana-cli-windows-manual</link><guid isPermaLink="true">https://blog.astrobot.tech/installing-solana-cli-windows-manual</guid><dc:creator><![CDATA[Aditya Raj]]></dc:creator><pubDate>Mon, 23 Feb 2026 19:12:12 GMT</pubDate><enclosure url="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/65d204e2728da825eb42aafc/456e0629-1449-4b9a-9461-9869d9fffbe8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Setting up the Solana CLI manually on Windows by grabbing the binaries straight from GitHub is a great way to have full control over your development environment. It sounds like you had a few autocorrect typos in your request, but you are looking exactly for the right thing: going to the Solana Labs GitHub, downloading the pre-built binary, and manually adding it to your Windows PATH.</p>
<p>Here is a straightforward guide to get you set up.</p>
<p><em>(A quick factual note before we begin: The core Solana Labs client recently transitioned to a new developer team called Anza, and the software is now called "Agave". You can still find the releases on the Solana Labs GitHub, but going forward, the most up-to-date versions will be on the Anza Agave GitHub repo. The steps below apply perfectly to both!)</em></p>
<h3>How to Manually Install the Solana CLI on Windows</h3>
<h2><strong>Step 1: Download the Pre-built Binary</strong></h2>
<ol>
<li><p>Navigate to the official releases page. You can either go to the <a href="https://github.com/solana-labs/solana/releases">Solana Labs GitHub Releases</a></p>
</li>
<li><p>Look for the <strong>Latest</strong> stable release (for example, <code>v1.18.26</code> or <code>v2.0.0</code>).</p>
</li>
<li><p>Scroll down to the <strong>Assets</strong> section at the bottom of the release notes.</p>
</li>
<li><p>Download the Windows binary archive. It will be named something like: <code>solana-release-x86_64-pc-windows-msvc.tar.bz2</code>.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/65d204e2728da825eb42aafc/005164fa-1999-4bb2-860b-cc291dbdc02c.png" alt="" style="display:block;margin:0 auto" /></li>
</ol>
<h2><strong>Step 2: Extract the Files</strong></h2>
<p>Windows doesn't always natively handle <code>.tar.bz2</code> files, so you may need a free extraction tool like <strong>7-Zip</strong> or <strong>WinRAR</strong>.</p>
<ol>
<li><p>Open your extraction tool and extract the downloaded file.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/65d204e2728da825eb42aafc/5c52cd85-aa01-4c9d-97d1-aa5bfba5ff42.png" alt="" style="display:block;margin:0 auto" />
</li>
<li><p>Move the extracted folder (it should be named <code>solana-release</code>) to a permanent, secure location on your hard drive where it won't be deleted. A good spot is <code>C:\solana-release</code>.  </p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/65d204e2728da825eb42aafc/a2b121ff-452a-418a-bcfd-0986e552caca.png" alt="" style="display:block;margin:0 auto" /></li>
</ol>
<p>Here are the Binaries Located</p>
<ol>
<li><p>Relocate the Binaries <code>C drive</code> and <code>C:\solana-cli\solana-release</code> in my case</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/65d204e2728da825eb42aafc/f222d722-7b20-4de8-93fa-f42ff2940a63.png" alt="" style="display:block;margin:0 auto" /></li>
</ol>
<h2><strong>Step 3: Manually Add the CLI to your Windows PATH</strong></h2>
<p>To use Solana commands from any folder in your terminal, Windows needs to know exactly where those tools live.</p>
<ol>
<li><p>Click the Windows Start button, type <strong>Environment Variables</strong>, and select <strong>Edit the system environment variables</strong>.</p>
</li>
<li><p>In the System Properties window that pops up, click the <strong>Environment Variables...</strong> button near the bottom right.</p>
</li>
<li><p>In the new window, look under the <strong>User variables</strong> (or <strong>System variables</strong> if you want it applied to all users) and find the variable named <strong>Path</strong>.</p>
</li>
<li><p>Select <strong>Path</strong> and click <strong>Edit</strong>.</p>
</li>
<li><p>Click <strong>New</strong>, and paste the exact folder path to the <code>bin</code> directory inside your extracted Solana folder. If you followed Step 2 exactly, this will be: <code>C:\solana-release\bin</code>.</p>
</li>
<li><p>Click <strong>OK</strong> on all three windows to save your changes.  </p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/65d204e2728da825eb42aafc/a54ab868-8601-467f-b657-e4f6a3bbf013.png" alt="" style="display:block;margin:0 auto" /></li>
</ol>
<h2><strong>Step 4: Verify the Installation</strong></h2>
<ol>
<li><p>Open a brand new <strong>Command Prompt</strong> or <strong>PowerShell</strong> window (if you had one open already, you must close and restart it so it can fetch the new PATH data).</p>
</li>
<li><p>Type the following command and press Enter:</p>
</li>
</ol>
<pre><code class="language-plaintext">solana --version
# solana-cli 1.18.26 (src:d9f20e95; feat:3241752014, client:SolanaLabs)
</code></pre>
<p>If everything is configured correctly, it will output the version of the Solana CLI you just installed!</p>
<ol>
<li><code>solana-keygen</code> for generating public-private keypair</li>
</ol>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/65d204e2728da825eb42aafc/f42ad807-1609-429e-b520-f438201960be.png" alt="" style="display:block;margin:0 auto" />

<ol>
<li><p><code>solana get config</code> to get config file content.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/65d204e2728da825eb42aafc/d59aa857-1916-4485-8d0e-15889607ad95.png" alt="" style="display:block;margin:0 auto" />
</li>
<li><p>A few more commands</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/65d204e2728da825eb42aafc/48456254-ed12-478c-a036-4eebc910ab96.png" alt="" style="display:block;margin:0 auto" />
</li>
<li><p>After Airdropping on devnet through <a href="https://faucet.solana.com/">https://faucet.solana.com/</a></p>
</li>
</ol>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/65d204e2728da825eb42aafc/5b193d39-27db-45a4-8f29-259ed155eb68.png" alt="" style="display:block;margin:0 auto" />

<p>Thanks for stopping by! If this helped you out, let me know. I'm actively exploring new ideas in AI and full-stack development, and I'd love to see what you're building too.</p>
<p>💼 <a href="https://linkedin.com/in/astro-adityaraj">LinkedIn</a> • 🐙 <a href="https://github.com/astrobot-me/">GitHub</a> • ✉️ <a href="http://astrobot.tech/">Portfolio</a></p>
<p>Ref:</p>
<p><a href="https://solana.com/docs/intro/installation/solana-cli-basics">https://solana.com/docs/intro/installation/solana-cli-basics</a></p>
]]></content:encoded></item><item><title><![CDATA[A Deep Dive into SQL Logical Query Processing]]></title><description><![CDATA[If you come from an imperative programming background, such as JavaScript, Python, or C++, SQL can feel counterintuitive. You define a variable, and one line later, the compiler tells you it doesn't exist.
This isn't a syntax error on your part; it i...]]></description><link>https://blog.astrobot.tech/a-deep-dive-into-sql-logical-query-processing</link><guid isPermaLink="true">https://blog.astrobot.tech/a-deep-dive-into-sql-logical-query-processing</guid><category><![CDATA[Evaluation-order]]></category><category><![CDATA[SQL]]></category><category><![CDATA[Query]]></category><category><![CDATA[Query Processing]]></category><dc:creator><![CDATA[Aditya Raj]]></dc:creator><pubDate>Thu, 01 Jan 2026 16:41:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1767285294570/3290ecc4-915b-42da-b219-576bda9dcaca.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you come from an imperative programming background, such as JavaScript, Python, or C++, SQL can feel counterintuitive. You define a variable, and one line later, the compiler tells you it doesn't exist.</p>
<p>This isn't a syntax error on your part; it is a fundamental misunderstanding of how the SQL engine parses and executes commands. To move from writing "working" queries to writing performant, production-grade queries, you need to understand <strong>Logical Query Processing</strong>.</p>
<h3 id="heading-1-the-common-pitfall">1. The Common Pitfall</h3>
<p>Let’s start with the scenario that trips up almost every junior developer. You want to calculate the total value of an order and filter for high-value transactions.</p>
<p>Intuitively, you write this:</p>
<pre><code class="lang-sql"><span class="hljs-comment">/* ❌ The "Imperative" Approach */</span>
<span class="hljs-keyword">SELECT</span> 
    order_id, 
    (quantity * unit_price) <span class="hljs-keyword">AS</span> total_amount <span class="hljs-comment">-- Variable defined here</span>
<span class="hljs-keyword">FROM</span> 
    orders
<span class="hljs-keyword">WHERE</span> 
    total_amount &gt; <span class="hljs-number">1000</span>; <span class="hljs-comment">-- Variable referenced here</span>
</code></pre>
<p><strong>The Result:</strong> <code>Error: Column 'total_amount' does not exist.</code></p>
<p><strong>The Confusion:</strong> In JavaScript, if you declare <code>const total = qty * price</code>You can use <code>total</code> immediately in the next line. Why can’t SQL do the same?</p>
<h3 id="heading-2-the-solution">2. The Solution</h3>
<p>Before explaining the <em>why</em>, here is the standard fix. You have two primary options:</p>
<p><strong>Option A: Repeat the Expression</strong></p>
<p>Since the alias is unavailable, you must pass the raw calculation to the filter.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> order_id, (quantity * unit_price) <span class="hljs-keyword">AS</span> total_amount
<span class="hljs-keyword">FROM</span> orders
<span class="hljs-keyword">WHERE</span> (quantity * unit_price) &gt; <span class="hljs-number">1000</span>;
</code></pre>
<p><strong>Option B: Common Table Expressions (CTEs)</strong></p>
<p>For complex logic, calculating variables in a preliminary step (a CTE) allows you to reference them later, mimicking the imperative flow.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">WITH</span> CalculatedOrders <span class="hljs-keyword">AS</span> (
    <span class="hljs-keyword">SELECT</span> order_id, (quantity * unit_price) <span class="hljs-keyword">AS</span> total_amount
    <span class="hljs-keyword">FROM</span> orders
)
<span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> CalculatedOrders
<span class="hljs-keyword">WHERE</span> total_amount &gt; <span class="hljs-number">1000</span>;
</code></pre>
<h3 id="heading-3-deep-dive-logical-query-processing-order">3. Deep Dive: Logical Query Processing Order</h3>
<p>To understand why the first query failed, we have to look at the <strong>Order of Execution</strong>.</p>
<p>SQL is a <strong>declarative</strong> language. You describe <em>what</em> result you want, and the database engine decides <em>how</em> to get it. However, the engine processes the clauses of your query in a strict, pre-defined sequence known as Logical Query Processing.</p>
<p>While you write the query in this order:</p>
<p><strong>SELECT → FROM → WHERE → GROUP BY → ORDER BY</strong></p>
<p>The database engine executes it in this order:</p>
<h4 id="heading-phase-1-from-and-join-the-source">Phase 1: FROM and JOIN ( The Source )</h4>
<p>The engine begins by identifying the data source. If you are using <code>JOINs</code>, it creates a virtual table representing the Cartesian product of all tables involved, then filters based on the join predicates (<code>ON</code>). At this stage, the engine only knows about the columns that physically exist in your tables.</p>
<h4 id="heading-phase-2-where-the-row-filter">Phase 2: WHERE ( The Row Filter )</h4>
<p>This is where our error occurs. The <code>WHERE</code> clause is applied to the rows returned from Phase 1. Its job is to discard rows that do not meet the criteria.</p>
<ul>
<li><strong>Crucial Detail:</strong> The <code>SELECT</code> clause has not happened yet. The engine has not computed any derived columns, renamed any fields, or assigned any aliases. Therefore, <code>total_amount</code> literally does not exist in memory yet. The engine can only filter based on the raw columns (<code>quantity</code>, <code>unit_price</code>).</li>
</ul>
<h4 id="heading-phase-3-group-by-the-bucketing">Phase 3: GROUP BY ( The Bucketing )</h4>
<p>If specified, the remaining rows are now grouped into "buckets" based on common values.</p>
<h4 id="heading-phase-4-having-the-group-filter">Phase 4: HAVING ( The Group Filter )</h4>
<p>This acts like a <code>WHERE</code> clause, but for groups. It filters out entire buckets (e.g., "only keep groups with more than 5 items").</p>
<h4 id="heading-phase-5-select-the-projection">Phase 5: SELECT ( The Projection )</h4>
<p><strong>This is the turning point.</strong> Only <em>after</em> the data has been sourced, filtered, grouped, and re-filtered does the engine finally compute the expressions in your <code>SELECT</code> list.</p>
<ul>
<li><p>This is where <code>(quantity * unit_price)</code> is calculated.</p>
</li>
<li><p>This is where the alias <code>total_amount</code> is assigned.</p>
</li>
<li><p>This explains why the alias was invisible to the <code>WHERE</code> clause—it hadn't been created yet.</p>
</li>
</ul>
<h4 id="heading-phase-6-order-by-the-presentation">Phase 6: ORDER BY ( The Presentation )</h4>
<p>The result set is sorted. Since this occurs after Phase 5, you can actually use aliases here.</p>
<p>ORDER BY total_amount DESC is perfectly valid because total_amount was created in the previous step.</p>
<h3 id="heading-4-why-this-design-matters">4. Why This Design Matters</h3>
<p>You might wonder why SQL was designed this way. Why not calculate <code>SELECT</code> earlier?</p>
<p>It comes down to efficiency.</p>
<p>If the engine calculated (quantity * unit_price) for every single row in the database (Phase 1) before filtering them (Phase 2), it would waste massive amounts of computational power on rows that are about to be discarded anyway.</p>
<p>By being forced <code>WHERE</code> to run before <code>SELECT</code>, the database ensures it only performs expensive calculations on the rows that actually qualify for the final result.</p>
<h2 id="heading-think-of-sql-as-two-phases">Think of SQL as Two Phases</h2>
<h3 id="heading-phase-1-decide-what-data-exists">🔹 Phase 1: Decide <em>WHAT DATA EXISTS</em></h3>
<p>This phase determines the <strong>shape of the data</strong>.</p>
<p>Order:</p>
<pre><code class="lang-sql">FROM →WHERE →GROUPBY →HAVING
</code></pre>
<p>Questions answered here:</p>
<ul>
<li><p><strong>Which tables?</strong></p>
</li>
<li><p><strong>Which rows?</strong></p>
</li>
<li><p><strong>Which groups?</strong></p>
</li>
<li><p><strong>Which groups are valid?</strong></p>
</li>
</ul>
<hr />
<h3 id="heading-phase-2-decide-what-to-show">🔹 Phase 2: Decide <em>WHAT TO SHOW</em></h3>
<p>This phase formats the output.</p>
<p>Order:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> →ORDERBY →<span class="hljs-keyword">LIMIT</span>
</code></pre>
<p>Questions answered here:</p>
<ul>
<li><p><strong>Which columns?</strong></p>
</li>
<li><p><strong>Which calculations?</strong></p>
</li>
<li><p><strong>In what order?</strong></p>
</li>
<li><p><strong>How many rows?</strong></p>
</li>
</ul>
<h2 id="heading-correct-mental-model-one-liner">Correct Mental Model (One-Liner)</h2>
<blockquote>
<p>SQL groups data first, then calculates aggregates, then sorts the final result.</p>
</blockquote>
<h2 id="heading-interview-grade-evaluation-order-full-version">Interview-Grade Evaluation Order (Full Version)</h2>
<pre><code class="lang-sql">FROM
→WHERE
→GROUPBY
→HAVING
→<span class="hljs-keyword">SELECT</span>
→ORDERBY
→<span class="hljs-keyword">LIMIT</span>
</code></pre>
<h3 id="heading-summary">Summary</h3>
<p>When writing SQL, you must mentally shift from an "<strong>Input → Process → Outpu</strong>t" model to a "<strong>Filter → Group → Project</strong>" model.</p>
<ol>
<li><p><strong>FROM</strong>: Load the tables.</p>
</li>
<li><p><strong>WHERE</strong>: Remove rows using raw data only.</p>
</li>
<li><p><strong>SELECT</strong>: Compute values and name them.</p>
</li>
<li><p><strong>ORDER BY</strong>: Sort the final output (aliases allowed).</p>
</li>
</ol>
<p>Understanding this pipeline prevents you from fighting the database and allows you to write queries that are not just syntactically correct but also logically sound.</p>
]]></content:encoded></item></channel></rss>