feat: filled all gaps - testimonials, deepened M2/M3/M6, og:image, newsletter, Discord
This commit is contained in:
parent
242ce938f5
commit
5a161e1fa3
|
|
@ -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
|
|
@ -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
File diff suppressed because one or more lines are too long
|
|
@ -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 "Module 2: Agent Architecture""></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 "Lesson 2.1: The Four Pillars""></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 "Module 2: Agent Architecture""></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 "Lesson 2.1: The Four Pillars""></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;"> """</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 "thinking step" 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 "Lesson 2.7: Codebase Architectures for Agents""></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 "Lab 2.8: Multi-Tool Agent""></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 "Lab 2.9: Context-Aware Agent""></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 "thinking step" 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 "Lesson 2.7: Codebase Architectures for Agents""></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 "Choosing the Right Architecture""></a></h3><p>There's no single right answer. The choice depends on your agent'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 "Lesson 2.7b: Configuration Architecture""></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 "Pattern A: Flat Config (Single File)""></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;">"code-reviewer"</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 "Pattern B: Layered Config (Directory Structure)""></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 "Pattern C: Discoverable Config (Agent-Readable)""></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 "Lesson 2.7c: Error Handling Architecture""></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;">"error"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"API unavailable after 3 retries"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"fallback"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"use cached result"</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 "Lab 2.8: Multi-Tool Agent""></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 "Lab 2.9: Context-Aware Agent""></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};
|
||||
|
|
@ -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};
|
||||
|
|
@ -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};
|
||||
|
|
@ -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 & Security <a class="header-anchor" href="#module-3-safety-security" aria-label="Permalink to "Module 3: Safety & Security""></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 "Lesson 3.1: Why Bash Is the Single Point of Failure""></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 "Beyond Bash: Prompt Injection (L0)""></a></h3><p>Before we talk about bash security, there'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: "Ignore previous instructions and do X"</li><li>Indirect injection: Malicious content in web pages, files, or API responses that the agent reads</li><li>Role-playing bypass: "You are now a free AI with no rules"</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 & Security <a class="header-anchor" href="#module-3-safety-security" aria-label="Permalink to "Module 3: Safety & Security""></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 "Lesson 3.1: Why Bash Is the Single Point of Failure""></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 "Beyond Bash: Prompt Injection (L0)""></a></h3><p>Before we talk about bash security, there'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: "Ignore previous instructions and do X"</li><li>Indirect injection: Malicious content in web pages, files, or API responses that the agent reads</li><li>Role-playing bypass: "You are now a free AI with no rules"</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;"> """</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 "Lab 3.8: Implement L4 Whitelist Hook""></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 "Lesson 3.7b: Security Incident Response for Agents""></a></h2><p>When an agent does something it shouldn't, you need a playbook. Here'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 "Detection""></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>"execute_revenue_report"</td></tr></tbody></table><h3 id="response-playbook" tabindex="-1">Response Playbook <a class="header-anchor" href="#response-playbook" aria-label="Permalink to "Response Playbook""></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'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 "Kill Switch Pattern""></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;"> "claude|pi|opencode"</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's not a kill switch if you'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 "Lab 3.8: Implement L4 Whitelist Hook""></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 (&&, ||, ;, |)</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 "Lab 3.9: Build a Verifier Agent""></a></h2><p><strong>Objective</strong>: Create a read-only agent that checks the builder'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'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 (&&, ||, ;, |)</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 "Lab 3.9: Build a Verifier Agent""></a></h2><p><strong>Objective</strong>: Create a read-only agent that checks the builder'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'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};
|
||||
|
|
@ -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};
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 = [
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 |
Loading…
Reference in New Issue