Inspiration

US insurers deny medically necessary care to millions of patients every year. The AMA's Prior Authorization Physician Survey shows the scale of the problem:

  • Physicians spend an average of 12 hours per week on prior-authorization work.
  • 94% report prior-authorization-related care delays.
  • 78% see patients abandon treatment because the appeal process is too slow.

The cruel twist is that 83% of appeals that are actually filed succeed, but only about 10% of denials are ever appealed at all.

Why? Because writing one appeal can cost twelve hours of a physician's time. At roughly three hundred dollars an hour, the math kills the appeal before it is ever written.

Most prior-authorization automation startups serve the payer, because that is where the budget lives.

Granum serves the denied side.

I wanted to build for the place where patients actually lose.

Separately, I had been reading about affinity maturation in germinal centers, especially Victora & Mesin's 2016 Science paper. Germinal centers are where B-cells evolve better antibodies against a new pathogen through somatic hypermutation, antigen-driven tournament selection, and apoptosis of low-affinity variants.

The part that fascinated me was not just evolution. It was commitment.

A B-cell that loses the tournament does not survive. There is no archive. No revert. No safe rollback button. That constraint forces every mutation to be a real bet.

That became the design metaphor for Granum.

What it does

Granum is a Google ADK agent that drafts prior-authorization appeals on behalf of denied patients and physicians.

Unlike a generic LLM appeal writer, Granum maintains an evolving population of appeal strategies for each payer and diagnosis pair. A strategy includes a system prompt, an evidence-retrieval template, and a tool-use pattern.

Each generation runs a germinal-center-inspired cycle:

  1. Selection: Granum chooses the top surviving strategies.
  2. Negative selection: Unsafe drafts are killed early if they contain hallucinated citations, unsupported clinical claims, or missing deadline references.
  3. Tournament: Candidate appeals are judged against a gold dataset of overturned appeals using a 5-axis rubric and median-of-3 sampling.
  4. Outcome ingestion: Results are written back to Phoenix datasets as new antigen data.
  5. Apoptosis: Losing strategies lose their production tag and gain a tombstoned tag, making them structurally ineligible for future selection.
  6. Mutation: Surviving strategies create small mutations through Phoenix MCP, such as swapping one citation, reframing one paragraph, or changing one clinical-guideline reference.

Granum also supports immune memory and antigen drift. Old champions can become memory_cell strategies and reactivate after repeated extinction. If denial patterns shift, dormant memory cells can be retested against the new distribution.

The frontend visualizes this as a lineage tree. Survivors branch. Apoptosed strategies grey out. The fitness curve climbs across generations.

Granum is not just an AI that writes appeals.

It is a learning organism for fighting medical denials.

How we built it

Granum uses Google ADK as the agent runtime, Gemini on Vertex AI for reasoning and mutation, Arize Phoenix as the observability and evolution backbone, FastAPI on Cloud Run for the API, and Next.js on Vercel for the frontend.

The core idea is that the population literally lives in Phoenix.

Phoenix prompts represent strategies. Phoenix tags represent life, death, memory, and promotion. Phoenix datasets represent antigen data. Phoenix traces and annotations become the feedback signal that drives the next generation.

The Phoenix MCP chain is load-bearing:

  • list-prompts reads the current strategy population.
  • upsert-prompt creates mutated descendants.
  • add-prompt-version-tag promotes, tombstones, and marks memory cells.
  • Phoenix REST removes the production tag during apoptosis.
  • add-dataset-examples writes new appeal outcomes back as training antigen.
  • get-spans, get-span-annotations, list-traces, and get-trace reconstruct the audit trail and lineage tree.
  • Phoenix Experiments run the tournament scoring loop.

Two cells evolved end-to-end on live Phoenix + Vertex Gemini:

  • Aetna + cardiac: judge-rated overturn likelihood improved from 0.40 to 0.98 over 10 generations.
  • United + oncology: improved from 0.62 to 0.98 over 10 generations.

Each run apoptosed 18 weak strategies.

Granum also tested cross-cell strategy transfer. The united_oncology champion transferred successfully into aetna_cardiac, producing a significant lift. The reverse transfer failed negative selection, which was the honest result. Some strategies generalize. Some do not.

Challenges we ran into

The biggest challenge was that Phoenix prompt versions are immutable.

My original design assumed I could delete losing prompt versions. A live Phoenix MCP capability audit proved that delete-prompt-version does not exist, and that actually makes sense: prompt registries should be append-only audit logs.

So I pivoted to functional apoptosis.

Instead of deleting a losing strategy, Granum removes its production tag and adds a tombstoned tag. That preserves the full audit lineage while making the strategy ineligible for future selection or mutation.

The constraint made the biology metaphor stronger. In real germinal centers, apoptosed B-cells are not erased from history. They are flagged for clearance. In Granum, tags are the immune-system markers.

Another challenge was LLM-as-judge circularity. If the judge shares the same priors as the generator, the system can climb a fake fitness gradient. To fight that, Granum includes a Red Queen co-evolution loop: a second adversarial payer-agent population evolves in parallel and looks for hallucinations, weak citations, and policy vulnerabilities in candidate appeals.

Survival means beating an adversary, not merely pleasing a judge.

I also wanted to avoid the common self-improving-agent pattern where a supervisor agent watches another agent and patches it. Granum takes the structural inverse. There is no babysitter. There is peer competition, permanent apoptosis, and commitment costs on every strategy.

Accomplishments

I am proud that Granum is not just a demo shell. The core loop runs.

  • Two payer-diagnosis cells evolved end-to-end on live infrastructure.
  • The full Phoenix MCP chain is wired into the agent loop.
  • Cross-cell transfer ran and produced an honest asymmetric result.
  • The apoptosis-via-tag design survived the immutability constraint.
  • Four curated cells exist with real payer policies, clinical citations, denial patterns, and gold appeal exemplars.
  • The system has test coverage across mutation operators, judge rubrics, tournament protocol, immune memory, antigen drift, payer personas, co-evolution, and cross-cell transfer.
  • The frontend renders real cell payloads through a lineage tree, prompt diff view, and fitness curve.

The part I like most is that the product is not only the generated appeal. The product is the lineage of strategies that learned how to fight better.

What we learned

I learned that affinity maturation generalizes surprisingly well to prompt learning.

If a system has a quality signal but no gradient, it needs structured search. Germinal centers are basically nature's answer to that problem: mutate, test, select, kill, remember, repeat.

I also learned that Phoenix MCP is more powerful than it first appears. Prompt-registry tags, dataset writeback, span retrieval, and experiment annotations together form a self-improvement substrate. Granum uses Phoenix not as a dashboard, but as its evolutionary memory.

The biggest technical lesson was restraint. Large prompt rewrites make lineage unreadable. Small mutations make the system interpretable. A citation swap, a paragraph reframe, or a guideline substitution is easier to evaluate than a full rewrite.

The hard part was not generation.

The hard part was making evolution honest.

What's next

Next, I want to evolve the remaining curated cells: Anthem + mental health and Humana + endocrinology. After that, I want to run cross-cell transfer across the full matrix to see which strategies generalize across payers and diagnoses.

The Red Queen payer co-evolution loop is built, but the next step is running it continuously so every writer population trains against an adapting adversary.

After that, the real goal is to onboard a few independent physician practices, run Granum on real denials with explicit consent and de-identified eval data, and build a patient-advocate dashboard.

Eventually, Granum instances could share anonymized fitness signals across practices without sharing patient data.

The long-term product is not "an AI that writes appeals."

It is a learning organism that gets better at fighting denials for every payer and diagnosis pair, indefinitely.

Built With

  • ai-agents
  • arize-phoenix
  • d3.js
  • evolutionary-algorithms
  • fastapi
  • gemini
  • google-adk
  • google-cloud
  • google-cloud-run
  • healthcare
  • llm-as-judge
  • mcp
  • medical-appeals
  • model-context-protocol
  • next.js
  • opentelemetry
  • phoenix-mcp
  • prior-authorization
  • prompt-learning
  • python
  • react
  • recharts
  • tailwind-css
  • typescript
  • uv
  • vertex-ai
Share this project:

Updates

Submission history