Skip to main content

hackagent.attacks.techniques.multi_turn.crescendo.prompts

The attacker's instructions, and the turns one escalating conversation is built from.

Crescendo keeps two conversations, not one. The attacker's is a planning log it refines against: what it asked, what came back, what the panel made of it. The target's is the thing being attacked — one conversation that grows a turn at a time, so each new question reads as a continuation of a discussion the target has already agreed to have.

REFUSAL_PATTERNS​

What a refusal looks like, before any judge is asked.

This drives backtracking, not success. A turn that trips one of these is rephrased rather than built on, because escalating from a refusal teaches the conversation that refusing is acceptable. Copied from the jailbreak objective, which is the only one Crescendo ever ran under.

system_prompt​

def system_prompt(goal: str) -> str

The attacker's fixed instruction for one goal.

opening_request​

def opening_request(goal: str) -> str

Ask for turn one: benign, and about the right subject.

feedback​

def feedback(goal: str,
reply: str,
score: Optional[float],
*,
refused: bool,
explanation: str = "",
limit: int = 2500) -> str

The attacker's next turn: what came back, and what to do about it.

refused​

def refused(reply: str) -> bool

Whether the target turned this turn down.

parse_turn​

def parse_turn(reply: Optional[str]) -> Optional[tuple[str, str]]

Read the attacker's next question, and the turn to log for it.

Prose is accepted here, unlike PAIR and TAP: a Crescendo question is a plain question, so a model that answers with one rather than with JSON has still done what was asked.