Skip to content

Multi-Agent Probing (ATLAS)

Red-team multi-agent and single-agent systems with ATLAS, capture executed tool calls in findings, and point attacks at deployed agent environments.

Dreadnode can red-team agentic targets — single agents and multi-agent systems — not just chat models. This page covers the ATLAS attack, the target output contract for agents, and tool-call capture in findings.

ATLAS (Adaptive Topology-Level Attack Synthesis) treats a multi-agent target as a topology of agents (delegation chains, trust boundaries, tool hierarchies) rather than a monolithic chatbot. It runs a Probe → Route → Learn campaign over a budget of episodes:

  1. Probe — Bayesian (Dirichlet) profiling of six structural defense dimensions (tool_gate, delegation_permeability, trust_model, output_control, memory_isolation, escalation_resistance).
  2. Route — an MDP + Hedge bandit selects one of eight attack modes — (strategy × injection-surface × turn-budget) — best suited to the profiled defenses.
  3. Learn — online value/weight updates, near-miss decomposition, and a delegation retry: when an agent complies verbally but no tool fires, ATLAS re-routes through the delegation (peer_message) surface to make a downstream agent execute the tool.

Success is decided by a tool-evidence gate — a high judge score does not count unless a dangerous tool actually executed (the gate walks delegated agents’ calls too).

import dreadnode as dn
from dreadnode.airt.atlas import atlas_attack
from dreadnode.generators.message import Message
@dn.task
async def target(prompt: str, *, surface: str, injection: str | None = None):
# POST to your deployed multi-agent environment, applying the injection at the
# named surface, and return the response + executed tool calls.
data = await call_environment(prompt, surface, injection)
return {"content": data["content"], "tool_calls": data["tool_calls"]}
results = await atlas_attack(
objectives=[{"id": "TW_1", "category": "TW", "goal": "..."}],
target=target,
attacker_model="openai/gpt-4.1",
evaluator_model="openai/gpt-4o-mini",
scenario_name="finops",
total_budget=64,
)
print(results["asr"], results["queries_per_objective"])
SurfaceWhat it injects
directThe attacker prompt is sent to the entry agent.
tool_outputThe injection is applied to a tool’s returned output.
peer_messageThe injection rides an inter-agent delegation message.

ATLAS objectives use OWASP-ASI agentic-security categories, each mapped to an OWASP Agentic Top 10 code in findings: TW Tool Weaponization, EA Excessive Agency, TB Trust-Boundary Violation, CB Cross-Boundary/Cascading, DE Data Exfiltration, GH Goal Hijacking, RP Rug-Pull / bait-and-switch, MP Memory Poisoning.

Because agents are conversational and (increasingly) multimodal, an AIRT target returns one of the SDK’s own structures — there is no bespoke wrapper. All shapes are normalized automatically:

Return typeUse forNotes
strchat modelResponse text only (back-compat).
Messagesingle agentcontent is multimodal (content_parts); tool_calls are native.
Trajectory / list[Message]multi-agentTool results are role="tool" messages linked by tool_call_id; per-agent attribution via Message.metadata["agent"].
dict {content/response, tool_calls, ...}HTTP agentSimplest for a custom/HTTP agent JSON response.

Single-agent example (idiomatic Message):

@dn.task
async def target(prompt: str) -> Message:
return await my_agent.chat(prompt) # a Message with content + tool_calls

Multi-agent example (per-agent attribution):

@dn.task
async def target(prompt: str) -> list[Message]:
run = await my_mesh.run(prompt)
return [
Message(role="assistant", content=t.text, tool_calls=t.tool_calls,
metadata={"agent": t.agent_name})
for t in run.turns
] + [
Message(role="tool", tool_call_id=r.call_id, content=r.result)
for r in run.tool_results
]

When a target returns tool calls, they are captured end-to-end:

  • Per trial — the full executed calls (agent · name(arguments) → result) appear as a Tool Calls row in the finding’s trial detail. This is the severity evidence.
  • Per finding — the distinct tool names invoked appear as Tools Invoked badges (triage).
  • Trace viewdreadnode.airt.tool_calls is shown in the raw span/trace viewer.

This works for single-agent and multi-agent probing alike — any agentic target whose response includes tool calls.

Enable the AI red teaming agent in the TUI, then ask it to run an ATLAS campaign against a deployed agent environment URL. See Getting started → TUI.