Spaces:
Running
Running
Commit
·
f7c428b
1
Parent(s):
47772a7
feat: New LLM Schema (Drivers Object List) and Frontend Support [v1.5.0]
Browse files- app.py +1 -1
- index.html +27 -3
- llm_explainer.py +20 -12
app.py
CHANGED
|
@@ -35,7 +35,7 @@ except ImportError as e:
|
|
| 35 |
|
| 36 |
# --- CONFIG ---
|
| 37 |
MODELS_DIR = Path("models")
|
| 38 |
-
APP_VERSION = "1.
|
| 39 |
THRESHOLD_AUTO_FLAG = 0.53
|
| 40 |
|
| 41 |
# Model registry
|
|
|
|
| 35 |
|
| 36 |
# --- CONFIG ---
|
| 37 |
MODELS_DIR = Path("models")
|
| 38 |
+
APP_VERSION = "1.5.0"
|
| 39 |
THRESHOLD_AUTO_FLAG = 0.53
|
| 40 |
|
| 41 |
# Model registry
|
index.html
CHANGED
|
@@ -874,11 +874,35 @@
|
|
| 874 |
panel.style.display = 'block';
|
| 875 |
|
| 876 |
if (llm && !llm.error) {
|
| 877 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 878 |
|
| 879 |
const bulletsUl = document.getElementById('llmBullets');
|
| 880 |
bulletsUl.innerHTML = '';
|
| 881 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 882 |
llm.bullets.forEach(b => {
|
| 883 |
const li = document.createElement('li');
|
| 884 |
li.style.marginBottom = "6px";
|
|
@@ -887,7 +911,7 @@
|
|
| 887 |
});
|
| 888 |
}
|
| 889 |
|
| 890 |
-
document.getElementById('llmDisclaimer').innerText = llm.disclaimer || "Disclaimer: These are statistical
|
| 891 |
} else {
|
| 892 |
const errorMsg = (llm && llm.error) ? llm.error : "AI explanation unavailable at this time.";
|
| 893 |
document.getElementById('llmSummaryText').innerHTML = `<span style="color: #ff9999;">⚠ ${errorMsg}</span>`;
|
|
|
|
| 874 |
panel.style.display = 'block';
|
| 875 |
|
| 876 |
if (llm && !llm.error) {
|
| 877 |
+
// Summary (+ Guidance if available)
|
| 878 |
+
let summaryHtml = llm.summary || "Summary unavailable.";
|
| 879 |
+
if (llm.guidance) {
|
| 880 |
+
summaryHtml += `<br><br><em style="opacity: 0.9; border-left: 2px solid #666; padding-left: 8px; display:block;">Guidance: ${llm.guidance}</em>`;
|
| 881 |
+
}
|
| 882 |
+
document.getElementById('llmSummaryText').innerHTML = summaryHtml;
|
| 883 |
|
| 884 |
const bulletsUl = document.getElementById('llmBullets');
|
| 885 |
bulletsUl.innerHTML = '';
|
| 886 |
+
|
| 887 |
+
// NEW SCHEMA: Drivers list
|
| 888 |
+
if (llm.drivers && Array.isArray(llm.drivers)) {
|
| 889 |
+
llm.drivers.forEach(d => {
|
| 890 |
+
const li = document.createElement('li');
|
| 891 |
+
li.style.marginBottom = "8px";
|
| 892 |
+
li.style.lineHeight = "1.4";
|
| 893 |
+
|
| 894 |
+
// Color/Arrow for effect
|
| 895 |
+
let effectColor = "#ccc";
|
| 896 |
+
let arrow = "•";
|
| 897 |
+
if (d.effect && d.effect.toLowerCase().includes("up")) { arrow = "↑"; effectColor = "#ff9999"; }
|
| 898 |
+
if (d.effect && d.effect.toLowerCase().includes("down")) { arrow = "↓"; effectColor = "#99ff99"; }
|
| 899 |
+
|
| 900 |
+
li.innerHTML = `<span style="color:${effectColor}; font-weight:bold; margin-right:4px;">${arrow}</span> <strong>${d.name}</strong>: ${d.explanation}`;
|
| 901 |
+
bulletsUl.appendChild(li);
|
| 902 |
+
});
|
| 903 |
+
}
|
| 904 |
+
// FALLBACK: Old bullets list
|
| 905 |
+
else if (llm.bullets && Array.isArray(llm.bullets)) {
|
| 906 |
llm.bullets.forEach(b => {
|
| 907 |
const li = document.createElement('li');
|
| 908 |
li.style.marginBottom = "6px";
|
|
|
|
| 911 |
});
|
| 912 |
}
|
| 913 |
|
| 914 |
+
document.getElementById('llmDisclaimer').innerText = llm.disclaimer || "Disclaimer: These are statistical patterns, not proof.";
|
| 915 |
} else {
|
| 916 |
const errorMsg = (llm && llm.error) ? llm.error : "AI explanation unavailable at this time.";
|
| 917 |
document.getElementById('llmSummaryText').innerHTML = `<span style="color: #ff9999;">⚠ ${errorMsg}</span>`;
|
llm_explainer.py
CHANGED
|
@@ -168,17 +168,21 @@ def _cached_llm_request(selected_model: str, ref_model: str, risk_str: str, driv
|
|
| 168 |
# Build prompt
|
| 169 |
prompt = f"""You explain insurance claim risk scores to busy humans.
|
| 170 |
|
|
|
|
|
|
|
| 171 |
Audience:
|
| 172 |
- A claims reviewer or operations specialist skimming many cases.
|
| 173 |
-
- They want orientation and context, not theory or instructions.
|
| 174 |
|
| 175 |
Tone:
|
| 176 |
- Clear, calm, and human.
|
| 177 |
- Slightly playful understatement is welcome (Douglas Adams–style), but no jokes or sarcasm.
|
| 178 |
-
- Avoid bureaucratic or brochure-like language.
|
| 179 |
|
| 180 |
Rules:
|
| 181 |
- Use ONLY the provided drivers. Do not invent facts.
|
|
|
|
|
|
|
| 182 |
- Do NOT say "fraud" or imply certainty.
|
| 183 |
- Do NOT claim causality. Describe statistical associations only.
|
| 184 |
- Do NOT mention models, SHAP, ML, or methodology.
|
|
@@ -187,13 +191,14 @@ Rules:
|
|
| 187 |
|
| 188 |
Style guidance:
|
| 189 |
- Start by explaining what the score means in human terms.
|
| 190 |
-
- Describe drivers as forces
|
| 191 |
- Be concrete and concise.
|
| 192 |
-
- Prefer clarity over completeness.
|
|
|
|
| 193 |
|
| 194 |
Optional guidance:
|
| 195 |
-
- Include a short
|
| 196 |
-
- Frame this as typical handling, not instructions or required actions.
|
| 197 |
|
| 198 |
Context:
|
| 199 |
- Prediction model: {selected_model}
|
|
@@ -206,16 +211,19 @@ Output:
|
|
| 206 |
Return ONLY valid JSON (no markdown, no extra text), matching this schema exactly:
|
| 207 |
|
| 208 |
{{
|
| 209 |
-
"summary": "2–3 sentences giving a clear, human-readable
|
| 210 |
-
"
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
|
|
|
|
|
|
|
| 214 |
],
|
| 215 |
-
"guidance": "One short sentence describing what this usually means for
|
| 216 |
"disclaimer": "One short sentence noting this reflects statistical patterns, not proof."
|
| 217 |
}}
|
| 218 |
|
|
|
|
| 219 |
"""
|
| 220 |
|
| 221 |
max_retries = 2
|
|
|
|
| 168 |
# Build prompt
|
| 169 |
prompt = f"""You explain insurance claim risk scores to busy humans.
|
| 170 |
|
| 171 |
+
You explain insurance claim risk scores to busy humans.
|
| 172 |
+
|
| 173 |
Audience:
|
| 174 |
- A claims reviewer or operations specialist skimming many cases.
|
| 175 |
+
- They want quick orientation and context, not theory or instructions.
|
| 176 |
|
| 177 |
Tone:
|
| 178 |
- Clear, calm, and human.
|
| 179 |
- Slightly playful understatement is welcome (Douglas Adams–style), but no jokes or sarcasm.
|
| 180 |
+
- Avoid bureaucratic, legalistic, or brochure-like language.
|
| 181 |
|
| 182 |
Rules:
|
| 183 |
- Use ONLY the provided drivers. Do not invent facts.
|
| 184 |
+
- List ALL provided drivers.
|
| 185 |
+
- For each driver, clearly indicate whether it pushes risk up or pulls it down.
|
| 186 |
- Do NOT say "fraud" or imply certainty.
|
| 187 |
- Do NOT claim causality. Describe statistical associations only.
|
| 188 |
- Do NOT mention models, SHAP, ML, or methodology.
|
|
|
|
| 191 |
|
| 192 |
Style guidance:
|
| 193 |
- Start by explaining what the score means in human terms.
|
| 194 |
+
- Describe drivers as forces acting on the score (pushing it up or pulling it down).
|
| 195 |
- Be concrete and concise.
|
| 196 |
+
- Prefer clarity and skimmability over completeness.
|
| 197 |
+
- Write so the explanation can be understood at a glance.
|
| 198 |
|
| 199 |
Optional guidance:
|
| 200 |
+
- Include a short line that helps the reviewer gauge how much attention this case deserves.
|
| 201 |
+
- Frame this as typical handling or attention level, not instructions or required actions.
|
| 202 |
|
| 203 |
Context:
|
| 204 |
- Prediction model: {selected_model}
|
|
|
|
| 211 |
Return ONLY valid JSON (no markdown, no extra text), matching this schema exactly:
|
| 212 |
|
| 213 |
{{
|
| 214 |
+
"summary": "2–3 short sentences giving a clear, human-readable orientation to the risk and overall takeaway.",
|
| 215 |
+
"drivers": [
|
| 216 |
+
{{
|
| 217 |
+
"name": "Readable driver name",
|
| 218 |
+
"effect": "up or down",
|
| 219 |
+
"explanation": "Short, plain-language explanation of how this driver influences risk."
|
| 220 |
+
}}
|
| 221 |
],
|
| 222 |
+
"guidance": "One short sentence describing what this usually means for attention or handling.",
|
| 223 |
"disclaimer": "One short sentence noting this reflects statistical patterns, not proof."
|
| 224 |
}}
|
| 225 |
|
| 226 |
+
|
| 227 |
"""
|
| 228 |
|
| 229 |
max_retries = 2
|