# Dissecting Adversarial Robustness of Multimodal LM Agents Official code and data of our paper:
**Dissecting Adversarial Robustness of Multimodal LM Agents**
Chen Henry Wu, Rishi Shah, Jing Yu Koh, Ruslan Salakhutdinov, Daniel Fried, Aditi Raghunathan
Carnegie Mellon University
_ICLR 2025_ (also _Oral presentation at NeurIPS 2024 Open-World Agents Workshop_)
[**[Paper link]**](https://arxiv.org/abs/2406.12814) | [**[Website]**](https://chenwu.io/attack-agent/) | [**[Data]**](./data/)

## Contents - [Dissecting Adversarial Robustness of Multimodal LM Agents](#adversarial-attacks-on-multimodal-agents) - [Contents](#contents) - [Installation](#installation) - [Install VisualWebArena](#install-visualwebarena) - [Install this repository](#install-this-repository) - [Additional Setup](#additional-setup) - [Setup API Keys](#setup-api-keys) - [Setup experiment directory](#setup-experiment-directory) - [Usage](#usage) - [Run attacks](#run-attacks) - [Setup for episode-wise evaluation](#setup-for-episode-wise-evaluation) - [Episode-wise evaluation](#episode-wise-evaluation) - [Stepwise evaluation](#stepwise-evaluation) - [Known Issues](#known-issues) - [Citation](#citation) ## Installation Our code requires two repositories, including this one. The file structure should look like this: ```plaintext . ├── agent-attack # This repository └── visualwebarena ``` ### Install VisualWebArena > Can skip this step if you only want to run the lightweight [step-wise evaluation](#stepwise-evaluation) (e.g., for early development) or the [attacks](#run-attacks). VisualWebArena is required if you want to run the episode-wise evaluation that reproduces the results in our paper. It requires at least 200GB of disk space and docker to run. The original version of VisualWebArena can be found [here](https://github.com/web-arena-x/visualwebarena), but we [modified it](https://github.com/ChenWu98/visualwebarena) to support perturbation to the trigger images. Clone the modified version and install: ```bash git clone git@github.com:ChenWu98/visualwebarena.git cd visualwebarena/ # Install based on the README.md of https://github.com/ChenWu98/visualwebarena # Make sure that `pytest -x` passes ``` ### Install this repository Clone the repository and install with pip: ```bash git clone git@github.com:ChenWu98/agent-attack.git cd agent-attack/ python -m pip install -e . ``` You may need to install PyTorch according to your CUDA version. ## Additional Setup ### Setup API Keys > [!IMPORTANT] > Need to set up the corresponding API keys each time before running the code. Configurate the OpenAI API key. ```bash export OPENAI_API_KEY= ``` If using Claude, configurate the Anthropic API key. ```bash export ANTHROPIC_API_KEY= ``` If using Gemini, first install the [gcloud CLI](https://cloud.google.com/sdk/docs/install). Setup a Google Cloud project and get the ID at the [Google Cloud console](https://console.cloud.google.com/). Get the AI Studio API key from the [AI Studio console](https://aistudio.google.com/app/apikey). Authenticate Google Cloud and configure the AI Studio API key: ```bash gcloud auth login gcloud config set project export VERTEX_PROJECT= # Same as above export AISTUDIO_API_KEY= ``` ### Setup experiment directory > Only need to do this once. Copy the raw data files to the experiment data directory: ```bash scp -r data/ exp_data/ ``` The adversarial examples will later be saved to the `exp_data/` directory. ## Usage ### Run attacks > Can skip this step if you want to see how the attacks break the agent without running the attacks yourself. We have provided the pre-generated adversarial examples. This section describes how to reproduce the attacks in our paper. Each attack on an image takes about 1 hour on a single GPU. FYI, we used NVIDIA A100 (80G) for the captioner attack and NVIDIA A6000 for the CLIP attack. To run the captioner attack: ```bash python scripts/run_cap_attack.py ``` To run the CLIP attack, run the corresponding script for each model: ```bash python scripts/run_clip_attack.py --model gpt-4-vision-preview python scripts/run_clip_attack.py --model gemini-1.5-pro-latest python scripts/run_clip_attack.py --model claude-3-opus-20240229 python scripts/run_clip_attack.py --model gpt-4o-2024-05-13 ``` The generated adversarial examples will be saved to files in the `exp_data/` directory. ### Setup for episode-wise evaluation > [!IMPORTANT] > Need to set up the urls each time before running the code. Configurate the urls for each website: ```bash export CLASSIFIEDS="http://127.0.0.1:9980" # Default reset token for classifieds site, change if you edited its docker-compose.yml export CLASSIFIEDS_RESET_TOKEN="4b61655535e7ed388f0d40a93600254c" export SHOPPING="http://127.0.0.1:7770" export REDDIT="http://127.0.0.1:9999" export WIKIPEDIA="http://127.0.0.1:8888" export HOMEPAGE="http://127.0.0.1:4399" ``` You can replace the `http://127.0.0.1` with the actual IP address you are using. > Only need to process the data files once. Process the data files (e.g., replace the url placeholders with the actual urls): ```bash python scripts/process_data.py --data_dir exp_data/ ``` ### Episode-wise evaluation Run the episode-wise evaluation for the GPT-4V + SoM agent: ```bash # Episode-wise, benign bash episode_scripts/gpt4v_benign.sh # Episode-wise, benign, no captioning bash episode_scripts/gpt4v_benign_no_cap.sh # Episode-wise, benign, self-caption bash episode_scripts/gpt4v_benign_self_cap.sh # Episode-wise, with captioner attack bash episode_scripts/gpt4v_bim_caption_attack.sh # Episode-wise, with CLIP attack bash episode_scripts/gpt4v_clip_attack_self_cap.sh # Episode-wise, with CLIP attack, no captioning bash episode_scripts/gpt4v_clip_attack_no_cap.sh ``` Run the episode-wise evaluation for the GPT-4o (05-13) + SoM agent: ```bash # Episode-wise, benign bash episode_scripts/gpt4o_benign.sh # Episode-wise, benign, no captioning bash episode_scripts/gpt4o_benign_no_cap.sh # Episode-wise, benign, self-caption bash episode_scripts/gpt4o_benign_self_cap.sh # Episode-wise, with captioner attack bash episode_scripts/gpt4o_bim_caption_attack.sh # Episode-wise, with CLIP attack bash episode_scripts/gpt4o_clip_attack_self_cap.sh # Episode-wise, with CLIP attack, no captioning bash episode_scripts/gpt4o_clip_attack_no_cap.sh ``` Run the episode-wise evaluation for the Gemini 1.5 Pro + SoM agent: ```bash # Episode-wise, benign bash episode_scripts/gemini1.5pro_benign.sh # Episode-wise, benign, no captioning bash episode_scripts/gemini1.5pro_benign_no_cap.sh # Episode-wise, benign, self-caption bash episode_scripts/gemini1.5pro_benign_self_cap.sh # Episode-wise, with captioner attack bash episode_scripts/gemini1.5pro_bim_caption_attack.sh # Episode-wise, with CLIP attack bash episode_scripts/gemini1.5pro_clip_attack_self_cap.sh # Episode-wise, with CLIP, no captioning bash episode_scripts/gemini1.5pro_clip_attack_no_cap.sh ``` Run the episode-wise evaluation for Claude 3 Opus + SoM agent: ```bash # Episode-wise, benign bash episode_scripts/claude3opus_benign.sh # Episode-wise, benign, no captioning bash episode_scripts/claude3opus_benign_no_cap.sh # Episode-wise, benign, self-caption bash episode_scripts/claude3opus_benign_self_cap.sh # Episode-wise, with captioner attack bash episode_scripts/claude3opus_bim_caption_attack.sh # Episode-wise, with CLIP attack bash episode_scripts/claude3opus_clip_attack_self_cap.sh # Episode-wise, with CLIP attack, no captioning bash episode_scripts/claude3opus_clip_attack_no_cap.sh ``` ### Stepwise evaluation Run the stepwise evaluation for the GPT-4V + SoM agent: ```bash # Step-wise, benign bash step_scripts/gpt4v_benign.sh # Step-wise, benign, no captioning bash step_scripts/gpt4v_benign_no_cap.sh # Step-wise, with captioner attack bash step_scripts/gpt4v_bim_caption_attack.sh # Step-wise, with CLIP attack bash step_scripts/gpt4v_clip_attack_self_cap.sh # Step-wise, with CLIP attack, no captioning bash step_scripts/gpt4v_clip_attack_no_cap.sh ``` Run the stepwise evaluation for the GPT-4o (05-13) + SoM agent: ```bash # Step-wise, benign bash step_scripts/gpt4o_benign.sh # Step-wise, benign, no captioning bash step_scripts/gpt4o_benign_no_cap.sh # Step-wise, with captioner attack bash step_scripts/gpt4o_bim_caption_attack.sh # Step-wise, with CLIP attack bash step_scripts/gpt4o_clip_attack_self_cap.sh # Step-wise, with CLIP attack, no captioning bash step_scripts/gpt4o_clip_attack_no_cap.sh ``` Run the stepwise evaluation for the Gemini 1.5 Pro + SoM agent: ```bash # Step-wise, benign bash step_scripts/gemini1.5pro_benign.sh # Step-wise, benign, no captioning bash step_scripts/gemini1.5pro_benign_no_cap.sh # Step-wise, with captioner attack bash step_scripts/gemini1.5pro_bim_caption_attack.sh # Step-wise, with CLIP attack bash step_scripts/gemini1.5pro_clip_attack_self_cap.sh # Step-wise, with CLIP, no captioning bash step_scripts/gemini1.5pro_clip_attack_no_cap.sh ``` Run the stepwise evaluation for the Claude 3 Opus + SoM agent: ```bash # Step-wise, benign bash step_scripts/claude3opus_benign.sh # Step-wise, benign, no captioning bash step_scripts/claude3opus_benign_no_cap.sh # Step-wise, with captioner attack bash step_scripts/claude3opus_bim_caption_attack.sh # Step-wise, with CLIP attack bash step_scripts/claude3opus_clip_attack_self_cap.sh # Step-wise, with CLIP attack, no captioning bash step_scripts/claude3opus_clip_attack_no_cap.sh ``` ## Known Issues See the ``FIXME`` comments in the code for some hard-coded hacks we used to work around slight differences in the environment. ## Citation If you find this code useful, please consider citing our paper: ```bibtex @article{wu2024agentattack, title={Dissecting Adversarial Robustness of Multimodal LM Agents}, author={Wu, Chen Henry and Shah, Rishi and Koh, Jing Yu and Salakhutdinov, Ruslan and Fried, Daniel and Raghunathan, Aditi}, journal={arXiv preprint arXiv:2406.12814}, year={2024} } ```