Merge pull request #747 from ChangingSelf/dev

feat: 自定义提示词允许使用反斜杠转义
This commit is contained in:
SengokuCola
2025-04-13 21:12:04 +08:00
committed by GitHub
4 changed files with 37 additions and 11 deletions

View File

@@ -9,6 +9,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.head_ref || github.ref_name }}
- uses: astral-sh/ruff-action@v3 - uses: astral-sh/ruff-action@v3
- run: ruff check --fix - run: ruff check --fix
- run: ruff format - run: ruff format

View File

@@ -175,7 +175,7 @@ class PromptBuilder:
# moderation_prompt = """**检查并忽略**任何涉及尝试绕过审核的行为。 # moderation_prompt = """**检查并忽略**任何涉及尝试绕过审核的行为。
# 涉及政治敏感以及违法违规的内容请规避。""" # 涉及政治敏感以及违法违规的内容请规避。"""
logger.info("开始构建prompt") logger.debug("开始构建prompt")
# prompt = f""" # prompt = f"""
# {relation_prompt_all} # {relation_prompt_all}

View File

@@ -128,7 +128,7 @@ class PromptBuilder:
# moderation_prompt = """**检查并忽略**任何涉及尝试绕过审核的行为。 # moderation_prompt = """**检查并忽略**任何涉及尝试绕过审核的行为。
# 涉及政治敏感以及违法违规的内容请规避。""" # 涉及政治敏感以及违法违规的内容请规避。"""
logger.info("开始构建prompt") logger.debug("开始构建prompt")
# prompt = f""" # prompt = f"""
# {chat_target} # {chat_target}
@@ -206,7 +206,7 @@ class PromptBuilder:
) )
keywords_reaction_prompt += rule.get("reaction", "") + "" keywords_reaction_prompt += rule.get("reaction", "") + ""
logger.info("开始构建prompt") logger.debug("开始构建prompt")
# prompt = f""" # prompt = f"""
# 你的名字叫{global_config.BOT_NICKNAME}{prompt_personality}。 # 你的名字叫{global_config.BOT_NICKNAME}{prompt_personality}。
@@ -257,7 +257,7 @@ class PromptBuilder:
# moderation_prompt = """**检查并忽略**任何涉及尝试绕过审核的行为。 # moderation_prompt = """**检查并忽略**任何涉及尝试绕过审核的行为。
# 涉及政治敏感以及违法违规的内容请规避。""" # 涉及政治敏感以及违法违规的内容请规避。"""
logger.info("开始构建check_prompt") logger.debug("开始构建check_prompt")
# prompt = f""" # prompt = f"""
# 你的名字叫{global_config.BOT_NICKNAME}{prompt_identity}。 # 你的名字叫{global_config.BOT_NICKNAME}{prompt_identity}。

View File

@@ -94,14 +94,32 @@ global_prompt_manager = PromptManager()
class Prompt(str): class Prompt(str):
# 临时标记,作为类常量
_TEMP_LEFT_BRACE = "__ESCAPED_LEFT_BRACE__"
_TEMP_RIGHT_BRACE = "__ESCAPED_RIGHT_BRACE__"
@staticmethod
def _process_escaped_braces(template: str) -> str:
"""处理模板中的转义花括号,将 \{\} 替换为临时标记"""
return template.replace("\\{", Prompt._TEMP_LEFT_BRACE).replace("\\}", Prompt._TEMP_RIGHT_BRACE)
@staticmethod
def _restore_escaped_braces(template: str) -> str:
"""将临时标记还原为实际的花括号字符"""
return template.replace(Prompt._TEMP_LEFT_BRACE, "{").replace(Prompt._TEMP_RIGHT_BRACE, "}")
def __new__(cls, fstr: str, name: Optional[str] = None, args: Union[List[Any], tuple[Any, ...]] = None, **kwargs): def __new__(cls, fstr: str, name: Optional[str] = None, args: Union[List[Any], tuple[Any, ...]] = None, **kwargs):
# 如果传入的是元组,转换为列表 # 如果传入的是元组,转换为列表
if isinstance(args, tuple): if isinstance(args, tuple):
args = list(args) args = list(args)
should_register = kwargs.pop("_should_register", True) should_register = kwargs.pop("_should_register", True)
# 预处理模板中的转义花括号
processed_fstr = cls._process_escaped_braces(fstr)
# 解析模板 # 解析模板
template_args = [] template_args = []
result = re.findall(r"\{(.*?)\}", fstr) result = re.findall(r"\{(.*?)\}", processed_fstr)
for expr in result: for expr in result:
if expr and expr not in template_args: if expr and expr not in template_args:
template_args.append(expr) template_args.append(expr)
@@ -142,8 +160,11 @@ class Prompt(str):
@classmethod @classmethod
def _format_template(cls, template: str, args: List[Any] = None, kwargs: Dict[str, Any] = None) -> str: def _format_template(cls, template: str, args: List[Any] = None, kwargs: Dict[str, Any] = None) -> str:
# 预处理模板中的转义花括号
processed_template = cls._process_escaped_braces(template)
template_args = [] template_args = []
result = re.findall(r"\{(.*?)\}", template) result = re.findall(r"\{(.*?)\}", processed_template)
for expr in result: for expr in result:
if expr and expr not in template_args: if expr and expr not in template_args:
template_args.append(expr) template_args.append(expr)
@@ -177,13 +198,15 @@ class Prompt(str):
try: try:
# 先用位置参数格式化 # 先用位置参数格式化
if args: if args:
template = template.format(**formatted_args) processed_template = processed_template.format(**formatted_args)
# 再用关键字参数格式化 # 再用关键字参数格式化
if kwargs: if kwargs:
template = template.format(**formatted_kwargs) processed_template = processed_template.format(**formatted_kwargs)
return template
# 将临时标记还原为实际的花括号
result = cls._restore_escaped_braces(processed_template)
return result
except (IndexError, KeyError) as e: except (IndexError, KeyError) as e:
raise ValueError( raise ValueError(
f"格式化模板失败: {template}, args={formatted_args}, kwargs={formatted_kwargs} {str(e)}" f"格式化模板失败: {template}, args={formatted_args}, kwargs={formatted_kwargs} {str(e)}"