# How Kimi CLI Implements Skill Loading and Execution for Workflow Automation

> Discover how Kimi CLI loads and executes automation skills. Learn about skill discovery, slash command registration, and LLM context injection or flowchart parsing for efficient workflow automation.

- Repository: [Moonshot AI/kimi-cli](https://github.com/MoonshotAI/kimi-cli)
- Tags: internals
- Published: 2026-07-20

---

**Kimi CLI discovers automation skills by scanning built-in, user, and project directories for [`SKILL.md`](https://github.com/MoonshotAI/kimi-cli/blob/main/SKILL.md) files, registers them as slash commands (`/skill:<name>` and `/flow:<name>`), and executes them by either injecting the skill instructions into the LLM context or by parsing and running automated flowcharts.**

The Kimi CLI (MoonshotAI/kimi-cli) treats **skills** as self-contained automation units that extend the assistant's capabilities. When the interactive shell starts, it executes a discovery pipeline that resolves skill roots, indexes available capabilities, and registers them as first-class slash commands, enabling both manual invocation and deterministic workflow automation.

## Skill Discovery from Multiple Roots

The discovery process begins inside `resolve_skills_roots()` in [`src/kimi_cli/soul/agent.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/soul/agent.py) (lines 229–236), which aggregates skill directories from three distinct scopes:

- **Built-in**: Packaged skills located at `src/kimi_cli/skills`
- **User-level**: Global user directories such as `~/.kimi/skills` and `~/.agents/skills`
- **Project-level**: Local workspace directories like `.kimi/skills` or `.agents/skills`

Additional paths supplied via `--skills-dir` CLI arguments or the `extra_skill_dirs` parameter are appended to this list.

Once roots are resolved, `discover_skills_from_roots()` in [`src/kimi_cli/skill/__init__.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/skill/__init__.py) (lines 229–238) walks each directory tree. It identifies skills using two layout conventions:

- **Directory-based**: A subfolder containing a mandatory [`SKILL.md`](https://github.com/MoonshotAI/kimi-cli/blob/main/SKILL.md) file (canonical layout)
- **Flat file**: A single `<name>.md` file (supported since v0.69)

## The Skill Model and Indexing

For every discovered skill, the CLI instantiates a **`Skill`** model defined at lines 405–425 in [`src/kimi_cli/skill/__init__.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/skill/__init__.py). This dataclass captures:

- `name`: The invocation identifier
- `description`: Help text shown in command listings
- `type`: Either `standard` or `flow`
- `path`: Absolute filesystem location
- `flow`: A parsed `Flow` object (present only for flow-type skills)

The `index_skills()` function builds a dictionary mapping `name → Skill` for O(1) lookups during execution. Separately, `format_skills_for_prompt()` renders a concise catalog that is injected into the system prompt, allowing the LLM to reason about available tools without loading their full content.

## Registering Skills as Slash Commands

Inside `KimiSoul.__init__` at [`src/kimi_cli/soul/kimisoul.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/soul/kimisoul.py) (lines 858–891), each indexed skill is exposed as a slash command. The registration logic prepends `SKILL_COMMAND_PREFIX` (typically `/skill:`) to the skill name:

```python
name = f"{SKILL_COMMAND_PREFIX}{skill.name}"
self._runtime.register_slash_command(
    name,
    func=self._make_skill_runner(skill),
    description=skill.description or ""
)

```

**Flow skills** receive an additional registration: a `/flow:<name>` command that instantiates a `FlowRunner` rather than the standard text injector. This dual registration allows users to choose between manual LLM-guided execution (via `/skill:`) or automated graph traversal (via `/flow:`).

## Executing Standard Skills

When a user invokes `/skill:<name>`, the `_make_skill_runner()` method returns an async function that executes three steps:

1. **Load**: Calls `read_skill_text()` (lines 392–426 in [`src/kimi_cli/skill/__init__.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/skill/__init__.py)) to read the [`SKILL.md`](https://github.com/MoonshotAI/kimi-cli/blob/main/SKILL.md) file and inline any referenced external files.
2. **Compose**: Optionally appends the user's specific request (`extra` parameter).
3. **Inject**: Creates a new user message containing the combined text and passes it to `soul._turn()`, effectively prepending the skill instructions to the conversation context.

This causes the LLM to continue reasoning while adhering to the skill's embedded guidelines.

## Flow-Based Workflow Automation

**Flow skills** enable deterministic automation by encoding workflow logic as diagrams. When invoked via `/flow:<name>`, the system creates a `FlowRunner` instance (lines 1787–1825 in [`src/kimi_cli/soul/kimisoul.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/soul/kimisoul.py)).

The execution pipeline proceeds as follows:

1. **Parse**: The `Flow` object is extracted from the first Mermaid or D2 fenced code block inside [`SKILL.md`](https://github.com/MoonshotAI/kimi-cli/blob/main/SKILL.md) using parsers located in `src/kimi_cli/skill/flow/`.
2. **Traverse**: The runner starts at the virtual `BEGIN` node and walks the graph, prompting the LLM at each task node.
3. **Decide**: Edge selection is performed automatically using `parse_choice` on the LLM's reply, routing to the next node based on semantic intent.
4. **Terminate**: Execution halts when the `END` node is reached or an error boundary is encountered.

```text

# Example flow skill execution

>>> /flow:release
BEGIN → "Run unit tests" → "Build package" → "Deploy to production" → END

```

## Runtime Integration

The skill subsystem integrates with the UI layer through the runtime object in [`src/kimi_cli/soul/agent.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/soul/agent.py). This runtime passes the `skills` dictionary and allowed `skills_dirs` to the interactive shell frontend. In [`src/kimi_cli/ui/shell/slash.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/ui/shell/slash.py), the UI renders visible slash commands, handles tab-completion, and expands placeholders before dispatching to the registered runner functions.

## Summary

- **Multi-root discovery**: Scans built-in, user, and project directories via `resolve_skills_roots()` and `discover_skills_from_roots()`.
- **Structured indexing**: Creates `Skill` objects and builds a fast lookup index while formatting a lightweight catalog for the system prompt.
- **Dual command registration**: Exposes skills as `/skill:<name>` (text injection) and `/flow:<name>` (automated execution) via `KimiSoul.__init__`.
- **Flexible execution**: Standard skills inject [`SKILL.md`](https://github.com/MoonshotAI/kimi-cli/blob/main/SKILL.md) content into the LLM context; flow skills parse Mermaid/D2 diagrams and execute via `FlowRunner`.
- **Deterministic workflows**: Flow skills traverse nodes from `BEGIN` to `END`, automatically routing based on LLM responses parsed through `parse_choice`.

## Frequently Asked Questions

### What file structure defines a valid Kimi CLI skill?

A valid skill requires either a directory containing a [`SKILL.md`](https://github.com/MoonshotAI/kimi-cli/blob/main/SKILL.md) file (canonical layout) or a standalone `<name>.md` file (flat layout, supported since v0.69). The [`SKILL.md`](https://github.com/MoonshotAI/kimi-cli/blob/main/SKILL.md) file must include a YAML frontmatter block specifying at minimum the `name` and `description` fields, followed by the skill instructions or a flowchart definition.

### How does Kimi CLI prioritize skill directories when duplicates exist?

The CLI resolves skills in the order: built-in → user-level → project-level → extra directories. Later registrations overwrite earlier ones in the internal index, allowing project-level and user-level skills to override built-in defaults with the same name.

### What is the difference between `/skill:` and `/flow:` commands?

The `/skill:<name>` command loads the skill's text via `read_skill_text()` and injects it as a user message, allowing the LLM to interpret the instructions organically. The `/flow:<name>` command instantiates a `FlowRunner` that parses the embedded diagram and automatically executes the workflow graph, moving between nodes deterministically until reaching the `END` state.

### Can skills reference external files beyond [`SKILL.md`](https://github.com/MoonshotAI/kimi-cli/blob/main/SKILL.md)?

Yes. The `read_skill_text()` function in [`src/kimi_cli/skill/__init__.py`](https://github.com/MoonshotAI/kimi-cli/blob/main/src/kimi_cli/skill/__init__.py) resolves relative file references within the skill directory and inlines their contents into the final prompt text. This allows skills to modularize large instruction sets or include template files without bloating the main [`SKILL.md`](https://github.com/MoonshotAI/kimi-cli/blob/main/SKILL.md).