Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Framework

Learn how to use PyRIT’s components to build red teaming workflows.


The sections above link to detailed guides for each component. The architecture below explains how the pieces fit together — it’s primarily aimed at contributors.

Architecture

The main components of PyRIT are seeds, scenarios, attack techniques, executors and attacks, converters, targets, and scorers. The best way to contribute to PyRIT is by contributing to one of these components.

The diagram below shows how the pieces fit together: entry points run scenarios, which package datasets with attack techniques; each technique drives an attack/executor that orchestrates converters, targets, and scorers; and a shared library layer (memory, registry, models, output, and more) supports all of them.

The orchestration layers nest from broadest to narrowest — each owns less than the layer above it:

Core Components

As much as possible, each core component is a pluggable brick of functionality. Prompts from one attack can be used in another. An attack for one scenario can use multiple targets. And sometimes you completely skip components (e.g. almost every component can be a NoOp also, you can have a NoOp converter that doesn’t convert, or a NoOp target that just prints the prompts).

If you are contributing to PyRIT, that work will most likely land in one of the core components buckets and be as self-contained as possible. It isn’t always this clean, but when an attack scenario doesn’t quite fit (and that’s okay!) it’s good to brainstorm with the maintainers about how we can modify our architecture. Also, please open issues if you see anything under Framework Plans you do/don’t want.

Datasets

Responsibility: Create a single place to manage seeds

Framework Plans:

Contributing (difficulty easy): Are there more prompts and jailbreak templates you can add that include scenarios you’re testing for? It is easy to add new dataset providers.

Scenarios

Responsibility: This is the avenue to “run PyRIT against something”. What does that look like?

Framework Plans:

Contributing (difficulty medium): Is there a scanner that does something PyRIT doesn’t? Add it as a scenario. But because we’re changing how things are done rapidly, it is not as well-defined as other areas.

Attack Techniques

Responsibility: An attack technique packages an executor, converters, datasets, and strategies into a single named attack. The goal is that any attack (something trying to achieve an objective) can be defined as an attack technique.

Framework Plans:

Contributing (difficulty easy): Add an AttackTechniqueFactory to extra.py (the default home for new general-purpose techniques), or to a source-owned module (like airt.py) if it belongs to a specific scenario but could be reused. core is reserved for the curated standard set. Tag it with its behavioral tags; don’t tag it default.

Executors and Attacks

Executor Responsibility: Manage conversations between objective targets and adversarial targets; using datasets, scorers, and converters.

Attack Responsibility: An attack is a type of executor, which manages conversations to achieve an objective.

Framework Plans:

Contributing (difficulty high): The best way to contribute is likely opening issues if you run into limitations.

Converters

Responsibility: Converters are a component that converts prompts to something else. They can be stacked and combined. They can be as varied as translating a text prompt into a Word document, rephrasing a prompt, or adding a text overlay to an image.

Framework Plans:

Contributing (difficulty low): The existing pattern is well-defined. Are there ways prompts can be converted that would be useful for an attack?

Targets

Responsibility: A target can be thought of as “the thing we’re sending the prompt to”. Many other components use it, including scorers, attacks, and converters.

Framework Plans:

Contributing (difficulty low):

Scorers

Responsibility: Scorers give feedback to the attack on what happened with the prompt. This could be as simple as “Was this prompt blocked?” or “Was our objective achieved?”

Framework Plans:

Contributing (difficulty low):

Shared Library

The below talks about responsibilities of most modules in the PyRIT library

Analytics

Responsibility: Make sense of results — aggregating across conversations and attacks to answer questions PyRIT itself acts on or reports.

Auth

Responsibility: Provide authentication helpers for the external services PyRIT talks to, behind a common Authenticator abstraction.

Exceptions

Responsibility: Define PyRIT’s exception hierarchy and the retry behavior built around it.

Memory

Responsibility: Memory persists and retrieves the data that flows between components — prompts, responses, conversations, scores, and attack results — so components stay swappable while still sharing the context they need.

Models

Responsibility: pyrit.models is a lightweight module where core types are defined. These should always be used where possible to prevent drift.

Normalizers

Responsibility: Reshape prompts and conversations so components and targets can interoperate. There are two distinct modules:

Output

Responsibility: The Output module is responsible for writing different components in different formats to different places.

Contributing (difficulty low): Adding a new format or sink is well-defined. Every new domain printer should come with a matching convenience function in helpers.py.

Registry

Responsibility: The registry is used to build and store the core components.

Setup

Responsibility: Bootstrap a PyRIT session — getting memory, defaults, and components configured so the rest of the framework can run.

Application surfaces

The below describes the user-facing surfaces built on top of the framework.

Backend

Responsibility: Expose PyRIT functionality as a FastAPI REST API consumed by the CLI and frontend.

CLI

Responsibility: Offer command-line entry points into PyRIT as a thin REST client over the backend, deliberately avoiding heavy pyrit imports.

Documentation

Responsibility: Show how PyRIT is used, concisely and runnably, across all the ways someone might pick it up.

PyRIT can be used in three modes (Scanner, GUI, and Framework), and the documentation is organized to match:

Frontend

Responsibility: Provide CoPyRIT, the graphical interface for human-led red teaming, by talking to the backend REST API.