AI EngineeringZero to ProductionHome·About·Contact
Case Studies & Reference Architectures · Part 8

Retrofitting AI into a legacy system

A full end-to-end walkthrough of adding AI into a large legacy system — a 20-year-old insurance claims platform — without a rewrite and without a big-bang cutover. Constraints → integration patterns → the strangler-fig approach → data plumbing → risk containment → incremental rollout, one defensible decision at a time. Engineering-leadership framing; the legacy platform is a representative composite.

⏱️ ~2.5 hours🧪 7 steps🎯 Advanced→Tech-lead

Learning objectives

  • Frame the real problem of a legacy retrofit: you cannot rewrite, cannot break the system of record, and cannot pause the business.
  • Choose integration patterns (anti-corruption layer, adapter, event tap, sidecar) that add AI without coupling it to legacy internals.
  • Apply the strangler-fig pattern to route a slice of traffic through the AI path while the legacy path stays authoritative.
  • Design the data plumbing — change-data-capture, read models, and a clean contract — so the AI reads legacy data safely.
  • Contain risk with feature flags, shadow mode, kill switches, and a legacy fallback that is always one config away.
  • Roll out incrementally by slice, measure against the legacy baseline, and know the exact rollback path at every step.
Representative scenario — not a real customerThe insurer, the platform, the volumes, and every number below are an illustrative composite invented for teaching. They are not a real deployment and no figure is a claimed result. The integration patterns are real, industry-standard practice; the story is a teaching device.

Meet "Continental Insurance" — a representative composite. Its claims platform is 20 years old: a monolith on an older stack, a database that is the undisputed system of record, batch jobs no one wants to touch, and a business that processes thousands of claims a day on top of it. Leadership wants AI to triage incoming claims and draft adjuster summaries. What they cannot have is a rewrite, a multi-quarter freeze, or any risk to the system of record. This is the most common enterprise AI job that isn't a greenfield demo, and it is dominated by three forces a new project never feels: you must not break what works, you must not couple to legacy internals, and you must be able to roll back in seconds.

1 · Framing the retrofit — the constraints that rule out a rewrite

The instinct is "let's just rebuild the claims flow with AI in it." In a real enterprise that is how you spend two years and ship nothing. Start by writing the constraints that make a rewrite a non-starter, because they also point straight at the pattern you should use instead.

ConstraintBusiness statementEngineering consequence
No rewriteThe claims monolith is too risky and expensive to replace.Add capability around the edges; the legacy code stays the system of record.
No downtimeClaims processing cannot pause for a migration.Every change ships behind a flag; the legacy path always still works.
No couplingThe AI must not reach into legacy internals and freeze them in place.An anti-corruption layer isolates the AI from the legacy schema and quirks.
Data integrityThe system of record must never be corrupted by the AI.AI writes are advisory/queued; the legacy DB stays authoritative and validated.
Instant rollbackAny regression must be reversible immediately.A kill switch reverts to the pure-legacy path in one config change.
Prove value per sliceLeadership funds what demonstrably works.Roll out by claim-type slice; measure each against the legacy baseline.
The constraints are the designRead the right column top to bottom and the architecture writes itself: an anti-corruption layer for no-coupling, flags + a kill switch for no-downtime and instant rollback, an advisory write path for data integrity, and per-slice rollout to prove value. You didn't choose the strangler-fig pattern because it's fashionable; the constraints chose it for you.

2 · Integration patterns — how the AI touches the legacy system

The core decision is how the new AI capability connects to the old system without becoming welded to it. Four patterns cover almost every case; you usually combine them. The unifying idea is an anti-corruption layer (ACL): a translation boundary so the AI speaks a clean domain model and never learns the legacy schema's 20 years of quirks.

PatternHow it worksUse it when
Anti-corruption layerA boundary that translates legacy models ↔ a clean domain model.Always — it's the wrapper the other patterns sit inside.
Adapter / façadeWrap a legacy API/DB call behind a clean interface the AI calls.The legacy system already exposes a callable surface (API, stored proc).
Event tap (CDC)Capture DB changes as an event stream the AI consumes read-only.You need current data but must not touch the legacy write path.
Sidecar / strangler façadeA new service intercepts requests, routes some to AI, rest to legacy.You want to peel off one behavior at a time behind one entry point.
Why the anti-corruption layer earns its keepWithout an ACL, your AI code ends up importing legacy enums, null-handling quirks, and column names — and now the legacy schema can never change without breaking the AI. The ACL is a small, boring translation layer that keeps the two worlds independent, so the legacy team and the AI team can move at different speeds. It is the single highest-leverage decision in the whole retrofit.

3 · The strangler-fig architecture

The strangler-fig pattern (a well-known, publicly documented approach to legacy modernization) is the backbone: put a façade in front of the legacy system, route a slice of traffic through the new AI path, and grow that slice only as it earns trust — while the legacy path stays authoritative the entire time. Read the diagram as one claim's journey: it enters the façade, which decides whether this slice is AI-enabled; the AI path reads legacy data through the ACL, produces an advisory output, and the legacy system remains the system of record.

Incoming claim from intake Strangler façade one entry point Route by slice + flag flag-gated AI path via ACL clean domain model Advisory output queue never authoritative Legacy system of record always still works
The legacy path never leaves — that's the safetyThe strangler façade does not replace the legacy system; it sits in front of it. Every claim can still be processed the old way, and for slices the flag hasn't enabled, it is. That is what makes the retrofit safe: the new path is always an addition you can switch off, never a bridge you've burned. The fig "strangles" the old tree slowly, and only where the new growth has proven it can bear the load.

4 · Data plumbing — reading legacy data safely

The AI needs current claims data, but the write path to the system of record is exactly what you promised not to touch. The answer is to read, never reach in: capture changes as a stream and build a purpose-shaped read model the AI queries, translated through the ACL. The legacy DB stays authoritative and untouched; the AI works off a derived, eventually-consistent view.

The read-side data flow

  1. Change-data-capture (CDC) taps the legacy DB's change log and emits events — no code changes to legacy writes.
  2. An ACL transform maps legacy rows into a clean domain event (stable names, resolved enums, no nulls-as-flags).
  3. A read model (a separate store shaped for the AI's queries) is built from those events.
  4. The AI path queries the read model, never the legacy DB directly — decoupling load and schema.
  5. Any AI output is written to an advisory queue, never back into the system of record without human/legacy validation.
Advisory writes only — the system of record stays sacredThe fastest way to lose the whole project is to let the AI write directly into the legacy database. Route every AI-produced value into an advisory queue that a human or the legacy system validates before it becomes truth. Eventual consistency on the read side is fine; a corrupted system of record is not recoverable trust.

5 · Risk containment — flags, shadow mode & the kill switch

A retrofit lives or dies on containment: the blast radius of any AI mistake must be small and reversible. Four mechanisms, layered, give you that. Notice they're the same mechanisms a mature deployment uses everywhere — the retrofit just makes them non-negotiable because the legacy system is unforgiving.

MechanismWhat it containsHow it's wired
Feature flagWhich slices/tenants see the AI path at all.Per-slice, per-tenant; default off.
Shadow modeWhether AI output is acted on or merely logged for comparison.AI runs, output compared to legacy offline, never shown.
Kill switchThe whole AI path, instantly.One config → façade routes 100% to legacy.
Circuit breakerCascading failure when the AI/model is slow or erroring.Trip on error/latency threshold → fall back to legacy.
Legacy fallbackAny single request the AI can't handle.Timeout/exception → serve the legacy result.
The kill switch is a launch requirement, not a nice-to-haveBefore the first real claim touches the AI path, you must be able to prove — in a drill — that one config change routes 100% of traffic back to pure legacy in seconds, with no deploy. If you can't demonstrate the rollback, you are not ready to roll forward. Rehearse it the way you'd rehearse a database failover.

6 · Incremental rollout — one slice at a time

Now sequence the actual rollout. The strangler-fig only works if you grow the AI slice deliberately, measure each step against the legacy baseline, and keep the rollback one config away the whole time. Never enable a slice you couldn't instantly disable.

StageAI scopeGate to advance
1 · ShadowRuns on one low-risk claim-type; output logged, never used.AI agrees with legacy at target rate on the shadow set.
2 · Assist (1 slice)Drafts adjuster summaries for that slice, shown to humans.Adjusters accept drafts at target rate; no integrity issues.
3 · Expand slicesEnable additional claim-type slices behind flags.Each new slice re-passes the shadow → assist gates.
4 · Steady stateAI path handles enabled slices with full monitoring.Legacy fallback + kill switch verified; baseline held.
Measure against the legacy baseline, alwaysThe baseline is the legacy system's own numbers — that's the honest bar. In shadow mode you're asking "does the AI agree with what legacy already does?"; in assist mode, "do humans accept the AI's drafts and is quality at least as good?" Every slice must beat or match the baseline before it advances, and any slice that regresses gets flagged back off — no debate.

7 · Failure modes & the containment that hardens each

A retrofit "designed for production" is one where every failure mode maps to a containment mechanism already in the architecture. If a row points at something you'd bolt on after an incident, that is your next incident.

Failure modeWhat goes wrongThe containment that hardens it
Legacy couplingAI freezes the legacy schema in place.Anti-corruption layer isolates the AI (§2)
System-of-record corruptionAI writes bad data into the authoritative DB.Advisory-write queue; legacy stays authoritative (§4)
Big-bang blast radiusOne bug affects all claims at once.Per-slice flags; grow the slice only as it earns trust (§3,§6)
Model outage / latencyAI path down takes claims down with it.Circuit breaker + legacy fallback (§5)
Silent quality dropAI drifts below the legacy baseline unnoticed.Shadow comparison + per-slice baseline monitoring (§5,§6)
No way backA regression can't be reversed fast.Kill switch → 100% legacy in one config, rehearsed (§5)
Stale dataAI acts on out-of-date claim state.CDC-fed read model with freshness monitoring (§4)
Agent or workflow inside the slice?Within an enabled slice you still choose: a fixed workflow (retrieve → summarize → queue) or a freer agent. For a legacy retrofit, start with the workflow — it's debuggable and its cost/behavior are bounded, which matters doubly when it's grafted onto a fragile system. Reserve any agentic autonomy for later slices where you've earned trust, and keep it inside the same ACL, flags, and kill switch. This is the agents-vs-workflows call from CS1, applied to a retrofit.
📋 Grade this design
DimensionMeets barAbove bar
Constraints firstNames no-rewrite, no-downtime, integrity, rollback.Derives the pattern (ACL + strangler + flags) directly from the constraints.
Decoupled integrationWraps legacy behind an interface.Anti-corruption layer keeps AI and legacy independently changeable; no legacy internals leak.
Strangler-fig rolloutRoutes some traffic to the AI path.Legacy path stays authoritative throughout; the slice grows only as it earns trust.
Safe data plumbingReads legacy data somehow.CDC → ACL → read model; AI never writes the system of record; freshness monitored.
Risk containmentHas a feature flag.Flags + shadow + circuit breaker + rehearsed kill switch + legacy fallback, layered.
Baseline-gated rolloutRolls out gradually.Each slice measured against the legacy baseline; regressions flagged off instantly.

Score each dimension Meets or Above. All six at least Meets = a retrofit you could run against a real system of record. Any dimension you can't hit is where the legacy system will bite you.

✓ Knowledge check

A teammate proposes having the AI write its triage decision straight into the claims table "so the downstream jobs just pick it up." Why is that dangerous, and what's the safer design?

Show answer
Writing directly into the system of record couples the AI to the legacy schema and makes any AI mistake corrupt authoritative data that downstream batch jobs will happily propagate — with no easy undo. The safer design routes the AI's output into an advisory queue (§4) that a human or the legacy system validates before it becomes truth, and reads legacy state through a CDC-fed read model rather than reaching into the DB. The legacy database stays the single authoritative source; the AI only ever proposes.
✓ Knowledge check

You've enabled the AI path for one claim-type slice and quality looks good. Leadership asks you to "turn it on for everything next week." What's your answer, and why?

Show answer
No — you expand slice by slice, and each new slice re-passes the shadow → assist gates against the legacy baseline before it advances (§6). A single good slice proves the mechanism works for that claim type, not that the AI generalizes to every claim type; each has different data, edge cases, and risk. Big-bang enablement also maximizes blast radius — the whole point of the strangler-fig (§3) is to keep the radius small and the rollback (§5) one config away. Speed comes from parallelizing slice evaluation, not from skipping the gate.

🪜 Practice ladder beginner → industry

Six graded exercises, easy to real-world. Try each before opening its solution.

Exercise 1 · State why a rewrite is the wrong first moveBeginner

Context: The most expensive mistake in enterprise AI is proposing a rewrite of a working legacy system. Being able to argue against it clearly is a leadership skill.

Your task: Write three constraints that rule out a rewrite of the claims platform, and name the pattern each one points toward instead.

Requirements:

  • No-downtime → the legacy path must keep working while you add the AI
  • No-coupling → the AI must not depend on legacy internals
  • Instant-rollback → any change must be reversible in seconds
  • For each constraint, name the mechanism it implies (flag/kill switch, ACL, strangler façade)

💡 Hint: The constraints aren't obstacles to the design — read together they are the design.

Show solution
  • No downtime: claims can't pause for a migration → ship behind a feature flag with the legacy path always live; the strangler façade adds capability without removing the old one.
  • No coupling: the AI can't freeze the legacy schema → an anti-corruption layer translates between a clean domain model and legacy internals, keeping both changeable.
  • Instant rollback: any regression must reverse fast → a kill switch routes 100% of traffic back to pure legacy in one config change.

A rewrite violates all three at once: it pauses the business, couples everything, and has no cheap rollback. The constraints point straight at the strangler-fig retrofit instead.

Exercise 2 · Choose integration patterns for the retrofitIntermediate

Context: Connecting new AI to an old system is mostly about how you touch it. The wrong connection welds the two together forever.

Your task: For the claims platform, pick the integration patterns you'd use to (a) read current claim data and (b) intercept incoming claims — and justify each.

Requirements:

  • Reading current data without touching the write path
  • Intercepting incoming claims to route some to the AI
  • Keeping the AI's domain model clean of legacy quirks
  • Justify each choice against the no-coupling / integrity constraints

💡 Hint: One boundary (the ACL) should wrap whatever specific mechanisms you choose.

Show solution
📋 Pattern choices
NeedPatternWhy
Read current claim dataEvent tap (CDC) → read modelGets fresh data without touching the legacy write path; decouples AI query load from the legacy DB.
Intercept incoming claimsStrangler façade / sidecarOne entry point routes a slice to the AI and the rest to legacy; lets you peel off behavior gradually.
Keep the AI cleanAnti-corruption layer (wraps both)Translates legacy models ↔ a clean domain model so neither side is frozen by the other.

The ACL is the outer boundary; CDC handles reads and the façade handles interception inside it. Together they satisfy no-coupling (nothing imports legacy internals) and integrity (no writes to the system of record).

Exercise 3 · Design the strangler-fig routingAdvanced

Context: The strangler-fig only helps if the façade routes precisely and the legacy path is always reachable. A sloppy façade turns a safe pattern into a single point of failure.

Your task: Design the façade's routing logic: how it decides AI-vs-legacy per request, and how the legacy path stays guaranteed-available.

Requirements:

  • Route by claim-type slice AND a feature flag (both must be on to use AI)
  • Every request has a guaranteed legacy path, even for enabled slices (fallback on error/timeout)
  • A kill switch forces 100% legacy regardless of flags
  • Shadow mode: run the AI but don't act on its output, for comparison
  • Explain why the legacy path is never removed, only bypassed

💡 Hint: Make 'serve the legacy result' the default that the AI path opts out of, not the other way around.

Show solution
route(request):
  if KILL_SWITCH_ON:                 return legacy(request)        # instant, config-only
  slice = classify_slice(request)
  if not flag_on(slice):             return legacy(request)        # slice not enabled
  try:
     ai = ai_path(request)                                          # reads via ACL/read model
     if SHADOW_MODE:  log_compare(ai, legacy(request)); return legacy(request)
     return ai
  except (Timeout, Error):           return legacy(request)        # circuit-breaker fallback

The invariant: every path ends in a valid result, and the default is legacy. The AI path is reachable only when the kill switch is off, the slice's flag is on, and the call succeeds — otherwise the request quietly falls back to the legacy system that always still works. The legacy path is never removed, only bypassed, which is exactly what makes the retrofit reversible.

Exercise 4 · Design the safe data plumbingExpert

Context: The AI needs fresh claim data, but the write path is the one thing you promised not to touch. Get this wrong and you either corrupt the system of record or act on stale state.

Your task: Design the read-side data flow from the legacy DB to the AI, and the write-side rule that protects the system of record.

Requirements:

  • Read: CDC from the legacy DB → ACL transform → a read model shaped for AI queries
  • The AI queries the read model, never the legacy DB directly
  • Write: AI output goes to an advisory queue, validated before it becomes truth
  • Handle eventual consistency: monitor read-model freshness and degrade gracefully if stale
  • Explain why direct writes to the system of record are prohibited

💡 Hint: Reads are derived and eventually consistent; writes to the system of record are someone else's validated job.

Show solution
  1. CDC tap: capture the legacy DB's change log as events — zero changes to legacy write code.
  2. ACL transform: map legacy rows to clean domain events (stable names, resolved enums, no nulls-as-flags) so the AI never learns the schema's quirks.
  3. Read model: build a separate store shaped for the AI's queries; the AI reads only from here, decoupling it from legacy load and schema.
  4. Advisory write: AI output lands in a queue; a human or the legacy system validates it before it becomes authoritative. The system of record is never written by the AI.
  5. Freshness: monitor read-model lag; if it exceeds a threshold, degrade (fall back to legacy for that request) rather than act on stale state.

The rule: read derived data, propose advisory outputs, and let the legacy system stay the single validated source of truth. Eventual consistency is acceptable; a corrupted system of record is not.

Exercise 5 · Design the risk-containment layerProfessional

Context: Containment is what lets you roll a retrofit forward without fear. Each mechanism shrinks a different blast radius, and they only work layered.

Your task: Design the containment layer: name the mechanisms, what each contains, and prove the rollback is real with a drill.

Requirements:

  • Feature flags (which slices/tenants), shadow mode (act vs log), kill switch (whole AI path)
  • Circuit breaker (cascading failure) and per-request legacy fallback (timeout/exception)
  • Describe a rollback drill that proves 100%-legacy in seconds with no deploy
  • State what each mechanism contains and how they layer
  • Make the kill switch a launch gate, not a post-incident addition

💡 Hint: For each mechanism, answer: what specific failure does it stop, and how fast?

Show solution
📋 Containment layer
MechanismContainsSpeed
Feature flagWhich slices/tenants ever see the AI path.Config, per-slice, default off.
Shadow modeWhether AI output is acted on at all.Off by default; flip to act only after shadow passes.
Circuit breakerCascading failure from a slow/erroring model.Auto-trips on threshold → legacy.
Legacy fallbackAny single failing request.Per-request, on timeout/exception.
Kill switchThe entire AI path.One config → 100% legacy, seconds, no deploy.

Rollback drill: in a game day, flip the kill switch and confirm 100% of traffic serves legacy results within seconds, with no deploy and no data loss. If you can't demonstrate it, you're not cleared to enable a single real slice. Layered, these shrink the blast radius from "all claims" down to "one request, logged."

Exercise 6 · Sequence the whole retrofit rolloutIndustry scenario

Context: The pilot slice works; now you must roll AI across a live claims platform, prove value per slice, and never once put the system of record at risk. This is the tech-lead deliverable.

Your task: Lay out the end-to-end retrofit plan: architecture, data plumbing, containment, and the staged, baseline-gated rollout — with the exact rollback path at each step.

Requirements:

  • Architecture: strangler façade + ACL; legacy stays the system of record throughout
  • Data: CDC → ACL → read model for reads; advisory queue for writes
  • Containment: flags + shadow + circuit breaker + rehearsed kill switch + legacy fallback
  • Rollout: shadow → assist (1 slice) → expand slices → steady state, each gated on the legacy baseline
  • For every stage, state the metric that advances it and the one-config rollback
  • Sequence it: prove the mechanism on one low-risk slice before widening

💡 Hint: Lead with containment and the ACL; earn each new slice against the legacy baseline, never on a demo's momentum.

Show solution
  1. Architecture. A strangler façade fronts the legacy platform; an anti-corruption layer isolates the AI. The legacy system stays the authoritative system of record for every claim, always.
  2. Data plumbing. CDC → ACL transform → a read model the AI queries; AI outputs go to an advisory queue, validated before they become truth. No AI writes to the system of record.
  3. Containment first. Per-slice flags, shadow mode, circuit breaker, per-request legacy fallback, and a rehearsed kill switch (100% legacy in seconds). Prove the rollback in a drill before enabling any real slice.
  4. Staged, baseline-gated rollout. Shadow on one low-risk slice (AI must agree with legacy at target rate) → assist on that slice (adjusters accept drafts at target rate) → expand slice by slice, each re-passing the gates → steady state with full monitoring.
  5. Rollback at every step. Each stage names the metric that advances it and the single config that reverts it. Any slice that drops below the legacy baseline is flagged off, no debate.

Order: containment and the ACL before anything; then prove the mechanism on one slice; then widen only against the legacy baseline. You add capability around a system that keeps working, and you can always switch the new growth off — that is what a safe retrofit at scale looks like.

✓ Checkpoint — you can move on when you can…

  • Argue why a rewrite is the wrong first move and derive the strangler-fig retrofit from the constraints.
  • Choose integration patterns (ACL, adapter, CDC event tap, strangler façade) and justify each against no-coupling and integrity.
  • Design strangler-fig routing where the legacy path is always the guaranteed default.
  • Design read-side plumbing (CDC → ACL → read model) and an advisory-write rule that protects the system of record.
  • Layer the containment mechanisms and rehearse a kill-switch rollback to 100% legacy.
  • Sequence an incremental, baseline-gated rollout with a one-config rollback at every stage.
© 2026 studybydoing.in · AI Engineering: Zero to Production · All rights reserved. · About · Privacy Policy · Terms · Contact
Educational content, provided as-is and without warranty. Code samples are examples — review, test, and adapt them before using in production. See the Terms of Use & Disclaimer. Use at your own risk.
© studybydoing.in