# Instructions and skills

> Author instructions.md or instructions.ts with defineInstructions, flat and packaged skills under agent/skills/, load_skill activation, and workspace seeding to /workspace/skills.

- Repository: vercel/eve
- GitHub: https://github.com/vercel/eve
- Human docs: https://www.grok-wiki.com/public/docs/vercel-eve-759e1d74a10f
- Complete Markdown: https://www.grok-wiki.com/public/docs/vercel-eve-759e1d74a10f/llms-full.txt

## Source Files

- `docs/instructions.mdx`
- `docs/skills.mdx`
- `packages/eve/src/public/definitions/instructions.ts`
- `packages/eve/src/public/skills/index.ts`
- `packages/eve/src/compiler/normalize-skill.ts`
- `apps/fixtures/weather-agent/agent/skills/get-weather.md`

---

---
title: "Instructions and skills"
description: "Author instructions.md or instructions.ts with defineInstructions, flat and packaged skills under agent/skills/, load_skill activation, and workspace seeding to /workspace/skills."
---

Eve splits agent context into always-on instructions (`agent/instructions.md`, `agent/instructions.ts`, or `agent/instructions/`) and on-demand skills (`agent/skills/`). Instructions prepend to every model call; skills advertise descriptions in the system prompt and load full procedure text only when the model calls the framework-owned `load_skill` tool. At build time, Eve compiles both surfaces into `.eve/compile/`; at session bootstrap, skill files seed into `/workspace/skills/<name>/` inside the sandbox workspace.

## Instructions vs skills

| Surface | Authored path | When it enters context | Use for |
| --- | --- | --- | --- |
| Instructions | `agent/instructions.md`, `.ts`, or `instructions/` | Every turn, prepended to the system prompt | Permanent identity, tone, standing rules |
| Skills | `agent/skills/*` | On demand via `load_skill` tool result | Long or situational procedures |

<Note>
Instructions never execute code. Skills add instructions to context, not new execution surfaces — tools remain visible whether or not a skill is loaded. For typed runtime behavior, author `agent/tools/` instead.
</Note>

## Author instructions

The root agent requires instructions. Subagents may omit them. Identity is path-derived; do not add a `name` field to `defineInstructions`.

### Flat markdown

```md title="agent/instructions.md"
You are a concise assistant. Use tools when they are available.
```

Keep this file short and stable: identity, tone, and rules that apply on every turn.

### TypeScript with `defineInstructions`

Switch to a module when you need typed helpers, `lib/` code, or build-time values:

```ts title="agent/instructions.ts"
import { defineInstructions } from "eve/instructions";
import { buildInstructionsPrompt } from "./lib/prompts.js";

export default defineInstructions({
  markdown: buildInstructionsPrompt(),
});
```

<ParamField body="markdown" type="string" required>
Resolved prompt text. The only field on `InstructionsDefinition`.
</ParamField>

Module-backed static instructions execute once at build time. Eve captures the resulting markdown into the compiled manifest; the runtime serves the same prompt every session without re-running the module.

### Multi-file `instructions/` directory

For more than one file, add `agent/instructions/`. Eve reads entries non-recursively and accepts `.md` and `.ts` modules (including `defineDynamic` resolvers). Entries combine in alphabetical order by filename (`localeCompare`).

A flat root file and the directory can coexist: the root file's content comes first, then sorted directory entries. You cannot author both `instructions.md` and `instructions.ts` at the root — that pairing emits a `discover/slot-collision` diagnostic.

## Author skills

Eve discovers skills from `agent/skills/` as flat markdown, flat modules, or packaged directories. Skill identity comes from the path (`agent/skills/summarize.md` → skill `summarize`; `agent/skills/research/SKILL.md` → skill `research`). Authored definitions do not carry a `name` field.

Skills follow the Agent Skills `SKILL.md` convention, so skill packs authored for that standard port over as-is.

### Flat markdown skill

The smallest skill is a single `.md` file. The body is the procedure; the description routes activation.

```md title="agent/skills/get-weather.md"
---
description: Use the weather tool before answering forecast or temperature questions.
---

When the user asks about weather, temperature, or forecast conditions, call the `get_weather` tool before answering.
```

Flat markdown skills may omit `description` frontmatter. When they do, Eve advertises the first non-empty, non-code-fence line of the body (with leading `#`, `>`, `*`, or `-` markers stripped). If no such line exists, Eve falls back to `Instructions for the <name> skill.` — a weak routing hint, so add explicit `description` frontmatter when intent-based routing matters.

### Packaged skill

A packaged skill is a directory with `SKILL.md` plus optional sibling trees:

:::files
agent/skills/research/
├── SKILL.md
├── references/
├── assets/
└── scripts/
:::

Packaged `SKILL.md` must carry `description` frontmatter; there is no filename slug to fall back on. Eve recognizes `references/`, `assets/`, and `scripts/` subdirectories during discovery.

```md title="agent/skills/research/SKILL.md"
---
description: Research unfamiliar topics before answering with confidence.
---

When the task is novel or ambiguous, gather evidence first, then answer with the key facts and the remaining uncertainty.
```

### TypeScript with `defineSkill`

When markdown cannot express typed values, generated content, or inline sibling files:

```ts title="agent/skills/research.ts"
import { defineSkill } from "eve/skills";

export default defineSkill({
  description: "Research unfamiliar topics before answering with confidence.",
  markdown:
    "When the task is novel or ambiguous, gather evidence first, then answer with the key facts and the remaining uncertainty.",
  files: {
    "references/checklist.md": "# Checklist\n\n- Find primary sources.\n",
  },
});
```

<ParamField body="description" type="string" required>
Routing hint advertised in the Available skills block. Write it as the task that should trigger activation.
</ParamField>

<ParamField body="markdown" type="string" required>
Procedure body returned by `load_skill` (frontmatter stripped).
</ParamField>

<ParamField body="files" type="Record<string, string | Uint8Array>">
Optional package-relative sibling files. Eve writes each entry under `/workspace/skills/<name>/` at compile and session bootstrap.
</ParamField>

Start with plain markdown; move to `defineSkill` only when you hit its limits.

### Per-agent scope

Skills are scoped to the agent that declares them. A subagent's `skills/` are invisible to the root agent, and the reverse holds. There is no shared-skill mechanism — put shared executable helpers in `lib/`.

## `load_skill` activation

When an agent declares skills, Eve injects an **Available skills** section into the system prompt and exposes the framework `load_skill` tool. All skills are always listed regardless of activation state; active skill bodies are never re-injected into the system prompt (they arrive via the tool result), which keeps the system prompt stable across the session for prompt caching.

```mermaid
sequenceDiagram
  participant Model
  participant Harness
  participant load_skill
  participant Sandbox

  Harness->>Model: System prompt (instructions + Available skills block)
  Model->>load_skill: skill: "research"
  load_skill->>Sandbox: read /workspace/skills/research/SKILL.md
  Sandbox-->>load_skill: markdown body (frontmatter stripped)
  load_skill-->>Model: skill instructions as tool result
  Model->>Model: Follow loaded procedure on subsequent steps
```

<ParamField body="skill" type="string" required>
Available skill name or id. Choose from the Available skills block.
</ParamField>

The `load_skill` tool reads from the active sandbox, never runs inside it, and is only surfaced when the agent declares skills. With no skills, Eve does not advertise descriptions and the model has nothing to load.

<Warning>
If activation fails (unsafe id, missing file), the AI SDK forwards the error as a tool-error result. The Available skills block instructs the model to say so briefly and continue with the best fallback.
</Warning>

## Workspace seeding to `/workspace/skills`

Eve does not mount the full `agent/` tree into the sandbox. Only two sources land in the workspace:

- `agent/skills/**` → `/workspace/skills/<name>/...`
- `agent/sandbox/workspace/**` → `/workspace/...`

At compile time, `materializeWorkspaceResources` writes per-agent skill trees under `.eve/compile/workspace-resources/<nodeId>/skills/`. Flat markdown and module-backed skills normalize into a package directory with `SKILL.md` at the root; packaged skills copy their full directory tree. Sandbox templates prewarm with per-agent skill seed files.

| Authored shape | Sandbox path |
| --- | --- |
| `agent/skills/forecast.md` | `/workspace/skills/forecast/SKILL.md` |
| `agent/skills/research/SKILL.md` + siblings | `/workspace/skills/research/SKILL.md`, `/workspace/skills/research/references/...` |
| `defineSkill` with `files` | `/workspace/skills/<name>/<relativePath>` for each entry |

<Warning>
Authoring `agent/sandbox/workspace/skills/...` is rejected at compile time. Eve manages the `skills/` workspace entry; put skill content under `agent/skills/` instead.
</Warning>

Packaged sibling files are not pasted into the prompt. The model inspects them with `bash`, `read_file`, or `glob` when a loaded skill references them.

## Read skill files from tools and hooks

`load_skill` returns `SKILL.md` body text. To read packaged siblings from inside a tool or hook, use `ctx.getSkill(id)`:

```ts
const research = ctx.getSkill("research");
const checklist = await research.file("references/checklist.md").text();
```

The handle exposes `name` and lazy `file(relativePath)` accessors that read from the active sandbox. Call `ctx.getSkill()` only from authored runtime functions (tools, hooks, channel events) inside a managed runtime context with sandbox access.

## Dynamic instructions and skills

Static sources are the same on every session. When context depends on the caller (tenant, team, channel), wrap resolvers in `defineDynamic`:

- `agent/instructions/` — returns per-session system prompt via `defineInstructions`
- `agent/skills/` — returns the set of skills a caller can load via `defineSkill`

Both read `ctx.session.auth` or channel metadata. Dynamic skills reuse the same Available skills formatter for durable context announcements.

## Discovery diagnostics

Run `eve info` or `eve build` to surface discovery issues. Common skill and instruction failures:

| Code | Cause |
| --- | --- |
| `discover/required-instructions-missing` | Root agent has no `instructions.md`, `.ts`, or `instructions/` directory |
| `discover/slot-collision` | Both `instructions.md` and `instructions.ts` at the agent root |
| `discover/skill-collision` | Conflicting sources for the same skill id (e.g. `foo.md` and `foo/` directory) |
| `discover/skill-markdown-missing` | Packaged skill directory lacks `SKILL.md` |
| `discover/skill-frontmatter-invalid` | Invalid YAML frontmatter or missing required `description` on packaged `SKILL.md` |

## Recommended layout

<Steps>
<Step title="Write stable identity in instructions">
Keep `agent/instructions.md` (or `.ts`) focused on rules that apply every turn. Move long procedures out.
</Step>
<Step title="Add on-demand procedures as skills">
Author flat `.md` skills for simple cases; use packaged directories when you need `references/`, `assets/`, or `scripts/`.
</Step>
<Step title="Verify discovery">
Run `eve info` and confirm skills appear with sensible descriptions and no collision diagnostics.
</Step>
<Step title="Exercise activation in dev">
Run `eve dev`, send a request that matches a skill description, and confirm the model calls `load_skill` before following the procedure.
</Step>
</Steps>

## Related pages

<CardGroup>
<Card title="Context control" href="/context-control">
Always-on instructions vs on-demand skills, workspace visibility, and dynamic capabilities.
</Card>
<Card title="Default harness" href="/default-harness">
Built-in `load_skill` tool, compaction defaults, and framework tool overrides.
</Card>
<Card title="Project layout" href="/project-layout">
Authored slots under `agent/`, path-derived naming, and what compiles into `.eve/`.
</Card>
<Card title="Sandbox" href="/sandbox">
Workspace seeding, sandbox backends, and bootstrap lifecycle.
</Card>
<Card title="State, hooks, and context" href="/state-hooks-and-context">
`ctx.getSkill`, `ctx.getSandbox`, and where managed-context APIs are valid.
</Card>
<Card title="Tools" href="/tools">
Typed executable integrations — the counterpart to instruction-only skills.
</Card>
</CardGroup>
