# Your First Agent

**What you'll learn:** How `kyvvu init` works, what the demo agent does, and how to read the policy evaluation output.

***

## Scaffold a project

```bash
kyvvu init my-agent
```

This scaffolds project files — `agent.py`, `requirements.txt`, `.env.example`, `.gitignore`, and `README.md`. No authentication is required.

The output looks like:

```
✓ Created my-agent/

Next steps:

    cd my-agent

    # Install requirements:
    pip install -r requirements.txt

    # Set your key:
    # (run `kyvvu register` if you have none)
    cp .env.example .env       # add your KV_API_KEY
    # or: export KV_API_KEY=your-key

    # Run the agent:
    python agent.py

To assign compliance policies, go to the dashboard:
    Manifests page → select a manifest → assign to your agent
Or use the CLI:
    kyvvu list-manifests
    kyvvu assign-manifest --agent-id <id> --repo-id <id> --manifest <path>
```

{% hint style="info" %}
**Caching:** `register_agent()` results are cached locally at `~/.kyvvu/registrations/`. If you call it on every startup with the same parameters, the SDK reuses the cached registration without a network call. You can safely call `register_agent()` every time your agent starts.
{% endhint %}

## Assign compliance policies

Policies are managed via **manifests** — YAML files stored in a GitHub repository. To assign policies to your agent:

1. Go to the **Manifests** page in the dashboard
2. Connect a repository containing manifest files (or use the default Kyvvu/manifests repo)
3. Click **Assign** on a manifest and select your agent

Or use the CLI:

```bash
kyvvu list-manifests
kyvvu assign-manifest --agent-id <id> --repo-id <id> --manifest owasp_agentic_default.yaml
```

See [Manifests](/policy-authoring/templates.md) for details on manifest structure and available policy sets.

## Run the demo agent

```bash
cd my-agent
pip install -r requirements.txt
export KV_API_KEY=KvKey-...
python agent.py
```

The demo agent (`agent.py`) defines three decorated functions:

```python
@kv.step(StepType.step_model, Verb.POST)
def call_llm(prompt: str) -> str:
    return f"(mocked response to: {prompt!r})"

@kv.step(StepType.step_resource, Verb.GET)
def fetch_user_data(user_id: str) -> dict:
    return {"user_id": user_id, "name": "Alice", "tier": "free"}

@kv.step(StepType.step_exec)
def run_script(code: str) -> str:
    return f"(would execute: {code!r})"
```

It starts a task, calls all three, and the third one gets blocked:

```
⛔ Policy blocked this step: ...
   Risk score: 1.00
   Action:     block
   * Code execution requires a preceding gate (critical)

This is Kyvvu working as intended — the OWASP security policies
flagged an action that requires oversight. In a real agent, you'd
add a step.gate (human approval) before the blocked action.
```

## What happened

The `@kv.step` decorator wraps each function call in a three-phase cycle:

1. **Evaluate** — the engine checks the intended behaviour against all applicable policies. It reads the task's history to make path-dependent decisions.
2. **Execute** — if the evaluation returns `allow` or `warn`, the function runs.
3. **Record** — the completed step (with output) is appended to the task's history for future evaluations.

Steps 1 and 2 passed for `call_llm` and `fetch_user_data`. When `run_script` was evaluated:

* The engine identified it as `step.exec` (code execution).
* The OWASP policy "Code execution requires a preceding gate" checked whether a `step.gate` existed earlier in the task history.
* No gate was found. The policy has severity `critical`, so the engine returned `block`.
* The decorator raised `KyvvuBlockedError` instead of executing the function.

## Inspect the policies

```bash
kyvvu list-policies
```

This shows policies assigned to your agent via manifests. If no manifest has been assigned yet, the list will be empty.

```
 NAME                                        SCOPE               RULE_TYPE              SEVERITY  SOURCE                       ENABLED
 Agent must declare a substantive purpose    agent_registration  field_matches_regex    high      owasp_agentic_default.yaml   ✓
 Agent must declare a tool allowlist         agent_registration  field_not_empty        high      owasp_agentic_default.yaml   ✓
 Agent must declare a valid risk class.      agent_registration  field_in_list          critical  owasp_agentic_default.yaml   ✓
 Tool calls must be in the declared allow.   step_execution      step_name_in_allowlist critical  owasp_agentic_default.yaml   ✓
 Code execution requires a preceding gate    step_execution      step_requires_gate     critical  owasp_agentic_default.yaml   ✓
 Destructive resource ops require a gate     step_execution      step_requires_gate     critical  owasp_agentic_default.yaml   ✓
 External content taint requires fresh gate  step_execution      not                    critical  owasp_agentic_default.yaml   ✓
 Bound resource calls per task (max 50)      step_execution      execution_max_steps    high      owasp_agentic_default.yaml   ✓
```

Each policy is an instance of a **rule** with specific **parameters**. For example, "Code execution requires a preceding gate" uses the `step_requires_gate` rule with `target_step_types: ["step.exec"]`. The same rule backs "Destructive resource ops require a gate" with different parameters (`target_step_types: ["step.resource"]`, `target_verb: "DELETE"`).

For the full details of each OWASP policy, see [OWASP Default Manifest](/policy-authoring/owasp-default.md).

***

## Next steps

* [Understanding the Output](/getting-started/understanding-output.md) — learn what each field in the behavioral trace means
* [OWASP Default Template](/policy-authoring/owasp-default.md) — the 8 default policies explained in detail
* [Python Decorator](/integrations/decorator.md) — full reference for `@kv.step`


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kyvvu.com/getting-started/first-agent.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
