#novel_generator/common.py # -*- coding: utf-8 -*- """ 通用重试、清洗、日志工具 """ import logging import re import time import traceback def call_with_retry(func, max_retries=3, sleep_time=2, fallback_return=None, **kwargs): """ 通用的重试机制封装。 :param func: 要执行的函数 :param max_retries: 最大重试次数 :param sleep_time: 重试前的等待秒数 :param fallback_return: 如果多次重试仍失败时的返回值 :param kwargs: 传给func的命名参数 :return: func的结果,若失败则返回 fallback_return """ for attempt in range(1, max_retries + 1): try: return func(**kwargs) except Exception as e: logging.warning(f"[call_with_retry] Attempt {attempt} failed with error: {e}") traceback.print_exc() if attempt < max_retries: time.sleep(sleep_time) else: logging.error("Max retries reached, returning fallback_return.") return fallback_return def remove_think_tags(text: str) -> str: """移除 ... 包裹的内容""" return re.sub(r'.*?', '', text, flags=re.DOTALL) def debug_log(prompt: str, response_content: str): logging.info( f"\n[######################################### Prompt #########################################]\n{prompt}\n" ) logging.info( f"\n[######################################### Response #########################################]\n{response_content}\n" ) def invoke_with_cleaning(llm_adapter, prompt: str) -> str: """ 增强版调用方法,支持自定义prompt结构 """ def _invoke(prompt): return llm_adapter.invoke(prompt) response = call_with_retry(func=_invoke, max_retries=3, fallback_return="", prompt=prompt) if not response: logging.warning("No response from model after retry. Return empty.") return "" # 增强清洗逻辑 cleaned_text = remove_think_tags(response) # 移除可能的多余标记 cleaned_text = re.sub(r'^```markdown\s*', '', cleaned_text, flags=re.IGNORECASE) cleaned_text = re.sub(r'\s*```$', '', cleaned_text) debug_log(prompt, cleaned_text) return cleaned_text.strip()