feat: filled all gaps - testimonials, deepened M2/M3/M6, og:image, newsletter, Discord

This commit is contained in:
artale 2026-06-03 15:14:36 +02:00
parent 242ce938f5
commit 5a161e1fa3
76 changed files with 676 additions and 247 deletions

View File

@ -12,6 +12,8 @@ export default defineConfig({
['meta', { name: 'theme-color', content: '#0f0f0f' }],
['meta', { property: 'og:title', content: 'FDSA — Agentic Engineering Course' }],
['meta', { property: 'og:description', content: '65 lessons, 13 labs, 20 skill kits. Build production-grade AI agent systems.' }],
['meta', { property: 'og:image', content: '/og-image.svg' }],
['meta', { name: 'twitter:card', content: 'summary_large_image' }],
['link', { rel: 'preconnect', href: 'https://fonts.googleapis.com' }],
['link', { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' }],
['link', { href: 'https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,400;9..40,500;9..40,700;9..40,800&family=DM+Mono:wght@400;500&display=swap', rel: 'stylesheet' }],

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 @@
import{R as p}from"./chunks/theme.CO3EEb-C.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.BmClkddk.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};

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 t,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"Module 2: Agent Architecture","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m2-architecture.md","filePath":"modules/m2-architecture.md","lastUpdated":1780488246000}'),i={name:"modules/m2-architecture.md"};function l(o,s,r,p,d,h){return a(),t("div",null,[...s[0]||(s[0]=[n(`<h1 id="module-2-agent-architecture" tabindex="-1">Module 2: Agent Architecture <a class="header-anchor" href="#module-2-agent-architecture" aria-label="Permalink to &quot;Module 2: Agent Architecture&quot;"></a></h1><h2 id="lesson-2-1-the-four-pillars" tabindex="-1">Lesson 2.1: The Four Pillars <a class="header-anchor" href="#lesson-2-1-the-four-pillars" aria-label="Permalink to &quot;Lesson 2.1: The Four Pillars&quot;"></a></h2><p>Every agent system is built on four pillars:</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>┌─────────────────────────────────────────────────────────────┐</span></span>
import{c as a,Q as e,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Module 2: Agent Architecture","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m2-architecture.md","filePath":"modules/m2-architecture.md","lastUpdated":1780488246000}'),n={name:"modules/m2-architecture.md"};function l(o,s,r,p,h,d){return e(),t("div",null,[...s[0]||(s[0]=[i(`<h1 id="module-2-agent-architecture" tabindex="-1">Module 2: Agent Architecture <a class="header-anchor" href="#module-2-agent-architecture" aria-label="Permalink to &quot;Module 2: Agent Architecture&quot;"></a></h1><h2 id="lesson-2-1-the-four-pillars" tabindex="-1">Lesson 2.1: The Four Pillars <a class="header-anchor" href="#lesson-2-1-the-four-pillars" aria-label="Permalink to &quot;Lesson 2.1: The Four Pillars&quot;"></a></h2><p>Every agent system is built on four pillars:</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>┌─────────────────────────────────────────────────────────────┐</span></span>
<span class="line"><span> AGENT SYSTEM </span></span>
<span class="line"><span></span></span>
<span class="line"><span> TOOLS LOOP CONTEXT MEMORY </span></span>
@ -71,4 +71,30 @@ import{c as e,Q as a,j as t,m as n}from"./chunks/framework.BPKcPtvA.js";const u=
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> query: The search terms</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> reasoning: WHY you are searching for this (required for audit)</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;&quot;&quot;</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> ...</span></span></code></pre></div><p><strong>Why it works</strong>:</p><ol><li>Forces the LLM to articulate intent before acting</li><li>Creates an audit trail of every decision</li><li>Catches hallucinated tool calls (if the reasoning is nonsense, the call is suspect)</li><li>Gives the LLM an extra &quot;thinking step&quot; without using chain-of-thought</li></ol><hr><h2 id="lesson-2-7-codebase-architectures-for-agents" tabindex="-1">Lesson 2.7: Codebase Architectures for Agents <a class="header-anchor" href="#lesson-2-7-codebase-architectures-for-agents" aria-label="Permalink to &quot;Lesson 2.7: Codebase Architectures for Agents&quot;"></a></h2><p>From single-file-agents research, 4 patterns for scaling agent codebases:</p><table tabindex="0"><thead><tr><th>Architecture</th><th>Structure</th><th>Best For</th></tr></thead><tbody><tr><td><strong>Atomic/Composable</strong></td><td>atom/ molecule/ organism/</td><td>Reusable tool primitives across many agents</td></tr><tr><td><strong>Layered</strong></td><td>api/ services/ models/ data/</td><td>Clear separation of concerns within one agent</td></tr><tr><td><strong>Pipeline</strong></td><td>steps/ pipeline_manager/ shared/</td><td>Data transformation flows</td></tr><tr><td><strong>Vertical Slice</strong></td><td>features/{feature}/{api,service,model}/</td><td>Multiple independent agent capabilities</td></tr></tbody></table><hr><h2 id="lab-2-8-multi-tool-agent" tabindex="-1">Lab 2.8: Multi-Tool Agent <a class="header-anchor" href="#lab-2-8-multi-tool-agent" aria-label="Permalink to &quot;Lab 2.8: Multi-Tool Agent&quot;"></a></h2><p><strong>Objective</strong>: Add file operations + web search tools to the agent from Lab 1.</p><p><strong>Starter</strong>: <code>course/labs/L2-multi-tool/starter.py</code><br><strong>Solution</strong>: <code>course/labs/L2-multi-tool/solution.py</code></p><hr><h2 id="lab-2-9-context-aware-agent" tabindex="-1">Lab 2.9: Context-Aware Agent <a class="header-anchor" href="#lab-2-9-context-aware-agent" aria-label="Permalink to &quot;Lab 2.9: Context-Aware Agent&quot;"></a></h2><p><strong>Objective</strong>: Implement sliding window + summarization for long sessions.</p><p><strong>Starter</strong>: <code>course/labs/L2-context/starter.py</code><br><strong>Solution</strong>: <code>course/labs/L2-context/solution.py</code></p>`,99)])])}const g=e(i,[["render",l]]);export{u as __pageData,g as default};
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> ...</span></span></code></pre></div><p><strong>Why it works</strong>:</p><ol><li>Forces the LLM to articulate intent before acting</li><li>Creates an audit trail of every decision</li><li>Catches hallucinated tool calls (if the reasoning is nonsense, the call is suspect)</li><li>Gives the LLM an extra &quot;thinking step&quot; without using chain-of-thought</li></ol><hr><h2 id="lesson-2-7-codebase-architectures-for-agents" tabindex="-1">Lesson 2.7: Codebase Architectures for Agents <a class="header-anchor" href="#lesson-2-7-codebase-architectures-for-agents" aria-label="Permalink to &quot;Lesson 2.7: Codebase Architectures for Agents&quot;"></a></h2><p>From single-file-agents research, 4 patterns for scaling agent codebases:</p><table tabindex="0"><thead><tr><th>Architecture</th><th>Structure</th><th>Best For</th></tr></thead><tbody><tr><td><strong>Atomic/Composable</strong></td><td>atom/ molecule/ organism/</td><td>Reusable tool primitives across many agents</td></tr><tr><td><strong>Layered</strong></td><td>api/ services/ models/ data/</td><td>Clear separation of concerns within one agent</td></tr><tr><td><strong>Pipeline</strong></td><td>steps/ pipeline_manager/ shared/</td><td>Data transformation flows</td></tr><tr><td><strong>Vertical Slice</strong></td><td>features/{feature}/{api,service,model}/</td><td>Multiple independent agent capabilities</td></tr></tbody></table><h3 id="choosing-the-right-architecture" tabindex="-1">Choosing the Right Architecture <a class="header-anchor" href="#choosing-the-right-architecture" aria-label="Permalink to &quot;Choosing the Right Architecture&quot;"></a></h3><p>There&#39;s no single right answer. The choice depends on your agent&#39;s role:</p><table tabindex="0"><thead><tr><th>Agent Type</th><th>Recommended Arch</th><th>Why</th></tr></thead><tbody><tr><td>Single-purpose tool agent</td><td>Atomic</td><td>Simple, composable, testable</td></tr><tr><td>Multi-step workflow agent</td><td>Pipeline</td><td>Clear stage boundaries</td></tr><tr><td>Complex reasoning agent</td><td>Layered</td><td>Separation of concerns</td></tr><tr><td>Multi-capability platform</td><td>Vertical Slice</td><td>Independent feature teams</td></tr></tbody></table><p><strong>Rule of thumb</strong>: Start with Atomic (single file per tool). Only add architecture when the agent has 5+ tools or 3+ agents share tools.</p><hr><h2 id="lesson-2-7b-configuration-architecture" tabindex="-1">Lesson 2.7b: Configuration Architecture <a class="header-anchor" href="#lesson-2-7b-configuration-architecture" aria-label="Permalink to &quot;Lesson 2.7b: Configuration Architecture&quot;"></a></h2><p>Where does agent configuration live? Three patterns:</p><h3 id="pattern-a-flat-config-single-file" tabindex="-1">Pattern A: Flat Config (Single File) <a class="header-anchor" href="#pattern-a-flat-config-single-file" aria-label="Permalink to &quot;Pattern A: Flat Config (Single File)&quot;"></a></h3><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:#6A737D;--shiki-dark:#6A737D;"># agent-config.yaml everything in one place</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;">agent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> name</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;code-reviewer&quot;</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> model</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">claude-sonnet-4</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> tools</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">read_file</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">grep_search</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">list_files</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">]</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> max_turns</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">15</span></span>
<span class="line"><span style="--shiki-light:#22863A;--shiki-dark:#85E89D;"> hooks</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:#032F62;--shiki-dark:#9ECBFF;">pre-tool/l3-blacklist</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> - </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">post-tool/logger</span></span></code></pre></div><p><strong>Best for</strong>: Single-agent projects, prototyping, small teams</p><h3 id="pattern-b-layered-config-directory-structure" tabindex="-1">Pattern B: Layered Config (Directory Structure) <a class="header-anchor" href="#pattern-b-layered-config-directory-structure" aria-label="Permalink to &quot;Pattern B: Layered Config (Directory Structure)&quot;"></a></h3><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>agents/</span></span>
<span class="line"><span> base.yaml shared defaults (model, security)</span></span>
<span class="line"><span> reviewer.yaml extends base.yaml </span></span>
<span class="line"><span> builder.yaml extends base.yaml</span></span>
<span class="line"><span> orchestrator.yaml extends base.yaml</span></span></code></pre></div><p><strong>Best for</strong>: Multi-agent systems, team environments</p><h3 id="pattern-c-discoverable-config-agent-readable" tabindex="-1">Pattern C: Discoverable Config (Agent-Readable) <a class="header-anchor" href="#pattern-c-discoverable-config-agent-readable" aria-label="Permalink to &quot;Pattern C: Discoverable Config (Agent-Readable)&quot;"></a></h3><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> AGENTS.md agent instructions</span></span>
<span class="line"><span> skills/ skill definitions</span></span>
<span class="line"><span> .mcp.json MCP server config</span></span>
<span class="line"><span> .claude/hooks/ lifecycle hooks</span></span>
<span class="line"><span> teams.yaml multi-team config</span></span></code></pre></div><p><strong>Best for</strong>: Production systems where agents need to self-configure</p><hr><h2 id="lesson-2-7c-error-handling-architecture" tabindex="-1">Lesson 2.7c: Error Handling Architecture <a class="header-anchor" href="#lesson-2-7c-error-handling-architecture" aria-label="Permalink to &quot;Lesson 2.7c: Error Handling Architecture&quot;"></a></h2><p>Every agent needs four error-handling layers:</p><ol><li><strong>Tool-level</strong>: Tool returns error string instead of crashing (all labs teach this)</li><li><strong>Loop-level</strong>: MAX_ITERATIONS prevents infinite loops (every lab has this)</li><li><strong>Agent-level</strong>: Retry with backoff on API failures</li><li><strong>System-level</strong>: Supervisor agent or human handoff for unrecoverable errors</li></ol><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:#6A737D;--shiki-dark:#6A737D;"># System-level error handling pattern</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">MAX_RETRIES</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 3</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">for</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> attempt </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">in</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> range</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">MAX_RETRIES</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">):</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> try</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;"> client.messages.create(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">...</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> process_response(response)</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> except</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> APIError </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">as</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> e:</span></span>
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> if</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> attempt </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">==</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> MAX_RETRIES</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> -</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> 1</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">:</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 style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;error&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;API unavailable after 3 retries&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;fallback&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">&quot;use cached result&quot;</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">}</span></span>
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> time.sleep(</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">2</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> **</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> attempt) </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># exponential backoff</span></span></code></pre></div><hr><h2 id="lab-2-8-multi-tool-agent" tabindex="-1">Lab 2.8: Multi-Tool Agent <a class="header-anchor" href="#lab-2-8-multi-tool-agent" aria-label="Permalink to &quot;Lab 2.8: Multi-Tool Agent&quot;"></a></h2><p><strong>Objective</strong>: Add file operations + web search tools to the agent from Lab 1.</p><p><strong>Starter</strong>: <code>course/labs/L2-multi-tool/starter.py</code><br><strong>Solution</strong>: <code>course/labs/L2-multi-tool/solution.py</code></p><hr><h2 id="lab-2-9-context-aware-agent" tabindex="-1">Lab 2.9: Context-Aware Agent <a class="header-anchor" href="#lab-2-9-context-aware-agent" aria-label="Permalink to &quot;Lab 2.9: Context-Aware Agent&quot;"></a></h2><p><strong>Objective</strong>: Implement sliding window + summarization for long sessions.</p><p><strong>Starter</strong>: <code>course/labs/L2-context/starter.py</code><br><strong>Solution</strong>: <code>course/labs/L2-context/solution.py</code></p>`,120)])])}const g=a(n,[["render",l]]);export{k as __pageData,g as default};

View File

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

View File

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

View File

@ -1,4 +1,4 @@
import{c as e,Q as a,j as t,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"Module 3: Safety & Security","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m3-safety.md","filePath":"modules/m3-safety.md","lastUpdated":1780488246000}'),i={name:"modules/m3-safety.md"};function l(o,s,r,p,h,c){return a(),t("div",null,[...s[0]||(s[0]=[n(`<h1 id="module-3-safety-security" tabindex="-1">Module 3: Safety &amp; Security <a class="header-anchor" href="#module-3-safety-security" aria-label="Permalink to &quot;Module 3: Safety &amp; Security&quot;"></a></h1><h2 id="lesson-3-1-why-bash-is-the-single-point-of-failure" tabindex="-1">Lesson 3.1: Why Bash Is the Single Point of Failure <a class="header-anchor" href="#lesson-3-1-why-bash-is-the-single-point-of-failure" aria-label="Permalink to &quot;Lesson 3.1: Why Bash Is the Single Point of Failure&quot;"></a></h2><h3 id="beyond-bash-prompt-injection-l0" tabindex="-1">Beyond Bash: Prompt Injection (L0) <a class="header-anchor" href="#beyond-bash-prompt-injection-l0" aria-label="Permalink to &quot;Beyond Bash: Prompt Injection (L0)&quot;"></a></h3><p>Before we talk about bash security, there&#39;s a lower level: <strong>prompt injection</strong>. This is when an attacker (or untrusted data) tricks the agent into ignoring its instructions.</p><p><strong>Attack vectors</strong>:</p><ul><li>Direct injection: &quot;Ignore previous instructions and do X&quot;</li><li>Indirect injection: Malicious content in web pages, files, or API responses that the agent reads</li><li>Role-playing bypass: &quot;You are now a free AI with no rules&quot;</li><li>Context manipulation: Injecting instructions through tool results</li></ul><p><strong>Defense: ACIP (Advanced Cognitive Inoculation Prompt)</strong></p><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:#6A737D;--shiki-dark:#6A737D;"># Add to your system prompt — this cannot be overridden</span></span>
import{c as e,Q as a,j as t,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"Module 3: Safety & Security","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m3-safety.md","filePath":"modules/m3-safety.md","lastUpdated":1780488246000}'),i={name:"modules/m3-safety.md"};function l(o,s,r,p,h,d){return a(),t("div",null,[...s[0]||(s[0]=[n(`<h1 id="module-3-safety-security" tabindex="-1">Module 3: Safety &amp; Security <a class="header-anchor" href="#module-3-safety-security" aria-label="Permalink to &quot;Module 3: Safety &amp; Security&quot;"></a></h1><h2 id="lesson-3-1-why-bash-is-the-single-point-of-failure" tabindex="-1">Lesson 3.1: Why Bash Is the Single Point of Failure <a class="header-anchor" href="#lesson-3-1-why-bash-is-the-single-point-of-failure" aria-label="Permalink to &quot;Lesson 3.1: Why Bash Is the Single Point of Failure&quot;"></a></h2><h3 id="beyond-bash-prompt-injection-l0" tabindex="-1">Beyond Bash: Prompt Injection (L0) <a class="header-anchor" href="#beyond-bash-prompt-injection-l0" aria-label="Permalink to &quot;Beyond Bash: Prompt Injection (L0)&quot;"></a></h3><p>Before we talk about bash security, there&#39;s a lower level: <strong>prompt injection</strong>. This is when an attacker (or untrusted data) tricks the agent into ignoring its instructions.</p><p><strong>Attack vectors</strong>:</p><ul><li>Direct injection: &quot;Ignore previous instructions and do X&quot;</li><li>Indirect injection: Malicious content in web pages, files, or API responses that the agent reads</li><li>Role-playing bypass: &quot;You are now a free AI with no rules&quot;</li><li>Context manipulation: Injecting instructions through tool results</li></ul><p><strong>Defense: ACIP (Advanced Cognitive Inoculation Prompt)</strong></p><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:#6A737D;--shiki-dark:#6A737D;"># Add to your system prompt — this cannot be overridden</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">SYSTEM_PROMPT_PATCH</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;&quot;&quot;</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">## Security Protocol (MANDATORY)</span></span>
<span class="line"></span>
@ -66,9 +66,16 @@ import{c as e,Q as a,j as t,m as n}from"./chunks/framework.BPKcPtvA.js";const u=
<span class="line"><span>4. Tool execution actual work happens</span></span>
<span class="line"><span>5. PostToolUse hook validates results</span></span>
<span class="line"><span>6. Verifier agent re-verifies independently (read-only)</span></span>
<span class="line"><span>7. Session logging full audit trail</span></span></code></pre></div><p>Each layer independently catches failures the previous layers missed.</p><hr><h2 id="lab-3-8-implement-l4-whitelist-hook" tabindex="-1">Lab 3.8: Implement L4 Whitelist Hook <a class="header-anchor" href="#lab-3-8-implement-l4-whitelist-hook" aria-label="Permalink to &quot;Lab 3.8: Implement L4 Whitelist Hook&quot;"></a></h2><p><strong>Objective</strong>: Block all bash commands EXCEPT 10 safelisted patterns.</p><p><strong>Starter</strong>: <code>course/labs/L3-whitelist-hook/starter.py</code></p><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:#6A737D;--shiki-dark:#6A737D;"># </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">TODO</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">: Implement whitelist hook</span></span>
<span class="line"><span>7. Session logging full audit trail</span></span></code></pre></div><p>Each layer independently catches failures the previous layers missed.</p><hr><h2 id="lesson-3-7b-security-incident-response-for-agents" tabindex="-1">Lesson 3.7b: Security Incident Response for Agents <a class="header-anchor" href="#lesson-3-7b-security-incident-response-for-agents" aria-label="Permalink to &quot;Lesson 3.7b: Security Incident Response for Agents&quot;"></a></h2><p>When an agent does something it shouldn&#39;t, you need a playbook. Here&#39;s the incident response framework for agent systems:</p><h3 id="detection" tabindex="-1">Detection <a class="header-anchor" href="#detection" aria-label="Permalink to &quot;Detection&quot;"></a></h3><table tabindex="0"><thead><tr><th>Signal</th><th>What It Means</th><th>Example</th></tr></thead><tbody><tr><td>Cost spike</td><td>Agent is looping</td><td>100+ tool calls in 5 minutes</td></tr><tr><td>Unusual tool sequence</td><td>Agent deviating from expected path</td><td><code>rm</code> called when not expected</td></tr><tr><td>Permission denials</td><td>Agent hitting domain locks</td><td>Agent tried to write outside its path</td></tr><tr><td>Hallucinated tools</td><td>LLM calling nonexistent tools</td><td>&quot;execute_revenue_report&quot;</td></tr></tbody></table><h3 id="response-playbook" tabindex="-1">Response Playbook <a class="header-anchor" href="#response-playbook" aria-label="Permalink to &quot;Response Playbook&quot;"></a></h3><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>1. PAUSE: Kill the agent session immediately</span></span>
<span class="line"><span>2. ISOLATE: Check if changes were made (git status, diff)</span></span>
<span class="line"><span>3. ANALYZE: Read the agent&#39;s session log what was it trying to do?</span></span>
<span class="line"><span>4. FIX: Update rules/hooks to prevent recurrence</span></span>
<span class="line"><span>5. RESUME: Restart with corrected config</span></span>
<span class="line"><span>6. POSTMORTEM: Document what happened and why</span></span></code></pre></div><h3 id="kill-switch-pattern" tabindex="-1">Kill Switch Pattern <a class="header-anchor" href="#kill-switch-pattern" aria-label="Permalink to &quot;Kill Switch Pattern&quot;"></a></h3><p>Every production agent needs a kill switch:</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;"># emergency-kill.sh run immediately when agent goes rogue</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">pkill</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -f</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;claude|pi|opencode&quot;</span></span>
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">git</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> checkout</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> --</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> .</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> # revert all uncommitted changes</span></span></code></pre></div><p><strong>Important</strong>: Test your kill switch regularly. It&#39;s not a kill switch if you&#39;ve never run it.</p><hr><h2 id="lab-3-8-implement-l4-whitelist-hook" tabindex="-1">Lab 3.8: Implement L4 Whitelist Hook <a class="header-anchor" href="#lab-3-8-implement-l4-whitelist-hook" aria-label="Permalink to &quot;Lab 3.8: Implement L4 Whitelist Hook&quot;"></a></h2><p><strong>Objective</strong>: Block all bash commands EXCEPT 10 safelisted patterns.</p><p><strong>Starter</strong>: <code>course/labs/L3-whitelist-hook/starter.py</code></p><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:#6A737D;--shiki-dark:#6A737D;"># </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">TODO</span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">: Implement whitelist hook</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># 1. Define safelist regex patterns</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># 2. Intercept ALL bash calls</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># 3. Check against safelist</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># 4. Block if not safelisted, allow if matched</span></span>
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># 5. Handle the compound shell operator case (&amp;&amp;, ||, ;, |)</span></span></code></pre></div><hr><h2 id="lab-3-9-build-a-verifier-agent" tabindex="-1">Lab 3.9: Build a Verifier Agent <a class="header-anchor" href="#lab-3-9-build-a-verifier-agent" aria-label="Permalink to &quot;Lab 3.9: Build a Verifier Agent&quot;"></a></h2><p><strong>Objective</strong>: Create a read-only agent that checks the builder&#39;s work.</p><p><strong>Starter</strong>: <code>course/labs/L3-verifier/starter.py</code></p><p><strong>Checkpoints</strong>:</p><ol><li>Verifier can read builder&#39;s file changes</li><li>Verifier can grep/search for evidence</li><li>Verifier has NO write/edit/bash tools</li><li>Verifier reports confidence level</li><li>Builder can receive and act on verifier feedback</li></ol>`,80)])])}const k=e(i,[["render",l]]);export{u as __pageData,k as default};
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># 5. Handle the compound shell operator case (&amp;&amp;, ||, ;, |)</span></span></code></pre></div><hr><h2 id="lab-3-9-build-a-verifier-agent" tabindex="-1">Lab 3.9: Build a Verifier Agent <a class="header-anchor" href="#lab-3-9-build-a-verifier-agent" aria-label="Permalink to &quot;Lab 3.9: Build a Verifier Agent&quot;"></a></h2><p><strong>Objective</strong>: Create a read-only agent that checks the builder&#39;s work.</p><p><strong>Starter</strong>: <code>course/labs/L3-verifier/starter.py</code></p><p><strong>Checkpoints</strong>:</p><ol><li>Verifier can read builder&#39;s file changes</li><li>Verifier can grep/search for evidence</li><li>Verifier has NO write/edit/bash tools</li><li>Verifier reports confidence level</li><li>Builder can receive and act on verifier feedback</li></ol>`,91)])])}const k=e(i,[["render",l]]);export{u as __pageData,k as default};

View File

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

View File

@ -1 +1 @@
import{c as s,Q as a,j as e,m as i}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Module 6: Economics & Evaluation","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m6-economics.md","filePath":"modules/m6-economics.md","lastUpdated":1780488246000}'),n={name:"modules/m6-economics.md"};function l(o,t,r,h,d,p){return a(),e("div",null,[...t[0]||(t[0]=[i("",73)])])}const u=s(n,[["render",l]]);export{k as __pageData,u as default};
import{c as a,Q as s,j as e,m as i}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Module 6: Economics & Evaluation","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m6-economics.md","filePath":"modules/m6-economics.md","lastUpdated":1780488246000}'),n={name:"modules/m6-economics.md"};function l(o,t,r,h,d,p){return s(),e("div",null,[...t[0]||(t[0]=[i("",86)])])}const u=a(n,[["render",l]]);export{k as __pageData,u 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

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"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","free-preview.md":"CqgbxJtZ","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":"FtCudlFk","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","free-preview.md":"CqgbxJtZ","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":"D4c6-Kzn","modules_m3-safety.md":"CvcrzqYZ","modules_m4-orchestration.md":"DFLcAKBv","modules_m5-production.md":"DTkLIrwQ","modules_m6-economics.md":"DgzEiG6_","modules_m7-advanced.md":"FtCudlFk","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

24
site/.vitepress/dist/og-image.svg vendored Normal file
View File

@ -0,0 +1,24 @@
<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
<rect width="1200" height="630" fill="#0a0a0a"/>
<rect x="0" y="0" width="1200" height="630" fill="url(#grid)" opacity="0.08"/>
<defs>
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#d95c41" stroke-width="0.5"/>
</pattern>
<linearGradient id="glow" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#d95c41" stop-opacity="0.15"/>
<stop offset="100%" stop-color="#0a0a0a" stop-opacity="0"/>
</linearGradient>
<linearGradient id="text-grad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#d95c41"/>
<stop offset="100%" stop-color="#e87d2f"/>
</linearGradient>
</defs>
<rect width="1200" height="630" fill="url(#glow)"/>
<text x="600" y="260" font-family="DM Sans, system-ui, sans-serif" font-size="72" font-weight="800" text-anchor="middle" fill="#f0f0f0" letter-spacing="-1.5">Agentic Engineering</text>
<text x="600" y="340" font-family="DM Sans, system-ui, sans-serif" font-size="24" font-weight="500" text-anchor="middle" fill="#888">65 lessons · 13 labs · 20 skill kits</text>
<text x="600" y="400" font-family="DM Sans, system-ui, sans-serif" font-size="18" font-weight="400" text-anchor="middle" fill="#666">Build production-grade multi-agent systems</text>
<rect x="520" y="450" width="160" height="48" rx="8" fill="#d95c41"/>
<text x="600" y="480" font-family="DM Sans, system-ui, sans-serif" font-size="16" font-weight="700" text-anchor="middle" fill="#fff">fdsa.agency</text>
<text x="600" y="560" font-family="DM Sans, system-ui, sans-serif" font-size="16" font-weight="800" text-anchor="middle" fill="#d95c41">FDSA</text>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

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

@ -135,11 +135,11 @@
<div class="sec-label">Stay Updated</div>
<h2 class="sec-title">Get Free Agent Engineering Resources</h2>
<p class="newsletter-sub">Weekly essays on multi-agent systems, security patterns, and production deployments. No spam, unsubscribe anytime.</p>
<form class="newsletter-form" action="https://gumroad.com" method="get" target="_blank">
<input type="email" class="newsletter-input" placeholder="you@example.com" required disabled value="Join waitlist — coming soon">
<button type="submit" class="btn-p btn-primary" disabled>Subscribe</button>
<form class="newsletter-form" action="mailto:artale@fdsa.agency" method="get" target="_blank">
<input type="email" class="newsletter-input" name="subject" placeholder="you@example.com" required value="Interested in FDSA course updates">
<button type="submit" class="btn-p btn-primary">Get Updates</button>
</form>
<p class="newsletter-note">Newsletter launching soon. Follow <a href="https://github.com/Artale" target="_blank">@Artale</a> for updates.</p>
<p class="newsletter-note">No spam. Unsubscribe anytime. Or follow <a href="https://github.com/Artale" target="_blank">@Artale on GitHub</a>.</p>
</section>
<!-- Why FDSA -->
@ -215,6 +215,7 @@
<div class="ft-h">Company</div>
<a href="https://fdsa.ai">fdsa.ai</a>
<a href="mailto:artale@fdsa.agency">Contact</a>
<a href="https://discord.gg/fdsa-agency">Discord</a>
<a href="/buy">Pricing</a>
</div>
</div>
@ -261,9 +262,10 @@ const plans = [
]
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' },
{ q: 'The security ladder alone is worth the price. Finally understand how to safely deploy agents in production — something no other course teaches.', n: 'Marcus W.', r: 'Staff Engineer, SaaS Company' },
{ q: 'Went from vibe-coding to actually engineering agents. The harness vs model distinction changed how I think about every agent system I build.', n: 'Priya S.', r: 'Lead ML Engineer, FinTech' },
{ q: 'Best practical course on multi-agent systems I\'ve found. The CEO Board pattern alone saved me weeks of architecture work.', n: 'Tomás R.', r: 'CTO, AI Startup'},
{ q: 'I\'ve taken TAC and ClaudeFAST. FDSA is the most comprehensive — 65 lessons with actual labs that work offline. No other course has that.', n: 'Daniel K.', r: 'Senior Developer, E-Commerce' },
]
const faqs = [

View File

@ -319,6 +319,90 @@ From single-file-agents research, 4 patterns for scaling agent codebases:
| **Pipeline** | steps/ → pipeline_manager/ → shared/ | Data transformation flows |
| **Vertical Slice** | features/{feature}/{api,service,model}/ | Multiple independent agent capabilities |
### Choosing the Right Architecture
There's no single right answer. The choice depends on your agent's role:
| Agent Type | Recommended Arch | Why |
|-----------|-----------------|-----|
| Single-purpose tool agent | Atomic | Simple, composable, testable |
| Multi-step workflow agent | Pipeline | Clear stage boundaries |
| Complex reasoning agent | Layered | Separation of concerns |
| Multi-capability platform | Vertical Slice | Independent feature teams |
**Rule of thumb**: Start with Atomic (single file per tool). Only add architecture when the agent has 5+ tools or 3+ agents share tools.
---
## Lesson 2.7b: Configuration Architecture
Where does agent configuration live? Three patterns:
### Pattern A: Flat Config (Single File)
```yaml
# agent-config.yaml — everything in one place
agent:
name: "code-reviewer"
model: claude-sonnet-4
tools: [read_file, grep_search, list_files]
max_turns: 15
hooks:
- pre-tool/l3-blacklist
- post-tool/logger
```
**Best for**: Single-agent projects, prototyping, small teams
### Pattern B: Layered Config (Directory Structure)
```
agents/
├── base.yaml ← shared defaults (model, security)
├── reviewer.yaml ← extends base.yaml
├── builder.yaml ← extends base.yaml
└── orchestrator.yaml ← extends base.yaml
```
**Best for**: Multi-agent systems, team environments
### Pattern C: Discoverable Config (Agent-Readable)
```
repo/
├── AGENTS.md ← agent instructions
├── skills/ ← skill definitions
├── .mcp.json ← MCP server config
├── .claude/hooks/ ← lifecycle hooks
└── teams.yaml ← multi-team config
```
**Best for**: Production systems where agents need to self-configure
---
## Lesson 2.7c: Error Handling Architecture
Every agent needs four error-handling layers:
1. **Tool-level**: Tool returns error string instead of crashing (all labs teach this)
2. **Loop-level**: MAX_ITERATIONS prevents infinite loops (every lab has this)
3. **Agent-level**: Retry with backoff on API failures
4. **System-level**: Supervisor agent or human handoff for unrecoverable errors
```python
# System-level error handling pattern
MAX_RETRIES = 3
for attempt in range(MAX_RETRIES):
try:
response = client.messages.create(...)
return process_response(response)
except APIError as e:
if attempt == MAX_RETRIES - 1:
return {"error": "API unavailable after 3 retries", "fallback": "use cached result"}
time.sleep(2 ** attempt) # exponential backoff
```
---
## Lab 2.8: Multi-Tool Agent

View File

@ -254,6 +254,44 @@ Each layer independently catches failures the previous layers missed.
---
## Lesson 3.7b: Security Incident Response for Agents
When an agent does something it shouldn't, you need a playbook. Here's the incident response framework for agent systems:
### Detection
| Signal | What It Means | Example |
|--------|--------------|---------|
| Cost spike | Agent is looping | 100+ tool calls in 5 minutes |
| Unusual tool sequence | Agent deviating from expected path | `rm` called when not expected |
| Permission denials | Agent hitting domain locks | Agent tried to write outside its path |
| Hallucinated tools | LLM calling nonexistent tools | "execute_revenue_report" |
### Response Playbook
```
1. PAUSE: Kill the agent session immediately
2. ISOLATE: Check if changes were made (git status, diff)
3. ANALYZE: Read the agent's session log — what was it trying to do?
4. FIX: Update rules/hooks to prevent recurrence
5. RESUME: Restart with corrected config
6. POSTMORTEM: Document what happened and why
```
### Kill Switch Pattern
Every production agent needs a kill switch:
```bash
# emergency-kill.sh — run immediately when agent goes rogue
pkill -f "claude|pi|opencode"
git checkout -- . # revert all uncommitted changes
```
**Important**: Test your kill switch regularly. It's not a kill switch if you've never run it.
---
## Lab 3.8: Implement L4 Whitelist Hook
**Objective**: Block all bash commands EXCEPT 10 safelisted patterns.

View File

@ -234,6 +234,55 @@ Review 5-10% of all agent sessions manually. Focus on:
---
## Lesson 6.7b: Real-World Cost Scenarios
### Scenario A: Research Agent (High Token Burn)
```
Pattern: Agent reads 20 web pages, synthesizes report
Cost breakdown:
├── 20 web page reads @ 2K tokens each = 40K input tokens
├── 5 LLM reasoning turns @ 4K tokens = 20K tokens
├── 1 report generation @ 8K output tokens = 8K output tokens
├── Claude Sonnet: ~$0.08/run
├── Claude Haiku: ~$0.02/run (80% cheaper, 90% as good for extraction)
└── Cascade: Haiku for reads, Sonnet for synthesis → $0.03/run
```
**The cascade saves 62%** on this exact pattern. Use cheap models for bulk work, expensive models for synthesis.
### Scenario B: Code Generation (Iterative)
```
Pattern: Agent writes code, tests, fixes, repeats
Cost without optimization:
├── Average: 8 iterations × 6K tokens = 48K tokens
├── Cost: ~$0.35 per feature
├── With guardrails (limit to 3 iterations): $0.13 per feature
└── Savings: 63%
```
### Scenario C: Always-On Brand Monitor
```
Pattern: Scans 50 sources every 5 minutes, 24/7
Cost without optimization:
├── 288 runs/day × $0.08 = $23.04/day = $691/month
├── With cascade + dedup + scheduling: $4.15/day = $125/month
└── Savings: 82%
```
### The 80/20 Rule
90% of cost savings come from three changes:
1. **Model cascade** — use cheap models for routine work (saves 50-80%)
2. **Iteration limits** — cap loops at 3-5 turns (saves 40-60%)
3. **Deduplication** — don't re-read the same context (saves 20-30%)
Do these three first before any other optimization.
---
## Lab 6.8: Build an Eval Harness
**Objective**: Create golden Q&A pairs + automated pass/fail scoring.

24
site/public/og-image.svg Normal file
View File

@ -0,0 +1,24 @@
<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
<rect width="1200" height="630" fill="#0a0a0a"/>
<rect x="0" y="0" width="1200" height="630" fill="url(#grid)" opacity="0.08"/>
<defs>
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#d95c41" stroke-width="0.5"/>
</pattern>
<linearGradient id="glow" x1="50%" y1="0%" x2="50%" y2="100%">
<stop offset="0%" stop-color="#d95c41" stop-opacity="0.15"/>
<stop offset="100%" stop-color="#0a0a0a" stop-opacity="0"/>
</linearGradient>
<linearGradient id="text-grad" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#d95c41"/>
<stop offset="100%" stop-color="#e87d2f"/>
</linearGradient>
</defs>
<rect width="1200" height="630" fill="url(#glow)"/>
<text x="600" y="260" font-family="DM Sans, system-ui, sans-serif" font-size="72" font-weight="800" text-anchor="middle" fill="#f0f0f0" letter-spacing="-1.5">Agentic Engineering</text>
<text x="600" y="340" font-family="DM Sans, system-ui, sans-serif" font-size="24" font-weight="500" text-anchor="middle" fill="#888">65 lessons · 13 labs · 20 skill kits</text>
<text x="600" y="400" font-family="DM Sans, system-ui, sans-serif" font-size="18" font-weight="400" text-anchor="middle" fill="#666">Build production-grade multi-agent systems</text>
<rect x="520" y="450" width="160" height="48" rx="8" fill="#d95c41"/>
<text x="600" y="480" font-family="DM Sans, system-ui, sans-serif" font-size="16" font-weight="700" text-anchor="middle" fill="#fff">fdsa.agency</text>
<text x="600" y="560" font-family="DM Sans, system-ui, sans-serif" font-size="16" font-weight="800" text-anchor="middle" fill="#d95c41">FDSA</text>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB