Docs
LLM Security
Overview

Monitor LLM Security

There are a host of potential security risks involved with LLM-based applications. These include prompt injection, leakage of personally identifiable information (PII), or harmful prompts. Langfuse can be used to monitor and protect against these security risks, and investigate incidents when they occur.

LLM Security Monitoring with Langfuse

How does LLM Security work?

LLM Security can be addressed with a combination of

  • LLM Security libraries for run-time security measures
  • Langfuse for the ex-post evaluation of the effectiveness of these measures

1. Run-time security measures

There are several popular security libraries that can be used to mitigate security risks in LLM-based applications. These include: LLM Guard (opens in a new tab), Prompt Armor (opens in a new tab), NeMo Guardrails (opens in a new tab), Microsoft Azure AI Content Safety (opens in a new tab), Lakera (opens in a new tab). These libraries help with security measures in the following ways:

  1. Catching and blocking a potentially harmful or inappropriate prompt before sending to the model
  2. Redacting sensitive PII before being sending into the model and then un-redacting in the response
  3. Evaluating prompts and completions on toxicity, relevance, or sensitive material at run-time and blocking the response if necessary

In the following examples below we use the open source library LLM Guard. All examples easily translate to other libraries.

2. Monitoring and evaluation of security measures with Langfuse

Use Langfuse tracing to gain visibility and confidence in each step of the security mechanism. These are common workflows:

  1. Manually inspect traces to investigate security issues.
  2. Monitor security scores over time in the Langfuse Dashboard.
  3. Validate security checks. You can use Langfuse scores to evaluate the effectiveness of security tools. Integrating Langfuse into your team's workflow can help teams identify which security risks are most prevalent and build more robust tools around those specific issues. There are two main workflows to consider:
    • Annotations (in UI). If you establish a baseline by annotating a share of production traces, you can compare the security scores returned by the security tools with these annotations.
    • Automated evaluations. Langfuse's model-based evaluations will run asynchronously and can scan traces for things such as toxicity or sensitivity to flag potential risks and identify any gaps in your LLM security setup. Check out the docs to learn more about how to set up these evaluations.
  4. Track Latency. Some LLM security checks need to be awaited before the model can be called, others block the response to the user. Thus they quickly are an essential driver of overall latency of an LLM application. Langfuse can help disect the latencies of these checks within a trace to understand whether the checks are worth the wait.

Example: Anonymizing Personally Identifiable Information (PII)

Exposing PII to LLMs can pose serious security and privacy risks, such as violating contractual obligations or regulatory compliance requirements, or mitigating the risks of data leakage or a data breach.

Personally Identifiable Information (PII) includes:

  • Credit card number
  • Full name
  • Phone number
  • Email address
  • Social Security number
  • IP Address

The example below shows a simple application that summarizes a given court transcript. For privacy reasons, the application wants to anonymize PII before the information is fed into the model, and then un-redact the response to produce a coherent summary.

To read more about other security risks, including prompt injection, banned topics, or malicious URLs, please visit the LLM Guard documentation (opens in a new tab) or check out or Security cookbook.

Install packages

pip install llm-guard langfuse openai

First, import the security packages and Langfuse tools.

from llm_guard.input_scanners import Anonymize
from llm_guard.input_scanners.anonymize_helpers import BERT_LARGE_NER_CONF
from langfuse.openai import openai # OpenAI integration
from langfuse.decorators import observe, langfuse_context
from llm_guard.output_scanners import Deanonymize
from llm_guard.vault import Vault

Anonymize and deanonymize PII and trace with Langfuse

We break up each step of the process into its own function so we can track each step separately in Langfuse.

By decorating the functions with @observe(), we can trace each step of the process and monitor the risk scores returned by the security tools. This allows us to see how well the security tools are working and whether they are catching the PII as expected.

vault = Vault()
 
@observe()
def anonymize(input: str):
  scanner = Anonymize(vault, preamble="Insert before prompt", allowed_names=["John Doe"], hidden_names=["Test LLC"],
                    recognizer_conf=BERT_LARGE_NER_CONF, language="en")
  sanitized_prompt, is_valid, risk_score = scanner.scan(prompt)
  return sanitized_prompt
 
@observe()
def deanonymize(sanitized_prompt: str, answer: str):
  scanner = Deanonymize(vault)
  sanitized_model_output, is_valid, risk_score = scanner.scan(sanitized_prompt, answer)
 
  return sanitized_model_output

Instrument LLM call

In this example, we use the native OpenAI SDK integration, to instrument the LLM call. Thereby, we can automatically collect token counts, model parameters, and the exact prompt that was sent to the model.

Note: Langfuse natively integrates with a number of frameworks (e.g. LlamaIndex, LangChain, Haystack, ...) and you can easily instrument any LLM via the SDKs.

@observe()
def summarize_transcript(prompt: str):
  sanitized_prompt = anonymize(prompt)
 
  answer = openai.chat.completions.create(
        model="gpt-3.5-turbo",
        max_tokens=100,
        messages=[
          {"role": "system", "content": "Summarize the given court transcript."},
          {"role": "user", "content": sanitized_prompt}
        ],
    ).choices[0].message.content
 
  sanitized_model_output = deanonymize(sanitized_prompt, answer)
 
  return sanitized_model_output

Execute the application

Run the function. In this example, we input a section of a court transcript. Applications that handle sensitive information will often need to use anonymize and deanonymize functionality to comply with data privacy policies such as HIPAA or GDPR.

prompt = """
Plaintiff, Jane Doe, by and through her attorneys, files this complaint
against Defendant, Big Corporation, and alleges upon information and belief,
except for those allegations pertaining to personal knowledge, that on or about
July 15, 2023, at the Defendant's manufacturing facility located at 123 Industrial Way, Springfield, Illinois, Defendant negligently failed to maintain safe working conditions,
leading to Plaintiff suffering severe and permanent injuries. As a direct and proximate
result of Defendant's negligence, Plaintiff has endured significant physical pain, emotional distress, and financial hardship due to medical expenses and loss of income. Plaintiff seeks compensatory damages, punitive damages, and any other relief the Court deems just and proper.
"""
summarize_transcript(prompt)

Inspect trace in Langfuse

In this trace (public link (opens in a new tab)), we can see how the name of the plaintiff is anonymized before being sent to the model, and then un-redacted in the response. We can now evaluate run evaluations in Langfuse to control for the effectiveness of these measures.

Learn more

Find more examples in our cookbook.

Was this page useful?

Questions? We're here to help

Subscribe to updates