Introduce 智能评估 as an evaluation paradigm parallel to static evaluation, driven by OpenClaw. The platform supplies storage, lifecycle, and reporting; OpenClaw plans and executes. - Data model: IntelligentEval + Session + Message tables (new, not reusing exploration) - Lifecycle state machine: draft → planning → pending_approval → executing → completed/cancelled/failed - Session API: create/message (channel-forwarded)/close with turn accounting - Report API: pydantic-validated structured report, executing → completed, Markdown export (pure renderer) - Alembic migration for the three tables; domain glossary added to CONTEXT.md
93 lines
3.1 KiB
Python
93 lines
3.1 KiB
Python
"""Unit tests for the pure Markdown report renderer (票据 04)."""
|
|
|
|
import pytest
|
|
from agenteval.intelligent_eval.report import render_report_markdown
|
|
from pydantic import ValidationError
|
|
|
|
|
|
def _report() -> dict:
|
|
return {
|
|
"summary": "整体表现良好,退货流程存在确认缺失。",
|
|
"scores": {"退货流程": 0.7, "投诉处理": 0.85},
|
|
"findings": [
|
|
{
|
|
"issue": "未主动确认订单号",
|
|
"severity": "high",
|
|
"dimension": "退货流程",
|
|
"evidence": [
|
|
{
|
|
"session_id": "s-1",
|
|
"turn_index": 3,
|
|
"user_said": "我要退货",
|
|
"assistant_replied": "好的,已为您发起",
|
|
}
|
|
],
|
|
"suggestion": "增加订单号确认步骤",
|
|
"related_sop": "退货处理流程 §3.2",
|
|
},
|
|
{
|
|
"issue": "投诉共情不足",
|
|
"severity": "low",
|
|
"dimension": "投诉处理",
|
|
},
|
|
],
|
|
"highlights": [{"description": "多轮追问保持上下文连贯", "dimension": "多轮追问"}],
|
|
"priority_recommendations": ["先修退货确认", "再优化投诉共情"],
|
|
}
|
|
|
|
|
|
def test_renders_title_and_summary():
|
|
md = render_report_markdown(_report(), name="客服评估", eval_id="e-1")
|
|
assert "# 客服评估" in md
|
|
assert "整体表现良好" in md
|
|
assert "`e-1`" in md
|
|
|
|
|
|
def test_renders_scores_table():
|
|
md = render_report_markdown(_report())
|
|
assert "| 维度 | 分数 |" in md
|
|
assert "| 退货流程 | 0.7 |" in md
|
|
|
|
|
|
def test_sorts_findings_by_severity():
|
|
md = render_report_markdown(_report())
|
|
high_index = md.index("未主动确认订单号")
|
|
low_index = md.index("投诉共情不足")
|
|
assert high_index < low_index
|
|
|
|
|
|
def test_renders_evidence_block():
|
|
md = render_report_markdown(_report())
|
|
assert "会话 `s-1`" in md
|
|
assert "第 3 轮" in md
|
|
assert "**用户**:我要退货" in md
|
|
assert "**对象**:好的,已为您发起" in md
|
|
|
|
|
|
def test_renders_highlights_and_recommendations():
|
|
md = render_report_markdown(_report())
|
|
assert "多轮追问保持上下文连贯(多轮追问)" in md
|
|
assert "- 先修退货确认" in md
|
|
|
|
|
|
def test_minimal_report():
|
|
md = render_report_markdown({"summary": "只有概述", "findings": [{"issue": "i", "severity": "s", "dimension": "d"}]})
|
|
assert "只有概述" in md
|
|
assert "## 维度评分" not in md
|
|
assert "## 亮点" not in md
|
|
|
|
|
|
def test_rejects_missing_summary():
|
|
with pytest.raises(ValidationError):
|
|
render_report_markdown({"findings": [{"issue": "i", "severity": "s", "dimension": "d"}]})
|
|
|
|
|
|
def test_rejects_empty_findings():
|
|
with pytest.raises(ValidationError):
|
|
render_report_markdown({"summary": "x", "findings": []})
|
|
|
|
|
|
def test_rejects_finding_missing_required_fields():
|
|
with pytest.raises(ValidationError):
|
|
render_report_markdown({"summary": "x", "findings": [{"issue": "i"}]})
|