Tackling SLO Cognitive Load with AI / AIでSLOの認知負荷に立ち向かう

目次

🌐 This post is bilingual. 日本語版は記事の後半にあります → 日本語版へ移動 ↓

目次

English Version

At PlatformCon 2026 I gave a talk titled “Tackling SLO Cognitive Load with AI — Coach Design, Automate the Rest” — on how our Platform Engineering Team at Nulab is using AI to help teams adopt SLOs. This post is the longer version.

A conference slot only had room to sketch the project at a high level, so here I fill in the details, starting from the background. It stands on its own — you don’t need to have seen the talk to follow along.

One caveat up front: this project is still young. We’ve only just started rolling it out to pilot teams, so treat this as a progress report — how we thought about the problem, what we designed, and where things stand today.

Background

At Nulab, the desire to adopt SLOs had been around for a while. The company wanted to push adoption forward, and plenty of engineers on the ground wanted it too.

The monitoring foundation was in place, too. Last year we consolidated our fragmented monitoring onto Datadog and, in the process, carefully reworked how we monitor — so we now have far better coverage than before. In other words, both the appetite for SLOs and the monitoring maturity to support them were there.

And yet SLO adoption barely moved. Despite the demand from both leadership and engineers, outside of a few teams no one was taking the first step.

Why not? Thinking it through, two reasons seemed likely.

Hypothesis 1: There’s too much to learn

The first is simply that there’s too much to learn. Plenty of engineers can explain what an SLO is, but putting one into actual operation is an entirely different skill. Concretely: you map out the user journey to work out what’s worth protecting, pick the right SLIs and decide where to measure them, set target values with justification, design an error budget policy, calculate burn rates, configure Datadog, design alerts and suppress duplicates, wire it all into on-call and incident management, and manage the whole thing as Infrastructure as Code — and so on. In short, the first step demanded far too much up front.

Hypothesis 2: A psychological barrier

The second is a psychological barrier. At its core, an SLO is a promise — “this service will hold this level of reliability,” “when the budget runs out, we stop feature work” — a promise the whole team takes on together. So you can’t start alone. What to protect first, what target to set, what to do when the budget is gone — every one of these is a decision that needs the agreement of the people involved. The moment you try to start, you naturally end up pulling in teammates and stakeholders, explaining, and winning them over.

That rules out the easy way in — “let me just try it myself and roll it back if it doesn’t work.” On top of that, it’s hard to estimate how much time and cost adoption will take. You have to involve a lot of people, yet the distance to the goal is invisible — no wonder the first step feels heavy.

Those were our two hypotheses.

The design

From here on, the story is about the design — how we set out to lower the cognitive load of adopting SLOs. Let’s start with the constraint that shaped it.

Constraint: we can’t staff an army of experts

From past experience, we already knew an easy way to make SLO adoption succeed: attach someone to the team who knows SLOs well and can also coordinate across stakeholders. Someone who can facilitate the discussion, draw out everyone’s agreement, and answer the technical questions — that’s enough. Such a person resolves both of our hypotheses at once: the sheer volume of things to learn, and the psychological barrier.

But our goal this time was to bring SLOs to every service that needs them. We have many teams and only a handful of experts. Placing an SLO expert on every team simply isn’t realistic. So we knew a method that works — but it depended on having an expert in the room.

Automate — but not all of it

If the expert can’t be in the room, move what the expert does onto the machine — that was our starting point. Automate what can be automated, like configuration and routine work, and hand the expert’s knowledge to an AI so teams can learn from it on the spot. If we can’t add more experts, we reproduce their work with tooling and AI.

But here we drew a line. We must not automate everything.

An SLO is the team’s promise. If an AI hands down “here is your team’s SLO” without going through a legitimate process, can the team really own it?

The most common way SLO adoption fails is when the numbers get set but the team never uses them to make decisions. Target values line up on a dashboard, yet no one looks at them, and nothing happens when the error budget drains. Can people really uphold SLOs and alerts that an AI simply handed them and that they don’t actually understand? We had serious doubts.

To repeat: an SLO is a promise. And because it’s a promise, humans must agree to it and humans must own it. We can’t let an AI make the call.

And so our design principle took shape: lower the barrier to adoption, but never take away human understanding and ownership. Holding both at once became the foundation for every design decision that followed.

Splitting cognitive load in two

With the principle set, all that remained was to turn it into a concrete design. To decide where to automate and where to leave things to humans, we broke down the work that SLO adoption requires. It splits into two kinds with very different natures.

One kind is what a team must understand and decide for itself in order to own its SLOs. For example, the priority judgment that “for this service, login availability matters more than dashboard load time.” What target to set; how to behave when the error budget is exhausted. Only the people who know the service best — the team that owns it — can decide these. No one else can do the thinking for them. This is intrinsic cognitive load. It can’t be skipped, and it shouldn’t be automated.

The other kind isn’t essential to SLOs at all — it’s the load the mechanics of the tooling impose, raising the barrier to adoption for no good reason. How to set up the monitoring tool. How to build the alert suppression logic. These are purely matters of how to operate the tools; the SLO runs fine even if not everyone on the team understands them. This is extraneous cognitive load. Since understanding it isn’t required, the load should be removed.

ExamplesHow we handle it
Intrinsic cognitive loadWhat to protect first / target values / error budget policy / stakeholder agreementThe team understands and decides (we coach)
Extraneous cognitive loadBurn rate math / monitoring tool setup / alert suppressionMechanical work common to every team (we automate)

The terms “intrinsic” and “extraneous” cognitive load are borrowed from Cognitive Load Theory. That said, the classification is debated, and I can’t claim our split lines up with any consensus among cognitive-load researchers. Take it simply as a way we found useful for organizing SLO adoption into two buckets.

The big picture

Before getting into the details, here’s the whole system on one diagram. A human converses with the AI coach, and the product of that conversation is an SLO definition document (Markdown) generated into a Git repository. The document is converted into Terraform and ultimately applied as Datadog resources — that’s the flow at a high level.

End-to-end overview of SLO adoption. A human converses with the AI coach (Converses); the AI coach fetches metrics from Datadog (Fetches) and generates an SLO definition document (Generates). The document is converted to Terraform (Converts) and provisioned to Datadog through a module (Provisions).

At the center is the SLO definition document, kept in a Git repository. A human and the AI coach build it through dialogue; the document is then converted to Terraform and applied to Datadog. Along the way, the AI coach also pulls real data from Datadog. And wherever the tooling can’t reach in this flow, a human steps in.

Supporting the intrinsic load — the AI coach

Let’s follow the flow from the first step. It begins where the team decides its own SLO — the intrinsic load. This load can’t be erased by automation; it’s where the team itself has to do the thinking.

This is where we brought in AI. The AI coach is implemented as an Agent Skill. We run it on Claude Code, but Agent Skills work on other AI coding tools too.

How the AI coach is built

Inside, the AI coach is a natural-language playbook written for the AI. It spells out, in prose, “what to ask in what order, and how to behave in each situation,” and the AI reads it to drive the conversation. It’s closer to an operations manual than to code.

The playbook breaks SLO definition into phases: identify the service → map out dependencies → define the SLIs → set targets and error budget → operational details → review and save. And the “don’t let the AI decide” rules I describe below aren’t written as abstract mindset; they’re baked in as concrete instructions within each of these phases.

The AI coach neither decides nor takes responsibility

What this AI coach does — and doesn’t do — is the core of the design.

The AI coach works through dialogue. It asks question after question, draws information out of the team, and in the end builds the SLO definition document together with them. But it offers no opinion on the team’s choices. Ask it about SLO best practices and it will teach you; ask “what target should our team set?” and it won’t answer — because that’s not the coach’s call. This is exactly how I behave myself when I sit in on another team’s SLO meeting as a facilitator. The reason is simple: neither the AI nor I know that team’s context.

What the AI coach doesExample
Presents data“Availability over the last 90 days was 99.97%.”
Explains what the options mean“99.9% gives you 43 minutes of error budget per month; 99.95% gives you 21 minutes.”
Lays out trade-offs“Raising the target tightens the budget and makes a feature freeze more likely.”
What the AI coach must not doExample
Recommend a specific value“99.9% is the right choice.”
Make a business decision“It’s Critical, so it should be SEV-1.”

The one exception is a clear best-practice violation. If a team tries to set a target stricter than its upstream dependency allows, for instance, the coach points it out. Even then, the final decision is the human’s.

An SLO is the team’s promise. The team has to agree to it and act accordingly. We decided we must not let an AI stand in for that decision.

Making “don’t let AI decide” a mechanism, not an ideal

“Don’t let the AI decide” can’t be upheld by good intentions alone. It has to be enforced by mechanism.

The top design principle we set was User Ownership: every decision must belong to the user in a way that holds up even when it’s questioned later. Several concrete rules follow from this principle.

Take Articulate-to-commit. At key points — choosing SLIs, target values, the error budget policy, severity — the coach won’t move on until the user explains, in their own words, why they’re choosing it. “Because the AI recommended it” or “because the default seems reasonable” won’t do. Not being able to state a reason is a sign you don’t yet understand what you’re committing to.

The coach also shows, whenever it presents something, where the basis comes from — whether it’s measured data pulled from Datadog, a company-recommended default configured into the agent, and so on. For a service that isn’t in production yet and has no track record, “set it provisionally for now and re-evaluate after launch” is accepted as a legitimate answer too — and in exchange, the coach has the team record the trigger for that re-evaluation.

And the AI coach can do things humans can’t

A human SLO expert can’t hold every team’s monitoring data in their head. The AI coach, though, can pull real data instantly through Datadog. Whether the metric you want to use as an SLI even exists, what its current value is — and beyond that, cross-team checks like whether your upstream dependency has an SLO and whether its target can actually support yours. If a service has too little traffic to make a sensible SLO, the coach tells you “this isn’t a good fit for an SLO” before you start writing a definition.

A quietly powerful benefit is that it takes the Datadog busywork off your hands while you build the definition. Take the SLI query: the coach looks up the metric names and tags that actually exist in Datadog and assembles a candidate query, so you can immediately go look at live data in Datadog. Hunting for metrics by hand, writing a query, and checking whether it’s roughly right — that heavy part goes to the machine, and the human gets to focus on the judgment that matters: does this metric truly capture the user experience?

One more thing we treated as essential for a platform: guarding against hallucination. The coach connects through Datadog’s official MCP server and only ever performs read operations — metric and span queries. And before it drafts an SLI query, it has to confirm that the metric actually exists and returns data, so it can’t conjure a plausible-sounding metric that isn’t there. The human still verifies the final query by eye in Metrics Explorer.

Making the definition a “contract” to prevent drift

What comes out of the dialogue with the AI coach is the SLO definition document (a Markdown file). It gathers the team’s decisions, their rationale, and the supporting evidence in one place. The contents follow a fixed template, roughly structured as follows:

  • Service overview and user journeys (what to protect)
  • Traffic volume and service maturity
  • Upstream dependencies and their SLO constraints
  • SLI definitions (what to measure and where, with Datadog queries)
  • Target values and their rationale
  • Error budget policy (when the budget drops, who decides what)
  • Operational contacts, notification targets, and severity
  • First response when an alert fires
  • Review cadence and a decision log

There are two design decisions here.

First, keeping the definition document in the same repository as the Terraform code. The Terraform is generated from this document. Keeping them in one place makes it less likely that one gets updated and the two drift apart — the “we updated the definition but the implementation never caught up” kind of mismatch — and easier to catch when it does happen. On top of that, Datadog resources are only ever created from this document through Terraform — so there’s no room for drift from clicking around in the UI (ClickOps), and the definition document stays the single source of truth.

The second decision is to manage the document through Git pull requests. We considered building it in a Datadog Notebook, but an SLO is a promise, and it only means something once the people involved agree to it. Going through a PR leaves a record, in the review exchange, of who agreed to what and when. We chose a PR over a Notebook precisely to keep that evidence of agreement.

Converting the definition into Terraform is handled by a dedicated Agent Skill. Here too we hold to one principle: the definition is a contract.

So the conversion skill never fills in missing values by inference. If a required field is empty, it refuses to convert — to keep a gap from quietly turning into “a default the skill decided on its own.” When it finds a blank, it distinguishes the nature of the gap and handles each differently. A required field the person hasn’t decided yet? It asks them, rather than guessing. A value deliberately left as “revisit later”? It checks whether to finalize it now or leave it pending. Leftover template text or a formatting error? It has them fix the document itself. Either way, the AI never silently fills in what a human should decide. Even in conversion — the last, mechanical step — ownership stays with the human.

Folding away the extraneous load — a Terraform module as the Golden Path

The AI coach produces the definition, and it gets converted into Terraform. The “destination” of that conversion — the part that actually assembles the Datadog resources — is this Terraform module. It takes on the extraneous load in full: all the “configuration that follows mechanically once the SLO definition exists.” Once a team has written down “what to protect, and at what level,” how that maps to which Datadog resources, configured how, is already determined — no further thought required.

In practice, operating a single SLO properly in Datadog takes around ten resources — the SLO itself, several burn-rate monitors, error budget alerts, notification routing, and so on. None of these are decisions that shape your service’s reliability; they’re work that follows mechanically from the definition. And what’s mechanical can be wrapped in a module and hidden away. We folded all of it into an slo module. The same philosophy extends to on-call routing — Datadog On-Call schedules, escalation policies, and incident notification rules are carved out into an oncall module (here I’ll focus on slo).

All the user passes to the module is the target value, the measurement queries, and a bit of metadata.

module "signin_availability" {
  source  = "app.terraform.io/Nulab/slo/datadog"
  version = "0.1.0"

  name     = "signin-availability"
  service  = "example-web"
  team     = "example-team"
  env      = "prod"
  target   = 99.9          # target (%)
  slo_type = "metric"      # metric / time_slice / monitor

  numerator   = "..."      # good events
  denominator = "..."      # total events
  severity    = "SEV-2"

  paging_notification_targets = ["@slack-example-team-urgent"]
  ticket_notification_targets = ["@slack-example-team"]
}

The burn-rate math, the Fast/Medium/Slow threshold design, how the alert suppression is wired — the user doesn’t need to know any of it. From just this input, a full set of resources is assembled with safe defaults set by the platform engineering team (and you can fine-tune them if you need to).

What gets assembled: three tiers of burn-rate alerts at different consumption speeds, alerts for both an error budget warning and an SLO breach, suppression logic to quiet duplicate notifications, window adjustments for low-traffic services, and automatic linkage to the Service Catalog. Thresholds, evaluation windows, and notification routing all come with defaults shared across every team.

A look inside the module

To the user it looks like “just pass a target and a query,” but this single module call expands internally into about ten Datadog resources. For the minimal setup shown above, what gets generated is roughly the following:

  • One SLO object
  • Three burn-rate monitors (Fast / Medium / Slow)
  • Two error-budget monitors (a low-budget warning, and an SLO breach)
  • Three composite monitors for notification suppression

Enabling the low-traffic handling (window extension and a volume gate) adds volume-check monitors and their composites on top, bringing the total to around a dozen.

Assembling each of these correctly is quietly tedious work. Hand it to the module, and the user never has to think about what’s inside.

Design decisions

Anyone fluent in SLOs, Terraform, and Datadog could reproduce the broad outline from what I’ve described so far. But there are a few decisions that are easy to miss if you build it the obvious way, so let me leave them here as pointers.

  • Make alert suppression a two-layer composite-monitor structure. Don’t attach notifications to the burn-rate monitors themselves; put the notifications and suppression conditions on separate composite monitors. With medium && !fast for Medium and slow && !fast && !medium for Slow, the lower tiers stay quiet while a higher-severity burn is firing. If you attach notifications directly to each monitor, Fast/Medium/Slow fire at once and you get multiple pages — this separation avoids that.
  • For low traffic, stop false alarms in two layers: extending the alert windows and a “volume gate.” First, lengthen the evaluation windows to smooth out the noise from sparse data. Then build a separate monitor that checks whether the denominator (request count) is above a threshold, and AND it with the burn-rate alert (burn && volume). With few data points the burn rate swings wildly and fires falsely, so it only alerts when there’s a large enough sample.
  • Split notifications into two channels, routing the urgent one through an Incident to On-Call. Fast/Medium burn and an SLO breach go to the paging channel (create a Datadog Incident and, depending on severity, page On-Call); Slow burn and the error budget warning go to the ticket channel (a Slack notification). What wakes someone at 2 a.m. and what can wait until the next business day are separated by route from the start.
  • Monitor burn rate (the speed of consumption) and error budget remaining (the stock) separately. Alongside the burn monitors, keep a monitor that warns when the remaining budget drops below a threshold and goes critical at 0% (a breach). “Burning fast right now” and “nothing left” are two different events.

Because best practices are embedded as default values, users are unlikely to get it wrong, and they can override when needed. This is our answer to extraneous cognitive load.

Running it: where we are now

To be honest, writing a single SLO definition with the AI takes somewhere around an hour and a half to two hours.

There are two reasons it takes that long. One is that the team writes the definition through discussion. What to protect, what target to set — this is the time the team spends facing, and agreeing on, the decisions I earlier called intrinsic load. It’s not that the AI is slow; this is the time humans need to make a promise to one another. The other is that how thoroughly the AI explains things varies with the team’s SLO experience. Start in beginner mode and the coach walks through each related term, each configuration step, and the intent behind it as it builds the definition — which takes longer. A team experienced in operations, by contrast, finishes in under an hour.

As for concrete results: two pilot teams have deployed SLOs to production through this flow. Engineers on teams that had never operated SLOs wrote a definition together with the AI coach, and are now actually running those SLOs.

That said, these SLOs were only just deployed. It’s too early to call it a success. Defining them is one thing; actually using them to drive decisions is another. Whether the SLOs keep their meaning over time is something we intend to watch carefully over the coming months.

What got solved, and what’s left

How far did this system get with the two hypotheses from the background? Let me look back honestly.

“Too much to learn” — the module and the AI coach lightened that considerably. And the “psychological barrier,” while it can’t be erased entirely, drops substantially, I believe, just by having a golden path. Teams no longer have to design their own adoption process from scratch, which lightens the burden of owning “how do we proceed.” The effort of adoption itself shrinks, too. And the more examples accumulate inside the company of teams that walked the same golden path, the easier it becomes to estimate “how much effort this takes and what you get back” — which lowers the cost of convincing stakeholders. In the background I wrote that you “have to involve a lot of people, yet the distance to the goal is invisible”; a well-paved golden path and a growing body of precedent are exactly what fill that gap.

Even so, a part remains that can’t be erased: easing the anxiety of changing how you operate, and drawing genuine agreement and ownership out of the people involved. And taking root a culture that decides, based on the error budget, to “stop feature work for now.” This isn’t territory tooling can take over. What the AI coach can handle is the “how,” not the “why.” An AI can’t be an evangelist.

That’s exactly why our next move is SLO Champions. There will always be things the tooling can’t cover, and we want people placed across the organization who can step in where the system doesn’t reach — who can stand alongside a team and help push consensus forward. So we’ve begun reaching out to engineers who are interested in SLOs.

Don’t over-rely on AI — build it on a foundation that runs without AI

I’ve been talking about AI this whole time, but this system works perfectly well without it. Write the SLO definition by hand and call the Terraform module, and your SLO ships to production without ever touching the AI coach. The AI is training wheels that make the process faster — not the foundation.

There are two reasons we didn’t make AI the foundation.

One is that we couldn’t predict, early on, how usable this AI-based system would be. Honestly, at the start of the project we didn’t know how accurately the AI coach would actually perform. It’s been working quite well for our pilot teams so far, but whether it can grow into an AI that handles every situation remains unclear. That’s exactly why we wanted the whole project to survive even if the AI fell short of expectations. Lock down a foundation that can produce SLOs without AI first, and the system holds up even if the AI turns out poorly.

The other is that this AI is meant to be training wheels. Teams that grow comfortable operating SLOs will eventually write definitions without the coach’s hand-holding, and much of its functionality should become unnecessary (though the convenient parts, like pulling real data from Datadog, will likely stick around). We don’t assume teams will keep using it forever.

Closing

The title of this post — Coach Design, Automate the Rest — is the short version of our answer. It started from a single point: not all cognitive load is equal. The parts a team must understand, agree to, and take responsibility for — the intrinsic load — are where we don’t let AI tread. The extraneous load, like how to operate the tools, we hand off to AI and the module. Drawing that line became the foundation of the design.

Even so, this isn’t a tidy story where drawing the line made adoption take off overnight. We did lighten the weight of what teams have to learn considerably, but the hurdle of “making it hold as a promise everyone shares” still remains a human job. How far the AI coach actually helps is something we’re still in the middle of verifying. As I said at the start, this is no more than an early progress report.

In other words, we’re still in the middle of testing our hypotheses. We’ll keep reporting the results — what worked, and what didn’t.


🌐 この記事はバイリンガルです。English version is in the first half → English version ↑

日本語版

先日 PlatformCon 2026 で「Tackling SLO Cognitive Load with AI — Coach Design, Automate the Rest」というタイトルで発表をしてきました。弊社の Platform Engineering Team で進めている、AI を活用して各チームの SLO 導入を支援する取り組みについてです。この記事はその詳細版です。

カンファレンスの限られた時間内では、プロジェクトの全体像をざっと話すのが精一杯で、詳細まではほとんど踏み込めませんでした。
この記事はそこを補うためのものです。発表を見ていなくても読めるように、背景から順に書いていきます。

また、実を言うとこのプロジェクトは、まだ始まったばかりでパイロットチームへの導入が始まったところです。
この記事は我々がどう考えてどういった設計を行い、今どういう状態なのかという途中報告になります。

背景

そもそも、Nulab では「SLO を導入したい」という声が、以前からありました。会社としても導入を推し進めたいと考えているし、現場にも「やりたい」というメンバーが少なくありませんでした。

監視の土台も整っていました。昨年、社内でばらばらだった監視基盤を Datadog に統一し、それに合わせて監視体制そのものも細かく見直したことで、以前よりずっと手厚く監視できるようになりました。つまり、SLO を始めたいという欲求も、SLO を始められるだけの監視体制も、どちらも揃っていたわけです。

それなのに、SLO の導入だけは、なかなか進みませんでした。経営からも現場からもほしいという声はあるのに、一部のチーム以外では最初の一歩がなかなか踏み出されません。

なぜ進まないのか。考えてみると、理由は二つありそうでした。

仮説1: 覚えることが多すぎる

一つは、単純に覚えなければならないことが多すぎること。「SLO とは何か」を説明できるエンジニアは多くても、それを実際の運用に乗せるのは別物のスキルです。具体的には、ユーザージャーニーを描いて何を守るべきかを見極め、適切な SLI を選んで計測点を決め、目標値を根拠とともに定め、エラーバジェットのポリシーを設計し、バーンレートを計算し、Datadog を設定し、アラートを設計して重複を抑制し、オンコールやインシデント管理と連携させ、それらを Infrastructure as Code で管理し……といった具合です。要は、最初の一歩を踏み出すには、覚えることが重すぎたのです。

仮説2: 心理的なハードル

もう一つは、心理的なハードルです。SLO は突き詰めれば「約束」——「このサービスはこの水準の信頼性を守る」「バジェットが尽きたら機能開発を止める」という、チーム全員で引き受ける約束です。だから、一人では始められません。何を優先して守るか、目標値をいくつにするか、バジェットが尽きたらどうするか。どれも関係者の合意が要る決めごとで、SLO を始めようとすれば、自然とチームメンバーやステークホルダーを巻き込み、説明し、納得してもらうことになります。

そうなると、「とりあえず自分で試して、ダメなら戻す」という気軽な始め方ができません。しかも、導入にどれだけの時間とコストがかかるのかも読みにくいものです。多くの人を巻き込む割に、ゴールまでの距離が見えない——これでは、最初の一歩が重くなって当然です。

——そう、仮説を立てました。

設計

ここからは、SLO 導入の認知負荷をどう下げるか——その設計の話に入ります。まずは、設計を縛っていた制約から。

制約:大量の専門家は用意できない

過去の経験から、SLO 導入を成功させる簡単な方法は分かっていました。SLO に詳しくて関係者間の調整もできる人をチームにつければ、導入はうまくいくのです。関係者の議論をファシリテートして全員の合意を引き出し、SLO の技術的な質問に答えられる人がいれば十分です。さきほどの二つの仮説——覚えることの多さと、心理的なハードル——を、その人が同時に解いてくれるわけです。

しかし、今回のゴールは SLO を必要とするすべてのサービスに SLO を導入することです。そして、弊社では多くのチームがあり、専門家の数は限られています。すべてのチームに SLO の専門家を配置するのは現実的ではありません。つまり、うまくいく方法は知っていたけど、その機能は「専門家がその場にいること」に依存していました。

自動化する。でも、全部はだめ

専門家がその場にいられないなら、専門家がやっていることを機械に移せばいい——これが出発点でした。設定や定型作業のように自動化できるところは自動化し、専門家が持っている知識は AI に渡して、その場で AI から教われるようにします。専門家を増やせないなら、その働きをツールと AI で再現する、という発想です。

ただ、ここで一線を引きました。全部を自動化してはいけない。

SLO は、チームの約束です。正当なフローを踏まずに AI が「これがあなたのチームの SLO です」と決めてきたとして、チームはそれに本当にオーナーシップを持てるでしょうか。

SLO 導入の最もよくある失敗は、値だけが決まっていて、チームがそれを意思決定に使っていないことです。ダッシュボードに目標値は並んでいるのに、誰も見ていないし、エラーバジェットが減っても何も起きません。AI に与えられただけで中身を理解していない SLO やアラートを、人間は本当に守れるのか——そこに強い疑念がありました。

くり返しになりますが、SLO は約束です。約束である以上、人間が合意し、人間が責任を持たなければなりません。AI に決めさせるわけにはいきません。

こうして、設計指針が定まりました。導入のハードルは下げる。けれど、人間の理解とオーナーシップは奪わない。この両立が、以降のすべての設計判断の土台になりました。

認知負荷を二つに分ける

指針は決まりました。あとは、それを具体的な設計に落とすだけです。どこを自動化し、どこを人間に残すのか——その線引きをするために、SLO 導入に必要な作業を分解して考えてみました。すると、性質の異なる二種類に分けられます。

片方は、チームが自分の SLO をオーナーとして引き受けるために、どうしても自分で理解し、自分で決めなければならないことです。たとえば「このサービスではダッシュボードの表示速度より、ログインの可用性のほうが重要だ」という優先順位の判断。目標値をいくつにするか、エラーバジェットが尽きたときどう振る舞うか。これらは、そのサービスを一番よく知っている人、つまりそのサービスをもっているチームにしか決められません。他人が代わりに考えることはできない——これが内在的認知負荷(Intrinsic Cognitive Load)です。省略できないし、自動化するべきでもありません。

もう片方は、SLO の本質ではないのに、道具の使い方として導入のハードルだけを上げている負荷です。監視ツールをどうセットアップするか。アラートの抑制ロジックをどう組むか。これらはただの道具の使い方の話で、チーム全員が理解していなくても SLO は運用できます。これが外在的認知負荷(Extraneous Cognitive Load)です。理解が必須ではないのだから、その負荷は取り除くべきです。

扱い
内在的認知負荷何を優先して守るか/目標値/エラーバジェットポリシー/ステークホルダー合意チームが理解し、決める(コーチする)
外在的認知負荷バーンレート計算/監視ツール設定/アラート抑制全チーム共通の機械的作業(自動化する)

「内在的認知負荷」「外在的認知負荷」という言葉は認知負荷理論(Cognitive Load Theory)から借りたものです。ただ、その分類には諸説があり、ここでの分け方が認知負荷理論の研究者間のコンセンサスに沿っているかは分かりません。今回は SLO 導入を整理するために、このように二つに分けて考えた、という程度に受け取ってください。

全体像

細かい話に入る前に、できあがった仕組みを一枚で見てください。人間が AI コーチと対話し、その産物として SLO 定義書(Markdown)が Git リポジトリに生成されます。定義書は Terraform に変換され、最終的に Datadog のリソースとして適用される——大きくはこの流れです。

SLO 導入の全体像。人間が AI コーチと対話し(Converses)、AI コーチは Datadog からメトリクスを参照しつつ(Fetches)、SLO 定義書を生成する(Generates)。定義書は Terraform に変換され(Converts)、モジュール経由で Datadog に適用される(Provisions)。

中心にあるのは、Git リポジトリに置かれた SLO 定義書です。人間と AI コーチが対話してこの定義書を作り、定義書は Terraform に変換されて Datadog に適用されます。AI コーチは途中で Datadog の実データも参照します。そして、この流れでツールが拾いきれないところは、人間が引き受けます。

内在的認知負荷を支える — AI コーチ

全体像の流れを、最初のステップからたどっていきましょう。出発点は、チームが自分の SLO を決める——内在的認知負荷の部分です。ここの負荷は自動化で消すことができません。チーム自身が考える必要があるところです。

ここで AI を使いました。AI コーチは Agent Skill として実装しています。弊社では Claude Code 上で動かしていますが、Agent Skill は他の AI コーディングツールでも動かせます。

AI コーチはどう作られているか

AI コーチの中身は、AI に対する自然言語の手順書です。「どんな順序で何を尋ね、各場面でどう振る舞うか」を文章で書き、AI がそれを読んで対話を進めます。コードというより、運用マニュアルに近いものです。

手順書は、SLO 定義づくりを、サービスの特定 → 依存関係の洗い出し → SLI の定義 → 目標値とエラーバジェット → 運用詳細 → レビューと保存、というフェーズに分けています。そして後述する「決めさせない」ためのルールは、抽象的な心構えとしてではなく、この各フェーズの具体的な指示として書き込まれています。

AI コーチは決めないし、責任も引き受けない

この AI コーチが何をして、何をしないのか。ここが設計の核です。

AI コーチは対話で進みます。質問を重ね、チームから情報を引き出し、最終的に SLO 定義書を一緒に作り上げます。ただし、チームの選択に意見を言いません。SLO のベストプラクティスを尋ねれば教えてくれますが、「あなたのチームはどの目標値にすべきか」には答えません。それは AI コーチが決めることではないからです。これは私自身が他のチームの SLO ミーティングにファシリテーターとして参加したときと同じふるまいです。理由はシンプルです。AI も私も、そのチームの文脈を知らないからです。

AI コーチがやること
データを提示する「直近90日の可用性は 99.97% でした」
選択肢の意味を説明する「99.9% なら月43分、99.95% なら月21分のエラーバジェットです」
トレードオフを提示する「目標を上げるとバジェットが厳しくなり、Feature Freeze が起きやすくなります」
AI コーチがやってはいけないこと
特定の値を推奨する「99.9% が適切です」
ビジネス上の意思決定をする「Critical だから SEV-1 にすべき」

唯一の例外は、明確なベストプラクティス違反です。たとえば上流の依存先が許す以上に厳しい目標値を設定しようとしたとき、AI コーチはそれを指摘します。それでも、最終的に決めるのは人間です。

SLO はチームの約束です。チームで合意して、そのとおりに動く必要があります。我々は AI にその決定を肩代わりさせてはいけないと考えました。

「決めさせない」を、理念ではなく仕組みにする

「AI に決めさせない」は、心がけだけでは保てません。仕組みで縛る必要があります。

設計の最重要原則に置いたのは User Ownership です。すべての意思決定は、あとで問い返されても揺らがない形で、ユーザー自身のものでなければなりません。この原則から、いくつかの具体的なルールが導かれます。

たとえば Articulate-to-commit。SLI の選定、目標値、エラーバジェットポリシー、Severity といった要所では、ユーザーが「なぜそれを選ぶのか」を自分の言葉で説明するまで、AI コーチは先に進みません。「AI が勧めたから」「デフォルトが妥当そうだから」は受け付けません。理由を書けないのは、自分が何にコミットしようとしているかをまだ理解していないサインだからです。

また、AI コーチが何かを提示するときは、その根拠がどこから来たのか(Datadog から取得した実測データなのか、AI エージェントに設定された会社の推奨設定なのか、など)もあわせて示します。まだ本番投入前で実績がないサービスなら、「いまは暫定で置き、ローンチ後に再評価する」という判断も正当な答えとして認め、代わりに再評価のトリガーを記録に残させます。

一方で、AI コーチは人間にできないこともできる

人間の SLO 専門家には、全チームの監視情報を頭の中に持っておくことはできません。けれど AI コーチは、Datadog 経由で実データを即座に引けます。SLI に使おうとしているメトリクスがそもそも存在するのか、現在値はどうか、さらに、上流の依存先に SLO があるか、その目標値が自分たちの目標を支えられるかといった、クロスチームのチェックまでできます。トラフィックが少なすぎて SLO として設定するにはむいていないサービスであれば、定義を作り始める前に「これは SLO に向きません」と伝えます。

地味に効くのが、定義書を作るうえでの Datadog まわりの手間を肩代わりしてくれることです。たとえば SLI のクエリ。AI コーチは Datadog に実在するメトリクス名やタグを調べたうえでクエリ案を組み立ててくれるので、すぐに Datadog 上のライブのデータを見にいけるようになります。手でメトリクスを探し、クエリを書いて当たりをつける——その重い部分は機械に任せ、人間は「この指標で本当にユーザー体験を表せているか」の判断に集中できます。

そしてもう一つ、プラットフォームとして外せないのがハルシネーション対策です。AI コーチは Datadog 公式の MCP サーバー経由で接続し、メトリクスやスパンの照会といった読み取り操作しか行いません。しかも SLI のクエリを組む前に「そのメトリクスが実在し、データが返ってくるか」を必ず確認させているので、存在しない指標をそれらしく作文することができません。最終的な妥当性は、人間が Metrics Explorer で目視確認します。

定義書を「契約」にして、ズレを防ぐ

AI コーチとの対話から出てくる成果物は、SLO 定義書(Markdown ファイル)です。チームの意思決定とその根拠、エビデンスが一枚にまとまっています。中身は決まったテンプレートに沿っていて、ざっくり次のような構成です。

  • サービス概要とユーザージャーニー(何を守るのか)
  • トラフィック量とサービスの成熟度
  • 上流依存と、その SLO 制約
  • SLI の定義(何を・どこで測るか、Datadog クエリ)
  • 目標値とその根拠
  • エラーバジェットポリシー(バジェットが減ったら、誰が何を決めるか)
  • 運用連絡先・通知先・Severity
  • アラート発火時の初動
  • レビュー周期と意思決定ログ

ここには、二つの設計判断があります。

まず、定義書を Terraform コードと同じリポジトリに置くこと。Terraform コードはこの定義書から生成されます。だから両者を同じ場所に置いておけば、片方だけが更新されて食い違う(ドリフトする)こと——「定義は更新したのに実装が追いついていない」といったズレ——が起きにくく、起きても検知しやすくなります。さらに、Datadog のリソースはこの定義書から Terraform 経由でしか作られません。画面で直接いじる(いわゆる ClickOps)による設定のドリフトが入り込まず、定義書が唯一の情報源(Single Source of Truth)として保たれます。

もう一つの判断は、定義書を Git の PR ベースで管理することです。Datadog の Notebook で作ることも考えましたが、SLO は約束であり、関係者の合意があってはじめて意味を持ちます。PR を通せば、レビューのやりとりとして「誰がいつ、何に合意したか」が記録に残ります。Notebook ではなく PR を選んだのは、この合意の証跡を残すためです。

定義書から Terraform への変換は、専用の Agent Skill が担います。ここでも一つの原則を守っています。定義書は契約である、という考え方です。

だから変換スキルは、定義書に欠けている値を推論で埋めません。必須項目が空いていたら、変換を拒否します。欠損が「スキルが勝手に決めたデフォルト」に化けるのを防ぐためです。空欄を見つけたときは、その性質を見分けて扱いを変えます。本人がまだ決めていない必須項目なら、推論せずに本人へ問い直します。意図的に「あとで見直す」と保留された値なら、いま確定するか保留のままにするかを確認します。テンプレートの書き残しや書式の誤りなら、定義書そのものを直してもらいます。いずれにせよ、人間が決めるべきことを AI が黙って埋めてしまうことはありません。変換という最後の機械的な工程でも、オーナーシップは人間に残ります。

外在的認知負荷を畳む — Terraform モジュールという Golden Path

AI コーチが定義書を作り、それが Terraform に変換されます。ここまでの流れの「変換先」——実際に Datadog のリソースを組み立てる部分——が、この Terraform モジュールです。ここが外在的認知負荷、つまり「SLO 定義書さえできれば、あとは機械的に決まる設定」を丸ごと引き受けます。チームが「何を、どの水準で守るか」を定義書に書き切ってしまえば、それを Datadog 上でどのリソースとしてどう設定するかは、もう考えるまでもなく決まります。

実際、Datadog で一つの SLO をきちんと運用しようとすると、SLO 本体・複数のバーンレート用モニター・エラーバジェットのアラート・通知ルーティングなど、十ほどのリソースが必要です。どれもサービスの信頼性を形づくる判断ではなく、定義から機械的に導かれる作業です。機械的なら、モジュールに包んで隠せます。私たちはこれを slo モジュールに畳み込みました。同じ思想で、オンコールのルーティング——Datadog On-Call のスケジュール、エスカレーションポリシー、インシデント通知ルール——も oncall モジュールに切り出しています(本稿では slo を中心に話します)。

利用者がモジュールに渡すのは、目標値と計測クエリ、それにいくつかのメタ情報だけです。

module "signin_availability" {
  source  = "app.terraform.io/Nulab/slo/datadog"
  version = "0.1.0"

  name     = "signin-availability"
  service  = "example-web"
  team     = "example-team"
  env      = "prod"
  target   = 99.9          # 目標値(%)
  slo_type = "metric"      # metric / time_slice / monitor

  numerator   = "..."      # good events
  denominator = "..."      # total events
  severity    = "SEV-2"

  paging_notification_targets = ["@slack-example-team-urgent"]
  ticket_notification_targets = ["@slack-example-team"]
}

バーンレートの数式も、Fast/Medium/Slow のしきい値設計も、アラート抑制の組み方も、利用者は知る必要がありません。これだけの入力から、プラットフォームエンジニアリングチームが定めた安全なデフォルトで、リソース一式が組み上がります(必要なら細かく調整もできます)。

組み上がるのは、消費速度の異なる三段のバーンレートアラート、エラーバジェットの警告と SLO 違反のアラート、重複通知を抑える抑制ロジック、低トラフィックなサービス向けのウィンドウ調整、そして Service Catalog への自動ひも付けです。しきい値も評価ウィンドウも通知の振り分けも、全チームで共通のデフォルトが入っています。

モジュールの中身をのぞいてみる

利用者からは「目標値とクエリを渡すだけ」に見えますが、この一つのモジュール呼び出しは、内部で十ほどの Datadog リソースに展開されます。先ほどの最小構成だと、生成されるのはおおよそ次の通りです。

  • SLO 本体 1つ
  • バーンレートのモニター 3つ(Fast / Medium / Slow)
  • エラーバジェットのモニター 2つ(残量の警告と、SLO 違反)
  • 通知抑制用の composite モニター 3つ

低トラフィック対応(ウィンドウ延長やボリューム gate)を有効にすると、ここにボリュームチェック用のモニターとその composite モニターが加わり、十数個になります。

こうした一つひとつを正しく組み立てるのは、地味に骨の折れる作業です。モジュールに任せれば、利用者はこの中身を考えなくて済みます。

設計判断

SLO・Terraform・Datadog に通じた人なら、ここまでの話で大枠は再現できるはずです。ただ、素直に作ると見落としがちな判断がいくつかあるので、勘どころとして残しておきます。

  • アラート抑制は composite monitor の二層構造にする。バーンレートのモニター本体には通知を付けず、通知と抑制条件は別の composite monitor 側に持たせます。Medium は medium && !fast、Slow は slow && !fast && !medium という式で、上位のバーンが鳴っているあいだは抑えます。各モニターに直接通知を付けると Fast/Medium/Slow が同時に発火して多重ページングになるので、それを避けるための分離です。
  • 低トラフィックは、ウィンドウ延長と「ボリューム gate」の二段で誤発報を止める。まずアラートの評価ウィンドウを延ばしてデータの少なさによるノイズをならし、さらに分母(リクエスト数)が一定数を超えているかを見るモニターを別に作って、バーンレートのアラートと AND で合成します(burn && volume)。データ点が少ないとバーンレートが暴れて誤発報するので、十分な母数があるときだけ鳴らします。
  • 通知は二系統に分け、緊急系は Incident 経由で On-Call へ流す。Fast/Medium burn と SLO 違反はページング系(Datadog Incident を作成し、Severity に応じて On-Call を呼ぶ)、Slow burn とエラーバジェット警告はチケット系(Slack 通知)。深夜に人を起こすものと、翌営業日に見ればいいものを、最初から経路で分けています。
  • バーンレート(消費の速度)とエラーバジェット残量(ストック)は別々に監視する。バーン用とは別に、残量が閾値を切ったら warning、0%(違反)で critical を出すモニターを持ちます。「急に燃えている」と「もう残っていない」は別の事象だからです。

ベストプラクティスがデフォルト値として埋め込まれているので、利用者は間違えにくく、必要があれば上書きもできます。これが外在的認知負荷に対する私たちの答えです。

動かしてみて、いまどうなっているか

正直に書くと、AI と一緒に SLO 定義書を一本書き上げるのに、だいたい 1 時間半から 2 時間ほどかかります。

時間がかかる理由は二つあります。一つは、定義書をチームで相談しながら書くから。何を守るか、目標値をいくつにするか——前半で内在的認知負荷と呼んだ決めごとに、チームで向き合って合意する時間です。AI の処理が遅いのではなく、人間が約束を交わすのに必要な時間が、ここにかかります。もう一つは、AI の説明の丁寧さが、チームの SLO 運用経験によって変わるからです。初心者向けの設定で始めると、関連用語や設定の方法、その意図まで AI がひとつずつ説明しながら定義書づくりを進めるので、そのぶん時間がかかります。逆に、運用に慣れたチームなら 1 時間を切ります。

具体的な成果としては、二つのパイロットチームが、この流れで SLO を本番にデプロイしました。SLO 運用をしたことがなかったチームのエンジニアが、AI コーチとともに SLO 定義書をかきあげ、実際に SLO を運用しています。

ただし、これらの SLO はデプロイされたばかりです。成功と言うのは時期尚早でしょう。定義することと、それを使って実際に意思決定を駆動することは別物です。SLO が時間とともに意味を持ち続けるか——ここはこれから数か月、注意深く見ていくつもりです。

どこまで解けて、何が残ったか

背景で挙げた二つの仮説は、この仕組みでどこまで解けたのか。正直に振り返ってみます。

「覚えることが多すぎる」ほうは、モジュールと AI コーチでかなり軽くできました。そして「心理的なハードル」も——完全には消せないものの——ゴールデンパスがあることで大きく下がる、と考えています。各チームが導入のやり方をゼロから設計する必要がなくなり、「どう進めるか」を背負う責任が軽くなります。導入そのものの工数も小さくなります。さらに、同じゴールデンパスを通ったチームの事例が社内で増えるほど、「これを使えばどれくらいの手間で、どんな見返りがあるか」を見積もりやすくなり、関係者を説得するコストも下がっていきます。背景で「多くの人を巻き込む割に、ゴールまでの距離が見えない」と書きましたが、整備されたゴールデンパスと前例の蓄積が、まさにそこを埋めていきます。

それでも、消せない部分は残ります。運用を変える不安をやわらげ、関係者から本物の合意と当事者意識を引き出すこと。そして、エラーバジェットに基づいて「いまは機能開発を止める」と判断する文化を根づかせること。ここはツールが肩代わりできる領域ではありません。AI コーチが扱えるのは「どうやるか(how)」であって、「なぜやるか(why)」ではありません。AI はエバンジェリストにはなれないのです。

だからこそ次に進めているのが SLO Champions です。ツールがカバーしきれないことは必ず残るし、システムが届かないところで踏み込み、チームに寄り添って合意形成を後押しできる人を、組織の各所に置きたいと考えています。そこで、SLO に関心のあるエンジニアへの声かけを始めています。

AI に過度に依存しない — AI なしで回る土台の上に乗せる

ここまで AI の話を続けてきましたが、この仕組みは AI がなくても完全に動きます。SLO 定義書を手で書き、Terraform モジュールを呼び出せば、AI コーチを一度も使わなくても SLO は本番に乗ります。AI は、その流れを速くする補助輪であって、土台ではありません。

AI を土台にしなかった理由は、二つあります。

一つは、AI を使ったこの仕組みが、初期段階でどこまで使いものになるか読めなかったから。正直なところ、AI コーチが実際どこまでの精度で動いてくれるのかは、プロジェクト開始時には分かりませんでした。パイロット導入したチームでは今のところかなりうまく動いてくれていますが、今後あらゆる場面に対応できる AI になれるかはまだわかりません。だからこそ、仮に AI が期待ほど働かなかったとしても、プロジェクト全体が潰れないようにしておきたかったのです。AI なしでも SLO を作れる土台を先に固めておけば、AI の出来が悪くても、仕組みそのものは成立します。

もう一つは、この AI が補助輪のような存在だから。SLO の運用に慣れたチームは、やがて AI コーチの手ほどきがなくても定義書を書けるようになり、その機能の多くは要らなくなっていくはずです(Datadog から実データを引くような便利な部分は残るでしょうが)。ずっと使い続けてもらうことを前提にはしていません。

おわりに

タイトルに掲げた「Coach Design, Automate the Rest」——設計はコーチし、残りは自動化する。この方針は、すべての認知負荷が等価ではない、という一点から出発しました。チームが理解し、合意し、責任を負う部分——内在的認知負荷——には、AI を踏み込ませない。道具の使い方のような外在的認知負荷は、AI とモジュールに引き受けさせる。そう分けることが、設計の土台になりました。

とはいえ、線を引いたら導入が一気に進んだ、という単純な話ではありません。覚えることの重さはかなり軽くできましたが、「全員の約束として成り立たせる」ハードルは、いまも人間の仕事として残っています。AI コーチが実際どこまで効くのかも、これから確かめる段階です。冒頭に書いたとおり、まだ始まったばかりの途中経過にすぎません。

言いかえれば、私たちはまだ、仮説を検証している最中です。その結果何がうまくいって、何がうまくいかなかったのかを、これからも報告していきます。

「AI活用事例」の関連記事

ブログ一覧へ