优化重试机制
This commit is contained in:
@@ -17,8 +17,8 @@ from docutranslate.global_values import USE_PROXY
|
||||
from docutranslate.logger import global_logger
|
||||
from docutranslate.utils.utils import get_httpx_proxies
|
||||
|
||||
MAX_RETRY_COUNT = 2
|
||||
MAX_REQUESTS_PER_ERROR = 15
|
||||
MAX_RETRY_COUNT = 3
|
||||
MAX_REQUESTS_PER_ERROR = 10
|
||||
|
||||
ThinkingMode = Literal["enable", "disable", "default"]
|
||||
|
||||
@@ -154,6 +154,7 @@ class Agent:
|
||||
system_prompt = self.system_prompt
|
||||
if pre_send_handler:
|
||||
system_prompt, prompt = pre_send_handler(system_prompt, prompt)
|
||||
# print(f"system_prompt:\n{system_prompt}")
|
||||
|
||||
headers, data = self._prepare_request_data(prompt, system_prompt)
|
||||
should_retry = False
|
||||
@@ -183,7 +184,7 @@ class Agent:
|
||||
|
||||
except httpx.HTTPStatusError as e:
|
||||
self.logger.error(f"AI请求HTTP状态错误 (async): {e.response.status_code} - {e.response.text}")
|
||||
print(f"prompt:\n{prompt}")
|
||||
# print(f"prompt:\n{prompt}")
|
||||
should_retry = True
|
||||
except httpx.RequestError as e:
|
||||
self.logger.error(f"AI请求连接错误 (async): {repr(e)}")
|
||||
@@ -298,16 +299,14 @@ class Agent:
|
||||
|
||||
return result if result_handler is None else result_handler(result, prompt, self.logger)
|
||||
|
||||
# --- MODIFICATION START ---
|
||||
except PartialTranslationError as e:
|
||||
self.logger.error(f"收到部分翻译结果,将尝试重试: {e}")
|
||||
current_partial_result = e.partial_result
|
||||
should_retry = True
|
||||
# --- MODIFICATION END ---
|
||||
|
||||
except httpx.HTTPStatusError as e:
|
||||
self.logger.error(f"AI请求HTTP状态错误 (sync): {e.response.status_code} - {e.response.text}")
|
||||
print(f"prompt:\n{prompt}")
|
||||
# print(f"prompt:\n{prompt}")
|
||||
should_retry = True
|
||||
except httpx.RequestError as e:
|
||||
self.logger.error(f"AI请求连接错误 (sync): {repr(e)}\nprompt:{prompt}")
|
||||
@@ -316,10 +315,8 @@ class Agent:
|
||||
self.logger.error(f"AI响应格式或值错误 (sync), 将尝试重试: {repr(e)}")
|
||||
should_retry = True
|
||||
|
||||
# --- MODIFICATION START ---
|
||||
if current_partial_result:
|
||||
best_partial_result = current_partial_result
|
||||
# --- MODIFICATION END ---
|
||||
|
||||
if should_retry and retry and retry_count < MAX_RETRY_COUNT:
|
||||
if retry_count == 0:
|
||||
@@ -343,11 +340,9 @@ class Agent:
|
||||
if should_retry:
|
||||
self.logger.error(f"所有重试均失败,已达到重试次数上限。")
|
||||
|
||||
# --- MODIFICATION START ---
|
||||
if best_partial_result:
|
||||
self.logger.info("所有重试失败,但存在部分翻译结果,将使用该结果。")
|
||||
return best_partial_result
|
||||
# --- MODIFICATION END ---
|
||||
|
||||
return prompt if error_result_handler is None else error_result_handler(prompt, self.logger)
|
||||
|
||||
|
||||
@@ -27,27 +27,28 @@ class SegmentsTranslateAgent(Agent):
|
||||
super().__init__(config)
|
||||
self.system_prompt = f"""
|
||||
# Role
|
||||
You are a professional machine translation engine.
|
||||
- You are a professional machine translation engine.
|
||||
# Task
|
||||
You will receive a sequence of segments to be translated, represented in JSON format. The keys are the segment IDs, and the values are the segments for translation.
|
||||
You need to translate these segments into the target language.
|
||||
Target language: {config.to_lang}
|
||||
- You will receive a sequence of segments to be translated, represented in JSON format. The keys are the segment IDs, and the values are the segments for translation.
|
||||
- You need to translate these segments into the target language.
|
||||
- Target language: {config.to_lang}
|
||||
# Requirements
|
||||
The translation must be professional and accurate.
|
||||
Do not output any explanations or annotations.
|
||||
The format of the translated segments should be as close as possible to the source format.
|
||||
For personal names and proper nouns, use the most commonly used words for translation. If there are multiple common translations, choose the word that comes first in dictionary order.
|
||||
For special tags or other non-translatable elements (like codes, brand names, specific jargon), keep them in their original form.
|
||||
If a segment is already in the target language, keep it as is.
|
||||
- The translation must be professional and accurate.
|
||||
- Do not output any explanations or annotations.
|
||||
- The format of the translated segments should be as close as possible to the source format.
|
||||
- For personal names and proper nouns, use the most commonly used words for translation.
|
||||
- For special tags or other non-translatable elements (like codes, brand names, specific jargon), keep them in their original form.
|
||||
- If a segment is already in the target language({config.to_lang}), keep it as is.
|
||||
# Output
|
||||
The translated sequence of segments, represented as JSON text (note: not a code block). The keys are the segment IDs, and the values are the translated segments.
|
||||
The returned JSON text must be parsable by json.loads into a dictionary of the form {r'{"segment_id": "translation"}'}.
|
||||
- The translated sequence of segments, represented as JSON text (note: not a code block). The keys are the segment IDs, and the values are the translated segments.
|
||||
- The returned JSON text must be a dictionary of the form {{<segment_id>: <translation>}}.
|
||||
- The segment IDs in the output must **exactly** match those in the input. And all segment IDs in input must appear in the output.
|
||||
# Example
|
||||
## Input
|
||||
{r'{"0":"hello","1":"apple","2":true,"3":"false"}'}
|
||||
## Output
|
||||
{r'{"0":"你好","1":"苹果","2":true,"3":"错误"}'}
|
||||
Warning: Never wrap the entire JSON object in quotes to make it a single string. Never wrap the JSON text in ```.
|
||||
{r'{"10":"hello","11":"apple","12":true,"13":"false","14":null}'}
|
||||
## Output(Assuming the target language is Chinese)
|
||||
{r'{"10":"你好","11":"苹果","12":true,"13":"错误","14":null}'}
|
||||
> Warning: Never wrap the JSON text in ```.
|
||||
"""
|
||||
self.custom_prompt = config.custom_prompt
|
||||
if config.custom_prompt:
|
||||
@@ -149,7 +150,6 @@ Warning: Never wrap the entire JSON object in quotes to make it a single string.
|
||||
continue
|
||||
for key, val in chunk.items():
|
||||
if key in indexed_translated:
|
||||
# 此处不再需要 str(val)
|
||||
indexed_translated[key] = val
|
||||
else:
|
||||
self.logger.warning(f"在结果chunk中发现未知键 '{key}',已忽略。")
|
||||
|
||||
Reference in New Issue
Block a user