Autonomous Agents
Kanoniv includes 12 autonomous agents that maintain your identity graph between reconciliation runs. Agents observe the state of your data, decide what actions to take, and execute them - with optional human approval gates.
Cloud-only
Agents require Kanoniv Cloud. They run on the server-side scheduler and are configured via the API or CLI. All agent API endpoints require admin role.
Quick Start
1. Enable an agent
kanoniv agent enable auto_merge \
--settings '{"min_confidence": 0.95, "require_approval": true}'import httpx
httpx.put(
"https://api.kanoniv.com/v1/agents/configs/auto_merge",
headers={"X-API-Key": "your-key"},
json={
"enabled": True,
"settings": {
"min_confidence": 0.95,
"require_approval": True
}
}
)curl -X PUT https://api.kanoniv.com/v1/agents/configs/auto_merge \
-H "X-API-Key: your-key" \
-H "Content-Type: application/json" \
-d '{"enabled": true, "settings": {"min_confidence": 0.95, "require_approval": true}}'2. Trigger a run
kanoniv agent trigger auto_mergecurl -X POST https://api.kanoniv.com/v1/agents/configs/auto_merge/trigger \
-H "X-API-Key: your-key"3. Review and approve
# List pending actions
kanoniv agent actions --status pending
# Approve one
kanoniv agent approve 550e8400-e29b-41d4-a716-446655440000# List pending actions
curl https://api.kanoniv.com/v1/agents/actions?status=pending \
-H "X-API-Key: your-key"
# Approve one
curl -X POST https://api.kanoniv.com/v1/agents/actions/550e8400-.../approve \
-H "X-API-Key: your-key"Agent Modes
Every agent operates in one of three modes:
| Mode | Behavior | When to use |
|---|---|---|
| Auto-execute | Actions execute immediately. No human review. | Dev/staging, high-confidence agents |
| Approval-required | Actions queue for human review before executing. | Production, lower-confidence decisions |
| Disabled | Agent does not run. Config preserved. | Temporarily pausing an agent |
Set the mode via require_approval in settings and enabled on the config:
// Auto-execute (default for most agents)
{ "enabled": true, "settings": { "require_approval": false } }
// Approval-required
{ "enabled": true, "settings": { "require_approval": true } }
// Disabled
{ "enabled": false }Agent Types
Core Agents
auto_merge
Automatically merges high-confidence entity pairs from the identity graph.
Observes match_audit for unacted pairs above the merge threshold, verifies they are not locked or overridden, then merges them.
| Setting | Type | Default | Constraints | Description |
|---|---|---|---|---|
min_confidence | float | 0.95 | 0.0 - 1.0, must be >= plan's merge threshold | Minimum match score to merge |
max_actions_per_run | int | 50 | >= 1 | Maximum merges per run |
min_interval_seconds | int | 300 | >= 10 | Seconds between runs |
require_approval | bool | false | - | Queue actions for review |
Example - Conservative production setup:
{
"min_confidence": 0.98,
"max_actions_per_run": 20,
"min_interval_seconds": 600,
"require_approval": true
}auto_split
Detects and splits incoherent entity clusters by rescoring all internal pairs. If the average pairwise score within a cluster falls below coherence_threshold, the weakest-linked member is ejected into a new entity.
| Setting | Type | Default | Constraints | Description |
|---|---|---|---|---|
coherence_threshold | float | 0.3 | 0.0 - 1.0 | Average score below this triggers split |
min_cluster_size | int | 3 | >= 2 | Only check clusters with at least this many members |
max_actions_per_run | int | 20 | >= 1 | Maximum splits per run |
min_interval_seconds | int | 600 | >= 10 | Seconds between runs |
require_approval | bool | false | - | Queue actions for review |
Example - Only split large, clearly incoherent clusters:
{
"coherence_threshold": 0.2,
"min_cluster_size": 5,
"max_actions_per_run": 10,
"require_approval": true
}auto_discover
Profiles tenant data periodically to detect new identity signals not covered by the current plan. Runs the field profiler over sampled records and compares against the existing identity plan. New signals are written as memory entries for review - this agent does not modify the plan directly.
| Setting | Type | Default | Constraints | Description |
|---|---|---|---|---|
min_interval_seconds | int | 86400 | >= 60 | Seconds between runs (default: daily) |
sample_size | int | 500 | >= 50 | Rows to sample for profiling |
Example - Run discovery every 12 hours with a larger sample:
{
"min_interval_seconds": 43200,
"sample_size": 1000
}auto_bootstrap
Generates an identity plan for tenants with data but no existing plan. Profiles the data, builds a plan via the field profiler, and either applies it directly or creates a pending action for review.
| Setting | Type | Default | Constraints | Description |
|---|---|---|---|---|
sensitivity | float | 0.5 | 0.0 - 1.0 | 0.0 = conservative, 1.0 = aggressive matching |
min_interval_seconds | int | 3600 | >= 60 | Seconds between runs |
auto_apply | bool | false | - | If true, plan is persisted directly without review |
Example - Bootstrap with human review:
{
"sensitivity": 0.5,
"auto_apply": false
}auto_tune
Runs mutation search to optimize identity plan thresholds using data and feedback labels. Samples up to 200,000 entities for memory safety.
| Setting | Type | Default | Constraints | Description |
|---|---|---|---|---|
max_iterations | int | 50 | >= 1 | Maximum mutation search iterations |
min_interval_seconds | int | 604800 | >= 3600 | Seconds between runs (default: weekly) |
auto_apply | bool | false | - | If true, persist optimized plan directly |
max_conflict | float | 0.05 | 0.0 - 1.0 | Maximum acceptable conflict rate |
max_entities | int | 200000 | >= 100 | Maximum entities to sample for tuning |
Example - Weekly tuning with conservative conflict tolerance:
{
"max_iterations": 100,
"max_conflict": 0.03,
"auto_apply": false
}scheduled_reconcile
Runs full batch reconciliation on a configurable schedule. Optionally skips if no new data has arrived since the last run.
| Setting | Type | Default | Constraints | Description |
|---|---|---|---|---|
min_interval_seconds | int | 3600 | >= 300 | Seconds between runs |
require_data_change | bool | true | - | Skip if no new data since last run |
Example - Reconcile hourly, only when data changes:
{
"min_interval_seconds": 3600,
"require_data_change": true
}quality_monitor
Tracks reconciliation quality metrics and alerts on degradation. Compares the latest run against a rolling baseline computed from recent runs. Writes findings as memory entries - this agent does not take corrective actions.
| Setting | Type | Default | Constraints | Description |
|---|---|---|---|---|
min_interval_seconds | int | 3600 | >= 300 | Seconds between runs |
merge_rate_drop_threshold | float | 0.10 | 0.0 - 1.0 | Merge rate drop that triggers alert |
conflict_rate_rise_threshold | float | 0.05 | 0.0 - 1.0 | Conflict rate rise that triggers alert |
baseline_run_count | int | 5 | >= 2 | Recent runs used for baseline |
Example - Tight quality monitoring:
{
"merge_rate_drop_threshold": 0.05,
"conflict_rate_rise_threshold": 0.02,
"baseline_run_count": 10
}feedback_learner
Retrains Fellegi-Sunter parameters when enough feedback labels accumulate. Runs supervised EM using the labels to refine match/non-match weight distributions.
| Setting | Type | Default | Constraints | Description |
|---|---|---|---|---|
min_labels | int | 20 | >= 5 | Minimum new labels to trigger retraining |
learning_rate | float | 0.3 | 0.0 - 1.0 | 0.0 = keep existing, 1.0 = fully replace |
min_interval_seconds | int | 86400 | >= 3600 | Seconds between runs (default: daily) |
auto_apply | bool | false | - | If true, persist updated plan directly |
Example - Cautious learning from analyst feedback:
{
"min_labels": 50,
"learning_rate": 0.2,
"auto_apply": false
}Graph Agents
merge_recommender
Surfaces high-weight cross-cluster relationship edges as merge candidates. Queries relationship_edges for pairs that belong to different canonical entities but have strong connections.
| Setting | Type | Default | Constraints | Description |
|---|---|---|---|---|
min_edge_weight | float | 0.75 | 0.0 - 1.0 | Minimum relationship weight to consider |
max_actions_per_run | int | 50 | >= 1 | Maximum recommendations per run |
min_interval_seconds | int | 3600 | >= 300 | Seconds between runs |
require_approval | bool | true | - | Queue actions for review (default: true) |
Example - Only surface very strong connections:
{
"min_edge_weight": 0.9,
"max_actions_per_run": 25,
"require_approval": true
}graph_anomaly
Detects structural anomalies in the identity graph: orphan entities (no identity links), unusually dense clusters, and isolated high-influence nodes. Writes investigation memory entries and optionally proposes cleanup actions for orphans.
| Setting | Type | Default | Constraints | Description |
|---|---|---|---|---|
min_interval_seconds | int | 86400 | >= 3600 | Seconds between runs (default: daily) |
orphan_cleanup | bool | true | - | Propose cleanup for orphan entities |
max_cleanup_per_run | int | 100 | >= 1 | Maximum orphan cleanups per run |
Example - Daily anomaly detection with cleanup:
{
"min_interval_seconds": 86400,
"orphan_cleanup": true,
"max_cleanup_per_run": 50
}influence_tracker
Tracks PageRank and betweenness centrality changes over time for the top-N entities. Compares against previous snapshots stored in memory entries and flags entities with significant relative change.
| Setting | Type | Default | Constraints | Description |
|---|---|---|---|---|
min_interval_seconds | int | 86400 | >= 3600 | Seconds between runs (default: daily) |
change_threshold | float | 0.20 | 0.0 - 1.0 | Relative change threshold to flag |
top_n | int | 50 | >= 5 | Number of top entities to track |
Example - Track top 100 entities, flag 10%+ changes:
{
"change_threshold": 0.10,
"top_n": 100
}relationship_builder
Incrementally rebuilds relationship edges between full reconciliations using bridge field detection. Profiles data to discover bridge fields, then recomputes edges using the Transitive Intelligence module.
| Setting | Type | Default | Constraints | Description |
|---|---|---|---|---|
min_interval_seconds | int | 3600 | >= 300 | Seconds between runs |
min_new_entities | int | 10 | >= 1 | Minimum new records to trigger rebuild |
min_edge_weight | float | 0.5 | 0.0 - 1.0 | Minimum edge weight to emit |
max_edges | int | 50000 | >= 100 | Maximum edges per tenant |
Example - Rebuild edges hourly if new data arrives:
{
"min_interval_seconds": 3600,
"min_new_entities": 5,
"min_edge_weight": 0.4,
"max_edges": 100000
}Approval Workflow
When an agent has require_approval: true, its actions are queued instead of executed immediately.
Action lifecycle
pending -> approved -> executed
\-> rejected
\-> rolled_back (via run rollback)Action types
| Type | Description | Targets |
|---|---|---|
merge | Merge two canonical entities | entity_a, entity_b |
split | Eject a member from a cluster | entity_a (canonical), entity_b (ejected) |
plan_update | Update existing identity plan | payload contains plan JSON |
plan_create | Bootstrap new identity plan | payload contains plan JSON |
cleanup | Delete orphan canonical entities | payload contains entity ID list |
Example: Review and approve a merge
# See what's pending
kanoniv agent actions --status pendingID AGENT ACTION STATUS CREATED
550e8400-e29b-41d4-a716-446655440000 auto_merge merge pending 2026-02-22 14:30:00
6ba7b810-9dad-11d1-80b4-00c04fd430c8 auto_merge merge pending 2026-02-22 14:30:00# Inspect the first one (via the API or MCP resource)
# kanoniv://agents/actions shows decision_trace with match scores
# Approve it
kanoniv agent approve 550e8400-e29b-41d4-a716-446655440000Approved action 550e8400-e29b-41d4-a716-446655440000# Reject the second one
kanoniv agent reject 6ba7b810-9dad-11d1-80b4-00c04fd430c8Rejected action 6ba7b810-9dad-11d1-80b4-00c04fd430c8Rollback
If an auto-executed run caused problems, you can rollback:
# Find the run ID
kanoniv agent runs --type auto_merge
# Rollback all merge actions from that run
curl -X POST https://api.kanoniv.com/v1/agents/runs/RUN_ID/rollback \
-H "X-API-Key: your-key"Rollback limitations
Rollback marks merge actions as rolled_back and emits entity.split events, but does not fully reverse identity link changes. Run a full reconciliation after rollback to restore the graph to a clean state.
API Reference
Config Endpoints
| Method | Path | Description |
|---|---|---|
GET | /v1/agents/configs | List all agent configs |
GET | /v1/agents/configs/{agent_type} | Get specific config |
PUT | /v1/agents/configs/{agent_type} | Create or update config |
DELETE | /v1/agents/configs/{agent_type} | Delete config |
POST | /v1/agents/configs/{agent_type}/trigger | Trigger immediate run (409 if disabled) |
Run Endpoints
| Method | Path | Query Params | Description |
|---|---|---|---|
GET | /v1/agents/runs | agent_type, status, limit (max 200), offset | List runs |
GET | /v1/agents/runs/{id} | - | Get run details |
POST | /v1/agents/runs/{id}/rollback | - | Rollback a completed run |
Action Endpoints
| Method | Path | Query Params | Description |
|---|---|---|---|
GET | /v1/agents/actions | status (default: pending), limit (max 200), offset | List actions |
POST | /v1/agents/actions/{id}/approve | - | Approve and execute |
POST | /v1/agents/actions/{id}/reject | - | Reject |
Response: AgentConfigResponse
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"tenant_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"agent_type": "auto_merge",
"enabled": true,
"settings": {
"min_confidence": 0.95,
"max_actions_per_run": 50,
"require_approval": true
},
"created_at": "2026-02-22T10:00:00Z",
"updated_at": "2026-02-22T10:00:00Z"
}Response: AgentRunResponse
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"tenant_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"agent_type": "auto_merge",
"status": "completed",
"actions_taken": 12,
"actions_skipped": 3,
"actions_deferred": 5,
"details": {},
"error_message": null,
"started_at": "2026-02-22T14:30:00Z",
"completed_at": "2026-02-22T14:30:08Z"
}Response: AgentActionResponse
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"tenant_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"agent_run_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"action_type": "merge",
"status": "pending",
"target_entity_a": "a1b2c3d4-...",
"target_entity_b": "e5f6a7b8-...",
"confidence": 0.97,
"decision_trace": {
"rule_scores": { "email_exact": 1.0, "name_fuzzy": 0.92 },
"composite_score": 0.97
},
"result": null,
"approved_by": null,
"created_at": "2026-02-22T14:30:05Z",
"executed_at": null
}Run statuses
| Status | Description |
|---|---|
queued | Scheduled or triggered, waiting for worker pickup |
running | Agent is currently executing |
completed | Run finished successfully |
failed | Run encountered an error |
rolled_back | Run was rolled back |
Action statuses
| Status | Description |
|---|---|
pending | Awaiting human approval |
approved | Approved, awaiting execution |
executed | Approved and executed |
rejected | Human rejected the action |
rolled_back | Undone via run rollback |
Recipes
Cautious production setup
Enable core agents with approval gates and tight thresholds:
# Merge only very high-confidence pairs, with approval
kanoniv agent enable auto_merge \
--settings '{"min_confidence": 0.98, "max_actions_per_run": 20, "require_approval": true}'
# Monitor quality every hour
kanoniv agent enable quality_monitor \
--settings '{"merge_rate_drop_threshold": 0.05, "conflict_rate_rise_threshold": 0.02}'
# Learn from feedback weekly
kanoniv agent enable feedback_learner \
--settings '{"min_labels": 50, "learning_rate": 0.2, "auto_apply": false}'
# Reconcile hourly if new data arrives
kanoniv agent enable scheduled_reconcile \
--settings '{"require_data_change": true}'Aggressive dev/staging setup
Move fast, auto-execute everything:
kanoniv agent enable auto_merge \
--settings '{"min_confidence": 0.90, "max_actions_per_run": 200}'
kanoniv agent enable auto_split \
--settings '{"coherence_threshold": 0.3, "min_cluster_size": 3}'
kanoniv agent enable auto_tune \
--settings '{"max_iterations": 100, "auto_apply": true}'
kanoniv agent enable scheduled_reconcile \
--settings '{"min_interval_seconds": 300, "require_data_change": false}'New dataset onboarding pipeline
Bootstrap a new tenant from scratch:
# Step 1: Discover what signals exist in the data
kanoniv agent enable auto_discover \
--settings '{"sample_size": 1000}'
kanoniv agent trigger auto_discover
# Step 2: Generate an identity plan from discovered signals
kanoniv agent enable auto_bootstrap \
--settings '{"sensitivity": 0.5, "auto_apply": false}'
kanoniv agent trigger auto_bootstrap
# Step 3: Review and approve the generated plan
kanoniv agent actions --status pending
kanoniv agent approve PLAN_ACTION_ID
# Step 4: Run initial reconciliation
kanoniv agent enable scheduled_reconcile
kanoniv agent trigger scheduled_reconcile
# Step 5: Build relationship edges
kanoniv agent enable relationship_builder \
--settings '{"min_new_entities": 1}'
kanoniv agent trigger relationship_builderGraph intelligence stack
Enable the full graph analysis suite:
# Track influence changes daily
kanoniv agent enable influence_tracker \
--settings '{"top_n": 100, "change_threshold": 0.10}'
# Detect anomalies daily
kanoniv agent enable graph_anomaly \
--settings '{"orphan_cleanup": true, "max_cleanup_per_run": 50}'
# Surface merge candidates from relationship edges
kanoniv agent enable merge_recommender \
--settings '{"min_edge_weight": 0.85, "require_approval": true}'
# Rebuild edges hourly
kanoniv agent enable relationship_builder \
--settings '{"min_interval_seconds": 3600}'