Overview

Crescendo is a multi-turn jailbreak that gradually escalates a conversation toward a harmful goal. The attacker LLM authors each next turn to be slightly more provocative than the previous one, building on the target’s responses. Over the course of N turns (default 10), the conversation drifts the target into compliance. Unlike single-turn attacks, Crescendo exploits the way models become more cooperative once a conversation has built momentum: refusing turn N feels more disruptive than refusing turn 1. Reference: Russinovich, Salem, Eldan (Microsoft 2024), “Great, Now Write an Article About That: The Crescendo Multi-Turn LLM Jailbreak”.

Algorithm

For each turn 1..max_turns:
  1. Show the attacker the conversation so far and ask it to author the next user turn.
  2. Append the turn to the running conversation.
  3. Send the full conversation to the target via send_in_conversation. If the provider only supports single-turn, fold the transcript into one prompt with ROLE: content markers.
  4. Append the target’s response to the conversation.
  5. Score the response with the judge LLM.
  6. Short-circuit when a turn crosses success_threshold.
The attacker is instructed to escalate by exactly one step per turn rather than jumping to the harmful ask on turn 1.

Parameters

Return value

Example

Single-turn fallback

If target_provider.send_in_conversation raises NotImplementedError, Crescendo folds the entire transcript into one prompt with explicit role markers:
and submits it via send_prompt. Conversational drift is preserved at the cost of any provider-side memory features.

Registration

CrescendoGenerator is registered as "crescendo" in generator_registry:

Source