-
-
Main Dashboard
-
Displaying hallucination and relevancy graphs
-
Social media post use case: generate tweet
-
Hallucination detected and started fixing
-
rewriting the tweet after teh healing effect
-
Comparision of pre-healing and post healing chat
-
Investment Analyst Use Case
-
Customer Services USe Case
-
Phoenix Traces
-
Past record of Phoenix Traces
🔧 Self-Healing AI Agent
What if an AI agent could notice it was broken, fix its own prompt, verify the fix, and report what changed — before a human ever woke up?
🌐 Live Demo
Demo: https://salkhan-ops.github.io/self-healing-agent-landing/
No login required. All three use cases are live.
Public demo note: The hosted demo is cost-controlled. The full multi-agent healing loop may be limited per session, while social media post generation and healing remain available for interactive testing.
The Problem That Kept Me Up at Night
AI agents fail silently.
A customer support bot starts inventing refund policies. A LinkedIn post generator fabricates revenue figures. An investment analyst cites a P/E ratio it made up. Nobody notices until a customer complains, a post goes viral for the wrong reason, or a regulator asks questions.
The worst part?
The AI keeps running. Confidently wrong. At scale. While everyone sleeps.
I kept thinking:
What if the AI could notice it was broken and fix itself?
What I Built
Self-Healing Agent is a production AI system that monitors its own behavior, detects hallucinations, learns reusable safety constraints, rewrites or patches its own prompt, verifies the fix worked, and sends a report — all without human intervention.
Three live use cases demonstrate the mechanism:
- Customer Support — an FAQ-grounded agent that catches itself guessing and learns to stop
- Social Media Posts — a content generator that stops inventing metrics, hype, and unsupported claims before they go live
- Investment Research — an SEC-grounded analyst that refuses to cite unverifiable financial figures or give unsupported investment advice
Why This Matters
Most AI monitoring tools tell you that something broke.
This project closes the loop:
Observe → Diagnose → Fix → Verify → Report
The agent does not just generate traces. It reads its own traces, understands what went wrong, updates its behavior, tests the new behavior, and produces an auditable report.
That turns monitoring from a passive dashboard into an active recovery system.
How It Works — The 7-Step Healing Loop
Step 1 ANSWER Agent answers questions → traces sent to Phoenix
Step 2 FETCH Agent reads own traces via Phoenix MCP server
Step 3 EVALUATE Cheap local rules judge first; Gemini handles ambiguous cases
Step 4 DIAGNOSE Root cause: GUESSING / HALLUCINATION / IRRELEVANT / UNSUPPORTED CLAIM
Step 5 REPAIR Known failures get prompt patches; novel failures use Gemini rewrite
Step 6 VERIFY Same or focused questions run again → before/after compared
Step 7 REPORT Incident report saved + Slack notification sent
The key insight is Step 2 — the agent queries its own traces through the official Arize Phoenix MCP server at runtime.
That gives the agent the ability to inspect its own past behavior and use that information to improve itself. No human reviews traces. No engineer updates the prompt. The loop is autonomous and auditable.
Cost-Aware Healing Cascade
The first version of the system called Gemini for almost every judgment and repair. That worked, but it was expensive for a public hackathon demo.
The current version uses a cost-aware cascade:
New output
↓
Cheap local rules judge it first
↓
If obvious pass/fail → no Gemini judge call
↓
If failure pattern is known → apply learned prompt patch
↓
If ambiguous or novel → use Gemini diagnosis/rewrite
This keeps the healing loop real while making it practical to run in a public demo.
What changed
1. Policy memory
The backend remembers learned constraints during the Cloud Run instance lifetime.
Example learned rules:
- Do not use unsupported superlatives.
- Do not invent percentages or growth metrics.
- Do not give buy/sell/hold investment advice.
- Ground investment claims in SEC context.
When the same class of failure appears again, the agent can reuse what it already learned instead of starting from zero.
2. Cheap judge first
Chat and social post scoring now use deterministic local evaluators before Gemini.
If an output is clearly good or clearly bad, Gemini is skipped. Gemini is reserved for cases where the result is ambiguous, nuanced, or novel.
3. Prompt patches instead of full rewrites
For known failure types, the system no longer asks Gemini to rewrite the entire system prompt. It appends a focused learned constraint.
Example:
LEARNED CONSTRAINTS:
- Learned rule: do not use unsupported superlatives unless they are present in the source brief.
- Learned rule: do not invent percentages, revenue figures, growth metrics, or investment ratings.
This preserves the agent's existing behavior while surgically fixing the failure.
4. Failure-pattern cache
If the same kind of failure happens again, the system reuses the prior patch.
That means no repeated diagnosis and rewrite cost for the same known issue while the Cloud Run instance is warm.
5. Smaller verification for known failures
Known failures verify against a smaller, focused sample. Ambiguous or novel failures still verify more broadly.
This reduces repeated healing delay while keeping the before/after comparison meaningful.
Important limitation
The learning memory is currently in-memory, not Firestore.
It resets when the Cloud Run instance cold-starts or redeploys. That is intentional for now: cheaper, safer, and simpler for a hackathon demo without adding database complexity.
Impact
- Faster scoring for obvious cases
- Lower Gemini usage
- Lower public-demo cost
- Less repeated healing delay
- Real Gemini-powered diagnosis and rewriting still works when the failure is new or unclear
The honest framing is:
The system learns reusable safety constraints from failures and routes easy decisions through local evaluators before spending on LLM judgment.
The Result
Same question. Same source material. Two completely different behaviors.
Before healing — Prompt v1:
"I believe we may ship to Pakistan for free on qualifying orders."
Invented — not present in the FAQ.
After healing — Prompt v2:
"We currently ship only within the United States."
Grounded — directly supported by the FAQ.
Hallucination rate: 1.00 → 0.00
Time taken: under 60 seconds
Human involvement: zero
Three Live Use Cases
💬 Customer Support
An FAQ-grounded support agent that catches itself hallucinating and stops.
Before healing:
"I believe we may ship to Pakistan for free on qualifying orders."
After healing:
"We currently ship only within the United States."
The agent learns to answer only from the FAQ and say when information is unavailable.
📱 Social Media Post Safety
A post generator that learns to stop inventing metrics before they go live.
Before healing:
"We crushed Q1 with 340% revenue growth! 🚀 Our revolutionary platform is disrupting the industry."
The 340% claim and hype language were not in the source brief.
After healing:
"Q1 was a strong quarter. We launched our new product and welcomed three new engineers."
Every claim is grounded in the original brief.
The cost-aware cascade is especially useful here because obvious hype phrases and unsupported metrics can be detected cheaply before involving Gemini.
📈 Investment Research
An SEC-grounded analyst that refuses to cite financial figures it cannot verify.
Before healing, the agent may invent ratios or give unsupported recommendations. After healing, it responds safely:
"I cannot confirm that figure without a verified SEC source."
The learned constraints also prevent unsupported buy/sell/hold advice unless it is grounded in the approved context.
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ Flutter Web Dashboard / Landing Demo │
│ Dashboard │ Reports │ Charts │ Agent Control │ Use Cases │
└──────────────────────────┬──────────────────────────────────────┘
│ REST + WebSocket
┌──────────────────────────▼──────────────────────────────────────┐
│ FastAPI Backend on Google Cloud Run │
│ /api/agent /api/chat /api/posts /api/investment /ws │
└───────────┬────────────────────────────┬────────────────────────┘
│ │
┌───────────▼──────────┐ ┌────────────▼──────────────────────┐
│ Self-Healing Loop │ │ Child Agents │
│ │ │ │
│ TaskAgent │ │ ChatAgent — Customer Support │
│ ↓ │ │ PostAgent — Social Media │
│ TraceReader ←── MCP ─┼────┼──→ Arize Phoenix │
│ ↓ │ │ InvestmentAgent — SEC Research │
│ Cheap Local Judge │ │ │
│ ↓ │ └────────────────────────────────────┘
│ Gemini Judge │ used only when needed
│ ↓
│ RootCauseAnalyzer
│ ↓
│ Policy Memory + Failure Cache
│ ↓
│ Prompt Patch or Gemini Rewrite
│ ↓
│ Verifier
│ ↓
│ Reporter ───────────────▶ Slack + SQLite + reports/
└───────────────────────┘
Partner Integration — Arize Phoenix MCP
The Arize Phoenix MCP server is not just used for dashboards — it is the mechanism that makes self-healing possible.
Every agent interaction is traced to Phoenix via OpenTelemetry. The healing loop then reads those traces back at runtime using the official Phoenix MCP server, giving the agent the ability to query its own past behavior as a tool:
# Agent reads its own traces via Phoenix MCP
result = subprocess.run([
"npx", "@arizeai/phoenix-mcp@latest",
"--baseUrl", PHOENIX_HOST
], input=json.dumps({
"tool": "list-traces",
"params": {
"project_name": "self-healing-agent",
"limit": 10
}
}), capture_output=True, text=True, timeout=30)
This moves the project beyond a monitoring dashboard into autonomous self-improvement. The agent is not just observed — it uses its own observations to change its behavior.
What Inspired Me
I have been building AI products for a while, and the same problem keeps appearing: you deploy an agent, it works great in testing, and then quietly degrades in production.
The prompt that worked in April stops working in June. A new user question exposes a knowledge-base gap. An edge case the agent was never trained on causes it to hallucinate — confidently.
The standard answer is “add more monitoring.”
But monitoring only tells you something broke. It does not fix it.
I wanted to build something that closes the loop completely — observe, diagnose, fix, verify, report. All automatic. All auditable.
Challenges I Faced
1. Phoenix MCP compatibility
The Phoenix Python client API changed between versions. query_spans() and get_spans_dataframe() both failed on my installed version.
I resolved this by switching to the official MCP server through npx, which is version-stable and protocol-correct.
2. Gemini model availability
gemini-2.0-flash-exp and gemini-1.5-flash were unavailable on my API key.
I queried list_models() to discover what was actually available and settled on gemini-2.5-flash, which performed better for this use case.
3. Scoring without hardcoding
Early versions used hardcoded hallucination scores for the demo.
I replaced those with real evaluation: deterministic local checks for obvious cases and Gemini-as-judge for ambiguous cases. That made the charts reflect real behavior instead of scripted values.
4. Cloud Run deployment
Cloud Run uses a dynamic $PORT variable, not a fixed port. The app was originally hardcoded to 8000.
I fixed this with a Procfile and environment-driven configuration.
5. Comparison flow fragility
The original before/after comparison was built client-side by matching question strings across chat history. This broke whenever timing was off.
I moved the comparison data to the backend. The agent runner already had both before and after answers from its verification pass, so the backend now broadcasts deterministic comparison data through WebSocket.
6. Public demo cost
The first version used Gemini too often. That was not ideal for a public hackathon link.
I redesigned healing as a cost-aware cascade: local rules first, policy memory for known failures, cached prompt patches for repeat failures, and Gemini only when needed.
What I Learned
The most surprising thing I learned is that Gemini genuinely hallucinates differently under different system prompts.
The weak prompt reliably causes invented metrics and superlatives, while the strict grounding prompt produces factual, conservative output. You do not need to fake this for a demo. The behavior is real.
I also learned that the self-improvement loop needs to own the before/after data.
Any design that asks the client to reconstruct this from timing and message history is fragile. The agent runner is the only component that has both the pre-healing and post-healing answers, so it should produce the comparison and broadcast it.
Finally, I learned that self-healing has to be cost-aware.
A real production system should not call an LLM for every obvious decision. It should use cheap deterministic checks when possible, learned policy memory when available, and LLM reasoning when the case is genuinely ambiguous or new.
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | Flutter Web, Dart, Provider, go_router, fl_chart |
| Backend | Python, FastAPI, Uvicorn, WebSockets |
| Agent / AI | Gemini 2.5 Flash |
| Observability | Arize Phoenix + OpenTelemetry |
| Partner MCP | @arizeai/phoenix-mcp official MCP server |
| Local Evaluation | Deterministic rule-based scoring for obvious pass/fail cases |
| Learning Layer | In-memory policy memory + failure-pattern cache |
| External Data | SEC EDGAR APIs |
| Persistence | SQLite, SQLAlchemy async |
| Scheduling | APScheduler |
| Deployment | Google Cloud Run + GitHub Pages |
Public Demo Cost Controls
The project includes safeguards to keep public judging costs predictable while preserving the real self-healing workflow:
- Static GitHub Pages frontend keeps the UI cheap to host.
- Cloud Run backend-only deploys avoid uploading unnecessary frontend build artifacts.
- Public demo mode limits expensive full healing runs per session.
- Cheap judge first skips Gemini for obvious pass/fail outputs.
- Policy memory reuses learned safety constraints while the instance is warm.
- Failure-pattern cache avoids repeated diagnosis and rewrite calls for known issues.
- Prompt patches apply targeted constraints instead of full prompt rewrites when possible.
- Focused verification uses smaller samples for known failures.
This means the public demo remains interactive without pretending the healing is fake.
Sample Healing Report
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔧 SELF-HEALING REPORT — 2026-05-17 03:47:00
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
App: Social Media Post Agent
Problem: Hallucination rate above threshold (1.00)
Root Cause: GUESSING — Agent invented metrics and unsupported hype
Fix Applied: Added learned fact-grounding constraint.
Blocked unsupported percentages and superlatives.
BEFORE:
Hallucination: 1.00
Relevance: 0.31
Latency: 2046ms
AFTER:
Hallucination: 0.00 (-100%) ✅
Relevance: 0.87 (+181%) ✅
Latency: 1.9s ✅
Cost Path:
Cheap judge: used
Learned policy patch: used
Gemini rewrite: skipped for known failure
Improvement: +94%
Human Action Needed: NO ✅
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
What Is Next
- Move policy memory from in-memory storage to Firestore or another persistent store
- Replace the local Phoenix instance with a persistent Cloud Run deployment so traces survive between sessions
- Add email alerting alongside Slack
- Support custom knowledge bases through a vector store instead of a static FAQ text file
- Add multi-agent healing, where one supervisor heals a fleet of specialized agents
- Expose a webhook API so external AI apps can plug into the self-healing loop
Built For
Google Cloud Rapid Agent Hackathon — Arize Track
- ✅ Powered by Gemini 2.5 Flash
- ✅ Deployed on Google Cloud Run
- ✅ Arize Phoenix MCP integration
- ✅ Multi-step autonomous healing loop
- ✅ Agent reads its own traces and improves itself
- ✅ Three real-world use cases
- ✅ Cost-aware cascade for public demo reliability
- ✅ Local evaluators + policy memory + Gemini fallback
License
Apache 2.0 — see LICENSE.
Built by Salman Khan · May 2026
Log in or sign up for Devpost to join the conversation.