TAGS: ai, automation, llm, python
There's a specific kind of dread in every independent insurance agency, and if you've ever built software for one, you've seen it: the renewal list. Somebody — usually the owner, at 9pm, after actual work — is supposed to pull every policy renewing in the next 60 days, cross-reference which clients haven't been contacted, and start making calls. It's tedious, it's never urgent today, and so it slides. Then a slow month happens, nobody works the book for three weeks, and four policies quietly lapse. No alarm goes off. The revenue just isn't there anymore, and nobody can point to the day it left.
We built a system to end that, and the interesting engineering lesson wasn't the AI part. It was this: the failure mode was attention, not information. The data was always sitting in the AMS. A dashboard showing it would have changed nothing, because dashboards require someone to log in, and "nobody logged in for three weeks" was the whole problem.
So we inverted the model: instead of a dashboard that waits, a pipeline that runs weekly and pushes a finished work product — a ranked risk list plus drafted outreach — into the agent's inbox.
The pipeline shape
Three stages, run on a cron:
- Ingest & normalize renewal data (this is 70% of the work, see below)
- Score each policy's lapse risk
- Draft outreach for the top of the list, human-reviewed before send
def weekly_run(book):
policies = normalize(fetch_renewals(book, horizon_days=90))
scored = sorted(
(score_lapse_risk(p) for p in policies),
key=lambda s: s.risk, reverse=True
)
actionable = [s for s in scored if s.risk > THRESHOLD
and not recently_contacted(s.policy, days=21)]
drafts = [draft_outreach(s) for s in actionable[:MAX_WEEKLY]]
deliver_digest(scored, drafts) # push, don't wait for a login
The tricky parts nobody warns you about
Renewal dates are lies. Effective dates, expiration dates, and actual renewal-processing dates disagree constantly across carriers. Some carriers auto-renew unless cancelled; others lapse silently at expiration. Your scoring function has to model what happens if nobody acts per carrier, not just "days until date X." We ended up with a per-carrier default-behavior table before any ML mattered at all.
Risk scoring can be embarrassingly simple. We started sketching a model and then realized a weighted heuristic — days to renewal, premium change at renewal (rate increases drive shopping), contact recency, payment-history flags — caught nearly everything an experienced agent would flag. Ship the heuristic first. The fancy model is a v3 problem; the cron job is the product.
The LLM's job is drafting, not deciding. We use the model to write the outreach email/text: it gets the client's first name, policy type, renewal date, and the premium delta, and produces a short, specific message ("your auto policy renews March 12 and the premium is going up $31/mo — want 10 minutes to review options?"). Two hard rules we learned to enforce in the harness, not the prompt: the model never sees or invents numbers — premium figures are injected into the template post-generation from source data — and every draft lands in a review queue. In insurance, a hallucinated dollar amount isn't a quality bug, it's an E&O claim.
Idempotency beats cleverness. A weekly job that occasionally double-runs will nag the same client twice and torch trust instantly. Every (policy, renewal_cycle) pair gets a deterministic key; outreach is recorded against it; the pipeline checks before drafting. Boring, essential.
The result
The agent's Monday inbox now contains the ten policies most likely to walk, each with a ready-to-edit message. The work that used to require someone remembering to do it now requires someone to stop it — and defaults are destiny.
If you're building for any business with a renewal-shaped revenue stream (SaaS, memberships, contracts), the pattern transfers whole: normalize the dates, score with a heuristic, let the LLM draft but never decide, and push the output instead of hosting it.
This is how we built Kynth Policy Renewals — it runs an agency's renewal pipeline every week so the book stops lapsing quietly.
Top comments (0)