feat(qa): add QAReport + QAValidator.validate_doc
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
"""QA 报告(Phase 5)。"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from genesis.eval.scorer import EvalReport
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class QAReport:
|
||||||
|
passed: bool
|
||||||
|
overall_score: float
|
||||||
|
per_chapter: list[EvalReport]
|
||||||
|
failed_chapters: list[str]
|
||||||
|
summary: str
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from genesis.eval.scorer import ChapterScorer, EvalReport, ChapterArtifact
|
from genesis.eval.scorer import ChapterScorer, EvalReport, ChapterArtifact
|
||||||
|
from genesis.qa.report import QAReport
|
||||||
from genesis.writer.models import ChapterContent
|
from genesis.writer.models import ChapterContent
|
||||||
|
|
||||||
|
|
||||||
@@ -29,3 +30,18 @@ class QAValidator:
|
|||||||
|
|
||||||
def validate_document(self, contents: list[ChapterContent], structured_source) -> list[tuple[bool, EvalReport]]:
|
def validate_document(self, contents: list[ChapterContent], structured_source) -> list[tuple[bool, EvalReport]]:
|
||||||
return [self.validate_chapter(c, structured_source) for c in contents]
|
return [self.validate_chapter(c, structured_source) for c in contents]
|
||||||
|
|
||||||
|
def validate_doc(self, contents: list[ChapterContent], structured_source) -> QAReport:
|
||||||
|
results = self.validate_document(contents, structured_source)
|
||||||
|
passed_flags = [ok for ok, _ in results]
|
||||||
|
reports = [rep for _, rep in results]
|
||||||
|
failed = [c.chapter_id for c, ok in zip(contents, passed_flags) if not ok]
|
||||||
|
overall = sum(r.total_score for r in reports) / len(reports) if reports else 0.0
|
||||||
|
summary = "全部章节通过" if all(passed_flags) else f"{len(failed)} 章未通过: {failed}"
|
||||||
|
return QAReport(
|
||||||
|
passed=all(passed_flags),
|
||||||
|
overall_score=round(overall, 4),
|
||||||
|
per_chapter=reports,
|
||||||
|
failed_chapters=failed,
|
||||||
|
summary=summary,
|
||||||
|
)
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
from genesis.qa.report import QAReport
|
||||||
|
from genesis.qa.validator import QAValidator
|
||||||
|
from genesis.writer.models import ChapterContent, ContentBlock
|
||||||
|
|
||||||
|
|
||||||
|
def _chapter(cid, text):
|
||||||
|
return ChapterContent(
|
||||||
|
chapter_id=cid, version=1, title=cid,
|
||||||
|
blocks=[ContentBlock(block_id="1", type="paragraph", text=text)],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_validate_doc_aggregates_qa_report():
|
||||||
|
v = QAValidator()
|
||||||
|
report = v.validate_doc(
|
||||||
|
[_chapter("a", "充分且规范的说明内容,满足写入规则要求。"), _chapter("b", "x")], None
|
||||||
|
)
|
||||||
|
assert isinstance(report, QAReport)
|
||||||
|
assert report.passed is False
|
||||||
|
assert "b" in report.failed_chapters
|
||||||
|
assert isinstance(report.overall_score, float)
|
||||||
|
assert len(report.per_chapter) == 2
|
||||||
|
assert "未通过" in report.summary
|
||||||
Reference in New Issue
Block a user