马一丁

Update Logic When JSON Cannot Be Parsed

... ... @@ -31,6 +31,7 @@ from .nodes import (
ChapterGenerationNode,
ChapterJsonParseError,
ChapterContentError,
ChapterValidationError,
DocumentLayoutNode,
WordBudgetNode,
)
... ... @@ -601,11 +602,16 @@ class ReportAgent:
stream_callback=chunk_callback
)
break
except (ChapterJsonParseError, ChapterContentError) as structured_error:
error_kind = (
"content_sparse" if isinstance(structured_error, ChapterContentError) else "json_parse"
)
readable_label = "内容密度异常" if error_kind == "content_sparse" else "JSON解析失败"
except (ChapterJsonParseError, ChapterContentError, ChapterValidationError) as structured_error:
if isinstance(structured_error, ChapterContentError):
error_kind = "content_sparse"
readable_label = "内容密度异常"
elif isinstance(structured_error, ChapterValidationError):
error_kind = "validation"
readable_label = "结构校验失败"
else:
error_kind = "json_parse"
readable_label = "JSON解析失败"
if isinstance(structured_error, ChapterContentError):
candidate = getattr(structured_error, "chapter_payload", None)
candidate_score = getattr(structured_error, "body_characters", 0) or 0
... ... @@ -636,6 +642,10 @@ class ReportAgent:
'error': str(structured_error),
'reason': error_kind,
}
if isinstance(structured_error, ChapterValidationError):
validation_errors = getattr(structured_error, "errors", None)
if validation_errors:
status_payload['errors'] = validation_errors
if will_fallback:
status_payload['warning'] = 'content_sparse_fallback_pending'
emit('chapter_status', status_payload)
... ...
... ... @@ -6,7 +6,12 @@ Report Engine节点处理模块。
from .base_node import BaseNode, StateMutationNode
from .template_selection_node import TemplateSelectionNode
from .chapter_generation_node import ChapterGenerationNode, ChapterJsonParseError, ChapterContentError
from .chapter_generation_node import (
ChapterGenerationNode,
ChapterJsonParseError,
ChapterContentError,
ChapterValidationError,
)
from .document_layout_node import DocumentLayoutNode
from .word_budget_node import WordBudgetNode
... ... @@ -17,6 +22,7 @@ __all__ = [
"ChapterGenerationNode",
"ChapterJsonParseError",
"ChapterContentError",
"ChapterValidationError",
"DocumentLayoutNode",
"WordBudgetNode",
]
... ...
... ... @@ -77,6 +77,18 @@ class ChapterContentError(ValueError):
self.non_heading_blocks: int = int(non_heading_blocks or 0)
class ChapterValidationError(ValueError):
"""
章节结构在本地和LLM修复后仍无法通过校验时抛出。
该异常用于在Agent层触发针对单章的重试,而无需重启整本报告。
"""
def __init__(self, message: str, errors: Optional[List[str]] | None = None):
super().__init__(message)
self.errors: List[str] = list(errors or [])
class ChapterGenerationNode(BaseNode):
"""
负责按章节调用LLM并校验JSON结构。
... ... @@ -268,8 +280,9 @@ class ChapterGenerationNode(BaseNode):
)
if not valid:
raise ValueError(
f"{section.title} 章节JSON校验失败: {'; '.join(errors[:5])}"
raise ChapterValidationError(
f"{section.title} 章节JSON校验失败: {'; '.join(errors[:5])}",
errors=errors,
)
if content_error:
raise content_error
... ... @@ -1555,4 +1568,9 @@ class ChapterGenerationNode(BaseNode):
raise last_exc
__all__ = ["ChapterGenerationNode", "ChapterJsonParseError"]
__all__ = [
"ChapterGenerationNode",
"ChapterJsonParseError",
"ChapterContentError",
"ChapterValidationError",
]
... ...