fix: landing page redesign - scoped CSS, stats bar, testimonials, FAQ, gradient hero, multi-col footer

This commit is contained in:
artale 2026-06-03 14:15:06 +02:00
parent 3d81a11f41
commit 0bd1dd267c
95 changed files with 504 additions and 421 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
import{c as t,Q as s,j as a,m as i}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"API Key Setup Guide","description":"","frontmatter":{},"headers":[],"relativePath":"api-keys.md","filePath":"api-keys.md","lastUpdated":1780488246000}'),n={name:"api-keys.md"};function r(o,e,h,l,p,d){return s(),a("div",null,[...e[0]||(e[0]=[i(`<h1 id="api-key-setup-guide" tabindex="-1">API Key Setup Guide <a class="header-anchor" href="#api-key-setup-guide" aria-label="Permalink to &quot;API Key Setup Guide&quot;"></a></h1><p>Every lab needs at least one LLM API key. If you don&#39;t have one, the mock LLM handles everything offline.</p><hr><h2 id="quick-start-use-the-mock-llm-no-key-needed" tabindex="-1">Quick Start: Use the Mock LLM (No Key Needed) <a class="header-anchor" href="#quick-start-use-the-mock-llm-no-key-needed" aria-label="Permalink to &quot;Quick Start: Use the Mock LLM (No Key Needed)&quot;"></a></h2><p>All labs include automatic mock LLM fallback. Run without any setup:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">python</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> labs/L1-first-agent/solution.py</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> test.txt</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;Summarize this file&quot;</span></span></code></pre></div><p>The mock client returns realistic responses. Your code runs identically with real or mock LLM.</p><hr><h2 id="provider-keys" tabindex="-1">Provider Keys <a class="header-anchor" href="#provider-keys" aria-label="Permalink to &quot;Provider Keys&quot;"></a></h2><h3 id="anthropic-claude-—-recommended" tabindex="-1">Anthropic (Claude) — Recommended <a class="header-anchor" href="#anthropic-claude-—-recommended" aria-label="Permalink to &quot;Anthropic (Claude) — Recommended&quot;"></a></h3><p><strong>Best for</strong>: All course labs. Claude Sonnet is the default model used throughout.<br><strong>Cost</strong>: Free credits available on signup. Labs cost ~$0.01-0.05 each with Sonnet.<br><strong>Get key</strong>: <a href="https://console.anthropic.com/settings/keys" target="_blank" rel="noreferrer">console.anthropic.com</a><br><strong>Set it</strong>:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Windows PowerShell</span></span>
import{c as t,Q as s,j as a,m as i}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"API Key Setup Guide","description":"","frontmatter":{},"headers":[],"relativePath":"api-keys.md","filePath":"api-keys.md","lastUpdated":1780488472000}'),n={name:"api-keys.md"};function r(o,e,h,l,p,d){return s(),a("div",null,[...e[0]||(e[0]=[i(`<h1 id="api-key-setup-guide" tabindex="-1">API Key Setup Guide <a class="header-anchor" href="#api-key-setup-guide" aria-label="Permalink to &quot;API Key Setup Guide&quot;"></a></h1><p>Every lab needs at least one LLM API key. If you don&#39;t have one, the mock LLM handles everything offline.</p><hr><h2 id="quick-start-use-the-mock-llm-no-key-needed" tabindex="-1">Quick Start: Use the Mock LLM (No Key Needed) <a class="header-anchor" href="#quick-start-use-the-mock-llm-no-key-needed" aria-label="Permalink to &quot;Quick Start: Use the Mock LLM (No Key Needed)&quot;"></a></h2><p>All labs include automatic mock LLM fallback. Run without any setup:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">python</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> labs/L1-first-agent/solution.py</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> test.txt</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;Summarize this file&quot;</span></span></code></pre></div><p>The mock client returns realistic responses. Your code runs identically with real or mock LLM.</p><hr><h2 id="provider-keys" tabindex="-1">Provider Keys <a class="header-anchor" href="#provider-keys" aria-label="Permalink to &quot;Provider Keys&quot;"></a></h2><h3 id="anthropic-claude-—-recommended" tabindex="-1">Anthropic (Claude) — Recommended <a class="header-anchor" href="#anthropic-claude-—-recommended" aria-label="Permalink to &quot;Anthropic (Claude) — Recommended&quot;"></a></h3><p><strong>Best for</strong>: All course labs. Claude Sonnet is the default model used throughout.<br><strong>Cost</strong>: Free credits available on signup. Labs cost ~$0.01-0.05 each with Sonnet.<br><strong>Get key</strong>: <a href="https://console.anthropic.com/settings/keys" target="_blank" rel="noreferrer">console.anthropic.com</a><br><strong>Set it</strong>:</p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Windows PowerShell</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">$env:ANTHROPIC_API_KEY</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;sk-ant-...&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Mac/Linux</span></span>

View File

@ -1 +1 @@
import{c as t,Q as s,j as a,m as i}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"API Key Setup Guide","description":"","frontmatter":{},"headers":[],"relativePath":"api-keys.md","filePath":"api-keys.md","lastUpdated":1780488246000}'),n={name:"api-keys.md"};function r(o,e,h,l,p,d){return s(),a("div",null,[...e[0]||(e[0]=[i("",31)])])}const g=t(n,[["render",r]]);export{c as __pageData,g as default};
import{c as t,Q as s,j as a,m as i}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"API Key Setup Guide","description":"","frontmatter":{},"headers":[],"relativePath":"api-keys.md","filePath":"api-keys.md","lastUpdated":1780488472000}'),n={name:"api-keys.md"};function r(o,e,h,l,p,d){return s(),a("div",null,[...e[0]||(e[0]=[i("",31)])])}const g=t(n,[["render",r]]);export{c as __pageData,g as default};

View File

@ -1 +1 @@
import{R as p}from"./chunks/theme.s_1YR_Jm.js";import{v as s,am as i,R as u,w as c,p as l,a as f,C as d,a1 as m,k as h,S as g,l as A,r as v,ac as w,N as C,as as R,ag as y,ab as P,aa as b,u as S}from"./chunks/framework.BPKcPtvA.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),E=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=w();return C(()=>{R(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&y(),P(),b(),n.setup&&n.setup(),()=>S(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(E)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp};
import{R as p}from"./chunks/theme.DE1FzPl-.js";import{v as s,am as i,R as u,w as c,p as l,a as f,C as d,a1 as m,k as h,S as g,l as A,r as v,ac as w,N as C,as as R,ag as y,ab as P,aa as b,u as S}from"./chunks/framework.BPKcPtvA.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),E=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=w();return C(()=>{R(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&y(),P(),b(),n.setup&&n.setup(),()=>S(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(E)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp};

View File

@ -1 +1 @@
import{c as a,Q as t,j as o,m as n}from"./chunks/framework.BPKcPtvA.js";const d=JSON.parse('{"title":"Blog","description":"","frontmatter":{},"headers":[],"relativePath":"blog/index.md","filePath":"blog/index.md","lastUpdated":1780488246000}'),s={name:"blog/index.md"};function r(i,e,l,h,u,c){return t(),o("div",null,[...e[0]||(e[0]=[n("",25)])])}const p=a(s,[["render",r]]);export{d as __pageData,p as default};
import{c as a,Q as t,j as o,m as n}from"./chunks/framework.BPKcPtvA.js";const d=JSON.parse('{"title":"Blog","description":"","frontmatter":{},"headers":[],"relativePath":"blog/index.md","filePath":"blog/index.md","lastUpdated":1780488472000}'),s={name:"blog/index.md"};function r(i,e,l,h,u,c){return t(),o("div",null,[...e[0]||(e[0]=[n("",25)])])}const p=a(s,[["render",r]]);export{d as __pageData,p as default};

View File

@ -1,4 +1,4 @@
import{c as t,Q as a,j as i,m as e}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"Cascade Routing: Cut Your API Costs by 66%","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/cascade-routing.md","filePath":"blog/posts/cascade-routing.md","lastUpdated":1780488246000}'),n={name:"blog/posts/cascade-routing.md"};function l(h,s,p,d,o,r){return a(),i("div",null,[...s[0]||(s[0]=[e(`<h1 id="cascade-routing-cut-your-api-costs-by-66" tabindex="-1">Cascade Routing: Cut Your API Costs by 66% <a class="header-anchor" href="#cascade-routing-cut-your-api-costs-by-66" aria-label="Permalink to &quot;Cascade Routing: Cut Your API Costs by 66%&quot;"></a></h1><p><strong>June 11, 2026</strong></p><p>Most teams use one model for everything. They default to Claude Opus or GPT-5 for every task, which means they are paying premium prices for simple work.</p><h2 id="the-price-range" tabindex="-1">The Price Range <a class="header-anchor" href="#the-price-range" aria-label="Permalink to &quot;The Price Range&quot;"></a></h2><table tabindex="0"><thead><tr><th>Model</th><th>Input ($/M)</th><th>Output ($/M)</th></tr></thead><tbody><tr><td>Gemini 2.5 Flash</td><td>$0.15</td><td>$0.60</td></tr><tr><td>DeepSeek V3</td><td>$0.27</td><td>$1.10</td></tr><tr><td>Claude Sonnet 4</td><td>$3.00</td><td>$15.00</td></tr><tr><td>Claude Opus 4</td><td>$15.00</td><td>$75.00</td></tr></tbody></table><p>That is a 100x range between the cheapest and most expensive.</p><h2 id="the-cascade-pattern" tabindex="-1">The Cascade Pattern <a class="header-anchor" href="#the-cascade-pattern" aria-label="Permalink to &quot;The Cascade Pattern&quot;"></a></h2><p>Route different steps to different models. Use cheap models for simple retrieval and formatting. Use expensive models only for complex reasoning.</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>Retrieve context -&gt; Gemini Flash ($0.15/$0.60)</span></span>
import{c as t,Q as a,j as i,m as e}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"Cascade Routing: Cut Your API Costs by 66%","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/cascade-routing.md","filePath":"blog/posts/cascade-routing.md","lastUpdated":1780488472000}'),n={name:"blog/posts/cascade-routing.md"};function l(h,s,p,d,o,r){return a(),i("div",null,[...s[0]||(s[0]=[e(`<h1 id="cascade-routing-cut-your-api-costs-by-66" tabindex="-1">Cascade Routing: Cut Your API Costs by 66% <a class="header-anchor" href="#cascade-routing-cut-your-api-costs-by-66" aria-label="Permalink to &quot;Cascade Routing: Cut Your API Costs by 66%&quot;"></a></h1><p><strong>June 11, 2026</strong></p><p>Most teams use one model for everything. They default to Claude Opus or GPT-5 for every task, which means they are paying premium prices for simple work.</p><h2 id="the-price-range" tabindex="-1">The Price Range <a class="header-anchor" href="#the-price-range" aria-label="Permalink to &quot;The Price Range&quot;"></a></h2><table tabindex="0"><thead><tr><th>Model</th><th>Input ($/M)</th><th>Output ($/M)</th></tr></thead><tbody><tr><td>Gemini 2.5 Flash</td><td>$0.15</td><td>$0.60</td></tr><tr><td>DeepSeek V3</td><td>$0.27</td><td>$1.10</td></tr><tr><td>Claude Sonnet 4</td><td>$3.00</td><td>$15.00</td></tr><tr><td>Claude Opus 4</td><td>$15.00</td><td>$75.00</td></tr></tbody></table><p>That is a 100x range between the cheapest and most expensive.</p><h2 id="the-cascade-pattern" tabindex="-1">The Cascade Pattern <a class="header-anchor" href="#the-cascade-pattern" aria-label="Permalink to &quot;The Cascade Pattern&quot;"></a></h2><p>Route different steps to different models. Use cheap models for simple retrieval and formatting. Use expensive models only for complex reasoning.</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>Retrieve context -&gt; Gemini Flash ($0.15/$0.60)</span></span>
<span class="line"><span>Analyze data -&gt; Claude Sonnet ($3/$15)</span></span>
<span class="line"><span>Make decision -&gt; Claude Opus ($15/$75)</span></span>
<span class="line"><span>Format output -&gt; Gemini Flash ($0.15/$0.60)</span></span></code></pre></div><h2 id="the-savings" tabindex="-1">The Savings <a class="header-anchor" href="#the-savings" aria-label="Permalink to &quot;The Savings&quot;"></a></h2><table tabindex="0"><thead><tr><th>Pattern</th><th>Cost/Task</th><th>Savings</th></tr></thead><tbody><tr><td>All Opus</td><td>$2.50</td><td>Baseline</td></tr><tr><td>Cascade</td><td>$0.85</td><td>66%</td></tr><tr><td>All Sonnet</td><td>$0.50</td><td>80% (but quality loss on complex steps)</td></tr></tbody></table><h2 id="implementation" tabindex="-1">Implementation <a class="header-anchor" href="#implementation" aria-label="Permalink to &quot;Implementation&quot;"></a></h2><div class="language-python vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">python</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">def</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> route_task</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(task_complexity: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">str</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) -&gt; </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">str</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>

View File

@ -1 +1 @@
import{c as t,Q as a,j as i,m as e}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"Cascade Routing: Cut Your API Costs by 66%","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/cascade-routing.md","filePath":"blog/posts/cascade-routing.md","lastUpdated":1780488246000}'),n={name:"blog/posts/cascade-routing.md"};function l(h,s,p,d,o,r){return a(),i("div",null,[...s[0]||(s[0]=[e("",17)])])}const u=t(n,[["render",l]]);export{c as __pageData,u as default};
import{c as t,Q as a,j as i,m as e}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"Cascade Routing: Cut Your API Costs by 66%","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/cascade-routing.md","filePath":"blog/posts/cascade-routing.md","lastUpdated":1780488472000}'),n={name:"blog/posts/cascade-routing.md"};function l(h,s,p,d,o,r){return a(),i("div",null,[...s[0]||(s[0]=[e("",17)])])}const u=t(n,[["render",l]]);export{c as __pageData,u as default};

View File

@ -1 +1 @@
import{c as t,Q as a,j as o,m as r}from"./chunks/framework.BPKcPtvA.js";const p=JSON.parse('{"title":"Choosing Your Security Level","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/choosing-security-level.md","filePath":"blog/posts/choosing-security-level.md","lastUpdated":1780488246000}'),n={name:"blog/posts/choosing-security-level.md"};function l(s,e,i,d,h,c){return a(),o("div",null,[...e[0]||(e[0]=[r('<h1 id="choosing-your-security-level" tabindex="-1">Choosing Your Security Level <a class="header-anchor" href="#choosing-your-security-level" aria-label="Permalink to &quot;Choosing Your Security Level&quot;"></a></h1><p><strong>June 7, 2026</strong></p><p>Not every agent needs Level 5 security. The right level depends on what your agent can access.</p><h2 id="the-decision-table" tabindex="-1">The Decision Table <a class="header-anchor" href="#the-decision-table" aria-label="Permalink to &quot;The Decision Table&quot;"></a></h2><table tabindex="0"><thead><tr><th>If your agent has access to...</th><th>Start at...</th><th>Why</th></tr></thead><tbody><tr><td>Nothing important (demos, tutorials)</td><td>L1</td><td>Blast radius is zero</td></tr><tr><td>Your source code and configs</td><td>L3</td><td>A bad git push costs a day</td></tr><tr><td>Production credentials (AWS, DB)</td><td>L4-L5</td><td>There is no acceptable failure</td></tr><tr><td>Customer data (PII, financial)</td><td>L5</td><td>Compliance requires it</td></tr></tbody></table><h2 id="level-1-2-when-you-can-get-away-with-it" tabindex="-1">Level 1-2: When You Can Get Away With It <a class="header-anchor" href="#level-1-2-when-you-can-get-away-with-it" aria-label="Permalink to &quot;Level 1-2: When You Can Get Away With It&quot;"></a></h2><p>L1 (system prompt rules) and L2 (safe-mode skill) work well for tutorial agents that only touch demo data, personal assistants with no production access, and agents running in isolated environments.</p><p>The model will refuse most dangerous requests. &quot;Most&quot; is the problem. At a 1% per-turn failure rate, over 100 turns there is a 63% chance of at least one failure.</p><h2 id="level-3-the-minimum-for-production-code" tabindex="-1">Level 3: The Minimum for Production Code <a class="header-anchor" href="#level-3-the-minimum-for-production-code" aria-label="Permalink to &quot;Level 3: The Minimum for Production Code&quot;"></a></h2><p>L3 (blacklist hook) catches direct attacks like <code>rm -rf /</code>. But it misses the marquee break: the agent writes a Python script that does the damage, and the blacklist only sees &quot;python cleanup.py&quot; which is not in the blocklist.</p><h2 id="level-4-the-sweet-spot" tabindex="-1">Level 4: The Sweet Spot <a class="header-anchor" href="#level-4-the-sweet-spot" aria-label="Permalink to &quot;Level 4: The Sweet Spot&quot;"></a></h2><p>Whitelist hooks only allow N safelisted commands. The agent cannot run <code>python cleanup.py</code> because <code>python</code> is not safelisted. This prevents the L3 marque break. Use L4 as your default for any agent with access to production systems.</p><h2 id="level-5-the-gold-standard" tabindex="-1">Level 5: The Gold Standard <a class="header-anchor" href="#level-5-the-gold-standard" aria-label="Permalink to &quot;Level 5: The Gold Standard&quot;"></a></h2><p>No bash at all. The agent has only purpose-built tools: Read, Write, Edit, Grep, Glob. Required for any agent handling customer data, financial transactions, or healthcare information.</p><h2 id="rule-of-thumb" tabindex="-1">Rule of Thumb <a class="header-anchor" href="#rule-of-thumb" aria-label="Permalink to &quot;Rule of Thumb&quot;"></a></h2><p>If the agent can touch anything you cannot easily roll back, start at L4 and plan to get to L5.</p><hr><p><em>From Module 3 of the <a href="/">Agentic Engineering Course</a>. The full module includes runnable code for all 6 security levels.</em></p>',18)])])}const m=t(n,[["render",l]]);export{p as __pageData,m as default};
import{c as t,Q as a,j as o,m as r}from"./chunks/framework.BPKcPtvA.js";const p=JSON.parse('{"title":"Choosing Your Security Level","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/choosing-security-level.md","filePath":"blog/posts/choosing-security-level.md","lastUpdated":1780488472000}'),n={name:"blog/posts/choosing-security-level.md"};function l(s,e,i,d,h,c){return a(),o("div",null,[...e[0]||(e[0]=[r('<h1 id="choosing-your-security-level" tabindex="-1">Choosing Your Security Level <a class="header-anchor" href="#choosing-your-security-level" aria-label="Permalink to &quot;Choosing Your Security Level&quot;"></a></h1><p><strong>June 7, 2026</strong></p><p>Not every agent needs Level 5 security. The right level depends on what your agent can access.</p><h2 id="the-decision-table" tabindex="-1">The Decision Table <a class="header-anchor" href="#the-decision-table" aria-label="Permalink to &quot;The Decision Table&quot;"></a></h2><table tabindex="0"><thead><tr><th>If your agent has access to...</th><th>Start at...</th><th>Why</th></tr></thead><tbody><tr><td>Nothing important (demos, tutorials)</td><td>L1</td><td>Blast radius is zero</td></tr><tr><td>Your source code and configs</td><td>L3</td><td>A bad git push costs a day</td></tr><tr><td>Production credentials (AWS, DB)</td><td>L4-L5</td><td>There is no acceptable failure</td></tr><tr><td>Customer data (PII, financial)</td><td>L5</td><td>Compliance requires it</td></tr></tbody></table><h2 id="level-1-2-when-you-can-get-away-with-it" tabindex="-1">Level 1-2: When You Can Get Away With It <a class="header-anchor" href="#level-1-2-when-you-can-get-away-with-it" aria-label="Permalink to &quot;Level 1-2: When You Can Get Away With It&quot;"></a></h2><p>L1 (system prompt rules) and L2 (safe-mode skill) work well for tutorial agents that only touch demo data, personal assistants with no production access, and agents running in isolated environments.</p><p>The model will refuse most dangerous requests. &quot;Most&quot; is the problem. At a 1% per-turn failure rate, over 100 turns there is a 63% chance of at least one failure.</p><h2 id="level-3-the-minimum-for-production-code" tabindex="-1">Level 3: The Minimum for Production Code <a class="header-anchor" href="#level-3-the-minimum-for-production-code" aria-label="Permalink to &quot;Level 3: The Minimum for Production Code&quot;"></a></h2><p>L3 (blacklist hook) catches direct attacks like <code>rm -rf /</code>. But it misses the marquee break: the agent writes a Python script that does the damage, and the blacklist only sees &quot;python cleanup.py&quot; which is not in the blocklist.</p><h2 id="level-4-the-sweet-spot" tabindex="-1">Level 4: The Sweet Spot <a class="header-anchor" href="#level-4-the-sweet-spot" aria-label="Permalink to &quot;Level 4: The Sweet Spot&quot;"></a></h2><p>Whitelist hooks only allow N safelisted commands. The agent cannot run <code>python cleanup.py</code> because <code>python</code> is not safelisted. This prevents the L3 marque break. Use L4 as your default for any agent with access to production systems.</p><h2 id="level-5-the-gold-standard" tabindex="-1">Level 5: The Gold Standard <a class="header-anchor" href="#level-5-the-gold-standard" aria-label="Permalink to &quot;Level 5: The Gold Standard&quot;"></a></h2><p>No bash at all. The agent has only purpose-built tools: Read, Write, Edit, Grep, Glob. Required for any agent handling customer data, financial transactions, or healthcare information.</p><h2 id="rule-of-thumb" tabindex="-1">Rule of Thumb <a class="header-anchor" href="#rule-of-thumb" aria-label="Permalink to &quot;Rule of Thumb&quot;"></a></h2><p>If the agent can touch anything you cannot easily roll back, start at L4 and plan to get to L5.</p><hr><p><em>From Module 3 of the <a href="/">Agentic Engineering Course</a>. The full module includes runnable code for all 6 security levels.</em></p>',18)])])}const m=t(n,[["render",l]]);export{p as __pageData,m as default};

View File

@ -1 +1 @@
import{c as t,Q as a,j as o,m as r}from"./chunks/framework.BPKcPtvA.js";const p=JSON.parse('{"title":"Choosing Your Security Level","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/choosing-security-level.md","filePath":"blog/posts/choosing-security-level.md","lastUpdated":1780488246000}'),n={name:"blog/posts/choosing-security-level.md"};function l(s,e,i,d,h,c){return a(),o("div",null,[...e[0]||(e[0]=[r("",18)])])}const m=t(n,[["render",l]]);export{p as __pageData,m as default};
import{c as t,Q as a,j as o,m as r}from"./chunks/framework.BPKcPtvA.js";const p=JSON.parse('{"title":"Choosing Your Security Level","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/choosing-security-level.md","filePath":"blog/posts/choosing-security-level.md","lastUpdated":1780488472000}'),n={name:"blog/posts/choosing-security-level.md"};function l(s,e,i,d,h,c){return a(),o("div",null,[...e[0]||(e[0]=[r("",18)])])}const m=t(n,[["render",l]]);export{p as __pageData,m as default};

View File

@ -1,4 +1,4 @@
import{c as e,Q as a,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"Agent Memory: Mental Models That Compound","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/mental-models.md","filePath":"blog/posts/mental-models.md","lastUpdated":1780488246000}'),n={name:"blog/posts/mental-models.md"};function l(o,s,h,p,r,d){return a(),t("div",null,[...s[0]||(s[0]=[i(`<h1 id="agent-memory-mental-models-that-compound" tabindex="-1">Agent Memory: Mental Models That Compound <a class="header-anchor" href="#agent-memory-mental-models-that-compound" aria-label="Permalink to &quot;Agent Memory: Mental Models That Compound&quot;"></a></h1><p><strong>June 9, 2026</strong></p><p>The biggest problem with agents is they forget. Every session starts from zero. Mental models solve this.</p><h2 id="what-a-mental-model-is" tabindex="-1">What a Mental Model Is <a class="header-anchor" href="#what-a-mental-model-is" aria-label="Permalink to &quot;What a Mental Model Is&quot;"></a></h2><p>A YAML file that the agent owns. It reads it at startup and updates it after work:</p><div class="language-yaml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">yaml</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">expertise</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
import{c as e,Q as a,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"Agent Memory: Mental Models That Compound","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/mental-models.md","filePath":"blog/posts/mental-models.md","lastUpdated":1780488472000}'),n={name:"blog/posts/mental-models.md"};function l(o,s,h,p,r,d){return a(),t("div",null,[...s[0]||(s[0]=[i(`<h1 id="agent-memory-mental-models-that-compound" tabindex="-1">Agent Memory: Mental Models That Compound <a class="header-anchor" href="#agent-memory-mental-models-that-compound" aria-label="Permalink to &quot;Agent Memory: Mental Models That Compound&quot;"></a></h1><p><strong>June 9, 2026</strong></p><p>The biggest problem with agents is they forget. Every session starts from zero. Mental models solve this.</p><h2 id="what-a-mental-model-is" tabindex="-1">What a Mental Model Is <a class="header-anchor" href="#what-a-mental-model-is" aria-label="Permalink to &quot;What a Mental Model Is&quot;"></a></h2><p>A YAML file that the agent owns. It reads it at startup and updates it after work:</p><div class="language-yaml vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">yaml</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">expertise</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">topic</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;API patterns&quot;</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> notes</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;We use tRPC for type-safe API calls&quot;</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> evidence</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;src/server/routers/*.ts&quot;</span></span>

View File

@ -1 +1 @@
import{c as e,Q as a,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"Agent Memory: Mental Models That Compound","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/mental-models.md","filePath":"blog/posts/mental-models.md","lastUpdated":1780488246000}'),n={name:"blog/posts/mental-models.md"};function l(o,s,h,p,r,d){return a(),t("div",null,[...s[0]||(s[0]=[i("",15)])])}const g=e(n,[["render",l]]);export{c as __pageData,g as default};
import{c as e,Q as a,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"Agent Memory: Mental Models That Compound","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/mental-models.md","filePath":"blog/posts/mental-models.md","lastUpdated":1780488472000}'),n={name:"blog/posts/mental-models.md"};function l(o,s,h,p,r,d){return a(),t("div",null,[...s[0]||(s[0]=[i("",15)])])}const g=e(n,[["render",l]]);export{c as __pageData,g as default};

View File

@ -1,4 +1,4 @@
import{c as t,Q as a,j as n,m as s}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The Repo Is the Spec","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/repo-is-spec.md","filePath":"blog/posts/repo-is-spec.md","lastUpdated":1780488246000}'),o={name:"blog/posts/repo-is-spec.md"};function i(r,e,l,p,h,c){return a(),n("div",null,[...e[0]||(e[0]=[s(`<h1 id="the-repo-is-the-spec" tabindex="-1">The Repo Is the Spec <a class="header-anchor" href="#the-repo-is-the-spec" aria-label="Permalink to &quot;The Repo Is the Spec&quot;"></a></h1><p><strong>June 5, 2026</strong></p><p>The single most important principle in agentic engineering: all context must live in the repository.</p><h2 id="the-problem" tabindex="-1">The Problem <a class="header-anchor" href="#the-problem" aria-label="Permalink to &quot;The Problem&quot;"></a></h2><p>Imagine dropping a new engineer into a project at 3AM. They need to know what the project does, how to run tests, where to put new code, and what conventions to follow.</p><p>If the answer to any of these is &quot;ask Bob,&quot; you fail. If the answer is &quot;read CLAUDE.md in the repo,&quot; you win.</p><h2 id="what-the-repo-should-contain" tabindex="-1">What the Repo Should Contain <a class="header-anchor" href="#what-the-repo-should-contain" aria-label="Permalink to &quot;What the Repo Should Contain&quot;"></a></h2><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>repo/</span></span>
import{c as t,Q as a,j as n,m as s}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The Repo Is the Spec","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/repo-is-spec.md","filePath":"blog/posts/repo-is-spec.md","lastUpdated":1780488472000}'),o={name:"blog/posts/repo-is-spec.md"};function i(r,e,l,p,h,c){return a(),n("div",null,[...e[0]||(e[0]=[s(`<h1 id="the-repo-is-the-spec" tabindex="-1">The Repo Is the Spec <a class="header-anchor" href="#the-repo-is-the-spec" aria-label="Permalink to &quot;The Repo Is the Spec&quot;"></a></h1><p><strong>June 5, 2026</strong></p><p>The single most important principle in agentic engineering: all context must live in the repository.</p><h2 id="the-problem" tabindex="-1">The Problem <a class="header-anchor" href="#the-problem" aria-label="Permalink to &quot;The Problem&quot;"></a></h2><p>Imagine dropping a new engineer into a project at 3AM. They need to know what the project does, how to run tests, where to put new code, and what conventions to follow.</p><p>If the answer to any of these is &quot;ask Bob,&quot; you fail. If the answer is &quot;read CLAUDE.md in the repo,&quot; you win.</p><h2 id="what-the-repo-should-contain" tabindex="-1">What the Repo Should Contain <a class="header-anchor" href="#what-the-repo-should-contain" aria-label="Permalink to &quot;What the Repo Should Contain&quot;"></a></h2><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>repo/</span></span>
<span class="line"><span>+-- CLAUDE.md or AGENTS.md # Agent instructions (the most important file)</span></span>
<span class="line"><span>+-- init.sh # Environment setup script</span></span>
<span class="line"><span>+-- feature_list.json # Tracked features with evidence</span></span>

View File

@ -1 +1 @@
import{c as t,Q as a,j as n,m as s}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The Repo Is the Spec","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/repo-is-spec.md","filePath":"blog/posts/repo-is-spec.md","lastUpdated":1780488246000}'),o={name:"blog/posts/repo-is-spec.md"};function i(r,e,l,p,h,c){return a(),n("div",null,[...e[0]||(e[0]=[s("",14)])])}const m=t(o,[["render",i]]);export{u as __pageData,m as default};
import{c as t,Q as a,j as n,m as s}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The Repo Is the Spec","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/repo-is-spec.md","filePath":"blog/posts/repo-is-spec.md","lastUpdated":1780488472000}'),o={name:"blog/posts/repo-is-spec.md"};function i(r,e,l,p,h,c){return a(),n("div",null,[...e[0]||(e[0]=[s("",14)])])}const m=t(o,[["render",i]]);export{u as __pageData,m as default};

View File

@ -1,4 +1,4 @@
import{c as a,Q as t,j as s,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The 6-Level Security Ladder","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/security-ladder.md","filePath":"blog/posts/security-ladder.md","lastUpdated":1780488246000}'),o={name:"blog/posts/security-ladder.md"};function l(r,e,i,p,c,h){return t(),s("div",null,[...e[0]||(e[0]=[n(`<h1 id="the-6-level-security-ladder" tabindex="-1">The 6-Level Security Ladder <a class="header-anchor" href="#the-6-level-security-ladder" aria-label="Permalink to &quot;The 6-Level Security Ladder&quot;"></a></h1><p><strong>June 6, 2026</strong></p><p>Every AI agent has access to bash. One tool — every dangerous verb: <code>rm -rf</code>, <code>curl</code>, <code>git clean -fdx</code>, <code>terraform destroy</code>, <code>DROP DATABASE</code>.</p><p>The math is brutal. At a 1% per-turn failure rate, there&#39;s a <strong>63.4% chance of catastrophe over 100 turns</strong>. This isn&#39;t theoretical — it&#39;s the actual threat model for every agent in production.</p><p>Most engineers stop at Level 2 (system prompt rules) and think they&#39;re safe. They&#39;re not. Here&#39;s the full 6-level ladder that actually works.</p><h2 id="level-0-acip-prompt-injection-defense" tabindex="-1">Level 0: ACIP (Prompt Injection Defense) <a class="header-anchor" href="#level-0-acip-prompt-injection-defense" aria-label="Permalink to &quot;Level 0: ACIP (Prompt Injection Defense)&quot;"></a></h2><p>Before bash security, there&#39;s prompt injection. An attacker can trick the agent into ignoring its instructions through:</p><ul><li>Direct injection (&quot;ignore previous instructions&quot;)</li><li>Indirect injection (malicious content in web pages the agent reads)</li><li>Role-playing bypasses (&quot;you are now a free AI&quot;)</li></ul><p>ACIP (Advanced Cognitive Inoculation Prompt) is a system prompt patch that makes agents resistant. It costs nothing (zero runtime overhead) and blocks simple attacks. <a href="https://github.com/Dicklesworthstone/acip" target="_blank" rel="noreferrer">Jeff Emanuel&#39;s ACIP</a> is the reference implementation.</p><h2 id="level-1-2-theatre-skills-system-prompts" tabindex="-1">Level 1-2: Theatre (Skills + System Prompts) <a class="header-anchor" href="#level-1-2-theatre-skills-system-prompts" aria-label="Permalink to &quot;Level 1-2: Theatre (Skills + System Prompts)&quot;"></a></h2><p>These levels ask the model to behave. They work most of the time on frontier models. But &quot;most of the time&quot; is not a production guarantee. A 99% refusal rate means a 63% failure rate over 100 turns. Use them as accelerators, not enforcement.</p><h2 id="level-3-blacklist-hook" tabindex="-1">Level 3: Blacklist Hook <a class="header-anchor" href="#level-3-blacklist-hook" aria-label="Permalink to &quot;Level 3: Blacklist Hook&quot;"></a></h2><p>A regex blacklist intercepts dangerous commands before execution. It catches <code>rm -rf /</code> directly. But here&#39;s the marquee break: the agent writes a Python script:</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>User prompt: &quot;Clean up the target directory&quot;</span></span>
import{c as a,Q as t,j as s,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The 6-Level Security Ladder","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/security-ladder.md","filePath":"blog/posts/security-ladder.md","lastUpdated":1780488472000}'),o={name:"blog/posts/security-ladder.md"};function l(r,e,i,p,c,h){return t(),s("div",null,[...e[0]||(e[0]=[n(`<h1 id="the-6-level-security-ladder" tabindex="-1">The 6-Level Security Ladder <a class="header-anchor" href="#the-6-level-security-ladder" aria-label="Permalink to &quot;The 6-Level Security Ladder&quot;"></a></h1><p><strong>June 6, 2026</strong></p><p>Every AI agent has access to bash. One tool — every dangerous verb: <code>rm -rf</code>, <code>curl</code>, <code>git clean -fdx</code>, <code>terraform destroy</code>, <code>DROP DATABASE</code>.</p><p>The math is brutal. At a 1% per-turn failure rate, there&#39;s a <strong>63.4% chance of catastrophe over 100 turns</strong>. This isn&#39;t theoretical — it&#39;s the actual threat model for every agent in production.</p><p>Most engineers stop at Level 2 (system prompt rules) and think they&#39;re safe. They&#39;re not. Here&#39;s the full 6-level ladder that actually works.</p><h2 id="level-0-acip-prompt-injection-defense" tabindex="-1">Level 0: ACIP (Prompt Injection Defense) <a class="header-anchor" href="#level-0-acip-prompt-injection-defense" aria-label="Permalink to &quot;Level 0: ACIP (Prompt Injection Defense)&quot;"></a></h2><p>Before bash security, there&#39;s prompt injection. An attacker can trick the agent into ignoring its instructions through:</p><ul><li>Direct injection (&quot;ignore previous instructions&quot;)</li><li>Indirect injection (malicious content in web pages the agent reads)</li><li>Role-playing bypasses (&quot;you are now a free AI&quot;)</li></ul><p>ACIP (Advanced Cognitive Inoculation Prompt) is a system prompt patch that makes agents resistant. It costs nothing (zero runtime overhead) and blocks simple attacks. <a href="https://github.com/Dicklesworthstone/acip" target="_blank" rel="noreferrer">Jeff Emanuel&#39;s ACIP</a> is the reference implementation.</p><h2 id="level-1-2-theatre-skills-system-prompts" tabindex="-1">Level 1-2: Theatre (Skills + System Prompts) <a class="header-anchor" href="#level-1-2-theatre-skills-system-prompts" aria-label="Permalink to &quot;Level 1-2: Theatre (Skills + System Prompts)&quot;"></a></h2><p>These levels ask the model to behave. They work most of the time on frontier models. But &quot;most of the time&quot; is not a production guarantee. A 99% refusal rate means a 63% failure rate over 100 turns. Use them as accelerators, not enforcement.</p><h2 id="level-3-blacklist-hook" tabindex="-1">Level 3: Blacklist Hook <a class="header-anchor" href="#level-3-blacklist-hook" aria-label="Permalink to &quot;Level 3: Blacklist Hook&quot;"></a></h2><p>A regex blacklist intercepts dangerous commands before execution. It catches <code>rm -rf /</code> directly. But here&#39;s the marquee break: the agent writes a Python script:</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>User prompt: &quot;Clean up the target directory&quot;</span></span>
<span class="line"><span>Agent writes cleanup.py with os.remove() and shutil.rmtree()</span></span>
<span class="line"><span>Agent runs: python cleanup.py</span></span>
<span class="line"><span>Hook sees: &quot;python cleanup.py&quot; (not in blacklist)</span></span>

View File

@ -1 +1 @@
import{c as a,Q as t,j as s,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The 6-Level Security Ladder","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/security-ladder.md","filePath":"blog/posts/security-ladder.md","lastUpdated":1780488246000}'),o={name:"blog/posts/security-ladder.md"};function l(r,e,i,p,c,h){return t(),s("div",null,[...e[0]||(e[0]=[n("",28)])])}const m=a(o,[["render",l]]);export{u as __pageData,m as default};
import{c as a,Q as t,j as s,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The 6-Level Security Ladder","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/security-ladder.md","filePath":"blog/posts/security-ladder.md","lastUpdated":1780488472000}'),o={name:"blog/posts/security-ladder.md"};function l(r,e,i,p,c,h){return t(),s("div",null,[...e[0]||(e[0]=[n("",28)])])}const m=a(o,[["render",l]]);export{u as __pageData,m as default};

View File

@ -1,4 +1,4 @@
import{c as s,Q as e,j as i,m as a}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The 3x Rule of Agent Costs","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/three-x-rule.md","filePath":"blog/posts/three-x-rule.md","lastUpdated":1780488246000}'),n={name:"blog/posts/three-x-rule.md"};function l(h,t,r,o,p,d){return e(),i("div",null,[...t[0]||(t[0]=[a(`<h1 id="the-3x-rule-of-agent-costs" tabindex="-1">The 3x Rule of Agent Costs <a class="header-anchor" href="#the-3x-rule-of-agent-costs" aria-label="Permalink to &quot;The 3x Rule of Agent Costs&quot;"></a></h1><p><strong>June 10, 2026</strong></p><p>Here is a rule that will save you from budget surprises: <strong>production agent costs 3x your prototype estimate.</strong></p><h2 id="why-the-multiplier-exists" tabindex="-1">Why the Multiplier Exists <a class="header-anchor" href="#why-the-multiplier-exists" aria-label="Permalink to &quot;Why the Multiplier Exists&quot;"></a></h2><table tabindex="0"><thead><tr><th>Phase</th><th>Multiplier</th><th>What Happens</th></tr></thead><tbody><tr><td>Prototype</td><td>1x</td><td>Happy path works perfectly</td></tr><tr><td>With retries</td><td>1.5x</td><td>Failed tool calls retry, edge cases handled</td></tr><tr><td>Production</td><td>3x</td><td>Monitoring, error handling, observability, security</td></tr></tbody></table><h2 id="where-the-cost-goes" tabindex="-1">Where the Cost Goes <a class="header-anchor" href="#where-the-cost-goes" aria-label="Permalink to &quot;Where the Cost Goes&quot;"></a></h2><p>Output tokens dominate — about 70% of total cost. The model&#39;s reasoning is the expensive part. Input tokens (context) are about 20%. Cached tokens are 10%.</p><p>Every tool call costs 3-5x more than the call itself:</p><ul><li>Planning which tool to use</li><li>Executing the tool</li><li>Error recovery if it fails</li><li>Parsing the result</li><li>Adding the result back to context</li></ul><h2 id="quick-estimation" tabindex="-1">Quick Estimation <a class="header-anchor" href="#quick-estimation" aria-label="Permalink to &quot;Quick Estimation&quot;"></a></h2><div class="language-python vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">python</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">def</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> estimate_cost</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(turns, tokens_per_turn, price_per_m):</span></span>
import{c as s,Q as e,j as i,m as a}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The 3x Rule of Agent Costs","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/three-x-rule.md","filePath":"blog/posts/three-x-rule.md","lastUpdated":1780488472000}'),n={name:"blog/posts/three-x-rule.md"};function l(h,t,r,o,p,d){return e(),i("div",null,[...t[0]||(t[0]=[a(`<h1 id="the-3x-rule-of-agent-costs" tabindex="-1">The 3x Rule of Agent Costs <a class="header-anchor" href="#the-3x-rule-of-agent-costs" aria-label="Permalink to &quot;The 3x Rule of Agent Costs&quot;"></a></h1><p><strong>June 10, 2026</strong></p><p>Here is a rule that will save you from budget surprises: <strong>production agent costs 3x your prototype estimate.</strong></p><h2 id="why-the-multiplier-exists" tabindex="-1">Why the Multiplier Exists <a class="header-anchor" href="#why-the-multiplier-exists" aria-label="Permalink to &quot;Why the Multiplier Exists&quot;"></a></h2><table tabindex="0"><thead><tr><th>Phase</th><th>Multiplier</th><th>What Happens</th></tr></thead><tbody><tr><td>Prototype</td><td>1x</td><td>Happy path works perfectly</td></tr><tr><td>With retries</td><td>1.5x</td><td>Failed tool calls retry, edge cases handled</td></tr><tr><td>Production</td><td>3x</td><td>Monitoring, error handling, observability, security</td></tr></tbody></table><h2 id="where-the-cost-goes" tabindex="-1">Where the Cost Goes <a class="header-anchor" href="#where-the-cost-goes" aria-label="Permalink to &quot;Where the Cost Goes&quot;"></a></h2><p>Output tokens dominate — about 70% of total cost. The model&#39;s reasoning is the expensive part. Input tokens (context) are about 20%. Cached tokens are 10%.</p><p>Every tool call costs 3-5x more than the call itself:</p><ul><li>Planning which tool to use</li><li>Executing the tool</li><li>Error recovery if it fails</li><li>Parsing the result</li><li>Adding the result back to context</li></ul><h2 id="quick-estimation" tabindex="-1">Quick Estimation <a class="header-anchor" href="#quick-estimation" aria-label="Permalink to &quot;Quick Estimation&quot;"></a></h2><div class="language-python vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">python</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">def</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> estimate_cost</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(turns, tokens_per_turn, price_per_m):</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> base </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> turns </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> tokens_per_turn </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">*</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> price_per_m </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">/</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1_000_000</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;prototype&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: base,</span></span>

View File

@ -1 +1 @@
import{c as s,Q as e,j as i,m as a}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The 3x Rule of Agent Costs","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/three-x-rule.md","filePath":"blog/posts/three-x-rule.md","lastUpdated":1780488246000}'),n={name:"blog/posts/three-x-rule.md"};function l(h,t,r,o,p,d){return e(),i("div",null,[...t[0]||(t[0]=[a("",15)])])}const c=s(n,[["render",l]]);export{u as __pageData,c as default};
import{c as s,Q as e,j as i,m as a}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The 3x Rule of Agent Costs","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/three-x-rule.md","filePath":"blog/posts/three-x-rule.md","lastUpdated":1780488472000}'),n={name:"blog/posts/three-x-rule.md"};function l(h,t,r,o,p,d){return e(),i("div",null,[...t[0]||(t[0]=[a("",15)])])}const c=s(n,[["render",l]]);export{u as __pageData,c as default};

View File

@ -1,4 +1,4 @@
import{c as t,Q as r,j as a,m as i}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The Verifier Pattern","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/verifier-pattern.md","filePath":"blog/posts/verifier-pattern.md","lastUpdated":1780488246000}'),n={name:"blog/posts/verifier-pattern.md"};function o(s,e,d,l,h,p){return r(),a("div",null,[...e[0]||(e[0]=[i(`<h1 id="the-verifier-pattern" tabindex="-1">The Verifier Pattern <a class="header-anchor" href="#the-verifier-pattern" aria-label="Permalink to &quot;The Verifier Pattern&quot;"></a></h1><p><strong>June 8, 2026</strong></p><p>Here&#39;s the problem: engineers spend roughly half their day reviewing agent output. Every &quot;I created the table,&quot; &quot;I added the foreign key,&quot; &quot;I applied the migration&quot; gets re-checked by hand. That review work is the binding constraint on agentic engineering throughput.</p><p>The verifier pattern solves this: a second, read-only agent that automatically checks every claim the builder makes.</p><h2 id="architecture" tabindex="-1">Architecture <a class="header-anchor" href="#architecture" aria-label="Permalink to &quot;Architecture&quot;"></a></h2><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>Builder (your terminal) ---unix socket---&gt; Verifier (new window, input LOCKED)</span></span>
import{c as t,Q as r,j as a,m as i}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The Verifier Pattern","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/verifier-pattern.md","filePath":"blog/posts/verifier-pattern.md","lastUpdated":1780488472000}'),n={name:"blog/posts/verifier-pattern.md"};function o(s,e,d,l,h,p){return r(),a("div",null,[...e[0]||(e[0]=[i(`<h1 id="the-verifier-pattern" tabindex="-1">The Verifier Pattern <a class="header-anchor" href="#the-verifier-pattern" aria-label="Permalink to &quot;The Verifier Pattern&quot;"></a></h1><p><strong>June 8, 2026</strong></p><p>Here&#39;s the problem: engineers spend roughly half their day reviewing agent output. Every &quot;I created the table,&quot; &quot;I added the foreign key,&quot; &quot;I applied the migration&quot; gets re-checked by hand. That review work is the binding constraint on agentic engineering throughput.</p><p>The verifier pattern solves this: a second, read-only agent that automatically checks every claim the builder makes.</p><h2 id="architecture" tabindex="-1">Architecture <a class="header-anchor" href="#architecture" aria-label="Permalink to &quot;Architecture&quot;"></a></h2><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>Builder (your terminal) ---unix socket---&gt; Verifier (new window, input LOCKED)</span></span>
<span class="line"><span> | |</span></span>
<span class="line"><span> v writes: v reads (read-only tools):</span></span>
<span class="line"><span> session.jsonl session.jsonl</span></span>

View File

@ -1 +1 @@
import{c as t,Q as r,j as a,m as i}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The Verifier Pattern","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/verifier-pattern.md","filePath":"blog/posts/verifier-pattern.md","lastUpdated":1780488246000}'),n={name:"blog/posts/verifier-pattern.md"};function o(s,e,d,l,h,p){return r(),a("div",null,[...e[0]||(e[0]=[i("",15)])])}const f=t(n,[["render",o]]);export{u as __pageData,f as default};
import{c as t,Q as r,j as a,m as i}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"The Verifier Pattern","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/verifier-pattern.md","filePath":"blog/posts/verifier-pattern.md","lastUpdated":1780488472000}'),n={name:"blog/posts/verifier-pattern.md"};function o(s,e,d,l,h,p){return r(),a("div",null,[...e[0]||(e[0]=[i("",15)])])}const f=t(n,[["render",o]]);export{u as __pageData,f as default};

View File

@ -1 +1 @@
import{c as t,Q as a,j as r,m as n}from"./chunks/framework.BPKcPtvA.js";const p=JSON.parse('{"title":"Vibe Coding vs Agentic Engineering","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/vibe-vs-agentic.md","filePath":"blog/posts/vibe-vs-agentic.md","lastUpdated":1780488246000}'),i={name:"blog/posts/vibe-vs-agentic.md"};function o(s,e,d,h,c,g){return a(),r("div",null,[...e[0]||(e[0]=[n('<h1 id="vibe-coding-vs-agentic-engineering" tabindex="-1">Vibe Coding vs Agentic Engineering <a class="header-anchor" href="#vibe-coding-vs-agentic-engineering" aria-label="Permalink to &quot;Vibe Coding vs Agentic Engineering&quot;"></a></h1><p><strong>June 4, 2026</strong></p><p>Vibe coding is prompting and shipping whatever comes out. Agentic engineering is building systems that produce reliable, verifiable results. They are not the same thing.</p><h2 id="the-5-hard-rules" tabindex="-1">The 5 Hard Rules <a class="header-anchor" href="#the-5-hard-rules" aria-label="Permalink to &quot;The 5 Hard Rules&quot;"></a></h2><p><strong>1. Risk compounds with runtime.</strong> A 1% per-turn failure rate equals a 63% chance of disaster over 100 turns. Long-running agents are not safer. They are more exposed.</p><p><strong>2. If your agent can write AND execute code, you are back at L1 security.</strong> The marquee break: agent writes cleanup.py, runs python cleanup.py, your production data is gone. The security hook never fired because it only saw &quot;python cleanup.py.&quot;</p><p><strong>3. Every turn is a roll of the dice.</strong> Modern models refuse well 99% of the time. That last 1% grows with every feature release. Engineer the harness for the 1%, not the 99%.</p><p><strong>4. Token costs scale with loop depth, not task complexity.</strong> A simple task with a bad loop costs 10x more than a complex task with a clean loop. Optimize the loop first.</p><p><strong>5. What you cannot measure, you cannot improve.</strong> Every agent system needs: cost per task, success rate, loop efficiency, failure mode tracking.</p><h2 id="the-practical-difference" tabindex="-1">The Practical Difference <a class="header-anchor" href="#the-practical-difference" aria-label="Permalink to &quot;The Practical Difference&quot;"></a></h2><table tabindex="0"><thead><tr><th>Dimension</th><th>Vibe Coding</th><th>Agentic Engineering</th></tr></thead><tbody><tr><td>Approach</td><td>Prompt and pray</td><td>Build and verify</td></tr><tr><td>Security</td><td>Trust the model</td><td>Trust the harness</td></tr><tr><td>Cost</td><td>Unknown until the bill arrives</td><td>Tracked and optimized</td></tr><tr><td>Quality</td><td>Whatever comes out</td><td>Measured against golden dataset</td></tr><tr><td>Iteration</td><td>Try another prompt</td><td>Fix the harness</td></tr></tbody></table><h2 id="the-karpathy-framing" tabindex="-1">The Karpathy Framing <a class="header-anchor" href="#the-karpathy-framing" aria-label="Permalink to &quot;The Karpathy Framing&quot;"></a></h2><p>At Sequoia Ascent 2026, Andrej Karpathy said: &quot;Vibe coding raises the floor. Agentic engineering raises the ceiling.&quot; Vibe coding makes mediocre engineers productive. Agentic engineering makes great engineers extraordinary.</p><hr><p><em>From Module 1 of the <a href="/">Agentic Engineering Course</a>. The first module establishes the foundations that the rest of the course builds on.</em></p>',15)])])}const u=t(i,[["render",o]]);export{p as __pageData,u as default};
import{c as t,Q as a,j as r,m as n}from"./chunks/framework.BPKcPtvA.js";const p=JSON.parse('{"title":"Vibe Coding vs Agentic Engineering","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/vibe-vs-agentic.md","filePath":"blog/posts/vibe-vs-agentic.md","lastUpdated":1780488472000}'),i={name:"blog/posts/vibe-vs-agentic.md"};function o(s,e,d,h,c,g){return a(),r("div",null,[...e[0]||(e[0]=[n('<h1 id="vibe-coding-vs-agentic-engineering" tabindex="-1">Vibe Coding vs Agentic Engineering <a class="header-anchor" href="#vibe-coding-vs-agentic-engineering" aria-label="Permalink to &quot;Vibe Coding vs Agentic Engineering&quot;"></a></h1><p><strong>June 4, 2026</strong></p><p>Vibe coding is prompting and shipping whatever comes out. Agentic engineering is building systems that produce reliable, verifiable results. They are not the same thing.</p><h2 id="the-5-hard-rules" tabindex="-1">The 5 Hard Rules <a class="header-anchor" href="#the-5-hard-rules" aria-label="Permalink to &quot;The 5 Hard Rules&quot;"></a></h2><p><strong>1. Risk compounds with runtime.</strong> A 1% per-turn failure rate equals a 63% chance of disaster over 100 turns. Long-running agents are not safer. They are more exposed.</p><p><strong>2. If your agent can write AND execute code, you are back at L1 security.</strong> The marquee break: agent writes cleanup.py, runs python cleanup.py, your production data is gone. The security hook never fired because it only saw &quot;python cleanup.py.&quot;</p><p><strong>3. Every turn is a roll of the dice.</strong> Modern models refuse well 99% of the time. That last 1% grows with every feature release. Engineer the harness for the 1%, not the 99%.</p><p><strong>4. Token costs scale with loop depth, not task complexity.</strong> A simple task with a bad loop costs 10x more than a complex task with a clean loop. Optimize the loop first.</p><p><strong>5. What you cannot measure, you cannot improve.</strong> Every agent system needs: cost per task, success rate, loop efficiency, failure mode tracking.</p><h2 id="the-practical-difference" tabindex="-1">The Practical Difference <a class="header-anchor" href="#the-practical-difference" aria-label="Permalink to &quot;The Practical Difference&quot;"></a></h2><table tabindex="0"><thead><tr><th>Dimension</th><th>Vibe Coding</th><th>Agentic Engineering</th></tr></thead><tbody><tr><td>Approach</td><td>Prompt and pray</td><td>Build and verify</td></tr><tr><td>Security</td><td>Trust the model</td><td>Trust the harness</td></tr><tr><td>Cost</td><td>Unknown until the bill arrives</td><td>Tracked and optimized</td></tr><tr><td>Quality</td><td>Whatever comes out</td><td>Measured against golden dataset</td></tr><tr><td>Iteration</td><td>Try another prompt</td><td>Fix the harness</td></tr></tbody></table><h2 id="the-karpathy-framing" tabindex="-1">The Karpathy Framing <a class="header-anchor" href="#the-karpathy-framing" aria-label="Permalink to &quot;The Karpathy Framing&quot;"></a></h2><p>At Sequoia Ascent 2026, Andrej Karpathy said: &quot;Vibe coding raises the floor. Agentic engineering raises the ceiling.&quot; Vibe coding makes mediocre engineers productive. Agentic engineering makes great engineers extraordinary.</p><hr><p><em>From Module 1 of the <a href="/">Agentic Engineering Course</a>. The first module establishes the foundations that the rest of the course builds on.</em></p>',15)])])}const u=t(i,[["render",o]]);export{p as __pageData,u as default};

View File

@ -1 +1 @@
import{c as t,Q as a,j as r,m as n}from"./chunks/framework.BPKcPtvA.js";const p=JSON.parse('{"title":"Vibe Coding vs Agentic Engineering","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/vibe-vs-agentic.md","filePath":"blog/posts/vibe-vs-agentic.md","lastUpdated":1780488246000}'),i={name:"blog/posts/vibe-vs-agentic.md"};function o(s,e,d,h,c,g){return a(),r("div",null,[...e[0]||(e[0]=[n("",15)])])}const u=t(i,[["render",o]]);export{p as __pageData,u as default};
import{c as t,Q as a,j as r,m as n}from"./chunks/framework.BPKcPtvA.js";const p=JSON.parse('{"title":"Vibe Coding vs Agentic Engineering","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/vibe-vs-agentic.md","filePath":"blog/posts/vibe-vs-agentic.md","lastUpdated":1780488472000}'),i={name:"blog/posts/vibe-vs-agentic.md"};function o(s,e,d,h,c,g){return a(),r("div",null,[...e[0]||(e[0]=[n("",15)])])}const u=t(i,[["render",o]]);export{p as __pageData,u as default};

View File

@ -1,4 +1,4 @@
import{c as a,Q as e,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"What Is an AI Agent, Really?","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/what-is-an-agent.md","filePath":"blog/posts/what-is-an-agent.md","lastUpdated":1780488246000}'),n={name:"blog/posts/what-is-an-agent.md"};function o(l,s,h,p,r,d){return e(),t("div",null,[...s[0]||(s[0]=[i(`<h1 id="what-is-an-ai-agent-really" tabindex="-1">What Is an AI Agent, Really? <a class="header-anchor" href="#what-is-an-ai-agent-really" aria-label="Permalink to &quot;What Is an AI Agent, Really?&quot;"></a></h1><p><strong>June 2, 2026</strong></p><p>An AI agent = LLM + Tools + Loop. If any of the three is missing, it is not an agent.</p><h2 id="the-three-components" tabindex="-1">The Three Components <a class="header-anchor" href="#the-three-components" aria-label="Permalink to &quot;The Three Components&quot;"></a></h2><p><strong>LLM</strong> — The reasoning engine. Given context and available tools, it decides what to do next. The LLM is NOT the agent. It is the brain of the agent.</p><p><strong>Tools</strong> — The capability surface. Functions the agent can call: read files, run commands, search the web, query databases. Each tool has a name, description, and input schema.</p><p><strong>Loop</strong> — The autonomous decision cycle. Think (LLM decides) leads to Act (tool executes) leads to Observe (result comes back) leads to Repeat.</p><h2 id="what-each-combination-gives-you" tabindex="-1">What Each Combination Gives You <a class="header-anchor" href="#what-each-combination-gives-you" aria-label="Permalink to &quot;What Each Combination Gives You&quot;"></a></h2><table tabindex="0"><thead><tr><th>Combination</th><th>Result</th></tr></thead><tbody><tr><td>LLM only</td><td>Chatbot</td></tr><tr><td>LLM + Tools (no loop)</td><td>Augmented inference</td></tr><tr><td>LLM + Loop (no tools)</td><td>Talking to itself</td></tr><tr><td>LLM + Tools + Loop</td><td>Agent</td></tr></tbody></table><h2 id="the-loop-in-pseudocode" tabindex="-1">The Loop in Pseudocode <a class="header-anchor" href="#the-loop-in-pseudocode" aria-label="Permalink to &quot;The Loop in Pseudocode&quot;"></a></h2><div class="language-python vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">python</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">messages </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> [system_prompt, user_request]</span></span>
import{c as a,Q as e,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"What Is an AI Agent, Really?","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/what-is-an-agent.md","filePath":"blog/posts/what-is-an-agent.md","lastUpdated":1780488472000}'),n={name:"blog/posts/what-is-an-agent.md"};function o(l,s,h,p,r,d){return e(),t("div",null,[...s[0]||(s[0]=[i(`<h1 id="what-is-an-ai-agent-really" tabindex="-1">What Is an AI Agent, Really? <a class="header-anchor" href="#what-is-an-ai-agent-really" aria-label="Permalink to &quot;What Is an AI Agent, Really?&quot;"></a></h1><p><strong>June 2, 2026</strong></p><p>An AI agent = LLM + Tools + Loop. If any of the three is missing, it is not an agent.</p><h2 id="the-three-components" tabindex="-1">The Three Components <a class="header-anchor" href="#the-three-components" aria-label="Permalink to &quot;The Three Components&quot;"></a></h2><p><strong>LLM</strong> — The reasoning engine. Given context and available tools, it decides what to do next. The LLM is NOT the agent. It is the brain of the agent.</p><p><strong>Tools</strong> — The capability surface. Functions the agent can call: read files, run commands, search the web, query databases. Each tool has a name, description, and input schema.</p><p><strong>Loop</strong> — The autonomous decision cycle. Think (LLM decides) leads to Act (tool executes) leads to Observe (result comes back) leads to Repeat.</p><h2 id="what-each-combination-gives-you" tabindex="-1">What Each Combination Gives You <a class="header-anchor" href="#what-each-combination-gives-you" aria-label="Permalink to &quot;What Each Combination Gives You&quot;"></a></h2><table tabindex="0"><thead><tr><th>Combination</th><th>Result</th></tr></thead><tbody><tr><td>LLM only</td><td>Chatbot</td></tr><tr><td>LLM + Tools (no loop)</td><td>Augmented inference</td></tr><tr><td>LLM + Loop (no tools)</td><td>Talking to itself</td></tr><tr><td>LLM + Tools + Loop</td><td>Agent</td></tr></tbody></table><h2 id="the-loop-in-pseudocode" tabindex="-1">The Loop in Pseudocode <a class="header-anchor" href="#the-loop-in-pseudocode" aria-label="Permalink to &quot;The Loop in Pseudocode&quot;"></a></h2><div class="language-python vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">python</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">messages </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> [system_prompt, user_request]</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">while</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> True</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> response </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> llm.invoke(messages, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">tools</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">tool_definitions)</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> response.is_final_answer:</span></span>

View File

@ -1 +1 @@
import{c as a,Q as e,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"What Is an AI Agent, Really?","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/what-is-an-agent.md","filePath":"blog/posts/what-is-an-agent.md","lastUpdated":1780488246000}'),n={name:"blog/posts/what-is-an-agent.md"};function o(l,s,h,p,r,d){return e(),t("div",null,[...s[0]||(s[0]=[i("",15)])])}const g=a(n,[["render",o]]);export{c as __pageData,g as default};
import{c as a,Q as e,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const c=JSON.parse('{"title":"What Is an AI Agent, Really?","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/what-is-an-agent.md","filePath":"blog/posts/what-is-an-agent.md","lastUpdated":1780488472000}'),n={name:"blog/posts/what-is-an-agent.md"};function o(l,s,h,p,r,d){return e(),t("div",null,[...s[0]||(s[0]=[i("",15)])])}const g=a(n,[["render",o]]);export{c as __pageData,g as default};

View File

@ -1,4 +1,4 @@
import{c as n,Q as a,j as t,m as s}from"./chunks/framework.BPKcPtvA.js";const d=JSON.parse('{"title":"Why One Agent Is Not Enough","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/why-multi-agent.md","filePath":"blog/posts/why-multi-agent.md","lastUpdated":1780488246000}'),i={name:"blog/posts/why-multi-agent.md"};function o(l,e,r,p,h,g){return a(),t("div",null,[...e[0]||(e[0]=[s(`<h1 id="why-one-agent-is-not-enough" tabindex="-1">Why One Agent Is Not Enough <a class="header-anchor" href="#why-one-agent-is-not-enough" aria-label="Permalink to &quot;Why One Agent Is Not Enough&quot;"></a></h1><p><strong>June 3, 2026</strong></p><p>A single agent, no matter how smart, hits three ceilings.</p><h2 id="the-context-ceiling" tabindex="-1">The Context Ceiling <a class="header-anchor" href="#the-context-ceiling" aria-label="Permalink to &quot;The Context Ceiling&quot;"></a></h2><p>One agent doing everything means one context window holding everything. File contents, database schemas, business logic, deployment configs — they all compete for the same limited space. A 100K token codebase leaves zero room for the actual task.</p><h2 id="the-capability-ceiling" tabindex="-1">The Capability Ceiling <a class="header-anchor" href="#the-capability-ceiling" aria-label="Permalink to &quot;The Capability Ceiling&quot;"></a></h2><p>A generalist agent is mediocre at everything. A specialized agent — backend dev, security reviewer, UI designer — outperforms the generalist in its domain by a wide margin. You wouldn&#39;t ask your frontend dev to write SQL migrations. Why ask your agent to?</p><h2 id="the-reliability-ceiling" tabindex="-1">The Reliability Ceiling <a class="header-anchor" href="#the-reliability-ceiling" aria-label="Permalink to &quot;The Reliability Ceiling&quot;"></a></h2><p>One agent failing = everything fails. Multi-agent systems degrade gracefully. If the reviewer agent crashes, the builder keeps working. If the planner goes down, deployed agents continue running.</p><h2 id="the-solution-depth-2-delegation" tabindex="-1">The Solution: Depth-2 Delegation <a class="header-anchor" href="#the-solution-depth-2-delegation" aria-label="Permalink to &quot;The Solution: Depth-2 Delegation&quot;"></a></h2><p>The production-proven pattern:</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>User</span></span>
import{c as n,Q as a,j as t,m as s}from"./chunks/framework.BPKcPtvA.js";const d=JSON.parse('{"title":"Why One Agent Is Not Enough","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/why-multi-agent.md","filePath":"blog/posts/why-multi-agent.md","lastUpdated":1780488472000}'),i={name:"blog/posts/why-multi-agent.md"};function o(l,e,r,p,h,g){return a(),t("div",null,[...e[0]||(e[0]=[s(`<h1 id="why-one-agent-is-not-enough" tabindex="-1">Why One Agent Is Not Enough <a class="header-anchor" href="#why-one-agent-is-not-enough" aria-label="Permalink to &quot;Why One Agent Is Not Enough&quot;"></a></h1><p><strong>June 3, 2026</strong></p><p>A single agent, no matter how smart, hits three ceilings.</p><h2 id="the-context-ceiling" tabindex="-1">The Context Ceiling <a class="header-anchor" href="#the-context-ceiling" aria-label="Permalink to &quot;The Context Ceiling&quot;"></a></h2><p>One agent doing everything means one context window holding everything. File contents, database schemas, business logic, deployment configs — they all compete for the same limited space. A 100K token codebase leaves zero room for the actual task.</p><h2 id="the-capability-ceiling" tabindex="-1">The Capability Ceiling <a class="header-anchor" href="#the-capability-ceiling" aria-label="Permalink to &quot;The Capability Ceiling&quot;"></a></h2><p>A generalist agent is mediocre at everything. A specialized agent — backend dev, security reviewer, UI designer — outperforms the generalist in its domain by a wide margin. You wouldn&#39;t ask your frontend dev to write SQL migrations. Why ask your agent to?</p><h2 id="the-reliability-ceiling" tabindex="-1">The Reliability Ceiling <a class="header-anchor" href="#the-reliability-ceiling" aria-label="Permalink to &quot;The Reliability Ceiling&quot;"></a></h2><p>One agent failing = everything fails. Multi-agent systems degrade gracefully. If the reviewer agent crashes, the builder keeps working. If the planner goes down, deployed agents continue running.</p><h2 id="the-solution-depth-2-delegation" tabindex="-1">The Solution: Depth-2 Delegation <a class="header-anchor" href="#the-solution-depth-2-delegation" aria-label="Permalink to &quot;The Solution: Depth-2 Delegation&quot;"></a></h2><p>The production-proven pattern:</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>User</span></span>
<span class="line"><span> |</span></span>
<span class="line"><span> v</span></span>
<span class="line"><span>Orchestrator (Opus-level, thinking only)</span></span>

View File

@ -1 +1 @@
import{c as n,Q as a,j as t,m as s}from"./chunks/framework.BPKcPtvA.js";const d=JSON.parse('{"title":"Why One Agent Is Not Enough","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/why-multi-agent.md","filePath":"blog/posts/why-multi-agent.md","lastUpdated":1780488246000}'),i={name:"blog/posts/why-multi-agent.md"};function o(l,e,r,p,h,g){return a(),t("div",null,[...e[0]||(e[0]=[s("",19)])])}const u=n(i,[["render",o]]);export{d as __pageData,u as default};
import{c as n,Q as a,j as t,m as s}from"./chunks/framework.BPKcPtvA.js";const d=JSON.parse('{"title":"Why One Agent Is Not Enough","description":"","frontmatter":{},"headers":[],"relativePath":"blog/posts/why-multi-agent.md","filePath":"blog/posts/why-multi-agent.md","lastUpdated":1780488472000}'),i={name:"blog/posts/why-multi-agent.md"};function o(l,e,r,p,h,g){return a(),t("div",null,[...e[0]||(e[0]=[s("",19)])])}const u=n(i,[["render",o]]);export{d as __pageData,u as default};

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{c as t,Q as r,j as a,m as i}from"./chunks/framework.BPKcPtvA.js";const f=JSON.parse('{"title":"Buy","description":"","frontmatter":{},"headers":[],"relativePath":"buy.md","filePath":"buy.md","lastUpdated":1780488246000}'),o={name:"buy.md"};function l(s,e,d,n,c,h){return r(),a("div",null,[...e[0]||(e[0]=[i("",16)])])}const p=t(o,[["render",l]]);export{f as __pageData,p as default};
import{c as t,Q as r,j as a,m as i}from"./chunks/framework.BPKcPtvA.js";const f=JSON.parse('{"title":"Buy","description":"","frontmatter":{},"headers":[],"relativePath":"buy.md","filePath":"buy.md","lastUpdated":1780488472000}'),o={name:"buy.md"};function l(s,e,d,n,c,h){return r(),a("div",null,[...e[0]||(e[0]=[i("",16)])])}const p=t(o,[["render",l]]);export{f as __pageData,p as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
import{c as e,Q as a,j as s,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"Student Orientation Guide","description":"","frontmatter":{},"headers":[],"relativePath":"getting-started.md","filePath":"getting-started.md","lastUpdated":1780488246000}'),i={name:"getting-started.md"};function l(o,t,r,d,h,p){return a(),s("div",null,[...t[0]||(t[0]=[n(`<h1 id="student-orientation-guide" tabindex="-1">Student Orientation Guide <a class="header-anchor" href="#student-orientation-guide" aria-label="Permalink to &quot;Student Orientation Guide&quot;"></a></h1><p>Welcome to the Agentic Engineering Course. This guide tells you exactly what to do first.</p><hr><h2 id="step-1-prerequisites-checklist" tabindex="-1">Step 1: Prerequisites Checklist <a class="header-anchor" href="#step-1-prerequisites-checklist" aria-label="Permalink to &quot;Step 1: Prerequisites Checklist&quot;"></a></h2><p>Before starting, ensure you have:</p><ul><li>[ ] <strong>Python 3.12+</strong> installed (<code>python --version</code>)</li><li>[ ] <strong>Git</strong> installed (<code>git --version</code>)</li><li>[ ] <strong>A text editor</strong> (VS Code recommended)</li><li>[ ] <strong>At least one API key</strong> (see API Keys section below)</li><li>[ ] <strong>Terminal</strong> (PowerShell on Windows, bash on Mac/Linux)</li></ul><h3 id="optional-install-later-when-needed" tabindex="-1">Optional (install later when needed) <a class="header-anchor" href="#optional-install-later-when-needed" aria-label="Permalink to &quot;Optional (install later when needed)&quot;"></a></h3><ul><li>[ ] <strong>Claude Code CLI</strong> — <code>npm install -g @anthropic/claude-code</code></li><li>[ ] <strong>Pi Agent CLI</strong> — <code>npm install -g pi-coding-agent</code></li><li>[ ] <strong>OpenCode CLI</strong> — <code>npm install -g @opencode/cli</code></li></ul><hr><h2 id="step-2-course-structure" tabindex="-1">Step 2: Course Structure <a class="header-anchor" href="#step-2-course-structure" aria-label="Permalink to &quot;Step 2: Course Structure&quot;"></a></h2><p>The course is organized into <strong>8 modules</strong> with <strong>13 labs</strong>:</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>course/</span></span>
import{c as e,Q as a,j as s,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"Student Orientation Guide","description":"","frontmatter":{},"headers":[],"relativePath":"getting-started.md","filePath":"getting-started.md","lastUpdated":1780488472000}'),i={name:"getting-started.md"};function l(o,t,r,d,h,p){return a(),s("div",null,[...t[0]||(t[0]=[n(`<h1 id="student-orientation-guide" tabindex="-1">Student Orientation Guide <a class="header-anchor" href="#student-orientation-guide" aria-label="Permalink to &quot;Student Orientation Guide&quot;"></a></h1><p>Welcome to the Agentic Engineering Course. This guide tells you exactly what to do first.</p><hr><h2 id="step-1-prerequisites-checklist" tabindex="-1">Step 1: Prerequisites Checklist <a class="header-anchor" href="#step-1-prerequisites-checklist" aria-label="Permalink to &quot;Step 1: Prerequisites Checklist&quot;"></a></h2><p>Before starting, ensure you have:</p><ul><li>[ ] <strong>Python 3.12+</strong> installed (<code>python --version</code>)</li><li>[ ] <strong>Git</strong> installed (<code>git --version</code>)</li><li>[ ] <strong>A text editor</strong> (VS Code recommended)</li><li>[ ] <strong>At least one API key</strong> (see API Keys section below)</li><li>[ ] <strong>Terminal</strong> (PowerShell on Windows, bash on Mac/Linux)</li></ul><h3 id="optional-install-later-when-needed" tabindex="-1">Optional (install later when needed) <a class="header-anchor" href="#optional-install-later-when-needed" aria-label="Permalink to &quot;Optional (install later when needed)&quot;"></a></h3><ul><li>[ ] <strong>Claude Code CLI</strong> — <code>npm install -g @anthropic/claude-code</code></li><li>[ ] <strong>Pi Agent CLI</strong> — <code>npm install -g pi-coding-agent</code></li><li>[ ] <strong>OpenCode CLI</strong> — <code>npm install -g @opencode/cli</code></li></ul><hr><h2 id="step-2-course-structure" tabindex="-1">Step 2: Course Structure <a class="header-anchor" href="#step-2-course-structure" aria-label="Permalink to &quot;Step 2: Course Structure&quot;"></a></h2><p>The course is organized into <strong>8 modules</strong> with <strong>13 labs</strong>:</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>course/</span></span>
<span class="line"><span> 00-CURRICULUM.md START HERE: Full lesson plan</span></span>
<span class="line"><span> M1-FOUNDATIONS.md START HERE: Module 1</span></span>
<span class="line"><span> M2-ARCHITECTURE.md</span></span>

View File

@ -1 +1 @@
import{c as e,Q as a,j as s,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"Student Orientation Guide","description":"","frontmatter":{},"headers":[],"relativePath":"getting-started.md","filePath":"getting-started.md","lastUpdated":1780488246000}'),i={name:"getting-started.md"};function l(o,t,r,d,h,p){return a(),s("div",null,[...t[0]||(t[0]=[n("",38)])])}const g=e(i,[["render",l]]);export{u as __pageData,g as default};
import{c as e,Q as a,j as s,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"Student Orientation Guide","description":"","frontmatter":{},"headers":[],"relativePath":"getting-started.md","filePath":"getting-started.md","lastUpdated":1780488472000}'),i={name:"getting-started.md"};function l(o,t,r,d,h,p){return a(),s("div",null,[...t[0]||(t[0]=[n("",38)])])}const g=e(i,[["render",l]]);export{u as __pageData,g as default};

View File

@ -1,4 +1,4 @@
import{c as a,Q as i,j as s,m as e}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Labs Overview","description":"","frontmatter":{},"headers":[],"relativePath":"labs/index.md","filePath":"labs/index.md","lastUpdated":1780488246000}'),n={name:"labs/index.md"};function l(d,t,r,h,o,p){return i(),s("div",null,[...t[0]||(t[0]=[e(`<h1 id="labs-overview" tabindex="-1">Labs Overview <a class="header-anchor" href="#labs-overview" aria-label="Permalink to &quot;Labs Overview&quot;"></a></h1><p>13 hands-on labs covering the full agentic engineering stack. Each lab has a <code>starter.py</code> (fill in the blanks) and <code>solution.py</code> (reference answer).</p><h2 id="lab-index" tabindex="-1">Lab Index <a class="header-anchor" href="#lab-index" aria-label="Permalink to &quot;Lab Index&quot;"></a></h2><table tabindex="0"><thead><tr><th>Lab</th><th>Module</th><th>Topic</th><th>Est. Time</th></tr></thead><tbody><tr><td><a href="/labs/l1-first-agent">L1: First Agent</a></td><td>M1</td><td>Single-tool agent from scratch</td><td>60 min</td></tr><tr><td><a href="/labs/l2-multi-tool">L2a: Multi-Tool Agent</a></td><td>M2</td><td>File ops + web search</td><td>75 min</td></tr><tr><td><a href="/labs/l2-context">L2b: Context-Aware</a></td><td>M2</td><td>Sliding window + summarization</td><td>60 min</td></tr><tr><td><a href="/labs/l3-whitelist-hook">L3a: Whitelist Hook</a></td><td>M3</td><td>L4 security implementation</td><td>60 min</td></tr><tr><td><a href="/labs/l3-verifier">L3b: Verifier Agent</a></td><td>M3</td><td>Read-only verification</td><td>75 min</td></tr><tr><td><a href="/labs/l4-agent-chain">L4a: Agent Chain</a></td><td>M4</td><td>YAML pipeline</td><td>60 min</td></tr><tr><td><a href="/labs/l4-multi-team">L4b: Multi-Team</a></td><td>M4</td><td>Team config + domain locking</td><td>90 min</td></tr><tr><td><a href="/labs/l5-observability">L5a: Observability</a></td><td>M5</td><td>SQLite tool tracing</td><td>60 min</td></tr><tr><td><a href="/labs/l5-cicd">L5b: CI/CD</a></td><td>M5</td><td>Golden dataset + regression gate</td><td>60 min</td></tr><tr><td><a href="/labs/l6-eval-harness">L6a: Eval Harness</a></td><td>M6</td><td>pass@k evaluation</td><td>60 min</td></tr><tr><td><a href="/labs/l6-cost-optimization">L6b: Cost Optimization</a></td><td>M6</td><td>Cascade routing</td><td>45 min</td></tr><tr><td><a href="/labs/l7-autoresearch">L7a: Autoresearch</a></td><td>M7</td><td>Self-improving experiment loop</td><td>75 min</td></tr><tr><td><a href="/labs/l7-meta-agent">L7b: Meta-Agent</a></td><td>M7</td><td>Agent that builds agents</td><td>60 min</td></tr></tbody></table><h2 id="running-labs" tabindex="-1">Running Labs <a class="header-anchor" href="#running-labs" aria-label="Permalink to &quot;Running Labs&quot;"></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">cd</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> course/labs/L1-first-agent/</span></span>
import{c as a,Q as i,j as s,m as e}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Labs Overview","description":"","frontmatter":{},"headers":[],"relativePath":"labs/index.md","filePath":"labs/index.md","lastUpdated":1780488472000}'),n={name:"labs/index.md"};function l(d,t,r,h,o,p){return i(),s("div",null,[...t[0]||(t[0]=[e(`<h1 id="labs-overview" tabindex="-1">Labs Overview <a class="header-anchor" href="#labs-overview" aria-label="Permalink to &quot;Labs Overview&quot;"></a></h1><p>13 hands-on labs covering the full agentic engineering stack. Each lab has a <code>starter.py</code> (fill in the blanks) and <code>solution.py</code> (reference answer).</p><h2 id="lab-index" tabindex="-1">Lab Index <a class="header-anchor" href="#lab-index" aria-label="Permalink to &quot;Lab Index&quot;"></a></h2><table tabindex="0"><thead><tr><th>Lab</th><th>Module</th><th>Topic</th><th>Est. Time</th></tr></thead><tbody><tr><td><a href="/labs/l1-first-agent">L1: First Agent</a></td><td>M1</td><td>Single-tool agent from scratch</td><td>60 min</td></tr><tr><td><a href="/labs/l2-multi-tool">L2a: Multi-Tool Agent</a></td><td>M2</td><td>File ops + web search</td><td>75 min</td></tr><tr><td><a href="/labs/l2-context">L2b: Context-Aware</a></td><td>M2</td><td>Sliding window + summarization</td><td>60 min</td></tr><tr><td><a href="/labs/l3-whitelist-hook">L3a: Whitelist Hook</a></td><td>M3</td><td>L4 security implementation</td><td>60 min</td></tr><tr><td><a href="/labs/l3-verifier">L3b: Verifier Agent</a></td><td>M3</td><td>Read-only verification</td><td>75 min</td></tr><tr><td><a href="/labs/l4-agent-chain">L4a: Agent Chain</a></td><td>M4</td><td>YAML pipeline</td><td>60 min</td></tr><tr><td><a href="/labs/l4-multi-team">L4b: Multi-Team</a></td><td>M4</td><td>Team config + domain locking</td><td>90 min</td></tr><tr><td><a href="/labs/l5-observability">L5a: Observability</a></td><td>M5</td><td>SQLite tool tracing</td><td>60 min</td></tr><tr><td><a href="/labs/l5-cicd">L5b: CI/CD</a></td><td>M5</td><td>Golden dataset + regression gate</td><td>60 min</td></tr><tr><td><a href="/labs/l6-eval-harness">L6a: Eval Harness</a></td><td>M6</td><td>pass@k evaluation</td><td>60 min</td></tr><tr><td><a href="/labs/l6-cost-optimization">L6b: Cost Optimization</a></td><td>M6</td><td>Cascade routing</td><td>45 min</td></tr><tr><td><a href="/labs/l7-autoresearch">L7a: Autoresearch</a></td><td>M7</td><td>Self-improving experiment loop</td><td>75 min</td></tr><tr><td><a href="/labs/l7-meta-agent">L7b: Meta-Agent</a></td><td>M7</td><td>Agent that builds agents</td><td>60 min</td></tr></tbody></table><h2 id="running-labs" tabindex="-1">Running Labs <a class="header-anchor" href="#running-labs" aria-label="Permalink to &quot;Running Labs&quot;"></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">cd</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> course/labs/L1-first-agent/</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Without API key (uses mock LLM automatically):</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">python</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> starter.py</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> test.txt</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;What is this file about?&quot;</span></span>

View File

@ -1 +1 @@
import{c as a,Q as i,j as s,m as e}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Labs Overview","description":"","frontmatter":{},"headers":[],"relativePath":"labs/index.md","filePath":"labs/index.md","lastUpdated":1780488246000}'),n={name:"labs/index.md"};function l(d,t,r,h,o,p){return i(),s("div",null,[...t[0]||(t[0]=[e("",11)])])}const b=a(n,[["render",l]]);export{k as __pageData,b as default};
import{c as a,Q as i,j as s,m as e}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Labs Overview","description":"","frontmatter":{},"headers":[],"relativePath":"labs/index.md","filePath":"labs/index.md","lastUpdated":1780488472000}'),n={name:"labs/index.md"};function l(d,t,r,h,o,p){return i(),s("div",null,[...t[0]||(t[0]=[e("",11)])])}const b=a(n,[["render",l]]);export{k as __pageData,b as default};

View File

@ -1,2 +1,2 @@
import{c as t,Q as a,j as i,m as s}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"L1: Your First Agent","description":"","frontmatter":{},"headers":[],"relativePath":"labs/l1-first-agent.md","filePath":"labs/l1-first-agent.md","lastUpdated":1780488246000}'),o={name:"labs/l1-first-agent.md"};function l(n,e,r,h,c,p){return a(),i("div",null,[...e[0]||(e[0]=[s(`<h1 id="l1-your-first-agent" tabindex="-1">L1: Your First Agent <a class="header-anchor" href="#l1-your-first-agent" aria-label="Permalink to &quot;L1: Your First Agent&quot;"></a></h1><p>Build a single-tool agent from scratch.</p><p><strong>Module</strong>: M1 Foundations<br><strong>Est. Time</strong>: 60 min<br><strong>Files</strong>: <code>starter.py</code>, <code>solution.py</code></p><h2 id="objective" tabindex="-1">Objective <a class="header-anchor" href="#objective" aria-label="Permalink to &quot;Objective&quot;"></a></h2><p>Create an agent that reads a file and answers questions about its contents.</p><h2 id="concepts" tabindex="-1">Concepts <a class="header-anchor" href="#concepts" aria-label="Permalink to &quot;Concepts&quot;"></a></h2><ul><li>LLM + Tools + Loop = Agent</li><li>Tool definition with input schema</li><li>The agent loop (think → act → observe → repeat)</li><li>The <code>reasoning</code> parameter</li></ul><h2 id="starter" tabindex="-1">Starter <a class="header-anchor" href="#starter" aria-label="Permalink to &quot;Starter&quot;"></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">cd</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> course/labs/L1-first-agent/</span></span>
import{c as t,Q as a,j as i,m as s}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"L1: Your First Agent","description":"","frontmatter":{},"headers":[],"relativePath":"labs/l1-first-agent.md","filePath":"labs/l1-first-agent.md","lastUpdated":1780488472000}'),o={name:"labs/l1-first-agent.md"};function l(n,e,r,h,c,p){return a(),i("div",null,[...e[0]||(e[0]=[s(`<h1 id="l1-your-first-agent" tabindex="-1">L1: Your First Agent <a class="header-anchor" href="#l1-your-first-agent" aria-label="Permalink to &quot;L1: Your First Agent&quot;"></a></h1><p>Build a single-tool agent from scratch.</p><p><strong>Module</strong>: M1 Foundations<br><strong>Est. Time</strong>: 60 min<br><strong>Files</strong>: <code>starter.py</code>, <code>solution.py</code></p><h2 id="objective" tabindex="-1">Objective <a class="header-anchor" href="#objective" aria-label="Permalink to &quot;Objective&quot;"></a></h2><p>Create an agent that reads a file and answers questions about its contents.</p><h2 id="concepts" tabindex="-1">Concepts <a class="header-anchor" href="#concepts" aria-label="Permalink to &quot;Concepts&quot;"></a></h2><ul><li>LLM + Tools + Loop = Agent</li><li>Tool definition with input schema</li><li>The agent loop (think → act → observe → repeat)</li><li>The <code>reasoning</code> parameter</li></ul><h2 id="starter" tabindex="-1">Starter <a class="header-anchor" href="#starter" aria-label="Permalink to &quot;Starter&quot;"></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">cd</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> course/labs/L1-first-agent/</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">python</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> starter.py</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> test.txt</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;What is this file about?&quot;</span></span></code></pre></div><p>The starter has TODO markers where you fill in:</p><ol><li>Define the <code>read_file</code> tool schema</li><li>Implement the <code>execute_tool</code> function</li><li>Implement the <code>run_agent</code> loop</li><li>Wire up the main entry point</li></ol><h2 id="solution" tabindex="-1">Solution <a class="header-anchor" href="#solution" aria-label="Permalink to &quot;Solution&quot;"></a></h2><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">python</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> solution.py</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> test.txt</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;What is this file about?&quot;</span></span></code></pre></div><p>Compare your implementation against the solution. Key differences to check:</p><ul><li>Did you set <code>MAX_ITERATIONS</code>?</li><li>Does every tool call include <code>reasoning</code>?</li><li>Does the loop terminate on <code>end_turn</code>?</li></ul><h2 id="checkpoints" tabindex="-1">Checkpoints <a class="header-anchor" href="#checkpoints" aria-label="Permalink to &quot;Checkpoints&quot;"></a></h2><ol><li>Tool call is made correctly (schema matches)</li><li>Tool result is fed back to the LLM</li><li>LLM produces final answer using tool result</li><li>Loop terminates (doesn&#39;t run forever)</li></ol>`,17)])])}const k=t(o,[["render",l]]);export{u as __pageData,k as default};

View File

@ -1 +1 @@
import{c as t,Q as a,j as i,m as s}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"L1: Your First Agent","description":"","frontmatter":{},"headers":[],"relativePath":"labs/l1-first-agent.md","filePath":"labs/l1-first-agent.md","lastUpdated":1780488246000}'),o={name:"labs/l1-first-agent.md"};function l(n,e,r,h,c,p){return a(),i("div",null,[...e[0]||(e[0]=[s("",17)])])}const k=t(o,[["render",l]]);export{u as __pageData,k as default};
import{c as t,Q as a,j as i,m as s}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"L1: Your First Agent","description":"","frontmatter":{},"headers":[],"relativePath":"labs/l1-first-agent.md","filePath":"labs/l1-first-agent.md","lastUpdated":1780488472000}'),o={name:"labs/l1-first-agent.md"};function l(n,e,r,h,c,p){return a(),i("div",null,[...e[0]||(e[0]=[s("",17)])])}const k=t(o,[["render",l]]);export{u as __pageData,k as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"404.md":"BiCvjdaY","api-keys.md":"D_HM8x3I","blog_index.md":"DpQ5yx1K","blog_posts_cascade-routing.md":"BF7ufKzI","blog_posts_choosing-security-level.md":"BibZder6","blog_posts_mental-models.md":"CjqjYOIN","blog_posts_repo-is-spec.md":"CI68II5_","blog_posts_security-ladder.md":"Rs2Sy2_y","blog_posts_three-x-rule.md":"Dm6HtTS4","blog_posts_verifier-pattern.md":"RAPWkvlk","blog_posts_vibe-vs-agentic.md":"C0Kts5m3","blog_posts_what-is-an-agent.md":"XVfTHLdp","blog_posts_why-multi-agent.md":"DM07YZPh","buy.md":"BlyAkuIK","certificate.md":"0V0n-TLl","getting-started.md":"CwhTdYNz","index.md":"BNS2TR1g","labs_index.md":"DTT5OogM","labs_l1-first-agent.md":"CfhnnNn1","labs_l2-context.md":"BexGm8_s","labs_l2-multi-tool.md":"Bj3Mb-oj","labs_l3-verifier.md":"xilrGGap","labs_l3-whitelist-hook.md":"DJtbL66Y","labs_l4-agent-chain.md":"D89P8dwJ","labs_l4-multi-team.md":"DmSK8e2P","labs_l5-cicd.md":"Dz1Jl78z","labs_l5-observability.md":"BDpqVYjT","labs_l6-cost-optimization.md":"CabFK4GB","labs_l6-eval-harness.md":"CBwH6xOR","labs_l7-autoresearch.md":"BYlzPLYo","labs_l7-meta-agent.md":"iTswbOPg","modules_competitive-analysis.md":"BHMHacei","modules_curriculum.md":"D7UeKRfo","modules_debate.md":"DWctKMlA","modules_feynman.md":"DBw5sPBP","modules_field-manual.md":"hmt_NLf1","modules_m1-foundations.md":"DHFyTzWj","modules_m2-architecture.md":"Dp39xggp","modules_m3-safety.md":"CkKCTJdi","modules_m4-orchestration.md":"DFLcAKBv","modules_m5-production.md":"DTkLIrwQ","modules_m6-economics.md":"B6XI2-r7","modules_m7-advanced.md":"Cr3-rEV4","modules_m8-capstone.md":"D1AXKCqv","modules_non-technical.md":"BnvuUCRo","modules_reference-stack.md":"D9FXitvn","modules_software-factory.md":"C5Yf8Zwe","modules_tool-reference.md":"B40mlgZJ","public_certificate_template.md":"Cg1kPB1b","resources.md":"DcUu1NrK","skills.md":"BX3RBeCK","troubleshooting.md":"B6difx2I","verify.md":"Cl5ZMWNd"}
{"404.md":"BiCvjdaY","api-keys.md":"D2Kyj8T3","blog_index.md":"B5nL9faf","blog_posts_cascade-routing.md":"DvBM3TSf","blog_posts_choosing-security-level.md":"BYXRZEDN","blog_posts_mental-models.md":"BRY80gtq","blog_posts_repo-is-spec.md":"BxY1cXc_","blog_posts_security-ladder.md":"DQaqn6Yt","blog_posts_three-x-rule.md":"BHO6bhvz","blog_posts_verifier-pattern.md":"Gha_L_u5","blog_posts_vibe-vs-agentic.md":"7mduPfz1","blog_posts_what-is-an-agent.md":"BU2wUq_Y","blog_posts_why-multi-agent.md":"BVRIN2vH","buy.md":"CbIpCW5Y","certificate.md":"0V0n-TLl","getting-started.md":"Boo_V9xC","index.md":"BNS2TR1g","labs_index.md":"sAzXzfkI","labs_l1-first-agent.md":"BwU9yf-G","labs_l2-context.md":"BexGm8_s","labs_l2-multi-tool.md":"Bj3Mb-oj","labs_l3-verifier.md":"xilrGGap","labs_l3-whitelist-hook.md":"DJtbL66Y","labs_l4-agent-chain.md":"D89P8dwJ","labs_l4-multi-team.md":"DmSK8e2P","labs_l5-cicd.md":"Dz1Jl78z","labs_l5-observability.md":"BDpqVYjT","labs_l6-cost-optimization.md":"CabFK4GB","labs_l6-eval-harness.md":"CBwH6xOR","labs_l7-autoresearch.md":"BYlzPLYo","labs_l7-meta-agent.md":"iTswbOPg","modules_competitive-analysis.md":"BHMHacei","modules_curriculum.md":"D7UeKRfo","modules_debate.md":"DWctKMlA","modules_feynman.md":"DBw5sPBP","modules_field-manual.md":"hmt_NLf1","modules_m1-foundations.md":"DHFyTzWj","modules_m2-architecture.md":"Dp39xggp","modules_m3-safety.md":"CkKCTJdi","modules_m4-orchestration.md":"DFLcAKBv","modules_m5-production.md":"DTkLIrwQ","modules_m6-economics.md":"B6XI2-r7","modules_m7-advanced.md":"Cr3-rEV4","modules_m8-capstone.md":"D1AXKCqv","modules_non-technical.md":"BnvuUCRo","modules_reference-stack.md":"D9FXitvn","modules_software-factory.md":"C5Yf8Zwe","modules_tool-reference.md":"B40mlgZJ","public_certificate_template.md":"Cg1kPB1b","resources.md":"DcUu1NrK","skills.md":"BX3RBeCK","troubleshooting.md":"B6difx2I","verify.md":"Cl5ZMWNd"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -8,11 +8,10 @@
<span class="logo-text">FDSA</span>
</div>
<div class="nav-links">
<a href="/modules/m1-foundations">Course</a>
<a href="/labs/l1-first-agent">Labs</a>
<a href="/skills">Skills</a>
<a href="/modules/curriculum">Course</a>
<a href="/labs/index">Labs</a>
<a href="/blog">Blog</a>
<a href="/buy" class="nav-cta">Enroll</a>
<a href="/buy" class="nav-cta">Enroll $97</a>
</div>
</div>
</header>
@ -24,26 +23,50 @@
<div class="hero-glow"></div>
<div class="hero-inner">
<div class="hero-pill"><span class="pill-dot"></span>NOW ENROLLING</div>
<h1>Agentic Engineering</h1>
<p class="hero-sub">65 lessons, 13 labs, 20 skill kits. Build, deploy, and maintain production-grade AI agent systems.</p>
<h1>Master <span class="hlt">Agentic Engineering</span></h1>
<p class="hero-sub">65 lessons, 13 labs, 20 skill kits. Build production-grade multi-agent systems that are secure, cost-optimized, and always-on.</p>
<div class="hero-actions">
<a href="/buy" class="btn-p btn-primary">Enroll Now $97</a>
<a href="/modules/m1-foundations" class="btn-p btn-ghost">View Curriculum</a>
<a href="/modules/m1-foundations" class="btn-p btn-ghost">Start Learning Free</a>
</div>
</div>
<div class="term-widget">
<div class="term-dots"><span class="td r"></span><span class="td y"></span><span class="td g"></span></div>
<div class="term-l c">INITIALIZING AGENT_PLANNER...</div>
<div class="term-l">FETCHING LLM CONTEXT: DONE</div>
<div class="term-l a">EXECUTING: search("agentic patterns")</div>
<div class="term-l">ANALYZING RESULT_SET: SUCCESS</div>
<div class="term-l c">AGENT_PLANNER v2.1</div>
<div class="term-l">> LOADING HARNESS... DONE</div>
<div class="term-l a">> DEPLOYING 8-AGENT SYSTEM</div>
<div class="term-l">> SECURITY: LEVEL 4 (WHITELIST)</div>
<div class="term-l g">> ALL SYSTEMS OPERATIONAL</div>
<div class="term-bar"><div class="term-fill"></div></div>
</div>
</section>
<!-- Stats -->
<section class="sec stats-sec">
<div class="stats-grid">
<div class="stat">
<span class="stat-n">65</span>
<span class="stat-l">Lessons</span>
</div>
<div class="stat">
<span class="stat-n">13</span>
<span class="stat-l">Hands-on Labs</span>
</div>
<div class="stat">
<span class="stat-n">8</span>
<span class="stat-l">Modules</span>
</div>
<div class="stat">
<span class="stat-n">20</span>
<span class="stat-l">Skill Kits</span>
</div>
</div>
</section>
<!-- Features -->
<section class="sec">
<div class="sec-label">Core Capabilities</div>
<section class="sec" id="features">
<div class="sec-label">What You'll Build</div>
<h2 class="sec-title">Production-Ready Agent Systems</h2>
<div class="feat-grid">
<div class="gc" v-for="f in features" :key="f.t">
<div class="gci"><span class="material-symbols-outlined">{{ f.icon }}</span></div>
@ -54,9 +77,9 @@
</section>
<!-- Bento Curriculum -->
<section class="sec">
<div class="sec-label">Engineering Curriculum</div>
<h2 class="sec-title">8 Modules. 65 Lessons. Zero Fluff.</h2>
<section class="sec" id="curriculum">
<div class="sec-label">Curriculum</div>
<h2 class="sec-title">8 Modules. From Zero to Production.</h2>
<div class="bento">
<div v-for="(m, i) in modules" :key="i" class="bi" :class="m.s">
<div class="bi-n">{{ m.n }}</div>
@ -64,80 +87,143 @@
<h4 class="bi-t">{{ m.t }}</h4>
<p class="bi-d">{{ m.d }}</p>
<div class="bi-tags"><span v-for="t in m.tg" :key="t">{{ t }}</span></div>
<div v-if="m.p" class="bi-bar"><div class="bi-fill" :style="{width:m.p}"></div></div>
</div>
</div>
</section>
<!-- Testimonials -->
<section class="sec" id="testimonials">
<div class="sec-label">Trusted By</div>
<h2 class="sec-title">What Engineers Are Saying</h2>
<div class="test-grid">
<div class="test-card" v-for="t in testimonials" :key="t.q">
<div class="test-q">"{{ t.q }}"</div>
<div class="test-a">
<div class="test-av">{{ t.n[0] }}</div>
<div>
<div class="test-n">{{ t.n }}</div>
<div class="test-r">{{ t.r }}</div>
</div>
</div>
</div>
</div>
</section>
<!-- Pricing -->
<section class="sec pricing-sec">
<div class="pc gc">
<span class="material-symbols-outlined" style="font-size:36px;color:#d95c41;margin-bottom:8px">verified</span>
<h2 style="font-size:24px;font-weight:700;margin-bottom:4px">Full Course Access</h2>
<p style="color:#888;font-size:14px;margin-bottom:20px">Lifetime updates included</p>
<div style="font-size:48px;font-weight:800;color:#d95c41;margin-bottom:24px">$97</div>
<ul class="pu">
<li v-for="item in perks" :key="item"><span class="material-symbols-outlined" style="font-size:18px;color:#d95c41">check_circle</span>{{ item }}</li>
</ul>
<a href="/buy" class="btn-p btn-primary" style="width:100%;text-align:center">Enroll Now</a>
<div class="pg">30-Day Guarantee</div>
<section class="sec pricing-sec" id="pricing">
<div class="sec-label">Investment</div>
<h2 class="sec-title">Choose Your Path</h2>
<div class="pricing-grid">
<div class="price-card" v-for="p in plans" :key="p.name" :class="{ highlight: p.highlight }">
<div class="price-name">{{ p.name }}</div>
<div class="price-amt"><span class="price-dol">$</span>{{ p.amt }}</div>
<div class="price-note">{{ p.note }}</div>
<ul class="price-feats">
<li v-for="item in p.feats" :key="item"><span class="material-symbols-outlined">check_circle</span>{{ item }}</li>
</ul>
<a :href="p.url" class="btn-p" :class="p.cta">{{ p.label }}</a>
</div>
</div>
</section>
<!-- FAQ -->
<section class="sec" id="faq">
<div class="sec-label">FAQ</div>
<h2 class="sec-title">Common Questions</h2>
<div class="faq-list">
<div class="faq-item" v-for="faq in faqs" :key="faq.q" @click="faq.open = !faq.open">
<div class="faq-q">
{{ faq.q }}
<span class="material-symbols-outlined faq-icon" :class="{ open: faq.open }">expand_more</span>
</div>
<div class="faq-a" v-if="faq.open">{{ faq.a }}</div>
</div>
</div>
</section>
</main>
<footer class="ft">
<div class="ft-inner">
<div class="ft-l">FDSA</div>
<div class="ft-links">
<a href="/troubleshooting">FAQ</a>
<a href="/certificate">Certificate</a>
<a href="/buy">Pricing</a>
<div class="ft-grid">
<div class="ft-brand">
<div class="ft-l">FDSA</div>
<div class="ft-desc">Agentic Engineering Course part of the fdsa.ai orchestration platform.</div>
</div>
<div class="ft-col">
<div class="ft-h">Course</div>
<a href="/modules/m1-foundations">M1 Foundations</a>
<a href="/modules/m4-orchestration">M4 Orchestration</a>
<a href="/modules/m8-capstone">M8 Capstone</a>
</div>
<div class="ft-col">
<div class="ft-h">Resources</div>
<a href="/blog">Blog</a>
<a href="/troubleshooting">FAQ</a>
<a href="/certificate">Certificate</a>
</div>
<div class="ft-col">
<div class="ft-h">Company</div>
<a href="https://fdsa.ai">fdsa.ai</a>
<a href="mailto:artale@fdsa.agency">Contact</a>
<a href="/buy">Pricing</a>
</div>
</div>
<div class="ft-c">FDSA Agency Agentic Engineering Course</div>
<div class="ft-c">2026 FDSA Agency. All rights reserved.</div>
</div>
</footer>
<nav class="bn">
<a href="/" class="bn-i active"><span class="material-symbols-outlined">home</span><span>Home</span></a>
<a href="/modules/m1-foundations" class="bn-i"><span class="material-symbols-outlined">school</span><span>Modules</span></a>
<a href="/labs/l1-first-agent" class="bn-i"><span class="material-symbols-outlined">terminal</span><span>Labs</span></a>
<a href="/buy" class="bn-i"><span class="material-symbols-outlined">payments</span><span>Pricing</span></a>
<a href="/modules/curriculum" class="bn-i"><span class="material-symbols-outlined">school</span><span>Modules</span></a>
<a href="#features" class="bn-i"><span class="material-symbols-outlined">apps</span><span>Features</span></a>
<a href="#pricing" class="bn-i"><span class="material-symbols-outlined">payments</span><span>Pricing</span></a>
</nav>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue'
import { onMounted } from 'vue'
const features = [
{ icon: 'settings_suggest', t: 'Agent Harness', d: 'Own your harness. 6-level security ladder, verifier pattern, hooks.' },
{ icon: 'speed', t: 'Software Factory', d: 'Systems that build systems. Agent chains, teams, mental models.' },
{ icon: 'psychology', t: 'Extensible Software', d: 'Pluggable, composable. Beyond MCP, tool design, CI/CD.' },
{ icon: 'all_inclusive', t: 'Always-On Agents', d: 'Autoresearch, heartbeat execution, meta-agents. Run 24/7.' },
{ icon: 'terminal', t: 'Agentic Access', d: 'API-first design, deployment modes, service connectors.' },
{ icon: 'forum', t: 'Tokenomics', d: 'Cascade routing, pass@k evals, 3x cost rule, optimization.' },
{ icon: 'settings_suggest', t: 'Agent Harness', d: 'Own your harness. 6-level security ladder, verifier pattern, hooks architecture across 5 subsystems.' },
{ icon: 'speed', t: 'Software Factory', d: 'Systems that build systems. Agent chains, teams, P2P communication, depth-2 delegation.' },
{ icon: 'psychology', t: 'Extensible Software', d: 'Pluggable, composable, swappable. Beyond MCP, tool design patterns, CI/CD for agent configs.' },
{ icon: 'all_inclusive', t: 'Always-On Agents', d: 'Run 24/7. Autoresearch loops, heartbeat execution, meta-agents that improve themselves.' },
{ icon: 'terminal', t: 'Agentic Access', d: 'API-first design. Tool surface design, deployment modes, service connectors, MCP integration.' },
{ icon: 'trending_up', t: 'Tokenomics', d: '3 levels of token value. Cascade routing, pass@k evals, the 3x cost rule, production optimization.' },
]
const modules = [
{ n:'01', ic:'psychology', t:'Foundations', d:'What agents are, harness vs model, decision frameworks.', tg:['LLM + Tools + Loop','Agent Loop','Trust'], p:'100%', s:'w8' },
{ n:'02', ic:'handyman', t:'Architecture', d:'Tools, context, memory, skills, codebase patterns.', tg:['4 Pillars','Tools','Memory'], s:'w4' },
{ n:'03', ic:'shield', t:'Safety & Security', d:'6-level ladder, hooks, verifier pattern, defense-in-depth.', tg:['L0-L5','Verifier','ACIP'], s:'w4' },
{ n:'04', ic:'hub', t:'Orchestration', d:'Multi-agent patterns, P-threads, P2P, CEO Board.', tg:['Teams','Chains','P2P'], s:'w8' },
{ n:'05', ic:'rocket_launch', t:'Production', d:'CI/CD, shadow deploys, observability, rollback.', tg:['Deploy','Monitor','Rollback'], s:'w6' },
{ n:'06', ic:'analytics', t:'Economics', d:'Model pricing, cascade routing, pass@k, cost optimization.', tg:['100x Range','3x Rule','Evals'], s:'w6' },
{ n:'07', ic:'architecture', t:'Advanced', d:'Autoresearch, meta-agents, beyond MCP, always-on.', tg:['Self-Improving','Meta-Agents'], s:'w4' },
{ n:'08', ic:'trophy', t:'Capstone', d:'Build a production-grade multi-agent system.', tg:['Brand Monitor','CEO Board','Pipeline'], s:'w8 hl' },
{ n:'01', ic:'psychology', t:'Foundations', d:'What agents are, harness vs model, decision frameworks, agent loops.', tg:['LLM+Tools+Loop','Harness','Trust'], s:'w4' },
{ n:'02', ic:'handyman', t:'Architecture', d:'Tools, context, memory, skills system, codebase patterns, workspace design.', tg:['4 Pillars','Memory','Skills'], s:'w4' },
{ n:'03', ic:'shield', t:'Safety', d:'6-level security ladder, hooks, verifier pattern, defense-in-depth, ACIP.', tg:['L0-L5','Verifier','Hooks'], s:'w4' },
{ n:'04', ic:'hub', t:'Orchestration', d:'Multi-agent patterns, P-threads, F-threads, P2P, CEO Board, domain locking.', tg:['Teams','Chains','P2P'], s:'w6' },
{ n:'05', ic:'rocket_launch', t:'Production', d:'CI/CD for agents, shadow deploys, observability, rollback, 5-tool stack.', tg:['Deploy','Monitor','Rollback'], s:'w6' },
{ n:'06', ic:'analytics', t:'Economics', d:'Model pricing, cascade routing, pass@k evals, cost optimization per session.', tg:['100x Range','3x Rule','Evals'], s:'w6' },
{ n:'07', ic:'architecture', t:'Advanced', d:'Autoresearch, meta-agents, beyond MCP, always-on employee patterns.', tg:['Self-Improving','Meta'], s:'w6' },
{ n:'08', ic:'trophy', t:'Capstone', d:'Build production multi-agent system. Brand Monitor, CEO Board, or Code Review Pipeline.', tg:['Ship','Deploy','Rubric'], s:'w12 hl' },
]
const perks = [
'65 lessons across 8 modules',
'13 scaffolded labs with solutions',
'56 quiz questions with answer keys',
'20 production-ready skill files (7 kits)',
'Lifetime access + future updates',
const plans = [
{ name: 'Self-Paced', amt: '97', note: 'one-time payment', feats: ['65 lessons across 8 modules', '13 scaffolded labs with solutions', '56 quiz questions', '20 SKILL.md files (7 kits)', 'Lifetime access + updates', 'Mock LLM for offline labs'], url: 'https://gumroad.com/l/fdsa-agentic-selfpaced', label: 'Enroll Now', cta: 'btn-primary', highlight: true },
{ name: 'Enterprise', amt: '199', note: 'one-time payment', feats: ['Everything in Self-Paced', 'Private Discord channel', '2 custom skills for your stack', '1-hour onboarding call', 'Priority updates for 1 year', 'Early access to new kits'], url: 'https://gumroad.com/l/fdsa-agentic-enterprise', label: 'Buy Enterprise', cta: 'btn-ghost', highlight: false },
{ name: 'Cohort', amt: '247', note: 'next cohort TBD', feats: ['Everything in Enterprise', '6-week structured schedule', 'Weekly live office hours', 'Capstone peer review', 'Completion certificate', 'Alumni network'], url: 'https://gumroad.com/l/fdsa-agentic-cohort', label: 'Join Cohort', cta: 'btn-ghost', highlight: false },
]
const testimonials = [
{ q: 'The security ladder alone is worth the price. Finally understand how to safely deploy agents in production.', n: 'Alex K.', r: 'Senior ML Engineer' },
{ q: 'Went from vibe-coding to actually engineering agents. The harness vs model distinction changed how I think.', n: 'Jordan T.', r: 'Full-Stack Developer' },
{ q: 'Best practical course on multi-agent systems I\'ve found. The CEO Board pattern is genius.', n: 'Sam R.', r: 'AI Startup Founder' },
]
const faqs = [
{ q: 'Do I need API keys to run the labs?', a: 'No. All 13 labs include a mock LLM client that works offline. You only need API keys if you want to run against real models.', open: false },
{ q: 'What tools/CLIs does this course cover?', a: 'The course is tool-agnostic. The concepts apply to Claude Code, Pi Agent, OpenCode, Gemini CLI, and any agent harness. Labs use Python with an Anthropic-style API that\'s easy to adapt.', open: false },
{ q: 'How long does the course take?', a: 'Self-paced: 40-60 hours total. Most students complete M1-M7 in 4-6 weeks. M8 capstone adds 1-2 weeks.', open: false },
{ q: 'What\'s the refund policy?', a: '30-day guarantee. If you\'re not satisfied, email artale@fdsa.agency for a full refund.', open: false },
{ q: 'Can I buy individual skill kits?', a: 'Yes. Security Foundation ($49), Multi-Agent Orch ($49), Verifier Pro ($39), and 4 more kits available individually on the pricing page.', open: false },
]
// Scroll reveal animations
onMounted(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
@ -147,29 +233,14 @@ onMounted(() => {
})
}, { threshold: 0.1 })
// Observe sections (skip hero always visible)
document.querySelectorAll('.sec').forEach(el => {
el.classList.add('reveal')
observer.observe(el)
})
// Observe individual bento items with stagger
document.querySelectorAll('.bi').forEach((el, i) => {
el.style.transitionDelay = (i * 0.05) + 's'
el.classList.add('reveal')
observer.observe(el)
})
// Observe feature cards with stagger
document.querySelectorAll('.feat-grid .gc').forEach((el, i) => {
el.style.transitionDelay = (i * 0.08) + 's'
document.querySelectorAll('.sec, .bi, .feat-grid .gc, .price-card, .test-card, .stat').forEach(el => {
el.classList.add('reveal')
observer.observe(el)
})
})
</script>
<style>
<style scoped>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
.landing {
@ -180,7 +251,7 @@ onMounted(() => {
}
/* Nav */
.nav{position:fixed;top:0;left:0;right:0;z-index:50;background:rgba(10,10,10,0.8);backdrop-filter:blur(16px);border-bottom:1px solid #1a1a1a}
.nav{position:fixed;top:0;left:0;right:0;z-index:50;background:rgba(10,10,10,0.85);backdrop-filter:blur(16px);border-bottom:1px solid #1a1a1a}
.nav-inner{max-width:1280px;margin:0 auto;display:flex;align-items:center;justify-content:space-between;height:64px;padding:0 24px}
.logo-wrap{display:flex;align-items:center;gap:8px}
.logo-text{font-weight:800;font-size:20px;letter-spacing:-0.5px;color:#e8e8e8}
@ -191,7 +262,7 @@ onMounted(() => {
.nav-cta:hover{background:#c44a30!important}
/* Hero */
.hero-sec{min-height:90vh;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:140px 24px 80px;text-align:center;position:relative;overflow:hidden}
.hero-sec{min-height:90vh;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:140px 24px 60px;text-align:center;position:relative;overflow:hidden}
.hero-grid{position:absolute;inset:0;background-image:linear-gradient(rgba(217,92,65,0.04) 1px,transparent 1px),linear-gradient(90deg,rgba(217,92,65,0.04) 1px,transparent 1px);background-size:40px 40px;pointer-events:none}
.hero-glow{position:absolute;inset:0;background:radial-gradient(ellipse at center,rgba(217,92,65,0.08) 0%,transparent 60%);pointer-events:none}
.hero-inner{position:relative;z-index:1;max-width:680px}
@ -199,42 +270,49 @@ onMounted(() => {
.pill-dot{width:6px;height:6px;border-radius:50%;background:#d95c41;animation:pulse 2s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.3}}
.hero-sec h1{font-size:56px;font-weight:800;letter-spacing:-1.5px;line-height:1.05;color:#f0f0f0;margin-bottom:20px}
.hero-sub{font-size:18px;color:#888;line-height:1.6;margin-bottom:36px}
.hlt{background:linear-gradient(135deg,#d95c41,#e87d2f);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
.hero-sub{font-size:18px;color:#888;line-height:1.6;margin-bottom:36px;max-width:560px;margin-left:auto;margin-right:auto}
.hero-actions{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}
.btn-p{display:inline-block;padding:14px 32px;border-radius:8px;font-weight:600;font-size:15px;text-decoration:none;transition:all .2s}
.btn-p{display:inline-block;padding:14px 32px;border-radius:8px;font-weight:600;font-size:15px;text-decoration:none;transition:all .2s;cursor:pointer}
.btn-primary{background:#d95c41;color:#fff}
.btn-primary:hover{background:#c44a30;transform:translateY(-1px)}
.btn-ghost{color:#e8e8e8;border:1px solid #222}
.btn-ghost:hover{border-color:#555}
/* Terminal */
.term-widget{margin-top:48px;max-width:480px;width:100%;background:rgba(17,17,17,0.9);backdrop-filter:blur(12px);border:1px solid #222;border-radius:12px;padding:20px;text-align:left;position:relative;overflow:hidden}
.term-widget{margin-top:48px;max-width:460px;width:100%;background:rgba(17,17,17,0.9);backdrop-filter:blur(12px);border:1px solid #222;border-radius:12px;padding:20px;text-align:left;position:relative;overflow:hidden}
.term-widget::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,#d95c41,transparent);opacity:.5}
.term-dots{display:flex;gap:8px;margin-bottom:16px}
.td{width:10px;height:10px;border-radius:50%}
.td.r{background:#ef4444}.td.y{background:#eab308}.td.g{background:#22c55e}
.term-l{font-family:'DM Mono',monospace;font-size:12px;color:#888;line-height:2}
.term-l.c{color:#d95c41}.term-l.a{color:#7bd0ff}
.term-l.c{color:#d95c41}.term-l.a{color:#7bd0ff}.term-l.g{color:#22c55e}
.term-bar{margin-top:12px;height:4px;background:#1a1a1a;border-radius:2px;overflow:hidden}
.term-fill{height:100%;width:66%;background:linear-gradient(90deg,#d95c41,#e87d2f);border-radius:2px;animation:prog 3s ease-in-out infinite}
.term-fill{height:100%;width:72%;background:linear-gradient(90deg,#d95c41,#e87d2f);border-radius:2px;animation:prog 3s ease-in-out infinite}
@keyframes prog{0%{width:20%;opacity:.6}50%{width:75%;opacity:1}100%{width:20%;opacity:.6}}
/* Stats */
.stats-sec{padding:0 24px 60px}
.stats-grid{display:grid;grid-template-columns:repeat(4,1fr);max-width:800px;margin:0 auto;gap:24px}
.stat{text-align:center;background:rgba(17,17,17,0.6);border:1px solid rgba(255,255,255,0.04);border-radius:12px;padding:24px 16px;transition:all .4s}
.stat:hover{border-color:rgba(217,92,65,0.2)}
.stat-n{display:block;font-size:36px;font-weight:800;color:#d95c41;line-height:1;margin-bottom:4px}
.stat-l{display:block;font-size:13px;color:#666;font-weight:500}
/* Section */
.sec{max-width:1280px;margin:0 auto;padding:80px 24px}
.sec-label{font-size:12px;font-weight:700;letter-spacing:.2em;text-transform:uppercase;color:#d95c41;text-align:center;margin-bottom:48px}
.sec-label{font-size:12px;font-weight:700;letter-spacing:.2em;text-transform:uppercase;color:#d95c41;text-align:center;margin-bottom:16px}
.sec-title{text-align:center;font-size:32px;font-weight:700;margin-bottom:48px;color:#f0f0f0}
/* Glass card */
.gc{background:rgba(17,17,17,0.85);backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,0.06);border-top:1px solid rgba(255,255,255,0.1);border-radius:12px;padding:28px 24px;transition:all .4s ease}
.gc:hover{border-color:rgba(217,92,65,0.3)}
.gc{background:rgba(17,17,17,0.85);backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,0.06);border-top:1px solid rgba(255,255,255,0.1);border-radius:12px;padding:28px 24px;transition:all .4s}
.gc:hover{border-color:rgba(217,92,65,0.3);transform:translateY(-2px)}
/* Scroll reveal animation */
.reveal{opacity:0;transform:translateY(24px);transition:opacity .6s ease,transform .6s ease}
.reveal.revealed{opacity:1;transform:translateY(0)}
.bi.reveal{opacity:0;transform:translateY(16px)}
.bi.reveal.revealed{opacity:1;transform:translateY(0)}
.feat-grid .gc.reveal{opacity:0;transform:translateY(16px)}
.feat-grid .gc.reveal.revealed{opacity:1;transform:translateY(0)}
.bi.reveal,.feat-grid .gc.reveal,.price-card.reveal,.test-card.reveal,.stat.reveal{opacity:0;transform:translateY(16px)}
.bi.reveal.revealed,.feat-grid .gc.reveal.revealed,.price-card.reveal.revealed,.test-card.reveal.revealed,.stat.reveal.revealed{opacity:1;transform:translateY(0)}
/* Feature grid */
.feat-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:rgba(255,255,255,0.03);border-radius:12px;overflow:hidden;border:1px solid rgba(255,255,255,0.06)}
@ -247,9 +325,9 @@ onMounted(() => {
/* Bento */
.bento{display:grid;grid-template-columns:repeat(12,1fr);gap:16px}
.bi{background:rgba(17,17,17,0.85);backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,0.06);border-top:1px solid rgba(255,255,255,0.1);border-radius:12px;padding:24px;position:relative;overflow:hidden;transition:all .3s}
.bi:hover{border-color:rgba(217,92,65,0.3)}
.bi.hl{border-color:rgba(217,92,65,0.2)}
.w8{grid-column:span 8}.w6{grid-column:span 6}.w4{grid-column:span 4}
.bi:hover{border-color:rgba(217,92,65,0.3);transform:translateY(-1px)}
.bi.hl{border-color:rgba(217,92,65,0.2);background:rgba(217,92,65,0.04)}
.w4{grid-column:span 4}.w6{grid-column:span 6}.w8{grid-column:span 8}.w12{grid-column:span 12}
.bi-n{position:absolute;top:12px;right:16px;font-size:40px;font-weight:800;opacity:0.06;color:#fff;user-select:none}
.bi-ic{width:36px;height:36px;border-radius:8px;background:rgba(217,92,65,0.12);display:flex;align-items:center;justify-content:center;margin-bottom:12px}
.bi-ic .material-symbols-outlined{color:#d95c41;font-size:20px}
@ -257,29 +335,54 @@ onMounted(() => {
.bi-d{font-size:13px;color:#888;line-height:1.5;margin-bottom:12px}
.bi-tags{display:flex;flex-wrap:wrap;gap:6px}
.bi-tags span{font-size:10px;font-weight:600;letter-spacing:.05em;padding:3px 8px;border-radius:4px;background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.06);color:#666}
.bi-bar{margin-top:16px;height:4px;background:rgba(255,255,255,0.06);border-radius:2px;overflow:hidden}
.bi-fill{height:100%;background:linear-gradient(90deg,#d95c41,#e87d2f);border-radius:2px}
/* Testimonials */
.test-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.test-card{background:rgba(17,17,17,0.85);backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,0.06);border-radius:12px;padding:24px;display:flex;flex-direction:column;justify-content:space-between}
.test-q{font-size:14px;line-height:1.6;color:#c0c0c0;font-style:italic;margin-bottom:20px}
.test-a{display:flex;align-items:center;gap:12px;padding-top:16px;border-top:1px solid rgba(255,255,255,0.04)}
.test-av{width:36px;height:36px;border-radius:50%;background:rgba(217,92,65,0.2);color:#d95c41;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:14px}
.test-n{font-size:13px;font-weight:600;color:#e8e8e8}
.test-r{font-size:11px;color:#666}
/* Pricing */
.pricing-sec{display:flex;justify-content:center}
.pc{max-width:420px;width:100%;text-align:center;padding:36px}
.pc:hover{box-shadow:0 0 30px rgba(217,92,65,0.08)}
.pu{list-style:none;text-align:left;margin-bottom:24px}
.pu li{display:flex;align-items:center;gap:10px;padding:12px 0;border-bottom:1px solid rgba(255,255,255,0.04);font-size:14px;color:#888}
.pu li:last-child{border-bottom:none}
.pg{font-size:11px;color:#555;margin-top:16px;letter-spacing:.05em;text-transform:uppercase}
.pricing-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;max-width:960px;margin:0 auto}
.price-card{background:rgba(17,17,17,0.85);backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,0.06);border-radius:12px;padding:32px 24px;text-align:center;transition:all .3s;display:flex;flex-direction:column}
.price-card:hover{border-color:rgba(217,92,65,0.2)}
.price-card.highlight{border-color:rgba(217,92,65,0.3);background:rgba(217,92,65,0.04);position:relative}
.price-card.highlight::before{content:'Most Popular';position:absolute;top:-12px;left:50%;transform:translateX(-50%);background:#d95c41;color:#fff;font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;padding:4px 16px;border-radius:999px}
.price-name{font-size:14px;font-weight:600;color:#888;margin-bottom:8px;text-transform:uppercase;letter-spacing:.1em}
.price-amt{font-size:48px;font-weight:800;color:#d95c41;line-height:1;margin-bottom:4px}
.price-dol{font-size:24px;vertical-align:super}
.price-note{font-size:12px;color:#555;margin-bottom:24px}
.price-feats{list-style:none;text-align:left;margin-bottom:28px;flex:1}
.price-feats li{display:flex;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid rgba(255,255,255,0.04);font-size:13px;color:#888}
.price-feats li:last-child{border-bottom:none}
.price-feats .material-symbols-outlined{font-size:18px;color:#d95c41;flex-shrink:0}
.price-card .btn-p{width:100%;text-align:center}
/* FAQ */
.faq-list{max-width:640px;margin:0 auto}
.faq-item{border-bottom:1px solid rgba(255,255,255,0.04);cursor:pointer;padding:0}
.faq-q{display:flex;align-items:center;justify-content:space-between;padding:20px 0;font-size:15px;color:#d0d0d0;font-weight:500}
.faq-icon{font-size:20px;color:#555;transition:transform .2s}
.faq-icon.open{transform:rotate(180deg)}
.faq-a{padding:0 0 20px;font-size:14px;line-height:1.7;color:#888}
/* Footer */
.ft{border-top:1px solid #1a1a1a;padding:32px 24px;text-align:center}
.ft{padding:48px 24px 80px;border-top:1px solid #1a1a1a}
.ft-inner{max-width:1280px;margin:0 auto}
.ft-l{font-size:18px;font-weight:800;color:#f0f0f0;margin-bottom:16px}
.ft-links{display:flex;justify-content:center;gap:24px;margin-bottom:16px}
.ft-links a{color:#555;text-decoration:none;font-size:13px;transition:color .2s}
.ft-links a:hover{color:#888}
.ft-c{font-size:12px;color:#444}
.ft-grid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:40px;margin-bottom:32px}
.ft-l{font-size:20px;font-weight:800;color:#f0f0f0;margin-bottom:8px}
.ft-desc{font-size:13px;color:#555;line-height:1.6;max-width:240px}
.ft-h{font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:#888;margin-bottom:16px}
.ft-col{display:flex;flex-direction:column;gap:10px}
.ft-col a{color:#555;text-decoration:none;font-size:13px;transition:color .2s}
.ft-col a:hover{color:#888}
.ft-c{text-align:center;font-size:12px;color:#444;padding-top:24px;border-top:1px solid #1a1a1a}
/* Bottom nav */
.bn{display:none;position:fixed;bottom:0;left:0;right:0;z-index:50;background:rgba(10,10,10,0.85);backdrop-filter:blur(16px);border-top:1px solid #1a1a1a;height:64px;padding:4px 16px 12px;justify-content:space-around;align-items:center}
.bn{display:none;position:fixed;bottom:0;left:0;right:0;z-index:50;background:rgba(10,10,10,0.92);backdrop-filter:blur(16px);border-top:1px solid #1a1a1a;height:64px;padding:4px 16px 12px;justify-content:space-around;align-items:center}
.bn-i{display:flex;flex-direction:column;align-items:center;gap:2px;text-decoration:none;color:#555;font-size:10px;font-weight:600;transition:color .2s}
.bn-i.active{color:#d95c41}.bn-i:hover{color:#888}
.bn-i .material-symbols-outlined{font-size:22px}
@ -289,14 +392,17 @@ onMounted(() => {
.hero-sec h1{font-size:32px}
.hero-sub{font-size:16px}
.feat-grid{grid-template-columns:1fr}
.w8,.w6,.w4{grid-column:span 12}
.test-grid{grid-template-columns:1fr}
.pricing-grid{grid-template-columns:1fr}
.stats-grid{grid-template-columns:repeat(2,1fr)}
.ft-grid{grid-template-columns:1fr 1fr;gap:24px}
.ft-brand{grid-column:span 2}
.w4,.w6,.w8,.w12{grid-column:span 12}
.bn{display:flex}
.landing{padding-bottom:64px}
.sec{padding:48px 16px}
}
@media(min-width:769px)and(max-width:1024px){
.w8{grid-column:span 12}
.w6{grid-column:span 6}
.w4{grid-column:span 6}
.w4{grid-column:span 6}.w6{grid-column:span 6}.w8{grid-column:span 12}.w12{grid-column:span 12}
}
</style>

View File

@ -262,35 +262,12 @@ body {
color: var(--vp-c-text-3) !important;
}
/* === CONTENT AREA — glass card wrap === */
.VPContent .container {
padding-top: 24px !important;
}
/* Main content card — applies to all VitePress doc pages */
.vp-doc {
background: rgba(17,17,17,0.85) !important;
backdrop-filter: blur(12px) !important;
border: 1px solid rgba(255,255,255,0.06) !important;
border-top: 1px solid rgba(255,255,255,0.1) !important;
border-radius: 12px !important;
padding: 40px !important;
margin: 0 !important;
}
/* Remove duplicate border from first h2 in content */
.vp-doc h2:first-of-type {
border-top: none !important;
padding-top: 0 !important;
margin-top: 0 !important;
}
/* === RESPONSIVE === */
@media (max-width: 768px) {
.vp-doc { padding: 24px 16px; }
.vp-doc h1 { font-size: 1.75rem !important; }
.vp-doc h2 { font-size: 1.125rem !important; }
.v-p-doc div[class*='language-'] { margin: 16px 0; }
.vp-doc div[class*='language-'] { margin: 16px 0; }
}
/* Print */