Skip to Content

Using AI to Optimize CI/CD Pipelines

Neon illustration of a CI/CD pipeline with AI assistants beside a build and test dashboard, titled Faster Pipelines with AI
AI speeds up the work around the pipeline gates, not the gates themselves.

Highlights

  • AI assists the pipeline, it does not own the gate. The value is triage, summarization, review, and suggestion. The decision to ship stays with your deterministic gates and your people.
  • Four jobs AI is genuinely good at: summarizing failures and root-causing them, triaging flaky tests, reviewing pull requests, and running custom LLM steps inside a job. Each is backed by a real, shipping tool.
  • A hands-on step you can copy. A real failing test, a real pipeline stage that sends the log to a model, and the verbatim diagnosis it returned, latency and token cost included.
  • Vendor tools mapped to the job they do, with whether each one advises or acts, so you match autonomy to the risk you can supervise.
  • The honest limits. Non-determinism, hallucinated fixes, cost and latency, and why you never pipe secrets into a model.
  • A safe adoption order. Start with the lowest-risk, highest-frequency job and earn the rest.

It is 4:47 on a Friday and the deploy pipeline is red. Not broken-code red, the worse kind: a test that passed on the last three runs and failed on this one, with 900 lines of stack trace and a job log that scrolls past anything useful. The engineer on the hook scrolls, greps for "Error", finds six of them, and starts the slow work of deciding which one actually matters. The fix, when it finally lands twenty minutes later, is one line. The twenty minutes was reading.

That gap, between a pipeline knowing something is wrong and a human understanding what, is where AI has quietly become useful in CI/CD. Not by taking over the pipeline, and not by deciding what ships. Google's 2025 DORA report found AI adoption among software professionals at 90%, yet the same data shows delivery throughput improving while stability does not automatically follow, and the report's blunt conclusion is that AI is an amplifier: it makes a disciplined pipeline faster and a fragile one more chaotic. So the useful question is not "can AI run my pipeline" but "which specific, bounded jobs in my pipeline is AI actually good at, and how do I wire one in without handing it the keys." This guide answers that, ends with a real CI step you can add today, and is honest about the parts that should stay human.

What "AI in CI/CD" Actually Means

Strip away the marketing and AI shows up in a pipeline in exactly one shape: something goes into a model as text (a failing log, a diff, a test history), and something comes back as text (an explanation, a review comment, a suggested fix). That is it. The model does not press the merge button, and you should be deeply suspicious of any setup that lets it.

This matters because a CI/CD pipeline is, at its heart, a series of deterministic gates. A test either passes or it does not. A build either produces an artifact or it fails. A policy check either allows the deploy or blocks it. Those gates are the whole point: they are what let you ship on a Friday without holding your breath. An LLM is the opposite of deterministic, so it cannot be one of those gates. What it can do is make the humans and the gates faster: read the wall of log nobody wants to read, spot the flaky test hiding in the noise, leave a first-pass review on a PR while a person is still finishing lunch.

Keep that division clear and everything else follows. AI advises; the pipeline decides. The best implementations lean into this: they put AI where a human would otherwise be doing tedious reading or first-pass triage, and they leave the accept, the merge, and the promote to prod exactly where they were. If the pipeline fundamentals underneath all this are shaky, AI will only amplify the mess, so KodeKloud's CI/CD learning path is worth working through to get the gates themselves solid first.

The Four Jobs AI Is Genuinely Good At

Summarizing failures and finding the root cause

This is the highest-value, lowest-risk job, and the one from that Friday-afternoon scene. A failed job produces a long, noisy log; an LLM is good at compressing it into "here is the likely cause, here is the line to look at, here is a suggested fix." GitLab ships this as GitLab Duo Root Cause Analysis: it forwards a portion of the failed job log (up to the last 100,000 characters) to its AI Gateway with a purpose-built prompt, and returns a probable cause and an example fix, reachable from the merge request's pipeline tab or straight from the job log. You do not have to buy a platform to get the behavior, though; the hands-on section below builds the same idea in about fifteen lines.

Triaging flaky tests

A flaky test is one that passes and fails on the same commit, and it is corrosive precisely because it trains your team to ignore red. Detecting flakiness is a data problem (does this test change result without the code changing?) that AI-driven tooling now handles well. Datadog Test Optimization maintains a central view to track and triage flaky tests, and its Early Flake Detection runs newly added tests multiple times to catch flakiness before it merges; Datadog reports the approach identifies up to 75% of flaky tests early. The important design point is that it can quarantine a known flake so it stops breaking the build, which is an action, but a bounded and reversible one, not a decision to ship.

Reviewing pull requests

GitHub Copilot code review is generally available and can review pull requests automatically: it reads the diff, comments on issues, and suggests fixes you can apply in a couple of clicks, in any language. You can set it to rerun on every push and even run on draft PRs so authors iterate before a human looks. Two details make it pipeline-relevant rather than gimmicky: it can use custom instructions checked into the repo, so it reviews against your standards, and it can pull context through MCP from issue trackers, docs, and incident tooling. It is still a reviewer, not an approver: its comments sit alongside your required human reviews and branch protections, not instead of them.

Running a custom LLM step inside a job

The most flexible option is the one you build: a step in your existing pipeline that calls a model through an API for a job you define. Summarize the failure and post it to Slack. Draft release notes from the merged commits. Explain a terraform plan diff in plain language before a human approves the apply. Because it is your code calling an OpenAI-compatible endpoint, you control the model, the prompt, the data that leaves your environment, and where the output goes. That is what the next section builds, end to end.

Here is how the four map out.

Job in the pipeline Representative tool Where it runs Advises / Acts
Summarize a failed job, find root cause GitLab Duo Root Cause Analysis Merge request / job log Advises (explains)
Detect and triage flaky tests Datadog Test Optimization Test stage + dashboard Advises (can quarantine)
Review a pull request GitHub Copilot code review On the PR, before merge Advises (suggests fixes)
Fix a broken pipeline GitLab Duo Fix Pipeline flow Agentic flow in the MR Acts (with approval)
Custom LLM step (your job) Your own model call in CI Any pipeline (Actions, GitLab CI) Advises (you scope it)

Hands-On: Add an AI Failure-Triage Step to Your Pipeline

Enough framing. Here is a real, working example: a test suite with a genuine bug, a pipeline stage that catches the failure and sends the log to a model, and the actual diagnosis it returned. Everything below was run for real; the model output is captured verbatim, not written by hand.

The scenario

A tiny billing module with a bug that a code review might miss. The function is supposed to apply a percentage discount, but it treats the percentage as a raw multiplier:

# billing.py
def apply_discount(price, percent):
    # Return the price after applying a percentage discount.
    return price - (price * percent)

And the test that catches it:

# test_billing.py
from billing import apply_discount

def test_20_percent_off_100():
    assert apply_discount(100, 20) == 80

def test_no_discount():
    assert apply_discount(50, 0) == 50

Running the suite produces a real failure, exit code 1, which is what stops the pipeline:

F.                                                                       [100%]
=================================== FAILURES ===================================
___________________________ test_20_percent_off_100 ____________________________

    def test_20_percent_off_100():
>       assert apply_discount(100, 20) == 80
E       assert -1900 == 80
E        +  where -1900 = apply_discount(100, 20)

test_billing.py:4: AssertionError
=========================== short test summary info ============================
FAILED test_billing.py::test_20_percent_off_100 - assert -1900 == 80
1 failed, 1 passed in 0.05s

The AI step

The script the pipeline runs on failure is short. It reads the captured log and asks a model, through any OpenAI-compatible endpoint, for a bounded, three-part answer. The prompt deliberately tells it not to invent code it cannot see, which is the single most useful guardrail against a confident-but-wrong reply:

# diagnose.py  -- runs only when tests fail
import os
from openai import OpenAI

log = open("test-output.log").read()
client = OpenAI(
    api_key=os.environ["AI_API_KEY"],
    base_url=os.environ["AI_BASE_URL"],   # OpenAI, a local model, or your gateway
)
prompt = (
    "You are a CI assistant. A test job just failed. From the pytest log below, "
    "in under 120 words: (1) name the most likely root cause, (2) point to the exact "
    "code to change, (3) suggest the fix. Do not invent code you cannot see in the log.\n\n"
    f"---\n{log}\n---"
)
resp = client.chat.completions.create(
    model=os.environ["AI_MODEL"],
    messages=[{"role": "user", "content": prompt}],
)
print(resp.choices[0].message.content.strip())

The AI_BASE_URL points at any OpenAI-compatible endpoint, so you are not locked to one vendor. This run used KodeKloud's KodeKey, an OpenAI-compatible AI API you can get a key for and drop straight into the AI_API_KEY and AI_BASE_URL variables; OpenAI, Azure OpenAI, or a local Ollama server slot in exactly the same way with no other code changes.

Wiring it into GitHub Actions

The pipeline runs the tests, saves the log, and runs the diagnosis only on failure. The API key comes from repository secrets, never from the code, and the diagnosis is posted to the job summary rather than gating anything:

# .github/workflows/ci.yml
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.13"
      - run: pip install pytest openai

      - name: Run tests
        run: pytest -q | tee test-output.log

      - name: AI failure triage
        if: failure()
        env:
          AI_API_KEY: ${{ secrets.AI_API_KEY }}
          AI_BASE_URL: ${{ secrets.AI_BASE_URL }}
          AI_MODEL: ${{ vars.AI_MODEL }}
        run: python diagnose.py >> "$GITHUB_STEP_SUMMARY"

The if: failure() condition is the whole design in one line: the model never runs on a green build, so it costs nothing when nothing is wrong, and it only ever adds information, never blocks a passing pipeline.

What the model actually returned

Running that step against the real failure produced this, verbatim:

Representative output, captured from google/gemini-3-flash-preview on KodeKloud's KodeKey during a real run. Your wording will differ every time; the diagnosis and the suggested fix are what to read.
1. **Root Cause**: The `apply_discount` function incorrectly treats the discount as a
raw multiplier instead of a percentage. The result `-1900` indicates the logic is
performing `100 - (100 * 20)`.

2. **Code to Change**: The return expression inside the `apply_discount` function
(referenced in `test_billing.py` at line 4).

3. **Fix**: Update the logic to divide the discount by 100 before calculation. Change
the formula to:
   `return price * (1 - discount / 100)` or `return price - (price * discount / 100)`.

The call took about 8 seconds and used roughly 1,500 tokens, so at current flash-model pricing this runs for a fraction of a cent per failure. It correctly read a real stack trace, named the real cause, pointed at the real line, and proposed a correct fix. Note the small imprecision worth pausing on: it called the parameter "discount" when the code calls it percent. Harmless here, and a perfect illustration of why this output goes into a human's job summary, not into an automatic commit.

Applying the suggested fix and rerunning closes the loop, and this is the part you can actually verify:

before fix -> pytest exit=1
..                                                                       [100%]
2 passed in 0.01s
after fix  -> pytest exit=0

The failure was real, the diagnosis was real, and the fix genuinely turned the suite green. The engineer still read the suggestion and made the change; the AI just deleted the twenty minutes of log-reading from the front of that process. This is the exact pattern KodeKloud Engineer drills on live systems, real broken CI/CD and Jenkins tickets you fix on running infrastructure, at engineer.kodekloud.com, which is the closest thing to practicing this on a genuine on-call.

πŸš€ Hands-On Course

Want the pipeline this step plugs into, built for real?

The workflow above assumes you already have a solid GitHub Actions pipeline to add AI to. KodeKloud's GitHub Actions course builds one hands-on, from your first workflow through matrix builds, secrets, and reusable actions, so the AI step you just saw has a real pipeline to live in.

Start the Course β†’

What AI Still Can't Do in Your Pipeline

The step above is genuinely useful and genuinely bounded. The boundaries are the point, so here they are stated plainly.

It cannot be a gate, because it is not deterministic. The same failure can produce a slightly different explanation on every run. That is fine for advice a human reads and fatal for anything that has to make a repeatable pass/fail decision. Never put an LLM in the position of deciding whether a build ships; keep it strictly on the "explain this to a human" side of the line.

Confident is not the same as correct. A model will describe a wrong root cause as fluently as a right one, and it will occasionally invent a function or a fix that does not exist in your code. The "do not invent code you cannot see" instruction reduces this but does not remove it. Every AI suggestion in a pipeline is a hypothesis for a human to confirm, which is exactly why the output above went to a job summary and not to an auto-commit.

Secrets do not go into a model. Job logs are full of tokens, connection strings, and internal hostnames. If you pipe raw logs to a hosted model, you are exfiltrating those. Redact before you send, or run a local or self-hosted model for anything sensitive, and treat the endpoint like any other third party that sees your data.

Cost and latency are real, even when small. Every failure that triggers a model call costs tokens and adds seconds. Gating the call behind if: failure() keeps it cheap, but a naive setup that summarizes every job, green or red, on a busy monorepo adds up fast in both dollars and pipeline time. Measure it, as we did above (about 8 seconds, roughly 1,500 tokens), and scope it to where it pays off.

How to Adopt This Without Making a Mess

The safe path mirrors the risk. Start with the job that is pure upside: failure summarization, exactly the step built above. It only runs when something is already broken, it only ever adds a human-readable explanation, and it cannot make anything worse. That is the ideal first AI step in any pipeline.

Next, turn on the advisory reviewers where your platform already offers them: Copilot code review on pull requests if you are on GitHub, Duo Root Cause Analysis if you are on GitLab, flaky-test detection if test noise is your real pain. These sit beside your existing gates and cost you nothing but a suggestion you are free to ignore. If you want the wider map of which AI tools fit which DevOps job, our rundown of the best AI tools for DevOps engineers covers the full set, and the piece on AI versus automation in DevOps is worth reading first if the line between "the model advises" and "the pipeline decides" still feels blurry.

Only after those are habits should you consider the acting tier, an agentic flow that proposes a fix commit or a pipeline change, and even then keep it behind human approval with scoped credentials, dry-run defaults, and full audit logs. The teams that get burned are the ones that let an agent modify pipelines on day one because a demo looked magical. The teams that win treat every AI step as a fast, tireless junior whose work still goes through the same review as everyone else's. If the code-and-review side is where you want to sharpen up, KodeKloud's AI-Assisted Development course covers using AI to write and review code without letting it merge unchecked.

Conclusion

AI does not optimize your CI/CD pipeline by running it. It optimizes it by deleting the slow, human-tedious parts around the gates: the log you did not want to read, the flaky test hiding in the noise, the first-pass review, the plain-language explanation of what just broke. The pipeline still decides, deterministically, exactly as it did before, and that is the feature, not the limitation. Add one bounded step, the failure-triage stage above is the ideal first one, measure what it saves and what it costs, keep the model on the advising side of every gate, and never let confidence stand in for correctness. Do that and AI earns its place in your pipeline the same way any good tool does: by making a disciplined process faster without making it less safe.

Ready to Build the Pipeline, Not Just Read About It?

A copied YAML snippet gets you one step. Understanding where AI belongs across an entire pipeline, and building it with the guardrails that keep a model on the safe side of every gate, is what makes you the engineer who ships AI into CI/CD without shipping an incident with it. Start with the pipeline itself: KodeKloud's CI/CD learning path takes you through building solid, gated pipelines hands-on, which is the foundation every AI step in this guide sits on. Pair it with the AI-Assisted Development course to get the code-and-review side right, and practice all of it for free in the KodeKloud playgrounds. When you build the failure-triage step from this guide, KodeKey gives you an OpenAI-compatible API key to run it against, exactly what powered the live example above. Add one AI step to a real pipeline this week, measure what it saves, and build from there.


FAQs

Q1: Can AI automatically fix a failing CI/CD pipeline?

It can suggest a fix, and agentic flows can even draft the change, but letting it apply one unsupervised is a mistake. LLM output is non-deterministic and occasionally confidently wrong, so it belongs on the advising side of your pipeline: it explains the failure and proposes a fix, and a human confirms and commits. Keep the actual merge and deploy behind your existing deterministic gates and human approval, exactly where they were before you added AI.

Q2: Is it safe to send my CI logs to an AI model?

Only after you account for what is in them. Job logs routinely contain secrets, tokens, and internal hostnames, and piping them raw to a hosted model sends that data to a third party. Redact sensitive values before the call, or run a local or self-hosted model for anything sensitive. Treat the AI endpoint like any other external service that sees your data, and never hard-code the API key; pull it from your CI secret store.

Q3: Which is better for AI in CI/CD, GitHub or GitLab?

Both ship strong, first-party features, so the better choice is usually the platform you already run. GitHub leans on Copilot code review for pull requests, while GitLab offers Duo Root Cause Analysis for failed jobs and agentic pipeline-fix flows. If you are on neither or want portability, a custom LLM step calling an OpenAI-compatible endpoint works in any pipeline and keeps you in control of the model, the prompt, and the data.

Q4: Do I need an expensive model to summarize pipeline failures?

No. Failure summarization is a lightweight task, and a fast, inexpensive model handles it well. The example in this guide cost roughly 1,500 tokens and about 8 seconds per failure, a fraction of a cent, and it only runs when a job actually fails. Start small and cheap, gate the call behind failure conditions so green builds cost nothing, and only reach for a larger model if the quality of the summaries genuinely needs it.


Sources: 2025 DORA State of AI-assisted Software Development report; How are developers using AI? Inside Google's 2025 DORA report; GitLab Duo Root Cause Analysis (blog); GitLab Duo use cases (docs); GitLab Duo Fix CI/CD Pipeline flow (docs); GitHub Copilot code review (docs); Copilot code review automatic reviews (GitHub changelog); Datadog Flaky Tests Management (docs); Datadog Early Flake Detection (docs).

Nimesha Jinarajadasa Nimesha Jinarajadasa
Nimesha Jianrajadasa is a DevOps & Cloud Consultant, K8s expert, and instructional content strategist-crafting hands-on learning experiences in DevOps, Kubernetes, and platform engineering.

Subscribe to Newsletter

Join me on this exciting journey as we explore the boundless world of web design together.