Understanding the Output¶
What you'll learn: What a behavioral trace is, what each field means, and the three kinds of "logging" in Kyvvu.
The behavioral trace¶
Every step your agent takes produces a structured JSON record — a Behavior. The complete sequence of Behaviors within a task is the behavioral trace. This is the audit trail Kyvvu produces.
A single Behavior looks like:
{
"agent_id": "ag_abc123",
"task_id": "task-def456",
"action_id": "3f6a1c0e9b2d4e7f8a5b6c7d8e9f0a1b",
"seq": 2,
"kind": "step.model",
"verb": null,
"step_name": "call_llm",
"input": {"prompt": "What's the weather?"},
"output": {"response": "(mocked response)"},
"properties": {"model": "gpt-4o"},
"meta": {
"kyvvu.eval": {
"action": "allow",
"risk_score": 0.0,
"policies": []
}
},
"timestamp": "2026-04-29T10:00:00.000000Z"
}
Field reference¶
| Field | Type | Description |
|---|---|---|
agent_id |
string | The registered agent's unique identifier. |
task_id |
string | Identifies this task (one end-to-end agent execution). |
action_id |
string | Identifies this action, unique within the task. Present on every step.*; may be absent on task.* boundaries. |
seq |
integer | Orders the task's steps: strictly increasing within the task, assigned by the client that opened it. It may have gaps and does not count steps. |
kind |
string | The atomic behaviour type (step.model, step.resource, task.start, etc.). |
verb |
string or null | HTTP-style verb (GET, POST, PATCH, DELETE) or null. |
step_name |
string | A human-readable name for the step (function name, tool name). |
input |
dict or null | The step's input data (function arguments, prompt, query). |
output |
dict or null | The step's output data (function return value, response). |
properties |
dict | Structured metadata — target system, auth access level, model info. |
meta |
dict or null | Engine- and framework-reserved metadata. Keys starting with kyvvu. are reserved for Kyvvu; a caller cannot set them. The engine stamps kyvvu.eval (the action, risk_score, and per-policy results from the pre-execution evaluation) on each evaluated step it records, a blocked one included; framework adapters add correlation fields (parent task ID, chain run ID). |
timestamp |
RFC 3339 | When the agent initiated the step, in UTC with microseconds and a Z suffix. |
See Atomic Behaviours for the complete vocabulary of action kinds and valid combinations.
Three kinds of "logging"¶
Kyvvu involves three distinct logging concepts. They are unrelated and should not be confused:
1. Application logging (Python logger)¶
Standard Python logging output from the Kyvvu engine and the Python client. Controlled by KV_LOG_LEVEL. Set to DEBUG for detailed per-evaluation traces:
Diagnostic message (timestamp omitted):
kyvvu_engine.engine DEBUG evaluate(): agent_id=agent-123 kind=step.model → action=allow risk_score=0.00 (7 policies)
This is diagnostic output for debugging. It goes to stdout by default.
2. Behavioral trace logging (engine batch flush)¶
The structured JSON Behaviors described above. The engine queues recorded
steps for delivery at the latest when the task ends (end_task()); a task may
be delivered in several batches. A background worker sends them, so a short
script calls kv.flush() before it exits.
Where they go is KV_LOG_LOCATION, and its default is auto: the trace
follows the policy source. An agent configured with KV_API_KEY and
KV_AGENT_KEY gets its policies from the platform, so it sends its steps
there too and they appear on the Logs page. An offline run — one driven by a
local manifest (KV_POLICY_FILE, or kyvvu try) — prints to stdout instead,
even in a shell that exports an API key, so a local trial never ships its
trace to the network.
To pin the destination yourself:
export KV_LOG_LOCATION=https://platform.kyvvu.com # always the platform
export KV_LOG_FORMAT=kv
export KV_LOG_LOCATION=stdout # always the terminal
To disable trace output entirely:
export KV_LOG_LOCATION=none
3. Platform event logging (API events module)¶
Server-side audit trail in the Kyvvu platform. Records platform-level events (policy changes, user logins, agent registrations). Visible in the dashboard under Workspace → Platform Events. Not something you configure in the Python client.
Reading the trace in the dashboard¶
When KV_LOG_LOCATION resolves to the platform API — which the default auto does for any agent whose policies come from the platform — behavioral traces appear in the dashboard:
- Navigate to Logs in the sidebar.
- Filter by agent, task ID, or time range.
- Click a task to see the full ordered sequence of steps.
- Each step shows its evaluation result (allow/warn/block), applicable policies, and the Behavior data.
The engine hash-chains each task's entries and the platform verifies the chain when it ingests them. The hash input fields are agent_id, task_id, seq, input_data (the stored input), and previous_hash (only when a previous entry exists). Only those fields are covered. The chain does not cover action_id, step_name, kind, verb, timestamp, output, properties, or meta; changing only those fields does not fail validation. A wider hash format is planned for engine 1.1. The Python client sends the engine's seq and hash with each entry; a trace written to stdout or a file carries no platform chain. The dashboard validates the covered fields against stored hashes.
This is chain v1. A valid result shows that the stored entries agree with their stored hashes; it is not proof against anyone with write access to the platform's database, who could recompute it. A client-signed chain that the platform can only append to is planned for engine 1.1.
Payload redaction¶
For GDPR-sensitive environments, you can redact input/output from the trace:
export KV_LOG_PAYLOADS=metadata_only
In this mode, present behavioral input and output values are replaced with:
{"redacted": true, "keys": ["prompt"], "length": 1}
The summary shows which top-level fields were present and how many there
were. For these dictionary payloads, length counts top-level keys; values
are stripped.
Absent payloads stay absent. Task markers carry no input or output, and a completed gate retains its output.decision.
Next steps¶
- Atomic Behaviours — the 12 behaviour types that form the vocabulary
- Policies and Rules — how policies evaluate against behaviours
- Architecture — the package split and data flow