Most DevOps guidance assumes something that stopped being true the moment teams started shipping LLM features. It assumes the same input produces the same output, and that a failure announces itself.
A pipeline can confirm a build compiled. It cannot confirm the assistant stopped refusing valid requests. A test suite can assert that a handler returns 200. It cannot assert that the answer inside the response body was correct.
Every practice below carries over from standard software delivery in shape. Each one breaks somewhere specific in substance, and the break is always the same: the practice needs a deterministic pass-or-fail signal, and a model call does not produce one.
What Is DevOps?
DevOps is a practice that merges software development and IT operations into a single continuous delivery loop, making the team that writes the code accountable for shipping and running it. It replaced the handoff model, where developers passed finished work over a wall to a separate operations team that deployed and maintained it.
That handoff created misaligned incentives. Developers were measured on shipping features quickly, operations on keeping systems stable, and each group's success made the other's job harder. DevOps removes the wall by making both groups responsible for the same outcome.
The Four Pillars of DevOps
Strip away the tooling and DevOps rests on four commitments that hold regardless of stack:
- Shared ownership - One team owns a service from commit to production incident, including the on-call rotation.
- Automation - Builds, tests, deployments, and infrastructure provisioning run as code rather than as manual runbooks.
- Continuous feedback - Monitoring, logging, and tracing return production behavior to the people writing the code, fast enough to act on.
- Small, frequent releases - Changes ship in increments, so each deploy carries less risk and failures are easier to isolate.
None of these four is a tool. Jenkins, Terraform, and Kubernetes are things teams use to practice them, which is why buying a toolchain has never made a team a DevOps team.
DevOps vs. LLMOps vs. MLOps
The three overlap enough to get used interchangeably, and they are not the same discipline.
MLOps grew up around training. Its center of gravity is the model itself: data pipelines, feature stores, training runs, model registries, and retraining schedules. The artifact under management is a set of weights the team produced.
LLMOps assumes the weights came from somewhere else. Most teams building on GPT, Claude, or Gemini never train anything. The artifacts they manage are prompts, retrieval configurations, tool definitions, routing rules, and evaluation suites. The model is an upstream dependency they call rather than an asset they build.
DevOps sits underneath both. Every practice in this article is a DevOps practice, applied to a system where one component happens to be nondeterministic. Teams shipping LLM features are not replacing DevOps with something new. They are running DevOps against an artifact their existing tooling was never designed to inspect.
Why Standard DevOps Practices Break on AI Systems
The Deterministic Assumption Underneath Every Practice
Standard delivery practices share a hidden dependency. Each one needs a clear, binary signal about whether a change worked.
A unit test needs an expected value to compare against. A canary needs an error rate that either crosses a threshold or does not. A rollback needs a previous state that behaves the way it did before. A change failure rate needs a definition of failure that a script can evaluate. None of these are controversial in a codebase, because a function that returns the wrong string returns the wrong string every time, on every machine, forever.
That dependency is invisible until it disappears.
What Changes When the Artifact Is a Model Call
Run the same prompt twice at temperature zero against the same model version and the outputs can still differ. Batching, floating-point nondeterminism on GPU kernels, and provider-side infrastructure changes all introduce variance the caller never sees.
Three consequences follow, and they drive everything below:
-
Quality becomes a distribution rather than a value. The question is no longer whether the output is correct. It is what share of outputs meet the bar, and whether that share moved after the last change.
-
Failures stop announcing themselves. A model that answers confidently and wrongly returns a well-formed response with a success status code. Nothing in the transport layer registers a problem.
-
The change surface leaves the repository. A prompt edit, a model version bump, a temperature adjustment, or a routing rule change can alter production behavior without touching application code. Anything watching the code for changes will miss all four.
10 DevOps Best Practices for AI Systems
None of the ten below is new. Each one is a standard delivery practice that needs a specific repair before it works on a system where the output is a model call.
- Extend Shared Ownership to Model Behavior
- Version Every Artifact That Changes Behavior
- Automate the Delivery Path, Not Just the Build
- Replace Assertions With Graders
- Gate Deploys on Eval Scores, Not Build Status
- Instrument for Silent Failure
- Ship Small and Roll Out Progressively
- Make Rollback Mean Something
- Shift Security Left for the AI Attack Surface
- Measure With Metrics That Survive Nondeterminism
The order is a sequence, not a ranking. Eval gates in practice 5 are unenforceable without the graders in practice 4, and the rollback plan in practice 8 depends on the version records built in practice 2.
1. Extend Shared Ownership to Model Behavior
Shared ownership is the pillar that survives contact with AI systems most intact, and the one teams quietly skip anyway.
Uptime has a clear owner. Output quality usually does not. When a support agent starts giving confidently wrong refund policies, the on-call engineer sees healthy dashboards and no alerts, product sees a spike in escalations, and neither treats it as an incident because nothing paged. The failure sits in the gap between the team that owns the service and the team that owns the experience.
The fix is unglamorous. Put output quality on the same rotation as latency and error rate, with a named owner, a defined threshold, and an alert that fires. A quality regression that nobody is paged for is a quality regression that ships to every user until somebody complains loudly enough to be noticed.
2. Version Every Artifact That Changes Behavior
Git tells the team what changed when the change was code. In an LLM application, most behavior-altering changes are not code.
Each of the following moves production behavior measurably, and none of them produces a diff a reviewer will see:
- A system prompt edited in a dashboard
- A model version switched from one snapshot to another
- A retrieval chunk size adjusted
- A tool description reworded
- A fallback list reordered
Teams end up in incident calls asking what changed and finding a clean commit history, because the change was real and the repository was not where it happened.
Treat every one of these as a versioned artifact with the same rigor as application code. That means an immutable identifier per version, an author, a timestamp, a diff against the previous version, and a record of which version served which request. The last part matters most, because without it a trace from three days ago cannot be tied to the prompt that produced it. Respan handles this by versioning prompts and referencing them by ID at call time, so the prompt that produced a given response is recoverable from the response itself rather than reconstructed from memory.
The mechanics of doing this well, including branching, staged rollout, and how to structure a prompt change workflow that does not break production, are covered in more depth in this guide to prompt versioning.
Stop guessing why your LLM app broke
See what your agents actually did in one place. Respan traces every prompt, tool call, and response, tracks cost and latency, and runs evals so you can go from a bad output to the exact step that caused it.
3. Automate the Delivery Path, Not Just the Build
Most teams automate the build and stop. The build was never the fragile part of an LLM application.
The fragile part is the call itself. Providers rate-limit without warning. Models get deprecated on a published schedule that nobody on the team read. A regional outage takes a single provider down for forty minutes. In a conventional service, this class of failure lives in infrastructure and gets handled by infrastructure. In an LLM application it lives on the hot path of a user-facing request, and if the handling is written inline it gets written eleven different ways in eleven different files.
The delivery-path automation worth building first is the part that keeps requests succeeding when the upstream misbehaves:
-
An ordered fallback list, so a failed model hands off to the next one instead of surfacing an error.
-
Load balancing across keys, so a single rate limit does not become a user-visible failure.
-
Retry with backoff, configured once rather than reimplemented at every call site.
-
Caching for repeated prompts, which cuts cost and latency on traffic that asks the same thing twice.
Centralizing these at the LLM gateways layer keeps the logic in one place, which also means it can be changed without redeploying application code.
Automation on a nondeterministic system amplifies whatever it is given. An automated fallback that silently routes to a weaker model will hold the error rate at zero while quality degrades, and every dashboard will look healthy throughout. Automate the recovery, then instrument the recovery, or the automation becomes the thing hiding the problem.
4. Replace Assertions With Graders
An assertion compares an output to an expected value. That works when there is one right answer and it is knowable in advance. Ask a model to summarize a support ticket and there are thousands of acceptable summaries, none of which will match a stored string.
Assertions do not stop being useful, they stop being sufficient. The replacement is a layered set of graders, each catching a different class of failure at a different cost.
Rule-based checks run first because they are deterministic, instant, and nearly free. Valid JSON, required fields present, output length within bounds, no PII in the response, no forbidden phrases, tool call arguments matching the schema. A surprising share of production LLM failures are structural rather than semantic, and structural failures do not need a language model to detect.
LLM judges handle what rules cannot: is the answer grounded in the retrieved context, does it address the question asked, is the tone appropriate, did the agent select the right tool for the task. These are slower and more expensive, and they carry their own failure mode, since a judge is a model and drifts like one. Anchor judges against human-labeled examples on a regular cadence, or the team ends up measuring judge bias and calling it quality.
Human review stays in the loop for the cases the other two cannot settle. It is the slowest and most expensive grader, so it should be pointed at sampled traffic and disputed cases rather than everything.
The test set matters as much as the graders. A hand-written set of twenty examples will pass consistently and predict nothing, because it does not contain the malformed inputs, adversarial phrasings, and edge cases that real users produce. Sample from production traffic, and promote real failures into the set as they are found, so the suite gets harder over time instead of staying comfortable. The full framework for building these, including how the three grader types divide the work, is laid out in this breakdown of prompt evaluation.
5. Gate Deploys on Eval Scores, Not Build Status
A CI gate is a boolean. Tests pass or they do not, and the pipeline proceeds or halts. Applied to a system whose output quality is a distribution, that boolean has to become a threshold.
The gate runs on every change to a prompt, model, or retrieval config:
- Run the eval suite against a fixed dataset.
- Compare the scores to the current production baseline.
- Block promotion when any criterion drops below its floor.
- Report the delta on the pull request, so a reviewer sees the quality impact next to the diff.
Step four is the one teams skip, and skipping it turns the gate into an obstacle rather than a source of information.
Threshold setting is where this goes wrong in both directions. Set the bar too high and the gate blocks on ordinary run-to-run variance, the team starts overriding it within a week, and the gate becomes decoration. Set it too low and regressions walk straight through.
Two things make thresholds hold. Measure the natural variance of the suite first, by running it several times against an unchanged baseline, and set the floor outside that band rather than guessing at a round number. Then decompose the score. A single blended quality number conflates a factual accuracy collapse with a tone shift, and averages the collapse into invisibility. Three to five separate criteria with independent floors catch what one number hides.
A team changes a system prompt to reduce verbosity. The suite runs against 400 sampled production cases. Conciseness improves as intended. Groundedness drops from 0.94 to 0.86 against a floor of 0.90, because the shorter outputs started omitting the retrieved citations. The pipeline blocks, the reviewer sees which criterion moved and by how much, and the prompt gets fixed before it reaches a user. Under a single blended score, that same change would have shown a small net improvement and shipped.
Choosing the platform to run this on is its own decision, and the tradeoffs between running evals in CI, against production traffic, or both are compared across the major options in this roundup of LLM evaluation tools.
6. Instrument for Silent Failure
This is the practice everything else depends on. Versioning, gating, rollback, and measurement all assume the team can see what production is doing. In an LLM application, the default instrumentation cannot see it.
Why a Degraded Response Returns HTTP 200
Conventional monitoring is built on the premise that failures surface as failures. A service that breaks throws exceptions, returns 5xx, and drives error-rate alerts. The transport layer carries the signal.
A model that produces a wrong answer produces a valid HTTP 200 with a well-formed body. Latency looks normal. Token counts look normal. The error rate does not move. From the perspective of every conventional monitor in the stack, the system is healthy while it is confidently giving users bad information.
The response is to capture the payload, not just the envelope. Inputs, outputs, model, version, parameters, retrieved context, tool calls, and token counts all need to be recorded, because the failure lives in the content and nothing outside the content reveals it. The structure of a useful trace, and what the OpenTelemetry GenAI conventions specify for it, is covered in this guide to LLM tracing.
Full Capture Before Sampling
Head-sampling decides whether to keep a trace before anything knows how good the output was. Since LLM failures return 200, they are indistinguishable from successes at that moment, and they land in the discarded portion at the same rate as everything else. The retained sample then looks cleaner than production actually is.
Default to full capture and sample only after the team knows what it can safely drop. Teams that sample from day one tend to discover their rule was written before anyone understood the failure modes, and that it discarded exactly the traffic that would have explained the first serious incident.
When sampling does become necessary, tail-based sampling survives contact with nondeterminism. Decide after the response exists, keep everything that failed an eval or an error check, keep the latency outliers, and sample the ordinary successful traffic.
Tracing Multi-Step Agent Runs
Single-call logging stopped being sufficient the moment agents started making decisions in sequence.
An agent run plans, retrieves, calls three tools, writes to memory, and produces an answer. When the answer is wrong, the wrongness entered at one of those steps and propagated. Flat logs show eight disconnected entries with no indication of which produced the bad input for the next. The debugging problem is not reading the logs, it is reconstructing the order and the parent-child relationships from timestamps.
A trace tree solves this by encoding the relationships in the data. Each step becomes a span with its own input, output, latency, and cost, and each span references its parent, so the execution path is recoverable regardless of the order the spans arrived in. That last detail matters more than it sounds, because in a distributed agent system spans routinely arrive out of order.
The practical requirement is that every step in a run shares a trace identifier and declares its parent. AI tracing built on this model lets a wrong answer be traced back to the specific retrieval that returned irrelevant context, rather than to a general suspicion that retrieval is the problem.
Closing the Loop From Production Signal to Fix With Respan
Capturing traces is the first half. The second half is doing something with them before the next release, and that is where most stacks fragment. Traces sit in one tool, eval scores in another, prompts in a third, and routing in a fourth. When quality drops, the engineer has the evidence and the fix in separate systems with no shared identifier between them, so connecting the two is manual work performed under time pressure.

Respan closes that loop by storing every LLM interaction as a span, whether it arrives from the tracing SDK, a framework integration, the gateway, or a direct API call. Evaluators attach to the same trace identifier used for debugging, so a failing score points at the exact run that produced it and monitors fire to Slack or email when a threshold breaches. The prompt fix that follows can be promoted from the UI with version control and rollout logic, without a code change or a redeploy.
The benefit is a shorter path from signal to fix. A quality regression is caught on live traffic rather than in a support ticket, traced to the span and prompt version that caused it rather than guessed at, and corrected without waiting on a release cycle.
For example, Retell AI scaled from 5M to 500M+ monthly API calls on Respan, and CTO Zexia Zhang credits the debugging layer with resolving production issues 10x faster. Instead of reading logs after the fact, use Respan to run observability in production, know when production shifts, and act before it spreads.
Catch the failures your error rate never shows
A degraded response looks identical to a healthy one from the outside. Respan keeps observability, evals, and prompt versions on the same span data, so a quality drop surfaces as an alert instead of a support ticket, and the trace and prompt version behind it are already attached.
7. Ship Small and Roll Out Progressively
Small releases were always about limiting blast radius. That logic gets stronger when the change is a prompt, because the effect of a prompt edit is genuinely hard to predict in advance.
Bundling a model swap, a prompt rewrite, and a retrieval change into one release makes the resulting quality shift uninterpretable. Something moved, and there is no way to attribute it. Ship the three separately and each one has a clean measurement.
Progressive rollout needs one adjustment for AI systems. A conventional canary watches error rate and latency, and both will look fine while a degraded model disappoints every user routed to it. The canary has to watch quality. Route a small share of live traffic to the new version, score both the new and the current version on the same evaluators, compare the score distributions rather than single results, and promote only when the new version holds or improves. Distribution matters here because on a nondeterministic system, one bad output in a canary sample is noise and a shifted median is a regression.
Shadow traffic is the lower-risk option when a change is large enough to be worrying. Send production requests to the new configuration in parallel, score the outputs, and discard them without returning anything to users. The comparison runs on real traffic with real edge cases, and nobody is exposed to the result. It costs a duplicate set of tokens, which is usually cheaper than the incident it prevents.
8. Make Rollback Mean Something
Rollback assumes a previous state that behaves the way it did before. That assumption is weaker than it looks when a third party owns the weights.
Reverting a prompt to the previous version restores the prompt exactly. It does not restore the behavior, because the model that prompt was tuned against may have changed underneath. Providers update model endpoints, adjust safety layers, and modify serving infrastructure without a version bump, and an alias like a bare model family name resolves to whatever is current at call time rather than what was current at deploy time.
Pinning is the first line of defense. Call specific model snapshot identifiers rather than floating aliases, so the version in production is the version that was tested. Record the resolved model version on every trace, because the pinned identifier in the config and the version that actually served the request are not guaranteed to agree, and the trace is the only place that disagreement becomes visible.
Pinning delays the problem rather than solving it. Snapshots get deprecated on published timelines, and the migration is not optional. Treat provider deprecation notices as scheduled work with a real cost, not as a config change. The move from one snapshot to the next is a behavioral change that needs the full eval suite, a canary, and a rollout, the same as any other release.
A rollback plan that survives this has three parts:
- Keep the previous prompt version and its recorded eval scores. A known-good baseline to compare against beats a vague sense that things used to be better.
- Keep the previous model snapshot reachable in the routing config, for as long as the provider supports it.
- Verify the rollback by running the eval suite after reverting, rather than assuming the revert worked.
In a deterministic system, step three is redundant. Here it is the only way to know the revert restored behavior and not just configuration.
9. Shift Security Left for the AI Attack Surface
Everything from conventional DevSecOps still applies. SAST on every commit, dependency scanning for CVEs, secrets detection before merge, least privilege on every service account. None of that goes away, and none of it addresses what is new.
What is new is that the application now processes untrusted natural language as though it were instruction, holds credentials to expensive third-party APIs, and routes user data through external providers. Each of those is a distinct attack surface with distinct controls.
Prompt Injection, Tool Permissions, and Untrusted Context
Prompt injection is not a variant of the injection attacks the team already knows. SQL injection has a clean fix, because parameterized queries separate code from data at the protocol level. Prompt injection has no equivalent, because the model receives instructions and data in the same channel and no delimiter reliably distinguishes them. Mitigations reduce the success rate. None of them close it.
The consequence is architectural. If injection cannot be prevented outright, the system has to be designed so that a successful injection is not catastrophic. That means constraining what the model can do rather than trying to control what it will be told.
- Scope tool permissions to the minimum. An agent with database read access can leak whatever it is talked into querying. An agent with write access can be talked into destruction.
- Require confirmation for irreversible actions. Sending an email, moving money, or deleting a record should not be reachable by a model acting alone on untrusted input.
- Treat retrieved content as hostile. Documents in a vector store, web pages fetched at runtime, and prior conversation turns are all attacker-controllable in the right circumstances. Indirect injection through retrieved context is harder to spot than a malicious user message and works the same way.
- Validate tool call arguments against a schema before execution. This is a deterministic rule-based check, it is cheap, and it catches a meaningful share of manipulated calls.
The pattern underneath all four is the same. Assume the model can be convinced of anything, and put the security boundary outside the model rather than inside it.
Secrets, Provider Keys, and Spend Caps
Provider API keys are credentials with a direct financial blast radius, which makes them different from most secrets in the stack. A leaked key does not just expose data, it bills.
Standard secret hygiene covers most of it: keys in a secret manager rather than environment files, scoped per service rather than shared across an organization, rotated on a schedule, and never logged. The addition specific to LLM applications is a spend limit that enforces independently of the code. Set soft warnings and hard caps per key, with alerts to Slack or email when a threshold crosses. A runaway agent loop and a compromised key produce the same billing curve, and a cap is the only control that stops either one without requiring somebody to be awake.
PII Redaction at Ingest
Full trace capture and data minimization pull against each other. Capturing inputs and outputs is what makes silent failures debuggable, and those inputs and outputs contain whatever users typed, which in a support or healthcare context is the exact data the team is obligated to protect.
Redaction has to happen at ingest rather than at query time. Once raw PII is written to a trace store it is in backups, in replicas, and in whatever downstream systems read from it, and scrubbing it later is a project rather than a setting. Configure redaction before go-live, not after the first audit.
The same reasoning applies to provider selection. Data sent to a model provider has left the perimeter, and the applicable controls are whatever that provider's terms specify about retention and training use. For teams operating under SOC 2, HIPAA, or GDPR obligations, that is a procurement question that belongs at design time, well before the first production request.
10. Measure With Metrics That Survive Nondeterminism
DORA now defines five software delivery metrics, split into throughput and instability. That split maps cleanly onto what survives on an AI system and what does not.
The three throughput metrics transfer without modification. Change lead time, deployment frequency, and failed deployment recovery time all measure how fast changes move and how fast a bad deploy gets reversed. Nondeterministic output does not change any of that, and the three are as useful here as anywhere.
Both instability metrics break, for the same reason. Change fail rate is the share of deployments requiring immediate intervention. Deployment rework rate is the share that are unplanned and follow a production incident. Both assume somebody recognized that a deployment went wrong. For an LLM application, a change can leave every technical indicator flat while degrading answer quality for a third of users. No incident gets declared, no hotfix ships, and the release counts clean on both.
Redefining failure is the fix, and the redefinition has to be written down and agreed on rather than assumed. A change fails when it drops any eval criterion below its floor on production traffic within a defined window, whether or not anything technical broke. That makes both instability metrics meaningful again, and it makes the eval suite load-bearing, since the definition of failure now depends on it.
Three additions are worth tracking alongside the DORA set:
-
Eval score trend by criterion, watched over time rather than checked at release, catches slow drift that no single deploy would flag.
-
Quality regression detection time, meaning the interval between a score dropping and somebody knowing, is usually far worse than teams expect and is not captured anywhere in the DORA set.
-
Cost per successful outcome ties spend to value in a way that raw token spend does not, since a cheaper model that fails more often is not cheaper.
DevOps Tools for AI Systems
The tooling question splits along the same line as the practices. Existing DevOps tools handle the parts of the pipeline that did not change. Git, CI runners, container orchestration, and infrastructure as code all work the same way whether the service calls a model or not, and replacing them is unnecessary.
The gap is everything that needs to inspect the content of a model call rather than the shape of a request. Nothing in a conventional stack can score an output, tie an eval result to a prompt version, or tell an engineer which retrieval step poisoned an agent run. That is a distinct category with distinct options, and the tradeoffs between them are compared in this roundup of LLM observability tools.
If the goal is one system rather than four, Respan runs observability, evals, prompt optimization, and an LLM gateway on the same span data, so an eval score, the trace that produced it, and the prompt version behind it are the same record rather than three lookups in three tools.
Where to Start With DevOps
Nobody adopts ten practices at once, and on an AI system the order is not arbitrary. Most of the list is unenforceable until the instrumentation exists.
Start with capture. Full traces on every call, including inputs, outputs, and the resolved model version. Until that is running, there is nothing to detect a regression with and no evidence to debug one.
Build a small eval suite next, drawn from failures already found in those traces rather than from imagination. Twenty real cases beat two hundred invented ones. Once scores exist, the deploy gate becomes possible, and versioning and rollback start paying off, because both depend on having a baseline to compare against.
Shared ownership is the exception. It costs no tooling and can be settled in a conversation this week.
FAQs
What is DevOps in simple terms?
DevOps is a way of working where the same team builds, ships, and runs a piece of software, instead of developers handing finished code to a separate operations team. It combines four things: shared ownership of a service end to end, automation of builds and deployments, continuous feedback from production, and small frequent releases. It is a cultural and operational model rather than a set of tools.
Is DevOps the same as LLMOps?
No. DevOps is the broader discipline covering how software gets built, shipped, and operated. LLMOps applies those ideas to applications built on language models the team did not train, where the managed artifacts are prompts, retrieval configs, tool definitions, and eval suites rather than model weights. LLMOps sits on top of DevOps rather than replacing it.
What are the four pillars of DevOps?
Shared ownership, automation, continuous feedback, and small frequent releases. Shared ownership puts one team on the hook from commit to incident. Automation replaces manual runbooks with code. Continuous feedback returns production behavior to the engineers who wrote the change. Small releases limit the blast radius of any single deploy.
How do you test an AI application in CI/CD?
Replace assertions with graders and replace the pass-fail gate with a score threshold. Run rule-based checks for structural failures, LLM judges for semantic quality, and human review on sampled cases. Run the suite against a dataset drawn from production traffic on every prompt, model, or retrieval change, compare the scores to the current baseline, and block promotion when any criterion falls below its floor. Decompose the score into three to five criteria rather than one blended number, and set floors outside the suite's natural run-to-run variance.
What is the biggest DevOps challenge with AI systems?
Silent failure. A model that returns a confidently wrong answer produces a valid HTTP 200 with normal latency and normal token counts, so error-rate monitoring, uptime checks, and status-code alerts all report a healthy system while users receive bad output. Every other difficulty follows from this one, because a pipeline that cannot detect a failure also cannot gate on it, roll back from it, or measure it.

