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:
- Parsing the tool call arguments (name + arguments)
- Retrieving the
SkillfromStore - Validating capability gates via
ValidateInvocation - Inline path: Render body as markdown, return as tool result
- Subagent path: Dispatch to
SubagentRunnerwith 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:
inlinefolds content into current context;subagentspawns 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →