Skills
Skills let a route offer long instructions without putting them all in the system prompt.
The model sees a short list of skills and calls readSkill({ name }) when it needs one, so the prompt stays small.
Use skills for instructions that are too long for systemPrompt or only apply sometimes, such as refund rules, triage steps or escalation playbooks.
Quick startCopy link to section: Quick start
Create a skill under a route's skills/ directory:
src/app/support/[tenant]/
index.ts
skills/
refund-policy/
SKILL.mdEvery skill file needs frontmatter with a description:
---
description: Instructions for refund, exchange, and exception questions.
---
Use this skill when the customer asks about refunds, exchanges, credits, or exceptions.
## Process
1. Check the order date.
2. Check whether the item is final sale.
3. Offer the standard path before requesting an exception.When this route runs, B4.run adds:
- a
# Skillsprompt section listingrefund-policyand its description - a
readSkill({ name })tool that returns the body ofSKILL.mdwhen the model asks for it
Skill namesCopy link to section: Skill names
By default, the skill name is the directory name. For example, this file creates a skill named refund-policy:
skills/refund-policy/SKILL.mdTo give the model a different name, set name in the frontmatter:
---
name: refunds
description: Instructions for refund, exchange, and exception questions.
---Each skill name must be unique within the route. If two skills end up with the same name, the route fails to load with a duplicate-name error.
A directory name starts with a letter or number and can contain letters, numbers, underscores, and hyphens. B4.run skips directories whose names start with a dot or contain spaces or other punctuation.
What the model seesCopy link to section: What the model sees
B4.run adds a short section to the prompt:
# Skills
The following skills are available. To use one, call `readSkill({ name: "<name>" })`
to load its full instructions before acting.
- **refund-policy** - Instructions for refund, exchange, and exception questions.Skills are listed by name, in alphabetical order.
The readSkill tool takes:
{ name: string }For a known skill, it returns the markdown body after the frontmatter. For an unknown name, it returns a string listing the available names. Input of the wrong shape fails schema validation.
B4.run reads the skill files once, when it prepares the route. readSkill serves them from memory.
Frontmatter requirementsCopy link to section: Frontmatter requirements
description is required, because it's all the model sees when it decides whether to load the skill.
Here is a valid skill:
---
description: Use for billing dispute triage.
---
...This one fails to load:
Use for billing dispute triage.So does this:
---
name: billing-disputes
---
...Keep the description short, and say when to use the skill.
B4.run's frontmatter parser is small on purpose. Stick to simple key: value fields rather than full YAML.
Generated typesCopy link to section: Generated types
When a route has at least one valid skills/<name>/SKILL.md file, b4 typegen adds readSkill to that route's generated tool types.
The generated input type is:
{ name: string }The output type is:
stringUnder the hoodCopy link to section: Under the hood
Skills are implemented by createSkillsMarker().
When B4.run prepares an agent route, it reads each skill's frontmatter and body, then adds the readSkill tool and the prompt section.
Skills add no state fields or stream transformers.