Skip to main content
Skills are the unit of reusable agent knowledge in DecimalAI. The SDK has two flows: sync (push your local SKILL.md files to the platform during instrument()) and pull (download platform skills to disk). At runtime, the Skill Router is what your agent talks to — it picks which skills to load on every query and emits the telemetry that powers per-skill effectiveness. This page covers the SDK surface; the Router page covers strategies, response shape, and the routing-id → trace join.

Sync skills from code to platform

The adapter entry points on this page were called install() in 0.10.0 and earlier. They were renamed to instrument() in 0.10.2 — same arguments, same behaviour — because install had come to mean something else entirely: adding a skill to your workspace. install() still works and emits a DeprecationWarning. See Vocabulary.SkillRouter.install(), further down this page, is that other meaning — the skill operation. It keeps its name.
The skill_dirs argument is supported by three instrument() calls — decimalai.openai_agents, decimalai.langchain and decimalai.otel. Other adapters (LlamaIndex, Anthropic, ADK, Pydantic AI, Claude Agent SDK) don’t take it; pass skill_dirs= to decimalai.start_trace() instead.

Pull skills from platform to disk

Pull a public skill — no signup required

For consumers who just want to read a published skill without forking it into an org, the CLI’s pull command works against the public registry endpoint with no auth:
pull is read-only — no fork is created, no activation telemetry is recorded. Use SkillRouter.install() (Python) once you sign up to get the full lifecycle. In the SDK, SkillRouter.install() = fork + write SKILL.md to disk (plus per-trace activation tracking); use fork() for the workspace copy without the disk write.

SkillRouter — full CRUD

For programmatic skill management, instantiate SkillRouter directly:
See the Skills API reference for the underlying REST surface.

On-demand bodies: the load_skill tool

The routed menu carries names + descriptions; bodies load on demand. On the openai_agents and pydantic_ai adapters, instrument(enable_skill_loader=True) also registers a native load_skill(name) tool on every agent — the model reads the menu, calls the tool with a skill’s exact name, and the full instructions arrive as the tool result mid-turn. Nothing to wire manually:
Body loads are budgeted per turn so they can’t blow the context window: Re-loading an already-loaded skill is free. Each load is recorded on the trace (skills_loaded_by_agent), closing the offered-vs-loaded join server-side.
On the OpenTelemetry-based rails — Pydantic AI and the raw provider SDKs — that recording needs a run to attach to, which is what agent_run() opens (and what decimalai.pydantic_ai.instrument() opens for you). Outside one, the SDK deliberately records nothing rather than guess which run a routing decision belonged to, so those traces still ship — they just carry no routing_id and no skill names. instrument(trace_runs=False) turns the run scope off and takes the skills rail with it.
The anthropic and langchain adapters have no tool loop to route a result through, so they stay on prompt injection — their inject_skill_body=True path applies the same trim and budget. Disable the tool everywhere with decimalai.init(load_skill_tool=False) or DECIMALAI_LOAD_SKILL_TOOL=0. You can also call the primitive directly:

What’s next

Skills guide

File format, registry, and SkillScore for skill effectiveness.

Skills Observability tutorial

Real-world example of measuring skill impact with experiments.