Task 8 · 8 tasks
Agent skills
Package company know-how as skills that the agent loads only when a question needs them.
The “House Rules” problem
HR has a fixed format for the headcount report, and Finance has strict rules for anything about pay. Pasting every team's rules into the system prompt makes it long, expensive and confusing. Ship each rule book as a skill instead: the agent sees a one-line description of each and opens the full instructions only when a question calls for them.
Build it
Write a skill
Challenge
Turn HR's headcount rules into
phase1/starter/skills/headcount-report/SKILL.md:- Count active employees only.
- One row per department, including departments with nobody active (count 0).
- Columns: Department, Active employees, Share of company (%, one decimal, computed in SQL).
- Largest department first, then a Total row.
- Finish with the line
Source: datastream_corp.db, active employees only.
skills/compensation-policy/SKILL.mdnext to it is a finished example; the agent gets both.Hint 1
A skill is a folder with a
SKILL.md: YAML frontmatter with aname(the folder's name, lowercase with hyphens) and adescription, then Markdown instructions. See the Agent Skills specification.Hint 2
The description is all the model sees until it loads the skill, so it decides whether the skill is ever used. Say what the skill is and when to use it, e.g. “Use when asked for headcount, employee counts per department or a staffing overview.”
Solution
phase1/starter/skills/headcount-report/SKILL.md--- name: headcount-report description: The standard DataStream Corp headcount report. Use when asked for headcount, employee counts per department or a staffing overview. --- # Headcount report 1. Count only employees with `status = 'active'`. 2. One row per department (`employees.department_id = departments.id`); keep departments with no active employees (LEFT JOIN, count 0). 3. Columns, in this order: Department | Active employees | Share of company (%, one decimal). Compute the share in the SQL query (`ROUND(100.0 * count / total, 1)`), never by hand. 4. Sort by active employees, largest first, then add a final **Total** row. 5. Answer with the markdown table, then exactly one line: `Source: datastream_corp.db, active employees only.`Give the agent its skills
Challenge
Build the agent with the database tools and every skill in
SKILLS_DIR.Work in
phase1/starter/t8_skills.py(look forTODO; an unfinished one prints[starter] TODO …) and run it withuv run bootcamp.py phase1 t8 --starter. The reference solution isphase1/t8_skills.py;uv run bootcamp.py phase1 t8runs it.Hint 1
Skills come from the
AgentSkillsplugin instrands.vended_plugins.skills. A plugin bundles hooks and tools; this one adds the skill list to the system prompt before each call and gives the agent askillstool that returns a skill’s full instructions. See Strands: agent skills.Hint 2
Pass the folder that contains the skill folders, and hand the plugin to the agent with
plugins=[...](nottools=).Solution
Paste each block below into
phase1/starter/t8_skills.pyin place of the definition with the same name (the TODO), including any import line that comes with it. Nothing else in the file changes.phase1/starter/t8_skills.py · replace build_agent() (keep its import line)from strands.vended_plugins.skills import AgentSkills def build_agent(mcp_client: MCPClient) -> Agent: """The data engineer with the database tools plus every skill under `SKILLS_DIR`.""" return Agent( name="Data Engineer", model=make_model(), system_prompt=SYSTEM_PROMPT, tools=mcp_client.list_tools_sync(), plugins=[AgentSkills(skills=SKILLS_DIR)], )Run it
terminal · your starter fileuv run bootcamp.py phase1 t8 --starter "Give me the headcount report" uv run bootcamp.py phase1 t8 --starter "What is Alice Chen's salary?" uv run bootcamp.py phase1 t8 --starter "Which projects are in planning?"terminal · reference solutionuv run bootcamp.py phase1 t8 "Give me the headcount report" uv run bootcamp.py phase1 t8 "What is Alice Chen's salary?" uv run bootcamp.py phase1 t8 "Which projects are in planning?"Experiments
- Watch for
[tool] skills: headcount-report: the agent loads a skill before it queries. The projects question loads none, so it pays nothing for the rules it does not need. - Delete the “keep departments with no active employees” rule from your skill and ask for the report again. Is Research still in the table?
- Make the headcount description vague (“Reporting helper.”) and ask again. Does the agent still find the skill?
- Write a third skill, for example a
project-statusreport, and ask for it. The agent code does not change.
- Watch for
Check your work
Phase 1 has no automated test: you check it by running the task and looking for the result below.
Headcount: [tool] skills: headcount-report, then a [tool] query_db that counts status = 'active' (long SQL is cut at 160 characters). The table has seven rows, largest first: Engineering 481 (40.0), Sales 360 (30.0), Marketing 180 (15.0), HR 84 (7.0), Finance 60 (5.0), Operations 36 (3.0), Research 0 (0.0), then Total 1,201, and ends with Source: datastream_corp.db, active employees only. No Research row, or 483 / 362 / 1,207, means a rule was skipped.
Salary: [tool] skills: compensation-policy; no individual salary, an offer of a rounded department average instead, and the line Compensation figures are confidential; do not forward.
Projects: no skills line, a [tool] query_db with status = 'planning', and exactly two projects: Brand Refresh Initiative and Office Expansion Project.
Failed? Run the same prompt on the reference (drop --starter). If the reference fails too, it's the model: rerun or try another MODEL_ID (uv run bootcamp.py llm models).
Under the hood
This is progressive disclosure: only each skill's name and description sit in the system prompt, and the body arrives as a tool result when the model asks for it. Prompts stay short however many skills you add, and each team can own its skill as a file in the repo. Claude Code reads the same SKILL.md format; this repository's .claude/skills/ folder holds skills for working on the bootcamp itself.