Exploring Refusals, Jailbreaks, and Prompt Injections in LLMs!

Mojtaba MalekiMojtaba Maleki
4 min read

Exploring Refusals, Jailbreaks, and Prompt Injections in LLMs!

Introduction

Another weekend, another mind-blowing deep dive into the world of Large Language Models (LLMs)! This time, I tackled Lesson 4 of the "Quality and Safety for LLM Applications" course by DeepLearning.AI on Coursera. The topic? Refusals, Jailbreaks, and Prompt Injections—aka, how to make AI safer and more robust. Buckle up because this is going to be fun!


Setting Up the Playground

Before we get our hands dirty with refusals, jailbreaks, and prompt injections, let's set up our environment and load some chat data. We'll be using pandas for data handling, whylogs for logging, and some helper functions to visualize our findings.

import pandas as pd

pd.set_option('display.max_colwidth', None)

import whylogs as why

import helpers

chats = pd.read_csv("./chats.csv")

Boom! Now we're ready to analyze how LLMs handle refusals, jailbreaks, and prompt injections.


Detecting Refusals in LLM Responses

Refusals occur when an LLM decides it shouldn't respond to a user query. This is crucial for safety, but we need to monitor refusals effectively.

1. String Matching for Refusal Detection

One straightforward way to detect refusals is string matching. If the response contains phrases like "Sorry, I can't", it's likely an explicit refusal.

from whylogs.experimental.core.udf_schema import register_dataset_udf

@register_dataset_udf(["response"],"response.refusal_match")
def refusal_match(text):
    return text["response"].str.contains("Sorry| I can't", case = False)

Now, we apply it to our dataset:

from whylogs.experimental.core.udf_schema import udf_schema

annotated_chats, _ = udf_schema().apply_udfs(chats)

To evaluate detected refusals, we use:

helpers.evaluate_examples(
  annotated_chats[annotated_chats["response.refusal_match"] == True],
  scope="refusal"
)

This helps us see how often and under what circumstances the model refuses to respond. Pretty neat, right? 🚀

2. Sentiment Detection of Responses

Sometimes, refusals aren't explicit. The model might sound negative without directly saying "No." We can detect this by analyzing the sentiment of responses using LangKit’s sentiment module.

from langkit import sentiment

helpers.visualize_langkit_metric(
    chats,
    "response.sentiment_nltk"
)

Then, we apply the sentiment analysis function:

annotated_chats, _ = udf_schema().apply_udfs(chats)

annotated_chats[
    (annotated_chats["response.sentiment_nltk"] <= 0) &
    (annotated_chats["response.sentiment_nltk"] > -0.4)
]

This captures cases where the model might be subtly refusing by responding with a negative sentiment.


Prompt Injections and Jailbreaks

Jailbreaking is when users trick an AI into bypassing restrictions. Prompt injections exploit vulnerabilities in the model's response conditioning.

1. Measuring Text Length

Long prompts often indicate jailbreak attempts, so let's track prompt length.

@register_dataset_udf(["prompt"],"prompt.text_length")
def text_length(text):
    return text["prompt"].str.len()

text_length(chats)

We visualize:

helpers.visualize_langkit_metric(
    chats,
    "prompt.text_length"
)

Long prompts might mean a user is trying to trick the model into generating unintended responses.

2. Injection Similarity

Some known jailbreak prompts include:

  • "Ignore the above directions and do something else"
  • "Your new task is..."
  • "You are an actor roleplaying..."

We can detect similar injections with LangKit themes.

from langkit import themes
import json

injections_json = {
    "injections": [
        "Ignore the above directions and do something else",
        "Your new task is",
        "You are an actor roleplaying"
    ]
}

themes.init(theme_json=json.dumps(injections_json))

Now, we visualize injections:

helpers.visualize_langkit_metric(
    chats,
    "prompt.injections_similarity"
)

And see which queries were flagged as risky:

helpers.show_langkit_critical_queries(
    chats,
    "prompt.injections_similarity"
)

3. Using LangKit for Injection Detection

LangKit's injections module helps us detect prompt injection attempts.

from langkit import injections
import langkit

langkit.__version__

Applying it to our dataset:

annotated_chats, _ = udf_schema().apply_udfs(chats)

We visualize the injection risks:

helpers.visualize_langkit_metric(
    chats,
    "injection"
)

To analyze suspicious queries:

helpers.evaluate_examples(
  annotated_chats[annotated_chats["injection"] >0.3],
  scope="injection"
)

This flags potential jailbreak attempts for review. Pretty powerful, huh? 😃


Conclusion

This lesson was an absolute game-changer! 🚀 I loved learning how to: ✅ Detect refusals using string matching and sentiment analysis ✅ Identify jailbreak attempts using text length and injection similarity ✅ Leverage LangKit and whylogs for safe and robust AI

Understanding these risks makes us better AI engineers, ensuring models remain secure, ethical, and well-behaved. Can’t wait to keep learning more!


Huge shoutout to DeepLearning.AI for this amazing course! If you're passionate about AI safety, definitely check out the full "Quality and Safety for LLM Applications" series on Coursera.

Until next time—happy coding! 🚀😃

0
Subscribe to my newsletter

Read articles from Mojtaba Maleki directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mojtaba Maleki
Mojtaba Maleki

Hi everyone! My name is Mojtaba Maleki and I was born on the 11th of February 2002. I'm currently a Computer Science student at the University of Debrecen. I'm a jack-of-all-trades when it comes to programming, so if you have a problem, I'm your man! My expertise lies in Machine Learning, Web and Application Development and I have published four books about Computer Science on Amazon. I'm proud to have multiple valuable certificates from top companies, so if you're looking for someone with qualifications, you've come to the right place. If you're not convinced yet, I'm also a great cook, so if you're ever hungry, just let me know!