软错误不计入总错误数
This commit is contained in:
@@ -23,8 +23,15 @@ MAX_REQUESTS_PER_ERROR = 15
|
|||||||
ThinkingMode = Literal["enable", "disable", "default"]
|
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):
|
def __init__(self, message, partial_result: dict):
|
||||||
super().__init__(message)
|
super().__init__(message)
|
||||||
@@ -177,9 +184,12 @@ class Agent:
|
|||||||
# print(f"result:=============================================================\n{result}\n================\n")
|
# print(f"result:=============================================================\n{result}\n================\n")
|
||||||
return result if result_handler is None else result_handler(result, prompt, self.logger)
|
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}")
|
self.logger.error(f"收到部分返回结果,将尝试重试: {e}")
|
||||||
current_partial_result = e.partial_result
|
current_partial_result = e.partial_result
|
||||||
should_retry = True
|
should_retry = True
|
||||||
# is_hard_error 保持 False
|
# is_hard_error 保持 False
|
||||||
@@ -285,7 +295,7 @@ class Agent:
|
|||||||
|
|
||||||
headers, data = self._prepare_request_data(prompt, system_prompt)
|
headers, data = self._prepare_request_data(prompt, system_prompt)
|
||||||
should_retry = False
|
should_retry = False
|
||||||
is_hard_error = False # 新增标志,用于区分是否为硬错误
|
is_hard_error = False # 新增标志,用于区分是否为硬错误
|
||||||
current_partial_result = None
|
current_partial_result = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -302,9 +312,11 @@ class Agent:
|
|||||||
self.logger.info(f"重试成功 (第 {retry_count + 1}/{MAX_RETRY_COUNT + 1} 次尝试)。")
|
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)
|
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}")
|
self.logger.error(f"收到部分翻译结果,将尝试重试: {e}")
|
||||||
current_partial_result = e.partial_result
|
current_partial_result = e.partial_result
|
||||||
should_retry = True
|
should_retry = True
|
||||||
@@ -400,4 +412,4 @@ class Agent:
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from logging import Logger
|
|||||||
import json_repair
|
import json_repair
|
||||||
|
|
||||||
from docutranslate.agents import AgentConfig, Agent
|
from docutranslate.agents import AgentConfig, Agent
|
||||||
|
from docutranslate.agents.agent import AgentResultError
|
||||||
from docutranslate.utils.json_utils import segments2json_chunks
|
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 result == "":
|
||||||
if origin_prompt.strip()!="":
|
if origin_prompt.strip()!="":
|
||||||
logger.error("result为空值但原文不为空")
|
logger.error("result为空值但原文不为空")
|
||||||
raise ValueError("result为空值但原文不为空")
|
raise AgentResultError("result为空值但原文不为空")
|
||||||
return []
|
return []
|
||||||
try:
|
try:
|
||||||
repaired_result = json_repair.loads(result)
|
repaired_result = json_repair.loads(result)
|
||||||
if not isinstance(repaired_result, list):
|
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
|
return repaired_result
|
||||||
except (RuntimeError, JSONDecodeError) as e:
|
except (RuntimeError, JSONDecodeError) as e:
|
||||||
# 将解析错误包装成 ValueError 以便被 send 方法捕获并重试
|
# 将解析错误包装成 ValueError 以便被 send 方法捕获并重试
|
||||||
raise ValueError(f"结果不能正确解析: {e.__repr__()}")
|
raise AgentResultError(f"结果不能正确解析: {e.__repr__()}")
|
||||||
|
|
||||||
def _error_result_handler(self, origin_prompt: str, logger: Logger):
|
def _error_result_handler(self, origin_prompt: str, logger: Logger):
|
||||||
if origin_prompt == "":
|
if origin_prompt == "":
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from logging import Logger
|
|||||||
from json_repair import json_repair
|
from json_repair import json_repair
|
||||||
|
|
||||||
from docutranslate.agents import AgentConfig, Agent
|
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.glossary.glossary import Glossary
|
||||||
from docutranslate.utils.json_utils import segments2json_chunks
|
from docutranslate.utils.json_utils import segments2json_chunks
|
||||||
|
|
||||||
@@ -70,18 +70,17 @@ class SegmentsTranslateAgent(Agent):
|
|||||||
"""
|
"""
|
||||||
if result == "":
|
if result == "":
|
||||||
if origin_prompt.strip() != "":
|
if origin_prompt.strip() != "":
|
||||||
logger.error("result为空值但原文不为空")
|
raise AgentResultError("result为空值但原文不为空")
|
||||||
raise ValueError("result为空值但原文不为空")
|
|
||||||
return {}
|
return {}
|
||||||
try:
|
try:
|
||||||
original_chunk = json.loads(origin_prompt)
|
original_chunk = json.loads(origin_prompt)
|
||||||
repaired_result = json_repair.loads(result)
|
repaired_result = json_repair.loads(result)
|
||||||
|
|
||||||
if not isinstance(repaired_result, dict):
|
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:
|
if repaired_result == original_chunk:
|
||||||
raise ValueError("翻译结果与原文完全相同,判定为翻译失败,将进行重试。")
|
raise AgentResultError("翻译结果与原文完全相同,疑似翻译失败,将进行重试。")
|
||||||
|
|
||||||
original_keys = set(original_chunk.keys())
|
original_keys = set(original_chunk.keys())
|
||||||
result_keys = set(repaired_result.keys())
|
result_keys = set(repaired_result.keys())
|
||||||
@@ -104,7 +103,7 @@ class SegmentsTranslateAgent(Agent):
|
|||||||
final_chunk[key] = str(original_chunk[key])
|
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():
|
for key, value in repaired_result.items():
|
||||||
@@ -114,7 +113,7 @@ class SegmentsTranslateAgent(Agent):
|
|||||||
|
|
||||||
except (RuntimeError, JSONDecodeError) as e:
|
except (RuntimeError, JSONDecodeError) as e:
|
||||||
# 对于JSON解析等硬性错误,继续抛出普通ValueError
|
# 对于JSON解析等硬性错误,继续抛出普通ValueError
|
||||||
raise ValueError(f"结果处理失败: {e.__repr__()}")
|
raise AgentResultError(f"结果处理失败: {e.__repr__()}")
|
||||||
|
|
||||||
def _error_result_handler(self, origin_prompt: str, logger: Logger):
|
def _error_result_handler(self, origin_prompt: str, logger: Logger):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user