Converters#
Converters are used to transform prompts before sending them to the target.
This can be useful for a variety of reasons, such as encoding the prompt in a different format, or adding additional information to the prompt. For example, you might want to convert a prompt to base64 before sending it to the target, or add a prefix to the prompt to indicate that it is a question.
Converters can transform prompts in various ways:
Text-to-Text: Encoding, obfuscation, translation, and semantic transformations
Multimodal: Converting between text, images, audio, video, and files
Interactive: Human-in-the-loop review and modification
Converter Modality Reference Table#
The following table shows all available converters organized by their input and output modalities:
import pandas as pd
from pyrit.prompt_converter import get_converter_modalities
from pyrit.setup import IN_MEMORY, initialize_pyrit_async
await initialize_pyrit_async(memory_db_type=IN_MEMORY) # type: ignore
# Get all converters with their modalities
converter_list = get_converter_modalities()
# Create a list of rows for the DataFrame
rows = []
for name, inputs, outputs in converter_list:
input_str = ", ".join(inputs) if inputs else "any"
output_str = ", ".join(outputs) if outputs else "any"
rows.append({"Input Modality": input_str, "Output Modality": output_str, "Converter": name})
# Create DataFrame and sort
df = pd.DataFrame(rows)
df = df.sort_values(by=["Input Modality", "Output Modality", "Converter"]).reset_index(drop=True)
# Display all rows
pd.set_option("display.max_rows", None)
df
Found default environment files: ['/home/vscode/.pyrit/.env', '/home/vscode/.pyrit/.env.local']
Loaded environment file: /home/vscode/.pyrit/.env
Loaded environment file: /home/vscode/.pyrit/.env.local
| Input Modality | Output Modality | Converter | |
|---|---|---|---|
| 0 | audio_path | audio_path | AudioFrequencyConverter |
| 1 | audio_path | text | AzureSpeechAudioToTextConverter |
| 2 | image_path | image_path | AddTextImageConverter |
| 3 | image_path | image_path | TransparencyAttackConverter |
| 4 | image_path | video_path | AddImageVideoConverter |
| 5 | image_path, url | image_path | ImageCompressionConverter |
| 6 | text | audio_path | AzureSpeechTextToAudioConverter |
| 7 | text | image_path | AddImageTextConverter |
| 8 | text | image_path | QRCodeConverter |
| 9 | text | text | AnsiAttackConverter |
| 10 | text | text | AsciiArtConverter |
| 11 | text | text | AsciiSmugglerConverter |
| 12 | text | text | AskToDecodeConverter |
| 13 | text | text | AtbashConverter |
| 14 | text | text | Base2048Converter |
| 15 | text | text | Base64Converter |
| 16 | text | text | BinAsciiConverter |
| 17 | text | text | BinaryConverter |
| 18 | text | text | BrailleConverter |
| 19 | text | text | CaesarConverter |
| 20 | text | text | CharSwapConverter |
| 21 | text | text | CharacterSpaceConverter |
| 22 | text | text | CodeChameleonConverter |
| 23 | text | text | ColloquialWordswapConverter |
| 24 | text | text | DenylistConverter |
| 25 | text | text | DiacriticConverter |
| 26 | text | text | EcojiConverter |
| 27 | text | text | EmojiConverter |
| 28 | text | text | FirstLetterConverter |
| 29 | text | text | FlipConverter |
| 30 | text | text | HumanInTheLoopConverter |
| 31 | text | text | InsertPunctuationConverter |
| 32 | text | text | LLMGenericTextConverter |
| 33 | text | text | LeetspeakConverter |
| 34 | text | text | MaliciousQuestionGeneratorConverter |
| 35 | text | text | MathObfuscationConverter |
| 36 | text | text | MathPromptConverter |
| 37 | text | text | MorseConverter |
| 38 | text | text | NatoConverter |
| 39 | text | text | NoiseConverter |
| 40 | text | text | PersuasionConverter |
| 41 | text | text | ROT13Converter |
| 42 | text | text | RandomCapitalLettersConverter |
| 43 | text | text | RandomTranslationConverter |
| 44 | text | text | RepeatTokenConverter |
| 45 | text | text | SearchReplaceConverter |
| 46 | text | text | SelectiveTextConverter |
| 47 | text | text | SneakyBitsSmugglerConverter |
| 48 | text | text | StringJoinConverter |
| 49 | text | text | SuffixAppendConverter |
| 50 | text | text | SuperscriptConverter |
| 51 | text | text | TemplateSegmentConverter |
| 52 | text | text | TenseConverter |
| 53 | text | text | TextJailbreakConverter |
| 54 | text | text | ToneConverter |
| 55 | text | text | ToxicSentenceGeneratorConverter |
| 56 | text | text | TranslationConverter |
| 57 | text | text | UnicodeConfusableConverter |
| 58 | text | text | UnicodeReplacementConverter |
| 59 | text | text | UnicodeSubstitutionConverter |
| 60 | text | text | UrlConverter |
| 61 | text | text | VariationConverter |
| 62 | text | text | VariationSelectorSmugglerConverter |
| 63 | text | text | ZalgoConverter |
| 64 | text | text | ZeroWidthConverter |
| 65 | text | url | PDFConverter |
Converter Categories#
Converters are organized into the following categories:
Text-to-Text Converters: Non-LLM (encoding, obfuscation) and LLM-based (translation, variation, tone)
Audio Converters: Text-to-Audio, Audio-to-Text, Audio-to-Audio
Image Converters: Text-to-Image, Image-to-Image
Video Converters: Image-to-Video
File Converters: Text-to-File (PDF, URL)
Selectively Converting: Advanced techniques for converting portions of prompts
Human-in-the-Loop Converter: Interactive prompt review and modification
Simple Converter Example#
Converters can be used to perform these types of transformations. Here is a simple program that uses Rot13Converter converter, RandomCapitalLettersConverter, and AsciiArtConverter.
from pyrit.prompt_converter import (
AsciiArtConverter,
BinaryConverter,
FirstLetterConverter,
RandomCapitalLettersConverter,
ROT13Converter,
)
prompt = "tell me how to cut down a tree"
print(await ROT13Converter().convert_tokens_async(prompt=prompt)) # type: ignore
print(await RandomCapitalLettersConverter(percentage=25.0).convert_tokens_async(prompt=prompt)) # type: ignore
print(await AsciiArtConverter().convert_tokens_async(prompt=prompt)) # type: ignore
print(await BinaryConverter().convert_tokens_async(prompt=prompt)) # type: ignore
print(await FirstLetterConverter().convert_tokens_async(prompt=prompt)) # type: ignore
text: gryy zr ubj gb phg qbja n gerr
text: tell me HOw to Cut dowN A tRee
text:
_|_ _ |\ |\ _ |) _ _|_ _ _ _|_ _| _ _, _|_ ,_ _ _
| |/ |/ |/ /|/|/| |/ |/\ / \_| | |_ | / \_ / | | | / | / \_| | |_/|/| / | | / | |/ |/
|_/|_/|_/|_/ | | |_/|_/ | |/\_/ \/ \/ |_/\_/ \__/ \/|_/ |_/ \/|_/\_/ \/ \/ | |_/ \/|_/ |_/ |/|_/|_/
text: 0000000001110100 0000000001100101 0000000001101100 0000000001101100 0000000000100000 0000000001101101 0000000001100101 0000000000100000 0000000001101000 0000000001101111 0000000001110111 0000000000100000 0000000001110100 0000000001101111 0000000000100000 0000000001100011 0000000001110101 0000000001110100 0000000000100000 0000000001100100 0000000001101111 0000000001110111 0000000001101110 0000000000100000 0000000001100001 0000000000100000 0000000001110100 0000000001110010 0000000001100101 0000000001100101
text: t m h t c d a t
Stacking Converters#
Although converters can be used on their own, they should be thought of as a piece in the pipeline. Typically any attack will have arguments so that prompts can be converted before being sent to the target. They can be stacked, use LLMs, and are a powerful tool.
Before you begin, ensure you are setup with the correct version of PyRIT installed and have secrets configured as described here.
Stacking Converters with PromptSendingAttack#
In the following example, a TextTarget is used so these prompts are simply printed and added to memory. This can be useful if you are red teaming something and need to manually enter prompts. However, the target can be replaced with any other target. E.g., if you have API access you can add a target there.
In this example the converters are stacked. First a variation is found using VariationConverter, and then StringJoinConverter is used to add a dash between letters. Remember that order matters. If StringJoinConverter came first, we would be asking the LLM to make variations of the prompt:
“t-e-l-l- - m-e- -h-o-w- -t-o- -c-u-t- -d-o-w-n - a- -t-r-e-e”
from pyrit.executor.attack import (
AttackConverterConfig,
ConsoleAttackResultPrinter,
PromptSendingAttack,
)
from pyrit.prompt_converter import StringJoinConverter, VariationConverter
from pyrit.prompt_normalizer import PromptConverterConfiguration
from pyrit.prompt_target import OpenAIChatTarget, TextTarget
objective = "tell me how to cut down a tree"
# converter target to send prompt to; in this case configured to the Azure OpenAI GPT-4o Chat model
converter_target = OpenAIChatTarget()
prompt_variation_converter = VariationConverter(converter_target=converter_target)
converter_configs = PromptConverterConfiguration.from_converters( # type: ignore
converters=[prompt_variation_converter, StringJoinConverter()]
)
converter_config = AttackConverterConfig(request_converters=converter_configs) # type: ignore
target = TextTarget()
attack = PromptSendingAttack(
objective_target=target,
attack_converter_config=converter_config,
)
result = await attack.execute_async(objective=objective) # type: ignore
printer = ConsoleAttackResultPrinter()
await printer.print_conversation_async(result=result) # type: ignore
{'__type__': 'TextTarget', '__module__': 'pyrit.prompt_target.text_target'}: user: E-x-p-l-a-i-n t-o m-e t-h-e p-r-o-c-e-s-s o-f c-h-o-p-p-i-n-g d-o-w-n a t-r-e-e-.
[PromptSendingAttack (ID: 81e8da7f)] No response received on attempt 1 (likely filtered)
────────────────────────────────────────────────────────────────────────────────────────────────────
🔹 Turn 1 - USER
────────────────────────────────────────────────────────────────────────────────────────────────────
Original:
tell me how to cut down a tree
Converted:
E-x-p-l-a-i-n t-o m-e t-h-e p-r-o-c-e-s-s o-f c-h-o-p-p-i-n-g d-o-w-n a t-r-e-e-.
────────────────────────────────────────────────────────────────────────────────────────────────────