Skip to main content
KRAIT

Skills System

Understand how KRAIT skills are structured, validated, and tested as Elixir modules.

What Is a Skill?

A skill is an Elixir module that implements the Krait.Skill behaviour. Skills are the atomic unit of agent capability — each one handles a specific task like parsing a file format, calling an API, or transforming data. When KRAIT self-evolves, it produces new skill modules.

The Skill Behaviour

Every skill must implement three callbacks:

defmodule Krait.Skill do
  @callback name() :: String.t()
  @callback description() :: String.t()
  @callback run(input :: map(), context :: Krait.Context.t()) ::
              {:ok, result :: term()} | {:error, reason :: term()}
end

Here is a minimal skill that reverses a string:

defmodule MyAgent.Skills.ReverseString do
  @behaviour Krait.Skill
  @moduledoc "Reverses a given string."

  @impl true
  def name, do: "reverse_string"

  @impl true
  def description, do: "Reverses the characters in a string."

  @impl true
  def run(%{"text" => text}, _context) when is_binary(text) do
    {:ok, String.reverse(text)}
  end

  def run(_input, _context) do
    {:error, :invalid_input}
  end
end

Validation Pipeline

Before any skill — whether hand-written or agent-generated — is loaded into the running system, it passes through the validation pipeline:

  1. Compilation check — The module must compile without warnings under Mix.compile/1.
  2. Behaviour conformance — All three callbacks must be implemented with correct arities.
  3. Narsil security scan — The module is scanned against the active rule set (see Configuration).
  4. Sandbox testing — Generated test cases are executed inside the Docker sandbox to verify the skill's run/2 returns expected results.

If any step fails, the skill is rejected with a structured error that the agent can use to iterate.

Writing Tests for Skills

KRAIT auto-generates tests during evolution, but you can also write them manually. Skill tests use standard ExUnit with a helper macro:

defmodule MyAgent.Skills.ReverseStringTest do
  use Krait.SkillCase, skill: MyAgent.Skills.ReverseString

  test "reverses a simple string" do
    assert {:ok, "olleh"} = run_skill(%{"text" => "hello"})
  end

  test "returns error on invalid input" do
    assert {:error, :invalid_input} = run_skill(%{"number" => 42})
  end
end

The Krait.SkillCase macro provides run_skill/1, which constructs a test context and invokes the skill's run/2 callback.

Rust NIFs in Skills

For performance-critical skills, you can delegate to Rust NIFs. KRAIT includes a Krait.NIF helper that manages compilation and loading:

defmodule MyAgent.Skills.FastHash do
  @behaviour Krait.Skill
  use Krait.NIF, rust_module: "fast_hash"

  @impl true
  def name, do: "fast_hash"

  @impl true
  def description, do: "Computes a BLAKE3 hash using a Rust NIF."

  @impl true
  def run(%{"data" => data}, _context) do
    {:ok, native_hash(data)}
  end
end

The Rust source lives in native/fast_hash/src/lib.rs and is compiled automatically when the skill is loaded.

Next Steps