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

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. This struct captures all metadata required to identify, describe, and execute a skill:

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:

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 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)

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. 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:

run_skill – Full Execution

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 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 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:

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) constructs an event.Profile:

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

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

# Note

{{Arguments}}

Please write the note to a file.

Save as .reasonix/skills/note.md. The {{Arguments}} placeholder receives the string passed at invocation.

Invoking the Skill

{
  "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

---
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

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

Returns the raw markdown without spawning any execution context.


Key Source Files

File Responsibility
internal/skill/skill.go Skill struct, Store, discovery logic, RunAs modes
internal/skill/tools.go runSkillTool, readSkillTool, readOnlySkillTool, profileForSkill
internal/skill/index.go System-prompt index generation (names + descriptions only)
internal/skill/builtins.go Built-in skills (explore, research, etc.)
internal/agent/usecapability.go Routes skill:<name> capability invocations
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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →