Skip to content

Skills

A skill is a Markdown-plus-metadata bundle that tells the Platform Agent how to accomplish a particular class of task. Skills follow the Claude skills format — a SKILL.md file with YAML frontmatter (name, description) followed by procedural guidance the model reads on demand.

The full skill catalog is on the Skill catalog page. This page covers how they work.

agents/platform/skills/
├── gke-cluster-creation/
│ └── SKILL.md
├── gke-multitenancy/
│ └── SKILL.md
├── submit-suggestion/
│ ├── SKILL.md
│ └── (supporting scripts)
└── ... (32 more)

Skills are placed by persona: fleet-wide, provisioning, and GitOps-write skills live in agents/platform/skills/ (the Platform Agent); the six read-only, single-cluster runtime-debugging skills live in agents/cluster/skills/ and are scaffolded into every per-cluster Cluster Agent profile.

Some skills are pure Markdown; others carry supporting files (helper scripts, YAML templates) in the same directory. The Hermes runtime discovers SKILL.md files automatically at startup.

---
name: gke-multi-tenancy
description: Guidance on implementing multi-tenancy and governance in Google Kubernetes Engine (GKE) clusters.
---
  • name — the skill identifier. Snake/kebab case; matches the directory name.
  • description — a one-sentence purpose. The agent uses this to decide whether to load the skill for a given task without reading the whole body.

Anything after the frontmatter is procedural instruction: workflows, SOPs, example manifests, safety red lines. The model reads it only when it decides the skill is relevant to the current turn.

Two ways a skill enters the model’s context:

  1. On-demand. The agent notices from the user’s prompt (or a cron job’s prompt) that a particular skill’s description matches. It loads the skill body and follows the procedure.

  2. Explicit reference from a cron job. cron/jobs.json entries can name skills in the "skills" field. Each fleet audit, for example, always loads fleet-audit:

    {
    "id": "compliance-audit",
    "prompt": "Run the daily fleet security and RBAC posture audit. ...",
    "skills": ["fleet-audit"]
    }

    This route is only open to jobs that run a model. A no_agent job such as github-repo-watcher runs a script instead of a turn, so skills has nothing to load into; when its script files a kanban card, the card body names the skill and the worker loads it on demand.

Most shipping skills follow this shape:

  • Overview — one paragraph explaining what the skill does and when the agent should use it.
  • Workflows — numbered procedures for common tasks.
  • Examples — YAML manifests, shell commands, or link templates the model can adapt.
  • Safety red lines — explicit “don’t do X” rules (e.g. the submit-suggestion skill lists commit-scope guardrails).

The gke-compute-classes skill is a good example — it explicitly delineates when the agent should not invoke it, guarding against over-eager use.

  1. Create agents/platform/skills/<your-skill>/SKILL.md — or agents/cluster/skills/<your-skill>/SKILL.md if it is a read-only, single-cluster runtime-debugging procedure that belongs to the Cluster Agents.
  2. Add frontmatter with name and a specific description — this is what routes the agent to the skill.
  3. Write the procedure. Prefer concrete steps and example manifests over abstract descriptions.
  4. If the skill has safety-critical operations (destructive changes, wide-blast-radius commands), list explicit red lines the model must honor.
  5. Test locally: DM the agent in Chat with a prompt that should trigger the skill, and verify it loads and follows the procedure. (The DM lands at the Planning Agent front door; the skill itself loads in the delegated Platform Agent worker.)
  6. If the skill should also run on schedule, add an entry to agents/platform/cron/jobs.json — see Adding a watchdog.

The agent discovers skills from two locations at startup:

  • Baked into the imagedeploy/docker/Dockerfile copies agents/platform/skills/ to /opt/platform-template/skills/ (and agents/cluster/skills/ to /opt/cluster-template/skills/), which are overlaid into the matching profile’s home when the profile is created and then replaced from the template on every pod start. Skills are image-owned — nothing writes runtime state under them — so an upgraded pod runs the image’s skills, not whichever version first created its volume, and a skill deleted from the image disappears. The profile’s own runtime state (USER.md, memory/, sessions/, profile.yaml, and a Cluster Agent’s identity-stamped config.yaml) is untouched.
  • The profile’s runtime workspace at $HERMES_HOME/profiles/<profile>/skillsHERMES_HOME defaults to /opt/data, so the Platform Agent’s is /opt/data/profiles/platform/skills. This path is backed by the agent’s persistent volume. Note it is not /opt/data/skills: that is the default profile’s home, which belongs to the Planning Agent, and agents/chat/config.yaml disables the skills toolset there — a skill dropped in that directory is loaded by nothing.

That gives you two ways to bring in additional skills — for example from the upstream google/skills catalog.

Method 1 — bake into a custom image (production)

Section titled “Method 1 — bake into a custom image (production)”

Reproducible and immutable: the skill ships inside the container.

  1. Copy the skill directory into agents/platform/skills/<skill>/ (it must contain SKILL.md plus any references/).

  2. Build and push the platform image stage:

    Terminal window
    docker build -f deploy/docker/Dockerfile --target platform \
    -t my-registry/kube-agents/platform-agent:v1.1.0 .
    docker push my-registry/kube-agents/platform-agent:v1.1.0
  3. Point the PlatformAgent CR at the new image and apply it:

    apiVersion: kubeagents.x-k8s.io/v1alpha1
    kind: PlatformAgent
    metadata:
    name: platform-agent
    namespace: kubeagents-system
    spec:
    deployment:
    image: my-registry/kube-agents/platform-agent
    tag: v1.1.0

The operator rolls the Deployment and the new skill loads on boot.

Method 2 — inject into the running pod (development)

Section titled “Method 2 — inject into the running pod (development)”

Faster for iterating: drop the skill into the target profile’s persistent workspace without rebuilding. Copy into the profile that should load the skill — profiles/platform/skills for the Platform Agent, profiles/cluster-<name>/skills for one Cluster Agent.

Terminal window
# The agent pod carries the label app=platform-agent-gateway; the container is `platform-agent`.
AGENT_POD=$(kubectl get pods -n kubeagents-system \
-l app=platform-agent-gateway -o jsonpath='{.items[0].metadata.name}')
kubectl cp <skill-dir>/ \
kubeagents-system/$AGENT_POD:/opt/data/profiles/platform/skills/<skill-dir> -c platform-agent

Verify it landed:

Terminal window
kubectl exec -n kubeagents-system -it $AGENT_POD -c platform-agent -- \
ls -la /opt/data/profiles/platform/skills/<skill-dir>

The runtime discovers the skill on its next relevant turn. It does not survive a pod restart: the entrypoint replaces each specialist profile’s skills/ from the baked template on every start, so an injected skill lasts only as long as the pod. That is the point of Method 2 — it is an iteration loop, not a deployment mechanism. Bake the skill into the image (Method 1) to keep it.

A few related concepts that are easy to confuse:

  • Skill — a reusable capability the agent loads when relevant. Lives in skills/.
  • Governance SOP — a fleet-wide operating procedure (e.g. “audit blueprints daily”). Lives in governance/. Invoked by cron jobs.
  • Cron job — a scheduled prompt that fires an SOP or skill on a timer. Lives in cron/jobs.json.

Skills are on-demand tools; SOPs are the codified playbooks; cron jobs are the schedules that fire them.