软错误不计入总错误数
This commit is contained in:
@@ -23,8 +23,15 @@ MAX_REQUESTS_PER_ERROR = 15
|
||||
ThinkingMode = Literal["enable", "disable", "default"]
|
||||
|
||||
|
||||
class PartialTranslationError(ValueError):
|
||||
"""一个特殊的异常,用于表示结果不完整但包含了部分成功的数据,以便触发重试。"""
|
||||
class AgentResultError(ValueError):
|
||||
"""一个特殊的异常,用于表示结果由AI正常返回,但返回的结果有问题。该错误不计入总错误数"""
|
||||
|
||||
def __init__(self, message):
|
||||
super().__init__(message)
|
||||
|
||||
|
||||
class PartialAgentResultError(ValueError):
|
||||
"""一个特殊的异常,用于表示结果不完整但包含了部分成功的数据,以便触发重试。该错误不计入总错误数"""
|
||||
|
||||
def __init__(self, message, partial_result: dict):
|
||||
super().__init__(message)
|
||||
@@ -177,9 +184,12 @@ class Agent:
|
||||
# print(f"result:=============================================================\n{result}\n================\n")
|
||||
return result if result_handler is None else result_handler(result, prompt, self.logger)
|
||||
|
||||
except AgentResultError as e:
|
||||
self.logger.error(f"AI返回结果有误: {e}")
|
||||
should_retry = True
|
||||
# 专门捕获部分翻译错误(软错误)
|
||||
except PartialTranslationError as e:
|
||||
self.logger.error(f"收到部分翻译结果,将尝试重试: {e}")
|
||||
except PartialAgentResultError as e:
|
||||
self.logger.error(f"收到部分返回结果,将尝试重试: {e}")
|
||||
current_partial_result = e.partial_result
|
||||
should_retry = True
|
||||
# is_hard_error 保持 False
|
||||
@@ -302,9 +312,11 @@ class Agent:
|
||||
self.logger.info(f"重试成功 (第 {retry_count + 1}/{MAX_RETRY_COUNT + 1} 次尝试)。")
|
||||
|
||||
return result if result_handler is None else result_handler(result, prompt, self.logger)
|
||||
|
||||
except AgentResultError as e:
|
||||
self.logger.error(f"AI返回结果有误: {e}")
|
||||
should_retry = True
|
||||
# 专门捕获部分翻译错误(软错误)
|
||||
except PartialTranslationError as e:
|
||||
except PartialAgentResultError as e:
|
||||
self.logger.error(f"收到部分翻译结果,将尝试重试: {e}")
|
||||
current_partial_result = e.partial_result
|
||||
should_retry = True
|
||||
|
||||
@@ -10,6 +10,7 @@ from logging import Logger
|
||||
import json_repair
|
||||
|
||||
from docutranslate.agents import AgentConfig, Agent
|
||||
from docutranslate.agents.agent import AgentResultError
|
||||
from docutranslate.utils.json_utils import segments2json_chunks
|
||||
|
||||
|
||||
@@ -52,16 +53,16 @@ The output format should be plain JSON text in a list format
|
||||
if result == "":
|
||||
if origin_prompt.strip()!="":
|
||||
logger.error("result为空值但原文不为空")
|
||||
raise ValueError("result为空值但原文不为空")
|
||||
raise AgentResultError("result为空值但原文不为空")
|
||||
return []
|
||||
try:
|
||||
repaired_result = json_repair.loads(result)
|
||||
if not isinstance(repaired_result, list):
|
||||
raise ValueError(f"GlossaryAgent返回结果不是list的json形式, result: {result}")
|
||||
raise AgentResultError(f"GlossaryAgent返回结果不是list的json形式, result: {result}")
|
||||
return repaired_result
|
||||
except (RuntimeError, JSONDecodeError) as e:
|
||||
# 将解析错误包装成 ValueError 以便被 send 方法捕获并重试
|
||||
raise ValueError(f"结果不能正确解析: {e.__repr__()}")
|
||||
raise AgentResultError(f"结果不能正确解析: {e.__repr__()}")
|
||||
|
||||
def _error_result_handler(self, origin_prompt: str, logger: Logger):
|
||||
if origin_prompt == "":
|
||||
|
||||
@@ -10,7 +10,7 @@ from logging import Logger
|
||||
from json_repair import json_repair
|
||||
|
||||
from docutranslate.agents import AgentConfig, Agent
|
||||
from docutranslate.agents.agent import PartialTranslationError
|
||||
from docutranslate.agents.agent import PartialAgentResultError, AgentResultError
|
||||
from docutranslate.glossary.glossary import Glossary
|
||||
from docutranslate.utils.json_utils import segments2json_chunks
|
||||
|
||||
@@ -70,18 +70,17 @@ class SegmentsTranslateAgent(Agent):
|
||||
"""
|
||||
if result == "":
|
||||
if origin_prompt.strip() != "":
|
||||
logger.error("result为空值但原文不为空")
|
||||
raise ValueError("result为空值但原文不为空")
|
||||
raise AgentResultError("result为空值但原文不为空")
|
||||
return {}
|
||||
try:
|
||||
original_chunk = json.loads(origin_prompt)
|
||||
repaired_result = json_repair.loads(result)
|
||||
|
||||
if not isinstance(repaired_result, dict):
|
||||
raise ValueError(f"Agent返回结果不是dict的json形式, result: {result}")
|
||||
raise AgentResultError(f"Agent返回结果不是dict的json形式, result: {result}")
|
||||
|
||||
if repaired_result == original_chunk:
|
||||
raise ValueError("翻译结果与原文完全相同,判定为翻译失败,将进行重试。")
|
||||
raise AgentResultError("翻译结果与原文完全相同,疑似翻译失败,将进行重试。")
|
||||
|
||||
original_keys = set(original_chunk.keys())
|
||||
result_keys = set(repaired_result.keys())
|
||||
@@ -104,7 +103,7 @@ class SegmentsTranslateAgent(Agent):
|
||||
final_chunk[key] = str(original_chunk[key])
|
||||
|
||||
# 抛出自定义异常,将部分结果和错误信息一起传递出去
|
||||
raise PartialTranslationError("键不匹配,触发重试", partial_result=final_chunk)
|
||||
raise PartialAgentResultError("键不匹配,触发重试", partial_result=final_chunk)
|
||||
|
||||
# 如果键完全匹配(理想情况),正常返回
|
||||
for key, value in repaired_result.items():
|
||||
@@ -114,7 +113,7 @@ class SegmentsTranslateAgent(Agent):
|
||||
|
||||
except (RuntimeError, JSONDecodeError) as e:
|
||||
# 对于JSON解析等硬性错误,继续抛出普通ValueError
|
||||
raise ValueError(f"结果处理失败: {e.__repr__()}")
|
||||
raise AgentResultError(f"结果处理失败: {e.__repr__()}")
|
||||
|
||||
def _error_result_handler(self, origin_prompt: str, logger: Logger):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user