LLM prompt caching 2026-ban: Anthropic, OpenAI és Gemini gyakorlati útmutató

Prompt caching gyakorlati útmutató 2026-ban: Anthropic cache_control, OpenAI automatikus cache és Gemini explicit CachedContent. Költségmatek, kódpéldák és a leggyakoribb hit rate-lenullázó hibák egy helyen.

Prompt Caching 2026: Anthropic, OpenAI, Gemini

Frissítve: 2026. július 18.

A prompt caching egy szolgáltatóoldali funkció, amellyel az LLM API-k újrahasznosítják az ismétlődő prompt-előtagot (rendszerprompt, tool-definíciók, RAG kontextus), így a bemeneti tokenek ára 75–90%-kal csökken, és a válaszlatencia akár 80%-kal is javulhat. 2026 közepén mind az Anthropic (Claude 4.5–4.8), az OpenAI (GPT-5.x) és a Google (Gemini 2.5+) natívan támogatja, de eltérő pricing-modellel. Az Anthropic explicit cache_control markerekkel és cache-írási felárral dolgozik, az OpenAI automatikusan és felár nélkül, a Gemini pedig óradíjas tárolást kér az explicit módért cserébe.

Előre szólok: az elmúlt fél évben három különböző csapatnál építettem be prompt caching-et éles rendszerbe, és az összes esetben más volt a nyerő szolgáltató. Ezért is döntöttem úgy, hogy inkább a tényleges költségmatekot és a nálam működő prompt-struktúrákat írom le, mint az általánosságokat.

  • Mindhárom nagy szolgáltató (Anthropic, OpenAI, Google) a bemeneti tokenek 90%-át engedi el cache olvasáson 2026 közepén. Claude Sonnet 4.6 esetén ez 3,00 USD/MTok-ról 0,30 USD/MTok-ra visz le.
  • Az Anthropic explicit opt-in modellje 1,25× (5 perc TTL) vagy 2,0× (1 óra TTL) írási felárat számít fel. Csak akkor éri meg, ha a hit rate 30% fölött van.
  • Egy request-en belül maximum 4 cache_control breakpoint helyezhető el, ezzel rétegzett cache-elés építhető (tools, system prompt, RAG dokumentumok külön-külön).
  • A statikus tartalom mindig a prompt elejére kerüljön, a dinamikus (időbélyeg, user query) a végére. Bármelyik változó karakter a cache-elt szakaszban lenullázza a hit rate-et.
  • A ProjectDiscovery 2026-ban 7%-ról 84%-ra emelte cache hit rate-jét, és 59%-kal csökkentette a teljes LLM költséget 9,8 milliárd cache-elt token mellett.
  • Éles rendszerben a 85% fölötti cache hit rate a reális célérték; 70% alatt szinte biztosan struktúra-hiba van a promptban.

Mi a prompt caching, és hogyan működik a gyakorlatban?

A prompt caching a szolgáltató oldalán tárolja el a már feldolgozott prompt-előtagot, hogy a következő request-nél ne kelljen újraszámolni rá a transformer attention rétegeit. Amikor egy LLM feldolgoz egy promptot, minden tokenre kiszámítja az attention key-value (KV) tenzorokat. Ez a „prefill” fázis, és tipikusan ez a request leglassabb része. Ha a következő request ugyanazzal az előtaggal indul, a modell egyszerűen betölti a cache-elt KV tenzorokat a memóriából, és csak a promptod végén lévő új tartalomra futtatja le a prefill-t.

Gyakorlati oldalról ez azt jelenti, hogy egy 50 000 tokenes RAG kontextus, ami minden hívásnál ugyanaz, először teljes áron megy át (plusz Anthropic-nál az írási felár), utána viszont csak a 10%-át fizeted. A generált output byte-azonos a cache nélküli válasszal, nincs minőségi különbség, csak a prefill-t rövidítjük le. Ez alapvetően megkülönbözteti a prompt cache-elést a szemantikus cache-eléstől, ami hasonló promptokra ad vissza cached választ, és így az output tokeneken is spórol.

A latencia-nyereség sokszor fontosabb, mint a költség. Az OpenAI mérései szerint cache-hit esetén a time-to-first-token akár 80%-kal is csökkenhet. Valós idejű chat, hangalapú asszisztens vagy agent tool loop esetén ez a különbség jelenti a használható és a frusztráló UX közti határvonalat. A cache-elt tokenek nem érintik az output token bill-t; bármilyen becslés, ami a 90%-os kedvezményt a teljes API-számlára extrapolálja, hibás. A megtakarítás kizárólag az input oldalon jelentkezik.

Mennyit spórolhatsz a prompt cachinggel 2026-ban?

A tényleges megtakarítás négy változótól függ: a cache hit rate, a cache-elhető prompt-hossz aránya a teljes bemenetből, a szolgáltató írási felára, és a batch API-val való kombinálás. Egy tipikus RAG chat alkalmazásban, ahol a rendszerprompt és a betöltött dokumentumok 40 000 token körüliek, a user query pedig 200–500 token, a promptnak nagyjából 98%-a cache-elhető. 80% hit rate-tel ez Claude Sonnet 4.6-on 3,00 USD/MTok-ról effektív 0,66 USD/MTok-ra viszi le a bemeneti költséget, azaz 78%-os megtakarítás.

A batch API discount mindhárom szolgáltatónál rátehető: Anthropic-nál a batch 50%-os kedvezménye és a cache 90%-a stackelődik, így Sonnet 4.6 batch + cache read effektíven 0,15 USD/MTok, tehát a listaár 5%-a. Ez az a szám, amit érdemes megcélozni async, nagy volumenű workload-oknál (dokumentum-feldolgozás, embedding pipeline, éjszakai adat-enrichment). Az egyetlen szolgáltató, ahol az extended TTL is számít a matekban, az Anthropic 1 órás cache-e. Itt a 2× írási felár csak akkor amortizálódik, ha ugyanaz az előtag ezen az órán belül legalább 20-szor újra megkérdeződik.

Nagyobb éles telepítéseknél a mérhető nyereség tipikusan 50–70% között mozog a teljes LLM-számlán. A ProjectDiscovery esettanulmánya szerint a cég 7%-ról 84%-ra emelte a cache hit rate-jét azzal, hogy a dinamikus munkamemóriát kivette a system promptból egy user message-be. A végeredmény 59%-os LLM-költségcsökkentés és 9,8 milliárd cache-ből kiszolgált token három hónap alatt. Kisebb rendszereknél a 2026 áprilisi Warung Digital Teknologi példa 612 USD-ról 167 USD-ra vitte le a havi API-költséget hat termékből álló portfólión rétegzett cache-eléssel.

Anthropic prompt caching: cache_control és breakpointok Claude-ban

Az Anthropic modellje a leginkább explicit a három közül. Külön cache_control markert kell tenned a prompt azon blokkjaira, amiket cache-elni akarsz, és pontosan azt kapod, amit kértél: nincs automatikus felismerés, nincs meglepetés. A cache write tokenek 1,25× (5 perc TTL) vagy 2,0× (1 óra TTL) áron mennek át az első hívásnál, majd minden további hit-en 0,10× árat fizetsz. A minimális cache-elhető blokkméret Claude Sonnet 4.6 és Opus 4.8 esetén 1024 token, Haiku 4.5-nél 2048 token.

Ez a minimális implementáció Pythonban a hivatalos Anthropic SDK-val:

from anthropic import Anthropic

client = Anthropic()

SYSTEM_PROMPT = """Te egy senior Python code review agent vagy.
[... 4000+ token statikus utasítás, style guide, példák ...]"""

RAG_CONTEXT = """[... 30 000 token betöltött kódbázis-részlet, minden hívásnál ugyanaz ...]"""

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": SYSTEM_PROMPT,
            "cache_control": {"type": "ephemeral", "ttl": "1h"},
        },
        {
            "type": "text",
            "text": RAG_CONTEXT,
            "cache_control": {"type": "ephemeral", "ttl": "5m"},
        },
    ],
    messages=[
        {"role": "user", "content": "Review the diff attached below: ..."}
    ],
)

usage = response.usage
print(f"Cache write: {usage.cache_creation_input_tokens}")
print(f"Cache read:  {usage.cache_read_input_tokens}")
print(f"Uncached in: {usage.input_tokens}")

A fenti példa két különálló cache réteget hoz létre: a stabil system prompt 1 órás TTL-lel, a gyakrabban frissülő RAG kontextus 5 perces TTL-lel. A 2026 februári API-változás óta a cache workspace-szintű, nem szervezet-szintű, tehát ha több csapat oszt meg egy Anthropic org-ot, minden workspace saját cache-t kap. A hívás után a cache_read_input_tokens mező mutatja, hány token jött cache-ből. Ha ez 0 minden hívásnál, akkor vagy a minimum token-küszöb alá esel, vagy dinamikus tartalom szökik be a cache-elt szakaszba. Az Anthropic hivatalos prompt caching dokumentációjában részletesen szerepel az összes edge case.

OpenAI automatikus caching: GPT-5.x és a nulla-kód opció

Az OpenAI caching automatikus és felár nélküli: nincs cache_control marker, nincs opt-in, nincs írási premium. Minden 1024 tokennél hosszabb prompt automatikusan cache-elődik, ha a prefix egyezik egy nemrég feldolgozott hívással, és a cached read tokenekre a GPT-5.x családon 90%, GPT-4.1-en 75% kedvezmény jár. A cache TTL 5–10 perc közötti in-memory tárolással, ami GPT-5.5 és GPT-5.4 esetén extended prompt caching-gel akár 24 órára is növelhető.

Kliens-oldali kód nem szükséges, de a struktúra igen. Pontosan ugyanaz az elv, mint Anthropic-nál: a statikus tartalom (system message, tool definíciók, RAG kontextus) a prompt elejére kerül, a variábilis rész a végére. A cache-hit-et a response usage.prompt_tokens_details.cached_tokens mezőjén tudod ellenőrizni:

from openai import OpenAI

client = OpenAI()

response = client.chat.completions.create(
    model="gpt-5.5",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT + "\n\n" + RAG_CONTEXT},
        {"role": "user", "content": user_query},
    ],
)

cached = response.usage.prompt_tokens_details.cached_tokens
total = response.usage.prompt_tokens
print(f"Cache hit rate: {cached / total:.1%}")

Az OpenAI modell akkor működik a legjobban, ha alacsony vagy közepes forgalmú workload-on dolgozol, ahol a manuális írási felár tervezése nem éri meg a fejlesztési overhead-et. A trade-off: kevesebb kontrollod van a cache boundary fölött, és ha egy statikus szakaszod éppen 1023 tokenes, semmilyen módszerrel nem tudod cache-elni. Az explicit rendszerek (Anthropic, Gemini explicit mód) itt előnyben vannak, de a nulla-kód egyszerűsége cserébe brutális gyorsan integrálható. Nálam egy három napos MVP-ben ezt választottam, és utólag sem bántam meg.

Google Gemini caching: explicit cache objektumok és tárolási díj

A Gemini kétféle módot kínál. Az implicit caching (2026 elején fizetős projekteknél elérhető) az OpenAI logikáját követi: automatikus, kód-változtatás nélkül, 10%-os áron a cache-elt tokenek után. Az explicit caching viszont egyedi a piacon. Létrehozol egy nevesített CachedContent objektumot, aminek van saját ID-je és TTL-je, és minden request-ben csak erre az ID-re hivatkozol. A minimális cache méret 4096 token (magasabb, mint a másik két szolgáltatónál), és Gemini 2.5 Pro fölött 4,50 USD/MTok/óra tárolási díj jár érte.

from google import genai
from google.genai import types

client = genai.Client()

cache = client.caches.create(
    model="gemini-2.5-pro",
    config=types.CreateCachedContentConfig(
        display_name="rag-context-2026-07",
        system_instruction=SYSTEM_PROMPT,
        contents=[RAG_CONTEXT],
        ttl="3600s",
    ),
)

response = client.models.generate_content(
    model="gemini-2.5-pro",
    contents=user_query,
    config=types.GenerateContentConfig(cached_content=cache.name),
)

print(f"Cache read tokens: {response.usage_metadata.cached_content_token_count}")

A tárolási díj a fő tervezési változó. Egy 100 000 tokenes Gemini Flash cache 0,10 USD/óra, tehát ha 24 óráig fenntartod, 2,40 USD-be kerül a puszta létezése. Nagy forgalmú, hosszú futású workload esetén ez triviálisan amortizálódik. 1000+ hívás óránként ugyanarra a cache-re már bőven megéri. Alacsony forgalmú fejlesztői környezetben viszont a tárolási díj gyorsan túlszaladhat azon, amit az olvasáson spórolsz. A hivatalos Gemini context caching dokumentációja minden modellre külön feltünteti a küszöböket.

Három szolgáltató összehasonlítása: melyiket válaszd?

Az alábbi táblázat 2026 júliusi árakkal és paraméterekkel dolgozik, minden szám a listaáras Claude Sonnet 4.6, GPT-5.5 és Gemini 2.5 Pro modellekre vonatkozik:

Jellemző Anthropic Claude OpenAI GPT-5.x Google Gemini 2.5+
Aktiválás módja Explicit cache_control Automatikus (implicit) Explicit + implicit
Minimum tokenszám 1024 (Sonnet/Opus), 2048 (Haiku) 1024 4096
Cache read kedvezmény 90% (0,10× ár) 90% GPT-5.x, 75% GPT-4.1 90% explicit, 90% implicit
Cache write felár 1,25× (5 min TTL), 2,0× (1 h TTL) Nincs Nincs
Tárolási díj Nincs Nincs 1,00–4,50 USD/MTok/óra
TTL beállítás 5 perc vagy 1 óra (explicit) 5–10 perc, 24 óra extended Testre szabható (perc–nap)
Max breakpoint / request 4 Nincs (automatikus) 1 explicit cache objektum
Batch API stacking Igen (50% × 10% = 5% effektív) Igen Igen

Prompt struktúra: statikus tartalom legelöl, dinamikus a végén

A cache invalidation hierarchikus mindhárom szolgáltatónál: bármelyik blokk módosítása érvényteleníti azt a blokkot és minden utána következőt. Ebből egyetlen alapelv következik. A soha nem változó tartalmat rakd a prompt elejére, a minden hívásnál változó tartalmat pedig a végére. A javasolt sorrend fentről lefelé: tool definíciók, system prompt, few-shot példák, statikus reference dokumentumok, beszélgetési előzmények, live user query.

A leggyakoribb tervezési hiba az, amikor a rendszerprompt tetejére kerül egy „Current date: 2026-07-18 14:23:11 UTC” sor. Ezt a hibát én is elkövettem egyszer, és két hétig nem értettem, miért marad 4% körül a hit rate. Az az egy sor lenullázza a hit rate-et, mert minden hívásnál változik a timestamp, és a cache-elt blokk „identity”-je pont ez a byte-szintű egyezés. A megoldás vagy az, hogy a timestamp-et áthelyezed egy külön user message-be a prompt végén, vagy (ha az idő pontosan nem fontos) kerekíted óra pontosságúra, hogy egy órán belül minden hívás azonos legyen. A conversation history is klasszikus csapda. Ha minden fordulóban a teljes history-t egy blokkban küldöd, a legutolsó user turn hozzáfűzése invalidálja a teljes cache-t. A megoldás: history a stabil helyre, csak a legutolsó user turn a variábilis blokkba.

Egy jó mentális modell: gondolj a promptra úgy, mint egy verziózott dokumentumra. A statikus rész a „main branch”, ami hetekig ugyanaz; a dinamikus rész a „per-request commit”, ami minden hívásnál új. A cache pontosan a stabil verziót tárolja, és a per-request diffet futtatja csak. Ha a promptod struktúrája nem tükrözi ezt a szeparációt, cache-elési szempontból törött. Egyébként ez a szemlélet átjön az agent-tervezésbe is, érdemes elolvasni a Model Context Protocol (MCP) 2026-os útmutatót, ahol ugyanezt az elvet alkalmazzuk a tool-szerver definíciókra.

Rétegzett cache-elés: max 4 breakpoint stratégia

Az Anthropic legfeljebb 4 cache_control breakpointot enged egy request-en belül. Ez látszólag semmiség, gyakorlatban viszont pont elég ahhoz, hogy nagyon hatékony rétegzett architektúrát építs. Egy tipikus production RAG chat 4 réteget használ ki: (1) tool definíciók, hetekig stabil, 1 óra TTL; (2) system prompt, hetekig stabil, 1 óra TTL; (3) betöltött reference dokumentumok, óra szintben stabil, 5 perc TTL; (4) beszélgetési előzmények, session-önként változó, 5 perc TTL.

A rétegek külön-külön cache-elődnek. Ha csak a reference dokumentumok frissülnek, a tools és system prompt cache-e sértetlen marad, csak a 3. és 4. blokk íródik újra. Ez az, ami elválasztja a jól megtervezett caching architektúrát a naiv „mindent egy blokkban” megoldástól. A naiv verzió minden dokumentum-frissítéskor teljes írási felárat fizet, a rétegzett viszont csak azon szakaszra, ami tényleg változott. Egy 50 000 tokenes prompton ez a különbség 50 000 × 1,25 vs. 15 000 × 1,25 tokent jelent, havi szinten több száz dollár.

Ha 4-nél több stabil réteged van, azt jelenti, hogy a promptod túl van tervezve. Vonj össze konceptuálisan hasonló blokkokat, vagy fogadd el, hogy a legritkábban változó rétegek nem kapnak külön breakpoint-ot. Az öt breakpoint helyett kettő gyakran ugyanolyan hatékony, viszont sokkal olvashatóbb kódot ad.

Cache hit rate monitoring és Langfuse integráció

Amit nem mérsz, azt nem tudod optimalizálni. A cache hit rate klasszikus példa arra, hogy az alapértékek megtévesztően jónak tűnnek egy tesztben, de éles forgalom mellett brutálisan zuhannak. A minimum, amit be kell építeni: minden LLM hívás után logold a cache_read_input_tokens, cache_creation_input_tokens, és input_tokens értékeket, valamint a request modell-jét és prompt-verzióját. Ebből számolható a hit rate = cache_read / (cache_read + cache_creation + uncached_input), és ez az érték kell, hogy 85% fölött legyen egy érett rendszernél.

Éles observability stackben tipikusan Langfuse, LangSmith vagy Phoenix a választás; mindhárom natívan támogatja a cache token-mezők automatikus rögzítését. Ha még nem választottál obszervabilitási platformot, a LLM observability 2026-os összehasonlításunkban minden szempontot végignéztünk. A minimális dashboard, amit érdemes kirakni: napi cache hit rate szolgáltatónként, cache write vs read token arány, és a top 10 prompt-verzió aggregált hit rate-je. Ez utóbbi különösen kritikus. Ha egy új prompt-verzió deploy után a hit rate 90%-ról 20%-ra zuhan, a rollback pár perc kérdése.

from langfuse import Langfuse
from anthropic import Anthropic

langfuse = Langfuse()
client = Anthropic()

@langfuse.observe(as_type="generation")
def cached_completion(user_query: str) -> str:
    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        system=[
            {"type": "text", "text": SYSTEM_PROMPT,
             "cache_control": {"type": "ephemeral", "ttl": "1h"}},
        ],
        messages=[{"role": "user", "content": user_query}],
    )
    langfuse.update_current_generation(
        usage_details={
            "input": response.usage.input_tokens,
            "cache_read_input": response.usage.cache_read_input_tokens,
            "cache_creation_input": response.usage.cache_creation_input_tokens,
            "output": response.usage.output_tokens,
        },
    )
    return response.content[0].text

Egy A/B teszt is szinte kötelező. Mielőtt production-be küldesz egy új prompt-struktúrát, futtasd le a régi verzió mellett néhány órán át, és nézd meg, hogy a hit rate tényleg megfelel-e az elvárásoknak. Egy jól tervezett prompt átcache-elődik pár perc alatt egy értelmes forgalmi minta mellett.

Gyakori hibák, amik lenullázzák a cache hit rate-et

A produktív telepítéseknél a hit rate ritkán marad 0%-on. Általában valahol 30–60% között ragad be, és pont ez a legrosszabb tartomány, mert még mindig fizetsz írási felárat, de már nem nyered vissza olvasáson. Ez a hat leggyakoribb hibaforrás:

  • Timestamp vagy request ID a cache-elt szakaszban. A leggyakoribb hiba. „Current time: 14:23:12” a system promptban lenullázza a hit rate-et minden hívásnál. Áthelyezni a végére, vagy órára kerekíteni.
  • Változó whitespace, sortörés, indentáció. A cache byte-egyezést vár. Egy plusz newline a template-ben elég ahhoz, hogy soha ne találjon egyezést. Deterministikus prompt-formázás (pl. textwrap.dedent) mindenhol.
  • Tenant-adatok keveredése. Ha egy multi-tenant SaaS-ban „User: John, tenant: acme” a system prompt tetején, minden felhasználónál saját cache-t kell építeni. Áthelyezni user message-be, vagy tenant-onként külön cache namespace.
  • Dinamikus tool listák. Ha a tool-definíciók sorrendje minden hívásnál különbözik (pl. random shuffle), a cache azonnal elszáll. Rögzített, deterministic sorrend.
  • Prompt verzió-inkonzisztencia. Ha egy A/B teszt során a promptot bármikor változtathatod, minden változás új cache write-ot okoz. Explicit prompt-verziózás és staged rollout.
  • Alul-küszöbös cache-elés. A minimum token-küszöb alatt (Anthropic 1024, Gemini 4096) semmilyen cache nem aktiválódik. Ha kicsi rendszerpromptod van, ne várd el a cache-t; vagy toldd meg few-shot példákkal, hogy elérje a küszöböt.

A stabil cache-elés amúgy szorosan kapcsolódik a jól strukturált LLM output-hoz. Ha a bemeneti struktúrát fegyelmezetten kezelted, érdemes ugyanezt a fegyelmet átvinni a kimeneti oldalra is. A strukturált LLM kimenetek 2026-os útmutatónk részletesen tárgyalja, hogyan tudsz determinisztikus JSON választ kikényszeríteni Pydantic-kal és constrained decoding-gal.

Gyakran ismételt kérdések

Hogyan működik a prompt caching a gyakorlatban?

A szolgáltató szervere eltárolja a prompt-előtag kiszámított attention KV tenzorait, és ha a következő request ugyanazzal a byte-egyezéses előtaggal indul, ezeket a tenzorokat betölti a lemezről ahelyett, hogy újraszámolná. A modell output-ja byte-azonos marad, csak a prefill fázis gyorsul fel és lesz olcsóbb.

Mennyit spórolhatsz prompt cachinggel?

A cache-elt bemeneti tokenekre mindhárom nagy szolgáltatónál 90% kedvezmény jár (OpenAI GPT-4.1-en 75%). Egy tipikus RAG chat 80% hit rate-tel 60–80% teljes bemeneti költségcsökkentést hoz. A batch API-val stackelve akár 95% is elérhető.

Mi a minimum tokenszám a prompt caching aktiválásához?

Anthropic Claude Sonnet 4.6 és Opus 4.8 esetén 1024 token, Haiku 4.5-nél 2048 token. OpenAI GPT-5.x-nél 1024 token. Google Gemini 2.5 Pro-nál 4096 token, ez a legmagasabb küszöb a három szolgáltató közül.

Mennyi ideig él egy cache bejegyzés?

Anthropic: 5 perc vagy 1 óra TTL, explicit választható breakpointonként. OpenAI: 5–10 perc automatikus, GPT-5.5/5.4-en extended prompt cachinggel 24 óráig. Gemini: testreszabható, percektől napokig, de tárolási óradíj jár érte.

Miért lehet 0%-os a cache hit rate-em Claude API-n?

Három leggyakoribb ok: (1) a promptod rövidebb, mint a minimum token-küszöb; (2) a cache-elt szakaszba dinamikus tartalom (timestamp, ID, session-adat) szivárgott be, ami minden hívásnál byte-szinten változik; (3) elfelejtetted a cache_control markert megadni a kérésben, mert az Anthropic-nál explicit opt-in kell.

OpenAI és Anthropic prompt caching közül melyik olcsóbb?

Magas hit rate-es (80%+) és nagy stabil promptú workloadnál az Anthropic dominál a 90% olvasási kedvezménnyel; az 1,25× írási felár amortizálódik. Alacsony vagy közepes forgalomnál, illetve gyakran változó prompt-verzióknál az OpenAI automatikus, felár nélküli modellje jobb. Ökölszabály: ha a hit rate várhatóan 30% alatti, OpenAI-t válassz.

Emma Bergstrom
A Szerzőről Emma Bergstrom

Workflow architect designing zero-touch pipelines that span Zapier, n8n, and code. Calls herself a recovering ops engineer.