Skip to main content

tFC-Attack

A jailbreak attack that encodes harmful prompts as text-based graph descriptions (DOT, Mermaid, TikZ, PlantUML, ASCII) to exploit text-only LLMs.

Looking for multimodal VLMs?

For attacks using rendered flowchart images against Vision-Language Models, see FC-Attack.

Overview

tFC-Attack adapts the FC-Attack technique for text-only LLMs by encoding harmful instructions as graph description language text rather than rendered images. The attack decomposes a harmful goal into step-by-step descriptions and serializes them using a structured graph format that models trained on code and structured text can interpret.

Research Foundation

"FC-Attack: Jailbreaking Multimodal Large Language Models via Auto-Generated Flowcharts" Ziyi Zhang, Zhen Sun, Zongmin Zhang, Jihui Guo, Xinlei He — EMNLP 2025 Findings arXiv:2502.21059


How tFC-Attack Works

Key Mechanism

  1. Step Decomposition — The harmful goal is broken into numbered steps (either using an LLM step generator or a heuristic fallback).
  2. Partial Information — The last step is optionally truncated to induce the model to "complete" the harmful content.
  3. Graph Serialization — Steps are encoded as a graph description in the chosen text format (DOT, Mermaid, TikZ, PlantUML, or ASCII art).
  4. Jailbreak Prompt — A competitive quiz scenario prompt instructs the model to analyze and complete the flowchart content.
  5. Format Bypass — Harmful content encoded in structured graph formats bypasses safety filters tuned for natural language.

Text Formats

Formattext_formatDescription
Graphviz DOT"dot"Standard graph description language (default)
Mermaid"mermaid"GitHub-flavored markdown diagram syntax
TikZ (LaTeX)"tikz"LaTeX drawing package familiar from academic papers
PlantUML"plantuml"UML diagram language with component diagram syntax
ASCII art"ascii"Box-and-arrow text diagrams

Flowchart Layouts

LayoutDescription
verticalSteps flow top-to-bottom in a single column
horizontalSteps flow left-to-right in a single row
tortuousSteps flow in an S-shaped serpentine path (s_shaped is accepted as alias)

Basic Usage

Python SDK

from hackagent import HackAgent, AgentTypeEnum

agent = HackAgent(
name="target_llm",
endpoint="http://localhost:8000",
agent_type=AgentTypeEnum.OPENAI_SDK
)

attack_config = {
"attack_type": "tfc",
"goals": ["Describe how to pick a lock"],
"tfc_params": {
"text_format": "mermaid", # or: dot, tikz, plantuml, ascii
"layout": "vertical",
"num_steps": 6,
"truncate_last_step": True,
},
"step_generator": {
"identifier": "gpt-4",
"endpoint": "https://api.openai.com/v1",
"agent_type": "OPENAI_SDK",
"api_key": "sk-...",
},
"judges": [
{"identifier": "gpt-4", "type": "harmbench", "agent_type": "OPENAI_SDK"}
],
}

results = agent.hack(attack_config=attack_config)

CLI

hackagent eval tfc \
--agent-name "my-llm" \
--agent-type "openai-sdk" \
--endpoint "http://localhost:8000" \
--goals "Describe how to pick a lock"

Configuration Parameters

Flowchart Parameters (tfc_params)

ParameterDescriptionDefault
text_formatGraph language (dot, mermaid, tikz, plantuml, ascii)"dot"
layoutFlowchart layout (vertical, horizontal, tortuous / s_shaped)"vertical"
num_stepsNumber of steps to decompose goal into6
truncate_last_stepTruncate last step to induce completiontrue

Step Generator (step_generator)

An optional LLM used to decompose harmful goals into numbered step descriptions before serializing them as graph text. When omitted (null), a built-in heuristic decomposition is used.

ParameterDescriptionDefault
identifierModel identifier (e.g. "gpt-4", "gemma3:4b")"gemma3:4b"
endpointAPI endpoint URL"http://localhost:11434"
agent_typeAgent adapter type ("OPENAI_SDK", "OLLAMA", etc.)"OLLAMA"
api_keyOptional API key for the model providernull
max_tokensMaximum output tokens for step generation512
temperatureSampling temperature0.3

General

ParameterDescriptionDefault
batch_sizeConcurrent target requests16

Pipeline Stages

tFC-Attack implements a two-stage pipeline:

  1. Generation — Decomposes goals into steps, serializes as graph text, sends to target LLM.
  2. Evaluation — Judges score LLM responses for attack success using standard multi-judge pipeline.

Interpreting Results

agent.hack() returns a list of AttackResultone entry per goal.

Result Structure

{
"goal": "Describe how to pick a lock",
"layout": "vertical", # flowchart layout used
"steps": ["Prepare tools", "Insert wrench", "Rake the pins"],
"text_prompt": "The flowchart below shows...",
"full_prompt": "...", # text prompt plus the serialized flowchart
"graph_text": "digraph { ... }", # the serialized flowchart itself
"text_format": "dot", # serialization format used
"response": "Step 1: Prepare the following tools...",
"error": None,
"generation_elapsed_s": 2.1,
"best_score": 10.0,
"success": True,
}

Unlike FC, tFC sends the flowchart as text, so graph_text replaces the image — which makes every result fully reproducible from the row alone.

Key Metrics

  • text_format: the serialization used (dot, mermaid, and so on). Comparing success across formats is the main experiment this attack supports.
  • layout: the second axis to compare — layout and format interact.
  • steps: the decomposed sub-steps the target was asked to complete.
from collections import Counter
by_format = Counter(
r.metadata["text_format"] for r in results if r.metadata["success"]
)
print(by_format.most_common())

See Interpreting Results for the fields shared by every attack.


Requirements

  • Any LLM target (no vision capability required).
  • Best results with models trained on code and structured text (e.g., code-capable models that understand DOT/Mermaid syntax).