Deferred items
We intentionally keep the notebook implementation small. These are the pieces that belong in the prototype, in a real implementation, or in a follow-up exercise.
Tool-description skill injection
OpenCode communicates available skills through the skill tool description.
That description contains the list of skill names and descriptions. The system
prompt can stay focused on behavior rules.
In the notebook you inject the skill list into the prompt instead. That's easier to implement in ToyAIKit during the workshop, and it's enough for the small models used here.
If you build your own agent, try both. Tool-description injection keeps capabilities closer to the tool schema, while prompt injection is simpler and often gets you far enough.
Command interception
In the notebook you expose commands through an execute_command tool. This is
the simpler path because it avoids modifying the runner.
For a real product, command interception is usually cleaner:
- Read the user's raw input.
- If it starts with
/, parse the command name and arguments. - Load the command markdown.
- Render the template.
- Send the rendered prompt to the agent.
The prototype implements this in RealAgent.chat().
Full template rendering
The notebook's process_template() returns command templates unchanged.
Command templates can use $1 through $3 plus $ARGUMENTS, but the notebook
doesn't implement those placeholders.
The prototype does implement positional and all-argument substitution in
prototype/src/commands.py.
Use that version if you want commands like:
/review src/agent.py
to become:
Review the code at src/agent.py for:
Skill validation
In the notebook the loader assumes that every subdirectory under skills/
contains a valid SKILL.md. That keeps the workshop code short.
A real loader should validate these fields and rules:
SKILL.mdexists.nameis present.descriptionis present.- The directory name matches the skill name.
- The description is short enough to include in the prompt or tool schema.
- Disabled skills are skipped.
The OpenCode-style rules require name and description, allow optional
metadata, and support a disabled flag.
Extra skill files
In the notebook you read only SKILL.md, but the examples show that useful
skills often include scripts/ and templates/.
The prototype resolves @scripts/deploy.sh and similar references into paths.
It still leaves the agent to read or run those files with normal tools, which is
the right boundary. The skill loader gives the agent instructions and paths, and
the file and shell tools do the work.
Permissions
OpenCode-style skill permissions let a config allow, deny, or ask before loading a skill. The prototype in this workshop doesn't include a separate permission module.
If you add permissions, keep them in the tool execution layer. Don't trust the model to decide whether it's allowed to load a restricted skill.
Benchmarks for skill adherence
In the Q&A, we answer a question about whether skill steps are followed 100 percent of the time. We don't include a benchmark here.
The prototype gives you the starting point for testing. Look at the recorded tool calls and assert that the expected skill was loaded.
For stricter evaluation, collect multiple prompts per skill and measure:
- Whether the correct skill was called.
- Whether the wrong skill was avoided.
- Whether referenced files were read.
- Whether required scripts were run.
- Whether the final answer followed the skill instructions.
Framework choice
We use ToyAIKit because it's interactive and clear for teaching. It's a good fit for a workshop notebook, not a full production agent framework.
For production, use a framework that fits your application. PydanticAI is a good default option, and the concepts here still apply. You still use tools, prompts, lazy-loaded skill instructions, and command rendering.
Continue with Appendix: workshop files for the file list.