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 @@
④ 最低分样本(点击展开逐条复核)
+
+
+
+
⑤ 优化建议 OPTIMIZATION ADVICE
+
+
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) => ``)
+ .replace(/\n\n+/g, "\n
\n");
+
+ body.innerHTML = `${html}
`;
+ },
};