From 1a2cc534b865682908ebf2abe87f98fe8c9b6669 Mon Sep 17 00:00:00 2001 From: wangwei Date: Tue, 16 Jun 2026 17:26:37 +0800 Subject: [PATCH] feat(webapp): add optimization advice section to report UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - index.html: add section ⑤ advice block (hidden by default, shown when advice_markdown present) - report.js: add renderAdvice() called in render(), simple Markdown→HTML converter - app.js: add noise_sensitivity / factual_correctness / semantic_similarity to shortMetric map - app.css: add .advice-panel, .advice-badge, .advice-md styles (purple left-border theme) Co-Authored-By: Claude --- webapp/static/css/app.css | 24 ++++++++++++++++++++++++ webapp/static/index.html | 12 ++++++++++++ webapp/static/js/app.js | 3 +++ webapp/static/js/report.js | 35 +++++++++++++++++++++++++++++++++-- 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/webapp/static/css/app.css b/webapp/static/css/app.css index 5880a9c..2735eb0 100644 --- a/webapp/static/css/app.css +++ b/webapp/static/css/app.css @@ -301,3 +301,27 @@ table.group-table td { border-bottom: 1px solid #f1f5f9; font-variant-numeric: t .llm-role-row { display: flex; align-items: center; gap: 14px; } .llm-role-label { font-size: 13px; font-weight: 600; min-width: 180px; color: var(--ink); } .llm-role-select { min-width: 240px; } + +/* ---------- ⑤ 优化建议面板 ---------- */ +.advice-panel { border-left: 3px solid #7c3aed; } +.advice-header { + display: flex; align-items: center; gap: 10px; + margin-bottom: 14px; +} +.advice-badge { + background: #7c3aed; color: #fff; + font-size: 11px; font-weight: 700; letter-spacing: 0.5px; + padding: 3px 8px; border-radius: 4px; text-transform: uppercase; +} +.advice-model { font-size: 12px; color: var(--slate); } +.advice-body { line-height: 1.7; color: var(--ink); } +.advice-md h1 { font-size: 16px; font-weight: 700; margin: 16px 0 8px; color: var(--ink); } +.advice-md h2 { + font-size: 14px; font-weight: 700; margin: 20px 0 8px; + padding-bottom: 4px; border-bottom: 1px solid var(--line); color: var(--ink-soft); +} +.advice-md h3 { font-size: 13px; font-weight: 600; margin: 12px 0 6px; color: var(--slate); } +.advice-md hr { border: none; border-top: 1px solid var(--line); margin: 14px 0; } +.advice-md ul { padding-left: 20px; margin: 6px 0; } +.advice-md li { margin: 3px 0; font-size: 13px; } +.advice-md strong { color: var(--ink); font-weight: 600; } diff --git a/webapp/static/index.html b/webapp/static/index.html index 4899e87..e8e2ba5 100644 --- a/webapp/static/index.html +++ b/webapp/static/index.html @@ -135,6 +135,18 @@
+ + + diff --git a/webapp/static/js/app.js b/webapp/static/js/app.js index 854c9f8..4cb11c0 100644 --- a/webapp/static/js/app.js +++ b/webapp/static/js/app.js @@ -119,6 +119,9 @@ const App = { answer_relevancy: "ans.rel.", context_recall: "ctx.recall", context_precision: "ctx.prec.", + noise_sensitivity: "noise.sens.", + factual_correctness: "fact.corr.", + semantic_similarity: "sem.sim.", }; return map[name] || name; }, diff --git a/webapp/static/js/report.js b/webapp/static/js/report.js index 882e27e..0c83afe 100644 --- a/webapp/static/js/report.js +++ b/webapp/static/js/report.js @@ -26,6 +26,7 @@ const Report = { Report.renderDistribution(detail.report); Report.renderGroupings(detail.report); Report.renderLowest(detail.report); + Report.renderAdvice(detail.summary, detail.report); content.style.opacity = "1"; } catch (err) { empty.hidden = false; @@ -186,8 +187,7 @@ const Report = { }, // ④ 最低分样本逐条复核表(点击展开)。 - renderLowest(report) { - const wrap = document.getElementById("lowest-table"); + renderLowest(report) { const wrap = document.getElementById("lowest-table"); const samples = report.lowest_samples || []; wrap.innerHTML = ""; if (samples.length === 0) { @@ -255,4 +255,35 @@ const Report = { `; }, + + // ⑤ 优化建议(仅 optimization_advice.md 存在时渲染)。 + renderAdvice(summary, report) { + const section = document.getElementById("advice-section"); + const body = document.getElementById("advice-body"); + const modelLabel = document.getElementById("advice-model-label"); + + const md = report.advice_markdown || ""; + if (!md.trim()) { + section.hidden = true; + return; + } + + section.hidden = false; + modelLabel.textContent = summary.judge_model ? `judge: ${summary.judge_model}` : ""; + + // 简单 Markdown → HTML 转换(标题、列表、分隔线、粗体) + const escaped = md + .replace(/&/g, "&").replace(//g, ">"); + const html = escaped + .replace(/^#{3}\s+(.+)$/gm, "

$1

") + .replace(/^#{2}\s+(.+)$/gm, "

$1

") + .replace(/^#{1}\s+(.+)$/gm, "

$1

") + .replace(/^---+$/gm, "
") + .replace(/\*\*(.+?)\*\*/g, "$1") + .replace(/^- (.+)$/gm, "
  • $1
  • ") + .replace(/(
  • [^]*?<\/li>\n?)+/g, (m) => `
      ${m}
    `) + .replace(/\n\n+/g, "\n
    \n"); + + body.innerHTML = `
    ${html}
    `; + }, };