马一丁

Improve the Way to Deal with Error JSON

@@ -25,6 +25,7 @@ from ..prompts import ( @@ -25,6 +25,7 @@ from ..prompts import (
25 build_chapter_recovery_payload, 25 build_chapter_recovery_payload,
26 build_chapter_user_prompt, 26 build_chapter_user_prompt,
27 ) 27 )
  28 +from ..utils.json_parser import RobustJSONParser, JSONParseError
28 from .base_node import BaseNode 29 from .base_node import BaseNode
29 30
30 try: 31 try:
@@ -143,6 +144,11 @@ class ChapterGenerationNode(BaseNode): @@ -143,6 +144,11 @@ class ChapterGenerationNode(BaseNode):
143 self._rescue_attempted_labels: Dict[str, Set[str]] = {} 144 self._rescue_attempted_labels: Dict[str, Set[str]] = {}
144 self._skipped_placeholder_chapters: Set[str] = set() 145 self._skipped_placeholder_chapters: Set[str] = set()
145 self._archived_failed_json: Dict[str, str] = {} 146 self._archived_failed_json: Dict[str, str] = {}
  147 + # 兜底使用更鲁棒的JSON解析器,尽可能拆出合法块
  148 + self._robust_parser = RobustJSONParser(
  149 + enable_json_repair=True,
  150 + enable_llm_repair=False,
  151 + )
146 152
147 def run( 153 def run(
148 self, 154 self,
@@ -551,6 +557,7 @@ class ChapterGenerationNode(BaseNode): @@ -551,6 +557,7 @@ class ChapterGenerationNode(BaseNode):
551 if repaired != cleaned: 557 if repaired != cleaned:
552 candidate_payloads.append(repaired) 558 candidate_payloads.append(repaired)
553 559
  560 + data: Dict[str, Any] | None = None
554 try: 561 try:
555 data = self._parse_with_candidates(candidate_payloads) 562 data = self._parse_with_candidates(candidate_payloads)
556 except json.JSONDecodeError as exc: 563 except json.JSONDecodeError as exc:
@@ -559,14 +566,19 @@ class ChapterGenerationNode(BaseNode): @@ -559,14 +566,19 @@ class ChapterGenerationNode(BaseNode):
559 candidate_payloads.append(repaired_payload) 566 candidate_payloads.append(repaired_payload)
560 try: 567 try:
561 data = self._parse_with_candidates(candidate_payloads[-1:]) 568 data = self._parse_with_candidates(candidate_payloads[-1:])
562 - except json.JSONDecodeError as inner_exc: 569 + except json.JSONDecodeError:
  570 + data = None
  571 + if data is None:
  572 + try:
  573 + data = self._robust_parser.parse(
  574 + cleaned,
  575 + context_name="ChapterJSON",
  576 + expected_keys=["chapter", "blocks", "chapterId", "title"],
  577 + )
  578 + except JSONParseError as robust_exc:
563 raise ChapterJsonParseError( 579 raise ChapterJsonParseError(
564 - f"章节JSON解析失败: {inner_exc}", raw_text=cleaned  
565 - ) from inner_exc  
566 - else:  
567 - raise ChapterJsonParseError(  
568 - f"章节JSON解析失败: {exc}", raw_text=cleaned  
569 - ) from exc 580 + f"章节JSON解析失败: {robust_exc}", raw_text=cleaned
  581 + ) from robust_exc
570 582
571 if "chapter" in data and isinstance(data["chapter"], dict): 583 if "chapter" in data and isinstance(data["chapter"], dict):
572 return data["chapter"] 584 return data["chapter"]