Skip to content

Your first Kind

In about ten minutes you will load a DNA scope, get typed access to a real marketplace Skill, and compose an Agent's system prompt — all from YAML/Markdown files, with no code change to alter behavior.

Everything here runs against examples/hello-genome, a minimal scope with one Genome, one Agent, and one real marketplace Skill. The runtime is Python; if you are reaching DNA from another language, see Talking to DNA from another language — the concepts below are identical, only the door changes.

Prerequisites

  • Python 3.12+.
pip install dna-sdk

Pre-release / exact-pin alternative: use the package straight from the repo — cd packages/sdk-py && uv sync. Either way, clone the repo to follow along — the example scope lives in it: git clone https://github.com/ruinosus/dna && cd dna.

Step 1 — A scope is a directory of manifests

A scope is a directory of instances under .dna/<scope-name>/. The hello-genome scope looks like this:

.dna/
└── hello-genome/
    ├── Genome.yaml            # scope root: identity + default agent
    ├── agents/
    │   └── greeter.yaml       # kind: Agent — instruction + skill wiring
    └── skills/
        └── verification-before-completion/
            └── SKILL.md        # kind: Skill — a real marketplace bundle

Three instances, three Kinds. Note the namespaces: Genome and Agent are DNA's own Kinds (github.com/ruinosus/dna/v1), while the Skill is a market format — DNA reads it byte-faithful under its owner's namespace, agentskills.io/v1. (Why that matters: Market fidelity.)

The scope root (Genome)

Every scope is rooted by exactly one Genome — its identity instance.

.dna/hello-genome/Genome.yaml
apiVersion: github.com/ruinosus/dna/v1
kind: Genome
metadata:
  name: hello-genome
spec:
  default_agent: greeter

The Agent

The Agent declares an instruction and references a skill by name. It does not inline the skill's text — that composition happens on read.

.dna/hello-genome/agents/greeter.yaml
apiVersion: github.com/ruinosus/dna/v1
kind: Agent
metadata:
  name: greeter
spec:
  instruction: |
    You are Helio, a friendly assistant.
  skills: [verification-before-completion]

Step 2 — Load the scope

Kernel.quick() / quickInstance() auto-wire the filesystem source and cache, the default resolvers (local:, github:, http(s):), and every built-in extension. One call gives you a ManifestInstance (mi) — the query surface over the loaded scope.

from dna import Kernel

mi = Kernel.quick("hello-genome", base_dir="examples/hello-genome/.dna")

print(f"scope: {mi.scope}")
for d in mi.instances:
    print(f"  {d.api_version:32s} {d.kind:8s} {d.name}")

Every instance is identified by (apiVersion, kind, name):

scope: hello-genome
  agentskills.io/v1                Skill    verification-before-completion
  github.com/ruinosus/dna/v1       Genome   hello-genome
  github.com/ruinosus/dna/v1       Agent    greeter

The _lib parent scope

You may see a log line about a _lib parent scope: every scope can inherit shared instances from a sibling .dna/_lib/ library scope. Create the (empty) directory to silence it, or put shared agents/skills there to actually use it. See Tenancy and layers.

Step 3 — Typed access to a Kind

mi.instances is the blessed query surface: filter by kind and name, then read typed fields.

skill = next(d for d in mi.instances if d.kind == "Skill")
print(skill.typed.metadata.name)
print(skill.typed.metadata.description)

The Skill's frontmatter was parsed into a typed model — you did not need to know anything about the agentskills.io format to read it.

Step 4 — Compose a prompt

Now the payoff. The Agent references a skill; the SDK composes the Agent's instruction with its wired-in Kinds into a single system prompt, on read:

print(mi.build_prompt(agent="greeter"))

You never wrote that composed prompt down — it is derived from the authored spec. That is the thesis in one call: the instance is intent; the prompt is the observed state the kernel reconciles into.

Step 5 — Change behavior with a file edit

Open agents/greeter.yaml, change the instruction or the wired skills, and re-run Step 4. The prompt changes — with no rebuild and no redeploy. That is the whole of it: behavior is data.

Run the finished example

The steps above are packaged as a runnable script in the repo, exercised by the test suite so it can never silently rot:

cd packages/sdk-py && uv sync
uv run python ../../examples/hello-genome/run.py

Next steps