AI in DevOps: using Jev as a decision layer for pipelines, incidents and Kubernetes
Introduction
Adopting Artificial Intelligence in DevOps usually starts with Large Language Models (LLMs) analyzing logs, explaining pipeline errors, generating commands, writing documentation, or suggesting fixes.
That approach is useful, but there's a category of problem where reaching for a full generative LLM can be overkill.
Consider a few common decisions a platform has to make:
- is this pipeline failure caused by code, infrastructure, or an external dependency?
- should the pipeline run again?
- does an incident need to be escalated?
- which team should receive a given alert?
- does this deploy carry enough risk to require manual approval?
- does this log look like an application error or infrastructure downtime?
- should we call in a more powerful AI agent to investigate the problem?
These questions don't necessarily need a long text answer.
They need a decision.
That's exactly the space Jev occupies — a model introduced by TypeSafe AI in September 2026. Unlike a traditional LLM, Jev was designed to take in a state, run bounded questions against it, and return structured decisions with probabilities and confidence scores. TypeSafe classifies this architecture as a System One model, built for fast decisions inside software.
For DevOps, SRE and Platform Engineering, this opens up an interesting architecture:
Pipeline / Kubernetes / Observability
↓
context collection
↓
Jev
↓
structured decision
↓
┌──────────┼──────────┐
↓ ↓ ↓
retry escalate ignore
↓
actionThe key point is that Jev doesn't replace Kubernetes, Azure DevOps, Prometheus, or an LLM.
It can work as a decision layer between technical events and automations.
What is Jev?
Jev is TypeSafe AI's first public model built around the concept of System One Models.
Instead of receiving a question and producing text token by token, the way a generative LLM normally does, the model works with a limited set of possible answers.
The conceptual contract is:
STATE + QUESTIONS
↓
JEV
↓
DECISIONS + PROBABILITIESA state could be:
Pipeline: payments-api
Stage: Build
ExitCode: 137
Logs:
Killed
npm ERR! process terminated
Node worker exited unexpectedlyAnd the application could ask:
What is the most likely failure category?
- application
- infrastructure
- dependency
- timeout
- resource
- unknownInstead of producing:
It looks like your process was probably killed due to running out of memory...the application receives something conceptually similar to:
{
"category": "resource",
"probability": 0.94
}The software can then decide:
if probability >= 0.90 and category == "resource":
retry_pipeline()This model is particularly well suited for automation because it reduces reliance on free-text parsing and constrains the possible answers to the decision space defined by the application. TypeSafe itself describes Jev as a kind of intelligent function call: unstructured state goes in, typed probabilistic decisions come out.
System One versus a traditional LLM
A simple way to visualize the difference:
| Characteristic | Jev | Generative LLM |
|---|---|---|
| Classification | Very well suited | Suited |
| Routing | Very well suited | Suited |
| Scoring | Very well suited | Suited |
| Binary decision | Very well suited | Suited |
| Long-form text | Not the goal | Very well suited |
| Technical explanation | Limited | Very well suited |
| Code generation | Not the goal | Very well suited |
| Open-ended analysis | Limited | Very well suited |
| Structured output | Native to the model | Usually requires a schema/structured output |
| Frequent decisions | Compelling | Can be more costly |
So an efficient architecture can combine both.
Event
↓
Jev
↓
classification
↓
simple problem?
├─ yes → automation
│
└─ no
↓
LLM
↓
detailed investigationThis creates a kind of AI Cascade.
The cheaper, specialized model handles simple decisions.
Larger models are reserved for situations that really need complex analysis.
Key concepts
State
The state represents the context to be analyzed.
In DevOps it can include:
pipeline name
stage
exit code
logs
duration
commit
environment
deployment status
pod status
Kubernetes events
metricsExample:
{
"pipeline": "checkout-api",
"stage": "deploy",
"exitCode": 1,
"environment": "production",
"logs": "ImagePullBackOff..."
}The quality of the state directly drives the quality of the decision.
There's no benefit in sending thousands of irrelevant lines.
An earlier layer should ideally normalize the data first.
Choice
Choice represents a selection among known options.
Example:
What's the likely cause?
application
infrastructure
dependency
security
resource
unknownIt's particularly useful for classification.
Score
Score lets you rate something on a scale.
For example:
Deployment risk:
1 - very low
2 - low
3 - medium
4 - high
5 - criticalThis can feed a deployment gate.
Noul
Another type of question is a decision roughly equivalent to yes/no together with a probability.
For example:
Will this failure likely be resolved by a retry?Conceptual result:
true: 0.91
false: 0.09Choice, Score and Noul are among the core question types documented in Jev's ecosystem.
AI architecture in DevOps using Jev
A real environment could use an architecture like:
Azure DevOps
│
│ logs / status
▼
Classifier Service
│
▼
Jev API
│
▼
Decision Engine
│
┌───┼────────────┐
│ │ │
▼ ▼ ▼
Retry Escalate Ignore
│ │
│ └───────────────► Teams / PagerDuty / Jira
│
▼
Azure DevOps APIIn Kubernetes:
EKS
│
├── API
├── Workers
├── RabbitMQ
└── PostgreSQL
│
▼
Prometheus / Loki
│
▼
Incident Collector
│
▼
Jev
│
▼
Decision Engine
│
├── retry
├── restart
├── alert
└── LLM InvestigatorJev doesn't necessarily execute the action.
It helps answer:
What should the system do?
The action stays the application's responsibility.
That separation matters for security.
A day-to-day example: classifying build failures
Imagine an organization with dozens of microservices.
Roughly 600 pipelines run on Azure DevOps every day.
A pipeline fails with:
##[error]The process '/usr/bin/docker' failed with exit code 1
error pulling image configuration:
download failed after attempts=6
TLS handshake timeoutNormally a developer opens the log and tries to figure out:
Code?
Docker?
Registry?
Network?
Agent?A service could collect:
{
"pipeline": "customer-api",
"stage": "docker-build",
"exit_code": 1,
"message": "TLS handshake timeout pulling base image"
}And ask:
Classify the most likely cause:
application
network
registry
dependency
agent
unknownHypothetical result:
registry: 0.72
network: 0.23
unknown: 0.05The pipeline could apply:
confidence >= 0.90 → automatic retry
0.70 to 0.89 → log the classification
< 0.70 → manual investigationThis detail is fundamental.
Probability should not be confused with certainty.
The ecosystem's own documentation stresses that confidence should guide the workflow, not be interpreted as a guarantee of correctness.
HTTP integration example
A basic integration can call the API directly.
A simplified structure would be:
curl -X POST \
"https://api.typesafe.ai/v1/systemone" \
-H "Authorization: Bearer ${TYPESAFE_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "jev-latest",
"state": {
"pipeline": "payments-api",
"stage": "build",
"exitCode": 137,
"logs": "Process terminated unexpectedly after memory usage increased."
},
"questions": {
"failure_type": {
"type": "choice",
"instructions": "Classify the most likely cause of this pipeline failure.",
"options": [
"application",
"dependency",
"infrastructure",
"resource",
"timeout",
"unknown"
]
}
}
}'The POST /v1/systemone endpoint, along with sending state together with typed questions, is part of the documented contract for the model.
The category names don't come from Jev.
The application defines the decision space.
This detail lets you model taxonomies specific to your company.
Classifier for Azure DevOps
We can build a small service dedicated to classification.
Flow:
Azure DevOps
↓
pipeline log
↓
failure-classifier
↓
Jev
↓
classification
↓
pipeline decisionA Python application could follow this logic:
import os
import requests
API_URL = "https://api.typesafe.ai/v1/systemone"
API_KEY = os.environ["TYPESAFE_API_KEY"]
def classify_failure(log: str) -> dict:
payload = {
"model": "jev-latest",
"state": {
"log": log
},
"questions": {
"failure_type": {
"type": "choice",
"instructions": (
"Classify the primary cause of this CI/CD failure."
),
"options": [
"application",
"dependency",
"network",
"infrastructure",
"resource",
"timeout",
"unknown"
]
}
}
}
response = requests.post(
API_URL,
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json=payload,
timeout=10,
)
response.raise_for_status()
return response.json()Production would still require:
- retry with backoff;
- timeout handling;
- circuit breaker;
- telemetry;
- secret redaction;
- rate limiting;
- controlling the size of the state.
Azure DevOps Pipeline
A pipeline could run the classification only after a failure.
Conceptual example:
trigger:
branches:
include:
- main
pool:
vmImage: ubuntu-latest
stages:
- stage: Build
jobs:
- job: BuildApplication
steps:
- script: |
npm ci
npm run build
displayName: Build application
- script: |
python scripts/classify_failure.py \
"$(System.DefaultWorkingDirectory)/pipeline.log"
condition: failed()
displayName: Classify failure with Jev
env:
TYPESAFE_API_KEY: $(TYPESAFE_API_KEY)The secret should be stored as a secret variable, a protected variable group, or another secret management solution.
Never:
TYPESAFE_API_KEY: abc123directly in the repository.
Using Jev with Kubernetes
Another interesting application is classifying Kubernetes incidents.
Consider:
Pod → CrashLoopBackOffThe system collects:
kubectl describe pod
kubectl logs
kubectl get eventsThen builds the context:
{
"pod": "checkout-api-76d88f",
"namespace": "production",
"status": "CrashLoopBackOff",
"restartCount": 14,
"logs": "connection refused postgres:5432"
}Jev can classify it as:
application
database
network
configuration
resource
unknownIn this example, probably:
databaseThe automation can then decide which runbook to run.
Kubernetes YAML
A service responsible for classifying events could be deployed to the cluster.
apiVersion: apps/v1
kind: Deployment
metadata:
name: jev-incident-classifier
namespace: platform
spec:
replicas: 2
selector:
matchLabels:
app: jev-incident-classifier
template:
metadata:
labels:
app: jev-incident-classifier
spec:
serviceAccountName: jev-classifier
containers:
- name: classifier
image: registry.example.com/platform/jev-classifier:1.0.0
ports:
- containerPort: 8080
env:
- name: TYPESAFE_API_KEY
valueFrom:
secretKeyRef:
name: jev-api
key: api-key
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
---
apiVersion: v1
kind: Service
metadata:
name: jev-incident-classifier
namespace: platform
spec:
selector:
app: jev-incident-classifier
ports:
- port: 80
targetPort: 8080
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jev-classifier
namespace: platformWhat this configuration does
It creates two replicas of the classification service.
The service receives events, prepares the context, and calls Jev.
replicas: 2 avoids depending on a single instance.
The requests guarantee minimum resources:
cpu: 100m
memory: 128Miwhile the limits prevent uncontrolled growth.
The probes let Kubernetes pull unhealthy containers out of traffic.
In production it would be advisable to add:
- PodDisruptionBudget;
- NetworkPolicy;
- HorizontalPodAutoscaler;
- observability;
- External Secrets;
- specific IAM;
- egress policies.
Security
Integrating AI with infrastructure requires care.
The biggest mistake would be turning:
Jev → direct executioninto:
Jev decided restart → kubectl delete podwithout intermediate controls.
A safer architecture would be:
Jev
↓
Decision Engine
↓
Policy Engine
↓
Risk Check
↓
ActionFor example:
if (
decision == "restart"
and confidence >= 0.95
and environment != "production"
):
restart()For production:
recommended restart
↓
policy
↓
approval / runbookPrinciple of least privilege
The classifier doesn't need to have:
cluster-adminIn most cases it doesn't even need to change resources.
Its RBAC can be read-only:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: incident-reader
namespace: production
rules:
- apiGroups:
- ""
resources:
- pods
- events
verbs:
- get
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: incident-reader-binding
namespace: production
subjects:
- kind: ServiceAccount
name: jev-classifier
namespace: platform
roleRef:
kind: Role
name: incident-reader
apiGroup: rbac.authorization.k8s.ioIf decisions result in actions, a separate service can hold specific permissions.
Redaction and secret leakage
Logs can contain:
Authorization: Bearer ...
password=
AWS_SECRET_ACCESS_KEY=
connectionString=Never send logs directly to any external service without sanitizing them first.
Before:
raw logs
↓
secret redaction
↓
normalization
↓
JevA simple pattern-based expression could strip known patterns.
But in production, sanitization should account for:
- JWT tokens;
- AWS credentials;
- HTTP headers;
- connection strings;
- cookies;
- personal information;
- regulated data.
Production example
Consider an EKS with:
120 microservices
600 pipelines/day
4,000 pods
Prometheus
Grafana
Loki
Tempo
Alertmanager
RabbitMQ
PostgreSQL
RedisHundreds of alerts can come in every day.
Instead of sending all of them straight to PagerDuty:
Prometheus
↓
Alertmanager
↓
PagerDutywe could add a layer:
Prometheus
↓
Alertmanager
↓
Incident Processor
↓
Jev
↓
severity / team / action
↓
Routing Engine
↓
PagerDuty / Slack / JiraFor example:
CPU 95%
pod restarts = 0
latency normal
duration = 2 minClassification:
severity=lowAnother event:
HTTP 5xx = 72%
checkout unavailable
3 replicas down
database latency 8sClassification:
severity=critical
team=platform
requires_human=trueThe system then creates the incident.
Jev + LLM
One of the most interesting architectures is combining both.
Incident
↓
Jev
↓
simple?
│
├─ YES
│ ↓
│ runbook
│
└─ NO
↓
GPT / Claude / another LLM
↓
investigationJev works as an intelligent router.
The LLM stays responsible for complex reasoning.
This combination avoids using more expensive models for tasks that are essentially classification.
Community projects are already experimenting with Jev in exactly this intermediate position, classifying before routing context to larger agents.
Observability
A solution like this needs to be observable.
It's not enough to know that:
Jev answered resourceYou need to log:
request_id
pipeline
decision
confidence
duration
action
model_version
timestampExample Prometheus metric:
jev_requests_total
jev_request_duration_seconds
jev_decision_total
jev_low_confidence_total
jev_errors_totalExample:
jev_decision_total{
decision="resource",
pipeline="payments"
} 143In Grafana you could have:
Decisions/minute
Average confidence
Top categories
Low confidence %
API errors
p95 latency
Automated actions
Manual escalationsLogs
A well-structured log would look like:
{
"timestamp": "2026-09-27T10:00:00Z",
"pipeline": "payments-api",
"classification": "resource",
"confidence": 0.94,
"action": "retry",
"duration_ms": 182
}In Loki:
{app="jev-classifier"}
| json
| classification="resource"Tracing
OpenTelemetry can track:
pipeline-event
↓
classifier
↓
Jev API
↓
decision-engine
↓
Azure DevOps APIThis lets you figure out whether a problem is:
in the collector
in the network
in the API
in the decision
in the automationTroubleshooting
API returning a timeout
Check connectivity:
curl -I https://api.typesafe.aiInside Kubernetes:
kubectl exec -n platform \
deploy/jev-incident-classifier \
-- curl -I https://api.typesafe.aiPossible causes:
DNS
NetworkPolicy
proxy
firewall
blocked egress
external outageClassifier pod restarting
kubectl get pods -n platform
kubectl describe pod \
-n platform \
<pod>
kubectl logs \
-n platform \
<pod>Events:
kubectl get events \
-n platform \
--sort-by=.metadata.creationTimestampCheck for:
OOMKilled
CrashLoopBackOff
ImagePullBackOff
probes
missing secretSecret not found
kubectl get secret jev-api \
-n platformNever print the secret's value in pipelines or logs.
Bad classifications
Not every problem is infrastructure.
The first thing to investigate should be the state.
For example:
BAD STATE
"pipeline failed"versus:
BETTER STATE
pipeline=payments-api
stage=deploy
exit_code=137
pod_status=OOMKilled
memory_limit=512Mi
memory_peak=510MiAI doesn't make up for poor context quality.
Development versus production
Development
Might be acceptable:
one replica
full logs
lower threshold
simulated actions
no autoscalingExample:
confidence > 0.70 → show a recommendationProduction
Should have:
redundancy
timeouts
retry
circuit breaker
rate limiting
redaction
observability
versioning
audit trail
higher thresholds
action controlsFor example:
confidence >= 0.95 → safe automatic action
0.80-0.94 → suggestion
<0.80 → manual investigationThresholds need to be calibrated with real data.
Best practices
Start with small decisions
Don't start by asking:
Fix any incident in my infrastructure.Start with:
Classify this failure.Then:
Determine whether a retry will likely fix it.Then:
Determine which runbook to use.Mature automation is built progressively.
Keep the decision space limited
Prefer:
resource
application
network
dependency
unknownover dozens of nearly identical categories.
Have an unknown option
Forcing a decision can produce bad automations.
Whenever possible:
unknownshould be a valid result.
Use confidence gates
Never treat:
0.51as equivalent to:
0.99Log every decision
For auditing:
input
model
decision
confidence
action
outcomeWhat to avoid
Avoid architectures like:
Alert
↓
AI
↓
kubectl deleteAlso avoid:
AI with cluster-adminor:
unfiltered logs containing secretsAnother common mistake is using AI where a simple rule would do.
For example:
if exit_code == 0:
return "success"doesn't need AI.
Costs and FinOps
The real cost of an AI-based architecture doesn't come only from the model call.
Consider:
tokens
API requests
intermediate service
observability
storage
network
secondary LLMsTypeSafe currently publishes a price of US$42 per billion input tokens, roughly US$0.042 per million tokens, positioning Jev as a low-cost decision layer compared to several generative models.
This can matter when there are thousands or millions of small decisions.
Consider:
100,000 events/dayIf all of them went to a large LLM:
100,000
↓
LLMthe architecture could instead be:
100,000
↓
simple rules
↓
Jev
↓
only 2,000 complex cases
↓
LLMThis strategy reduces:
tokens
latency
cost
dependency on larger modelsKubernetes and cost
The classification service itself tends to be lightweight.
For example:
requests:
cpu: 100m
memory: 128MiSo it can run on Spot nodes when appropriate.
But the classification service shouldn't be put on Spot without considering availability.
One approach could be:
2 replicasspread across nodes.
The local compute cost will likely be small compared to pipelines, observability and core workloads.
When to use Jev
Jev makes sense when there are frequent, well-bounded decisions.
Examples:
pipeline classification
incident triage
alert routing
ticket routing
deployment risk scoring
agent routing
tool selection
prioritization
log classification
confidence gates
retry decisionsWhen not to use it
Don't use Jev for problems like:
"Explain why my Kubernetes cluster is slow."
"Write my Terraform."
"Design a complete architecture."
"Summarize these 500 logs."
"Fix my code."These problems need generation or open-ended reasoning.
A traditional LLM is a better fit.
Also don't use AI when a deterministic rule solves the problem.
if pod.status == "Succeeded":
returnis better than any model.
Recommended architecture
A mature AI-in-DevOps strategy could have four layers:
EVENTS
↓
DETERMINISTIC RULES
↓
JEV
↓
COMPLEX CASE?
┌──────┴──────┐
│ │
NO YES
│ │
▼ ▼
RUNBOOK LLM
│
▼
HUMAN REVIEWThis architecture avoids two extremes.
The first:
never use AI for anythingThe second:
use an LLM for absolutely everythingThe best design tends to combine:
deterministic code
+
fast decision models
+
LLMs
+
automation
+
human-in-the-loopPractical summary
Jev shouldn't be understood as a drop-in replacement for ChatGPT, Claude or other generative models.
Its role is different.
LLM
→ generates
Jev
→ decidesIn DevOps, this lets you build an intelligent layer between events and automations.
A pipeline can use Jev to determine:
failure type
risk
whether a retry is needed
whether escalation is neededA Kubernetes cluster can use it for:
incident classification
alert routing
runbook selection
prioritizationAnd agent systems can use it to decide:
which tool to call
which model to use
when to escalate
when to stopAll of this should be paired with:
confidence thresholds
RBAC
audit trail
observability
sanitization
policy engines
human-in-the-loopConclusion
For many years, the connection between Artificial Intelligence and DevOps was focused on tools that generate text: explaining logs, writing YAML, creating scripts, or helping during incidents.
The rise of decision-oriented models opens up a different layer.
Not every problem needs a model that writes five paragraphs.
Sometimes the system just needs to answer:
Which category?
Which priority?
Which action?
Retry or not?
Escalate or not?
Which tool?
Which agent?This is exactly where a technology like Jev becomes particularly interesting.
In a modern platform, we can picture:
Azure DevOps
Kubernetes
Prometheus
Loki
OpenTelemetry
Alertmanager
│
▼
Event Layer
│
▼
Jev
│
▼
Decision Engine
│
├── automation
├── runbook
├── LLM
└── humanThe outcome isn't simply "putting AI in the pipeline."
It's building an intelligent decision layer inside the platform.
For DevOps, SRE and Platform Engineering, that difference matters.
The goal stops being just "use AI to answer questions" and becomes "use AI to help systems make small operational decisions with speed, structure, observability and clear limits."
Combined with deterministic code, policies, telemetry, runbooks, LLMs and human controls, Jev can occupy exactly that spot: the fast decision layer between what happened in the infrastructure and what the platform should do next.
Related articles
Want to apply this to your environment?
Book a free 30-minute call. I will look at your setup and tell you where to start.
Book a callGet new articles by email
One email when a new article on infrastructure, backend and AI is published. No spam, unsubscribe anytime.