> For the complete documentation index, see [llms.txt](https://docs.kyvvu.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kyvvu.com/core-concepts/templates.md).

# Templates

> **Note:** This page covers **behavior templates** — YAML rules that map framework events to Kyvvu Behaviors. For **policy manifests** (compliance policy sets assigned to agents), see [Manifests](/policy-authoring/templates.md).

**What you'll learn:** How YAML templates map framework events to Behaviors, how matching works, and how to customize templates.

***

## What templates do

Templates are the translation layer between your framework's events and Kyvvu's canonical vocabulary. When your agent calls an LLM, reads a database, or sends a message, the SDK needs to know which `(step_type, verb)` pair to use, and which properties to set. Templates define this mapping.

Without templates, every integration would need hardcoded mappings. With templates, the same SDK can support any framework — you just write a YAML file.

## Built-in templates

The template **engine** (loading, matching, interpolation) lives in `kyvvu_engine.templates`. The SDK ships the bundled template **YAML files** and a small `load(name)` helper that returns an engine `BehaviorTemplate`:

```python
from kyvvu.templates import load

decorator_template = load("decorator")
langchain_template = load("langchain")
```

The SDK bundles four per-integration templates:

* **`decorator`** — for the `@kv.step` decorator integration. Maps decorator arguments directly to Behavior fields.
* **`langchain`** — for the LangChain/LangGraph callback handler. Maps LangChain callback events (`on_llm_start`, `on_tool_start`, etc.) to Behaviors.
* **`langgraph`** — for LangGraph graph executions.
* **`crewai`** — for CrewAI agents.

Each integration (and kyvvu-claude) loads its own template by path. To load any template file directly, use the engine loader:

```python
from kyvvu_engine.templates import BehaviorTemplate, load_template

tpl = BehaviorTemplate.from_path("/path/to/template.yaml")  # or load_template(...)
```

## How matching works

Templates use **first-match-wins** rule evaluation. Each template contains an ordered list of rules. For each framework event, the SDK walks the rules top to bottom and uses the first match.

Each rule has:

* **Conditions** — predicates on the framework event (event type, function name, arguments).
* **Output** — the Behavior fields to set (`step_type`, `verb`, `properties`).

If no rule matches, the template falls back to `step.unknown`.

## Deep-merge semantics

When the SDK constructs a Behavior, it deep-merges three sources (in order of priority):

1. **Caller overrides** — values passed explicitly via `@kv.step(properties={...})` or `kv.start_task(properties={...})`.
2. **Template output** — the matched rule's output.
3. **Framework defaults** — base values from the framework event itself.

**Caller overrides win at leaves.** If the template sets `properties.model.provider = "openai"` and the caller sets `properties.model.name = "gpt-4o"`, the result is `{model: {provider: "openai", name: "gpt-4o"}}`. But if the caller sets `properties.model.provider = "anthropic"`, the caller's value wins.

## Template properties vs. tool metadata

For LangChain and LangGraph, a tool can declare its own Kyvvu attributes under `metadata["kyvvu"]`, co-located with the tool definition. Those attributes **deep-merge over the template-matched properties**: the tool's value wins on any leaf conflict, siblings from the template are preserved, and a runtime warning is logged when a tool overrides a template-set property. In short, code wins over the org baseline. See [LangChain / LangGraph — Attaching Kyvvu attributes to tools](/integrations/langchain.md#attaching-kyvvu-attributes-to-tools-two-layers) for the full picture.

## Two tiers of developer effort

Templates support two levels of detail:

### Lazy (generic fallback)

Use the built-in templates without customization. Every step gets a correct `step_type` and `verb` based on the framework event. Properties are sparse — mostly framework-inferred defaults.

This is fine for getting started and for development-time tracing.

### Rich (named rules with properties)

Write a custom template with rules that match specific functions and set detailed properties — target system, data classification, auth access level, domain. This enables fine-grained policies that check properties like `target.table == "customer-data"` or `target.trust == "external"`.

This is what production deployments use.

## Loading custom templates

Two ways to use a custom template:

```python
from kyvvu_engine.templates import BehaviorTemplate

# Constructor kwarg
custom = BehaviorTemplate.from_path("/path/to/template.yaml")
kv = Kyvvu(api_key="...", agent_key="bot", template=custom)

# Environment variable (resolution order: template kwarg > KV_TEMPLATE_LOCATION > built-in)
# export KV_TEMPLATE_LOCATION=/path/to/template.yaml
kv = Kyvvu(api_key="...", agent_key="bot")
```

## Template YAML structure

A minimal template:

```yaml
name: my-agent-template
version: "1.0"

rules:
  - name: llm_call
    conditions:
      step_type: step.model
    output:
      properties:
        model:
          provider: openai
          name: gpt-4o

  - name: db_read
    conditions:
      step_name: read_customer
    output:
      step_type: step.resource
      verb: GET
      properties:
        target:
          system: postgres
          table: customer-data
          trust: internal
        data:
          classification: pii

  - name: fallback
    conditions: {}
    output:
      step_type: step.unknown
```

Rules are evaluated in order. The `fallback` rule with empty conditions matches everything and should be last.

***

## Next steps

* [Python Decorator](/integrations/decorator.md) — how `@kv.step` uses templates
* [LangChain / LangGraph](/integrations/langchain.md) — the LangChain callback handler and its template
* [Writing a New Integration](/integrations/custom.md) — how to author templates for other frameworks

## Further reading

* [Template Authoring Guide](/integrations/authoring.md) — step-by-step walkthrough for creating a custom behavioral template, including match semantics, property extraction, and a worked example.
* [Agent Pattern Templates](https://github.com/Kyvvu/platform/tree/main/kyvvu-sdk/kyvvu/templates/patterns/README.md) — reference snippets for common agent architectures (RAG, ReAct, human-in-the-loop, multi-agent) that show how to map these patterns to Kyvvu's behavior vocabulary.
