<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Part 4: Skills and Agents | Garage Education</title><link>https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/</link><atom:link href="https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/index.xml" rel="self" type="application/rss+xml"/><description>Part 4: Skills and Agents</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>en-US</language><copyright>©</copyright><lastBuildDate>Sat, 10 Oct 2026 00:00:00 +0000</lastBuildDate><image><url>https://www.garageeducation.org/media/logo.svg</url><title>Part 4: Skills and Agents</title><link>https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/</link></image><item><title>Chapter 14: Skills as files</title><link>https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/14-skills-as-files/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/14-skills-as-files/</guid><description>&lt;p&gt;A skill is a folder with a &lt;code&gt;SKILL.md&lt;/code&gt; file. The file has a name and a one-line description in front matter, then the full instructions. The harness loads only names and descriptions at the start. A &lt;code&gt;useSkill&lt;/code&gt; tool loads the full text when the model asks for it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;triage-error-group&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Judge the severity of one error group from its rate, the services it affects, and whether a runbook exists.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nn"&gt;---&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gh"&gt;# Steps
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;1.&lt;/span&gt; Read the error rate for the last 15 minutes.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;2.&lt;/span&gt; List the affected services.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;3.&lt;/span&gt; Search runbooks for the error fingerprint.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;4.&lt;/span&gt; Return one severity: low, medium, or critical.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;figure class="seq"&gt;
&lt;script type="application/json"&gt;
{
"title": "Progressive loading: front matter first, full text on demand.",
"lifelines": [
{"id": "files", "label": "SKILL.md files", "tone": "platform"},
{"id": "harness", "label": "Harness", "tone": "platform"},
{"id": "model", "label": "Model", "tone": "subscriber"}
],
"messages": [
{"from": "harness", "to": "files", "label": "at start: read name + description only"},
{"from": "harness", "to": "model", "label": "prompt lists triage-error-group and its description"},
{"from": "model", "to": "harness", "label": "tool call: useSkill(triage-error-group)", "kind": "response"},
{"from": "harness", "to": "files", "label": "load the full SKILL.md"},
{"from": "harness", "to": "model", "label": "tool result: steps 1 to 4"},
{"from": "model", "to": "harness", "label": "follows the steps; returns low, medium, or critical", "kind": "response"}
]
}
&lt;/script&gt;
&lt;figcaption&gt;Figure 14.1. A skill costs one line of the prompt until the model asks for it. The figure leaves out the tool calls the model makes while following the steps.&lt;/figcaption&gt;
&lt;/figure&gt;</description></item><item><title>Chapter 15: Skill selection</title><link>https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/15-skill-selection/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/15-skill-selection/</guid><description>&lt;p&gt;Skills are indexed by their description embedding in PostgreSQL. For each task, the harness takes the five nearest skills. Only those five appear in the prompt, and &lt;code&gt;useSkill&lt;/code&gt; accepts only those names. Measure recall at five on 20 labeled tasks. Include pre-filtering only when the catalog grows past about ten skills.&lt;/p&gt;
&lt;figure class="flow"&gt;
&lt;script type="application/json"&gt;
{
"title": "Selecting skills for one task.",
"steps": [
{"label": "A task arrives"},
{"label": "Embed the task"},
{"label": "Take the five nearest skill descriptions from PostgreSQL"},
{"label": "Put only those five in the prompt"},
{"label": "Is the useSkill name one of the five?", "no": "Reject the call"},
{"label": "Load the full SKILL.md", "tone": "platform"}
]
}
&lt;/script&gt;
&lt;figcaption&gt;Figure 15.1. Skill selection for one task. The same five names are the prompt list and the &lt;code&gt;useSkill&lt;/code&gt; allowlist. Recall at five, on 20 labeled tasks, says whether the right skill made the cut.&lt;/figcaption&gt;
&lt;/figure&gt;</description></item><item><title>Chapter 16: Sub-agents</title><link>https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/16-sub-agents/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/16-sub-agents/</guid><description>&lt;p&gt;A sub-agent has its own system prompt, its own tool allowlist, and its own step limit. The parent calls it through a tool that returns a short summary. A focused agent does one job well.&lt;/p&gt;
&lt;figure class="arch"&gt;
&lt;script type="application/json"&gt;
{
"title": "A parent calls a sub-agent through a tool.",
"nodes": [
{"id": "pb", "type": "boundary", "x": 0, "y": 0, "w": 300, "h": 240, "label": "Parent agent"},
{"id": "parent", "x": 30, "y": 50, "w": 240, "label": "Parent loop", "detail": "its own goal", "tone": "platform"},
{"id": "tool", "x": 30, "y": 150, "w": 240, "label": "Sub-agent tool", "detail": "one entry in the parent's allowlist", "tone": "platform"},
{"id": "sb", "type": "boundary", "x": 370, "y": 0, "w": 450, "h": 240, "label": "Sub-agent"},
{"id": "sloop", "x": 400, "y": 50, "w": 190, "label": "Sub-agent loop", "tone": "platform"},
{"id": "prompt", "x": 610, "y": 40, "w": 190, "label": "Own system prompt", "tone": "muted"},
{"id": "allow", "x": 610, "y": 105, "w": 190, "label": "Own tool allowlist", "tone": "muted"},
{"id": "limit", "x": 610, "y": 170, "w": 190, "label": "Own step limit", "tone": "muted"}
],
"edges": [
{"from": "parent", "to": "tool", "label": "tool call"},
{"from": "tool", "to": "sloop", "label": "task", "fromSide": "right", "toSide": "bottom"},
{"from": "sloop", "to": "parent", "label": "short summary", "fromSide": "left", "toSide": "right"}
]
}
&lt;/script&gt;
&lt;figcaption&gt;Figure 16.1. To the parent, a sub-agent is one more tool. Its prompt, tools, and step limit are its own. Chapter 18 fixes the shape of the summary.&lt;/figcaption&gt;
&lt;/figure&gt;</description></item><item><title>Chapter 17: Agent selection</title><link>https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/17-agent-selection/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/17-agent-selection/</guid><description>&lt;p&gt;Three patterns exist. A direct agent handles the task itself. A router labels the task and sends it to one agent. A supervisor plans several subtasks and combines the results. Start with direct handling. Add a router only when the cost of a wrong route is clear. Test each pattern with the eval set.&lt;/p&gt;
&lt;figure class="arch"&gt;
&lt;script type="application/json"&gt;
{
"title": "Three ways to pick who handles a task.",
"nodes": [
{"id": "d", "type": "boundary", "x": 0, "y": 0, "w": 230, "h": 340, "label": "Direct · start here"},
{"id": "dt", "x": 25, "y": 50, "w": 180, "label": "Task"},
{"id": "da", "x": 25, "y": 180, "w": 180, "label": "Agent", "detail": "handles it itself", "tone": "platform"},
{"id": "r", "type": "boundary", "x": 260, "y": 0, "w": 270, "h": 340, "label": "Router"},
{"id": "rt", "x": 305, "y": 50, "w": 180, "label": "Task"},
{"id": "rr", "x": 305, "y": 140, "w": 180, "label": "Router", "detail": "labels the task", "tone": "ai"},
{"id": "ra", "x": 280, "y": 260, "w": 110, "label": "Agent A", "tone": "platform"},
{"id": "rb", "x": 400, "y": 260, "w": 110, "label": "Agent B", "tone": "muted"},
{"id": "s", "type": "boundary", "x": 560, "y": 0, "w": 300, "h": 340, "label": "Supervisor"},
{"id": "st", "x": 620, "y": 50, "w": 180, "label": "Task"},
{"id": "ss", "x": 620, "y": 140, "w": 180, "label": "Supervisor", "detail": "plans, then combines", "tone": "ai"},
{"id": "sa", "x": 580, "y": 260, "w": 120, "label": "Subtask 1", "tone": "platform"},
{"id": "sb", "x": 720, "y": 260, "w": 120, "label": "Subtask 2", "tone": "platform"}
],
"edges": [
{"from": "dt", "to": "da"},
{"from": "rt", "to": "rr"},
{"from": "rr", "to": "ra", "label": "one route"},
{"from": "st", "to": "ss"},
{"from": "ss", "to": "sa", "both": true},
{"from": "ss", "to": "sb", "both": true}
]
}
&lt;/script&gt;
&lt;figcaption&gt;Figure 17.1. The three patterns. A router sends each task to exactly one agent; Agent B is greyed out because it was not chosen this time. A supervisor sends to several and combines the results. Each pattern is tested on the same eval set.&lt;/figcaption&gt;
&lt;/figure&gt;</description></item><item><title>Chapter 18: Context isolation</title><link>https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/18-context-isolation/</link><pubDate>Sat, 10 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.garageeducation.org/docs/agent-harness-spring-ai/04-skills-and-agents/18-context-isolation/</guid><description>&lt;p&gt;A sub-agent keeps its full detail in the log. It returns a capped summary with a fixed shape: a finding, a confidence, and a detail id. Set the cap in code, not in the prompt. The parent&amp;rsquo;s context stays small.&lt;/p&gt;
&lt;figure class="arch"&gt;
&lt;script type="application/json"&gt;
{
"title": "Where a sub-agent's output goes.",
"nodes": [
{"id": "sub", "x": 0, "y": 100, "w": 190, "label": "Sub-agent", "detail": "many steps, long outputs", "tone": "platform"},
{"id": "log", "x": 300, "y": 0, "w": 230, "label": "Log", "detail": "full detail, by detail id", "tone": "data"},
{"id": "cap", "x": 300, "y": 190, "w": 230, "label": "Cap, in code", "detail": "finding · confidence · detail id", "tone": "platform"},
{"id": "parent", "x": 640, "y": 190, "w": 200, "label": "Parent context", "detail": "stays small", "tone": "platform"}
],
"edges": [
{"from": "sub", "to": "log", "label": "everything"},
{"from": "sub", "to": "cap", "label": "summary"},
{"from": "cap", "to": "parent", "label": "capped summary"},
{"from": "parent", "to": "log", "label": "detail id, when needed", "dashed": true}
]
}
&lt;/script&gt;
&lt;figcaption&gt;Figure 18.1. Two outputs from one sub-agent. The detail id links the short summary back to the full record. The chapter does not say whether the parent can fetch the detail itself, so that edge is dashed.&lt;/figcaption&gt;
&lt;/figure&gt;</description></item></channel></rss>