# How Skills Are Implemented and How They Interact with the Agent in DeepSeek‑Reasonix

> Discover how DeepSeek-Reasonix implements skills as reusable Markdown playbooks. Learn about the `run_skill`, `read_skill`, and `read_only_skill` tools that manage agent interactions.

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: internals
- Published: 2026-08-13

---

**DeepSeek‑Reasonix implements skills as reusable Markdown playbooks that are discovered, indexed, and executed through three core tools—`run_skill`, `read_skill`, and `read_only_skill`—which mediate all agent‑skill interactions.**

In the DeepSeek‑Reasonix architecture, skills provide a structured way to encapsulate repeatable workflows and domain expertise. This article examines the complete skill lifecycle from definition to execution, based on the source code in the `esengine/DeepSeek-Reasonix` repository.

---

## Skill Representation and Structure

At the core of the system is the **`Skill` struct** defined in [`internal/skill/skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/skill.go). This struct captures all metadata required to identify, describe, and execute a skill:

```go
type Skill struct {
    Name        string
    Description string
    Body        string      // Full markdown content
    Scope       Scope       // project | custom | global | builtin
    RunAs       RunAs       // inline | subagent
    Model       string      // Optional model override
    Requires    []string    // Capability gates
    // ... additional front-matter fields
}

```

The **`RunAs`** field controls execution semantics. As defined in [`skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/skill.go):

```go
const (
    RunInline   RunAs = "inline"    // Render in current context
    RunSubagent RunAs = "subagent"  // Spawn isolated child agent
)

```

Skills are authored as **Markdown files with YAML front‑matter**. The `store` package parses fields like `description`, `runAs`, `model`, `allowed-tools`, and `read-only` during load time.

---

## Skill Discovery and Indexing

The `Store` type in [`skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/skill.go) orchestrates discovery across multiple directory conventions:

| Priority | Location | Purpose |
|----------|----------|---------|
| 1 | `.reasonix/skills` | Project-local skills |
| 2 | `.agents` | Compatibility with other agent frameworks |
| 3 | `.claude` | Cross-tool portability |
| 4 | `~/.reasonix/skills` | User-global skills |
| 5 | Built-in | Shipped defaults ([`builtins.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/builtins.go)) |

Discovery follows a **winner-takes-all hierarchy**: project scope overrides custom, which overrides global, which overrides built-in.

### The Index: Cache-Stable, Body-Lazy

Only **names and descriptions** enter the system prompt index generated by [`internal/skill/index.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/index.go). This keeps the context window small and deterministic. The full `Skill.Body` loads only upon invocation—a critical optimization for large skill libraries.

---

## How the Agent Invokes Skills: The Tool Layer

The Agent never calls skills directly. Instead, the language model requests **tool calls** that the runtime maps to skill operations. Three tools implement the complete interface in [`internal/skill/tools.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/tools.go):

### `run_skill` – Full Execution

```go
type runSkillTool struct {
    store          *skill.Store
    subagentRunner SubagentRunner
}

```

The `Execute` method handles:
1. Parsing the tool call arguments (name + arguments)
2. Retrieving the `Skill` from `Store`
3. Validating capability gates via `ValidateInvocation`
4. **Inline path**: Render body as markdown, return as tool result
5. **Subagent path**: Dispatch to `SubagentRunner` with isolated context

### `read_skill` – Inspect Without Running

Returns the rendered Markdown body without executing any tool calls. Useful for planning steps where the model needs to understand a skill's logic before committing.

### `read_only_skill` – Sandboxed Subagent

Mirrors `run_skill` but forces a **read-only sub-agent runner**. No writer tools are available in the child context, enabling safe exploration of untrusted skills.

These tools are **registered during system boot** in [`internal/boot/boot.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/boot/boot.go) and become part of the model's available capabilities.

---

## Execution Modes: Inline vs Subagent

The distinction between `RunInline` and `RunSubagent` is fundamental to DeepSeek‑Reasonix's security and composability model.

### Inline Skills (`runAs: inline`)

- **Body renders** into the current turn as a tool result
- **Same context**: Model continues reasoning with skill content visible
- **No isolation**: Skill logic can influence immediate next steps

### Subagent Skills (`runAs: subagent`)

- **Isolated child loop**: Spawns a complete Agent instance
- **Skill body becomes system prompt**
- **Arguments become the task input**
- **SubagentRunner required**: If `nil`, execution fails with clear error
- **Final answer only**: Child reasoning never leaks into parent context

This pattern, implemented in [`tools.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/tools.go) lines 11–27, ensures that complex multi-step skills cannot corrupt or pollute the parent conversation state.

---

## Validation, Gating, and Profiles

### Capability Gates

Before execution, `ValidateInvocation` checks:

```go
if !s.hasRequiredCapabilities(skill.Requires) {
    return ErrInvocationUnavailable
}

```

Skills with unmet requirements are invisible to the model (when `Invocation: manual`) or return explicit errors (when directly called).

### Model Profile Resolution

Subagent skills may specify `model` and `effort` overrides. The `profileForSkill` function (lines 48–60 in [`tools.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/tools.go)) constructs an `event.Profile`:

```go
func profileForSkill(skill *Skill, customResolver ProfileResolver) event.Profile {
    if customResolver != nil {
        return customResolver(skill)
    }
    return event.Profile{
        Model:  skill.Model,
        Effort: skill.Effort,
    }
}

```

This enables dynamic GPU allocation and model selection based on skill-declared requirements.

---

## Practical Examples

### Defining an Inline Skill

```markdown
---
description: take a quick note
runAs: inline
---

# Note

{{Arguments}}

Please write the note to a file.

```

Save as [`.reasonix/skills/note.md`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/.reasonix/skills/note.md). The `{{Arguments}}` placeholder receives the string passed at invocation.

### Invoking the Skill

```json
{
  "name": "run_skill",
  "arguments": {
    "name": "note",
    "arguments": "Remember to check the logs tomorrow."
  }
}

```

The Agent renders the body, substitutes the argument, and returns the result.

### Subagent Skill with Custom Profile

```markdown
---
description: deep research on a topic
runAs: subagent
model: deepseek-pro
effort: max
requires: mcp-server:github
---
Perform a multi-step investigation of {{Arguments}} and return a concise summary.

```

The `requires` field gates access; the `model` and `effort` fields configure the sub-agent environment.

### Read-Only Inspection

```json
{
  "name": "read_skill",
  "arguments": {
    "name": "research"
  }
}

```

Returns the raw markdown without spawning any execution context.

---

## Key Source Files

| File | Responsibility |
|------|--------------|
| [`internal/skill/skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/skill.go) | `Skill` struct, `Store`, discovery logic, `RunAs` modes |
| [`internal/skill/tools.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/tools.go) | `runSkillTool`, `readSkillTool`, `readOnlySkillTool`, `profileForSkill` |
| [`internal/skill/index.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/index.go) | System-prompt index generation (names + descriptions only) |
| [`internal/skill/builtins.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/skill/builtins.go) | Built-in skills (`explore`, `research`, etc.) |
| [`internal/agent/usecapability.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/agent/usecapability.go) | Routes `skill:<name>` capability invocations |
| [`internal/boot/boot.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/boot/boot.go) | Tool registration at agent startup |

---

## Summary

- **Skills are Markdown playbooks** with YAML front‑matter defining metadata, execution mode, and requirements.
- **Discovery** scans `.reasonix/skills`, `.agents`, `.claude`, and home directories with project-local priority.
- **Indexing** keeps only names and descriptions in the system prompt; bodies load on demand.
- **Three tools**—`run_skill`, `read_skill`, `read_only_skill`—are the exclusive interface between agent and skills.
- **Two execution modes**: `inline` folds content into current context; `subagent` spawns isolated child agents.
- **Validation** enforces capability gates before execution; profile resolution enables custom model/effort configurations.

---

## Frequently Asked Questions

### What file format do DeepSeek‑Reasonix skills use?

Skills are authored as **Markdown files with YAML front‑matter**. The front‑matter includes `description`, `runAs` (inline or subagent), optional `model` and `effort` overrides, and `requires` for capability gating. The body contains the playbook logic with `{{Arguments}}` placeholders for parameter substitution.

### How does the Agent decide between inline and subagent execution?

The decision is **declared by the skill author** via the `runAs` front‑matter field, not determined at runtime. `runAs: inline` renders the skill body as a tool result in the current context. `runAs: subagent` triggers the `SubagentRunner` to spawn an isolated child agent where the skill body becomes the system prompt.

### What happens if a required capability is missing?

The `ValidateInvocation` method in [`skill.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/skill.go) checks all `requires` entries against enabled capabilities. If any requirement is unmet, the tool returns `ErrInvocationUnavailable`. For skills with `Invocation: manual`, the skill is excluded from the model-visible index entirely.

### Can the model inspect a skill before running it?

Yes. The **`read_skill`** tool loads and returns the skill body without execution. This allows planning phases where the model examines the playbook logic, understands required tools, and decides whether to invoke `run_skill` or request human clarification.