> For the complete documentation index, see [llms.txt](/llms.txt).
> A full single-fetch corpus is available at [llms-full.txt](/llms-full.txt).
---
title: Give agents skills and project guidance
description: Load capabilities on demand with SKILL.md folders, and apply always-on project guidance with AGENTS.md, instead of stuffing everything into one large prompt.
last_verified: 2026-06-23
---

**Skills** give an agent a library of capabilities without bloating its prompt. Each skill is a folder with a `SKILL.md` file. Only the skill's name and description stay in the agent's context; when a task matches, the agent loads the full instructions on demand.

Skills work alongside **`AGENTS.md`**, which provides always-on project guidance. Use `AGENTS.md` for conventions that apply to every task, such as coding style or project structure, and use skills for capabilities the agent reaches for only when relevant.

## Write a skill

A skill is a folder with a `SKILL.md` file. The `name` and `description` fields at the top of the file are the only parts that stay in context; the body loads when the agent decides the skill is relevant.

```text
skills/
  pdf-extraction/
    SKILL.md
    scripts/
      extract.py
```

```markdown
---
name: pdf-extraction
description: Extract tables and text from PDF files
---

# PDF extraction

To extract content from a PDF:

1. Write the PDF bytes to `input.pdf` in the sandbox.
2. Run `scripts/extract.py input.pdf` to produce `output.json`.
3. Read `output.json` and summarize the tables it contains.
```

Because `SKILL.md` is plain markdown, skills written for other agent frameworks work in AGNT5 unchanged. The `skills/` folder ships alongside your worker code in the same deployment bundle.

## Give an agent skills

Pass a curated list of skill names and the directory pool they resolve against. Each agent sees only the skills you select, so its catalog and context cost stay small.



**Python:**

```python
from agnt5 import Agent, Sandbox

researcher = Agent(
    name="researcher",
    model="openai/gpt-4o-mini",
    instructions="Help the user analyze documents.",
    skills_dir="./skills",
    skills=["pdf-extraction", "sql-reporting"],
    sandbox=Sandbox(),
)

reporter = Agent(
    name="reporter",
    model="openai/gpt-4o-mini",
    instructions="Build reports from warehouse data.",
    skills_dir="./skills",
    skills=["sql-reporting"],
)
```





**TypeScript:**

```ts
const researcher = new Agent({
  name: 'researcher',
  model: LM.openai(),
  modelName: 'openai/gpt-4o-mini',
  instructions: 'Help the user analyze documents.',
  skillsDir: './skills',
  skills: ['pdf-extraction', 'sql-reporting'],
  sandbox: new Sandbox(),
});

const reporter = new Agent({
  name: 'reporter',
  model: LM.openai(),
  modelName: 'openai/gpt-4o-mini',
  instructions: 'Build reports from warehouse data.',
  skillsDir: './skills',
  skills: ['sql-reporting'],
});
```



Two agents can draw different subsets from the same `skills/` pool. A name that isn't in the pool fails at construction with the list of available skills, so typos surface immediately.

## Run a skill's bundled scripts

If a **[sandbox](/docs/build/sandboxes.md)** is attached, loading a skill also copies its bundled files into the sandbox workspace under `skills/<name>/`. The agent can then run those files using sandbox tools without any extra setup. Without a sandbox, `load_skill` still returns the skill's instructions; running the bundled scripts requires one.

## How loading works

When an agent has skills, the SDK adds a `<skills>` catalog of names and descriptions to the system prompt and registers a built-in `load_skill` tool. When a task matches, the agent calls `load_skill("pdf-extraction")` and receives the full instructions for that skill. Only loaded skills consume context; everything else stays out of the prompt.

Each load emits a `skill.loaded` event carrying the skill name, instruction length, and how many bundled files were copied into the sandbox, so a run's timeline shows exactly which skills were pulled in and when. To observe skill loads in your own code, iterate the agent's event stream.



**Python:**

```python
from agnt5 import SkillLoaded

async for event in agent.stream("Analyze this PDF"):
    if isinstance(event, SkillLoaded):
        print(f"Loaded: {event.skill_name} ({event.instructions_length} chars)")
```





**TypeScript:**

```ts
for await (const event of agent.stream('Analyze this PDF')) {
  if (event.eventType === 'skill.loaded') {
    console.log(`Loaded: ${event.skillName} (${event.instructionsLength} chars)`);
  }
}
```



## Load every skill in a pool

Omit `skills` to load every skill in the directory. This is convenient for a single agent that should have the whole pool.



**Python:**

```python
agent = Agent(
    name="generalist",
    model="openai/gpt-4o-mini",
    instructions="Use whichever skill fits the task.",
    skills_dir="./skills",
)
```





**TypeScript:**

```ts
const agent = new Agent({
  name: 'generalist',
  model: LM.openai(),
  modelName: 'openai/gpt-4o-mini',
  instructions: 'Use whichever skill fits the task.',
  skillsDir: './skills',
});
```



You can also load individual skills by path when you don't want a shared pool.



**Python:**

```python
from agnt5 import Agent, Skill

agent = Agent(
    name="analyst",
    model="openai/gpt-4o-mini",
    instructions="Analyze documents.",
    skills=[Skill.from_path("./my-skills/pdf-extraction")],
)
```





**TypeScript:**

```ts
const agent = new Agent({
  name: 'analyst',
  model: LM.openai(),
  modelName: 'openai/gpt-4o-mini',
  instructions: 'Analyze documents.',
  skills: [Skill.fromPath('./my-skills/pdf-extraction')],
});
```



### Inspect the pool directly

Use `discover_skills` / `discoverSkills` to inspect the pool without constructing an agent, for example to list available skills at startup or validate the directory.



**Python:**

```python
from agnt5 import discover_skills

pool = discover_skills("./skills")
for name, skill in pool.items():
    print(f"{name}: {skill.description}")
```





**TypeScript:**

```ts
const pool = discoverSkills('./skills');
for (const [name, skill] of pool) {
  console.log(`${name}: ${skill.description}`);
}
```



## Apply always-on project guidance with AGENTS.md

`AGENTS.md` is always-on guidance loaded into every prompt, so use it for conventions that always apply. Point the agent at a file, a directory (which uses its `AGENTS.md`), or a list of paths where later entries are more specific than earlier ones.



**Python:**

```python
agent = Agent(
    name="researcher",
    model="openai/gpt-4o-mini",
    instructions="Help the user analyze documents.",
    agents_md="./AGENTS.md",
    skills_dir="./skills",
    skills=["pdf-extraction"],
)
```





**TypeScript:**

```ts
const agent = new Agent({
  name: 'researcher',
  model: LM.openai(),
  modelName: 'openai/gpt-4o-mini',
  instructions: 'Help the user analyze documents.',
  agentsMd: './AGENTS.md',
  skillsDir: './skills',
  skills: ['pdf-extraction'],
});
```



To pass multiple files, use a list. The agent reads them in order, so put the most general file first and the most specific last.



**Python:**

```python
agent = Agent(
    name="researcher",
    model="openai/gpt-4o-mini",
    instructions="Help the user analyze documents.",
    agents_md=["./AGENTS.md", "./research/AGENTS.md"],
)
```





**TypeScript:**

```ts
const agent = new Agent({
  name: 'researcher',
  model: LM.openai(),
  modelName: 'openai/gpt-4o-mini',
  instructions: 'Help the user analyze documents.',
  agentsMd: ['./AGENTS.md', './research/AGENTS.md'],
});
```



Guidance loads before the skills catalog, so the agent reads its standing rules before the list of on-demand capabilities. To automatically merge a root `AGENTS.md` with any directory-specific ones, use `discover_agents_md` / `discoverAgentsMd` and pass the result.



**Python:**

```python
from agnt5 import Agent, discover_agents_md

agent = Agent(
    name="researcher",
    model="openai/gpt-4o-mini",
    instructions="Help the user analyze documents.",
    agents_md=discover_agents_md("."),  # root AGENTS.md first, most specific last
)
```





**TypeScript:**

```ts
const agent = new Agent({
  name: 'researcher',
  model: LM.openai(),
  modelName: 'openai/gpt-4o-mini',
  instructions: 'Help the user analyze documents.',
  agentsMd: discoverAgentsMd('.'), // root AGENTS.md first, most specific last
});
```



`discover_agents_md` / `discoverAgentsMd` walks upward from the start directory and stops at the repository root (the directory containing `.git`), so it never reads files outside your project.

## When to use which

| Use | For | Loaded |
|-----|-----|--------|
| `AGENTS.md` | Standing rules that apply to every task | Always, in every prompt |
| Skills | Capabilities the agent reaches for occasionally | On demand, when a task matches |

Both are optional. An agent with neither behaves exactly as before. Guidance and skills only change the prompt when you configure them.
