load_skill. The model reads the list, decides a skill applies, and calls the tool. The skill’s full text comes back as the tool’s answer, and the model follows it.
So a skill costs a line of context until it’s needed, and a task that needs no skill pays almost nothing for it.
Every framework’s agent_config() works this way. They differ only in where you plug the list and the tool in, which each framework’s page shows. CrewAI’s instrument(enable_skill_loader=True) has no tool loop to work with, so it puts a skill’s text directly into the prompt, under the same limits.
How skills are picked for a run
With no DecimalAI key, the list is every skill your project’s.decimal/skills.toml names. Nothing is searched. See below.
With a key, the list comes from the skills offered to that agent. DecimalAI ranks them against each message, on what the message is about and how well each skill has performed.
- The first run is ranked before the model is called.
- Later runs use the list they already have, and the ranking for that message is recorded in the background, so no run waits for it.
- An agent with more skills than the list holds is ranked before every model call, so the list fits the message. The list holds 30 skills.
What load_skill will serve
Each load names the ranking it came from, and DecimalAI decides what to return. A skill your organization owns, has installed or has given to the agent loads whether or not this run’s list showed it. A skill reachable only through the public registry loads only if this run was offered it.
A run loads at most 3 skills, about 6,000 tokens in total and 24,000 characters each. A skill arrives whole or not at all, never cut short, so the version a trace records is the version the model read.
Offered, Delivered, Loaded
Whether a skill was used has three steps, and they mean different things. Traces and the agent’s page show them under these names:
Only Loaded says the model chose the skill. A skill pasted into a prompt counts as Delivered, because finding text in a prompt can’t show that the model reached for it. If it counted as Loaded, skills that were merely pasted in would rank above skills that models pick.
The API and SDK use older names for the same step:
skills_loaded_by_agent, active_skills and “activation” all mean Loaded. To see these on a real run, read Read a run. To find skills nobody loads, see Which skills get used.
Without a DecimalAI key
With noDECIMAL_API_KEY set and decimalai.init() never called, agent_config() runs from your project alone:
- The prompt is your
fallback=. With none, the instructions are the skill list alone, andprompt_sourcesays"fallback (no key)". - The skills are the ones
.decimal/skills.tomllists: registry skillsdecimalai skills add <name>installed in.agents/skills/, and skills you wrote there thatdecimalai skills add <folder>listed under[authored]. A folder there that the file doesn’t list is left out, because Cursor, Codex and other coding tools read that folder too. The first run names any such folder once. - Every run reads the list and the text from disk, so an edit takes effect on the next run.
- Nothing is sent: no traces, no ranking, no registry requests.
skills.toml gives them. Skills you wrote are uploaded to your organization, not published.
.decimal/link.toml records this, so commit it. From then on the agent’s skills live on DecimalAI: change them on the agent’s page, or with decimalai skills add <name>, which now adds to the agent and writes no files. A run never changes them. If a project with a link.toml loses its key, agent_config() raises DecimalConfigError, so a broken deploy fails at startup instead of quietly running without its skills. Runs made before the key are never uploaded.
Turn it off
DECIMALAI_LOAD_SKILL_TOOL=0, ordecimalai.init(load_skill_tool=False): with a key, no tool. The text of the skills picked for each message goes straight into the instructions instead. With no key, this changes nothing.decimalai.init(enabled=False), called afteragent_config(): no ranking and no skills for that config. The prompt it already read keeps running.agent_config(..., on_unavailable="fail"): by default, a run whose skill list never came back answers without skills. With this, it raises before the model is called.
A chat on Claude
Claude rejects a conversation whose system prompt or tool definitions changed after a thinking block entered its history (HTTP 400, “The block is bound to a different conversation”), and Claude 5.x models think by default. A new run follows the newest saved prompt and skill list, so a chat that starts a fresh run per message breaks as soon as someone saves a prompt or assigns a skill. So a chat keeps what its first message got. Each message is still ranked, for its trace, but what the model sees stays the same, and a newer prompt or skill list reaches the next chat. The call that starts a chat differs by framework, usuallysupport.conversation(), and so does how to continue one in another process. Each framework’s page shows both under Conversations.
Deliver a skill one way
A skill can reach a model throughagent_config(), or through a loader that reads files from disk, such as Claude Code, Cursor, or a framework’s own skill loader. Doing both on one agent puts the same skill in front of the model twice.
The SDK warns once when CrewAI’s skill loader is turned on inside Claude Code or Cursor. Set
DECIMALAI_SUPPRESS_DISK_RUNTIME_WARNING=1 if you chose that on purpose.