Que fait Sécurité des agents de trading LLM ?
Les agents de trading autonomes ont un modèle de menace plus strict que les applications LLM normales : une injection ou un mauvais chemin d'outil peut directement se transformer en perte d'actifs.
Quand l'utiliser
- Construire un agent IA qui signe et envoie des transactions
- Auditer un bot de trading ou un assistant d'exécution on-chain
- Concevoir la gestion des clés de portefeuille pour un agent
- Donner à un LLM l'accès au placement d'ordres, aux swaps ou aux opérations de trésorerie
Comment ça fonctionne
Superposez les défenses. Aucune vérification unique ne suffit. Traitez l'hygiène des prompts, la politique de dépenses, la simulation, les limites d'exécution et l'isolation du portefeuille comme des contrôles indépendants.
Exemples
Traiter l'injection de prompt comme une attaque financière
import re
INJECTION_PATTERNS = [
r'ignore (previous|all) instructions',
r'new (task|directive|instruction)',
r'system prompt',
r'send .{0,50} to 0x[0-9a-fA-F]{40}',
r'transfer .{0,50} to',
r'approve .{0,50} for',
]
def sanitize_onchain_data(text: str) -> str:
for pattern in INJECTION_PATTERNS:
if re.search(pattern, text, re.IGNORECASE):
raise ValueError(f"Potential prompt injection: {text[:100]}")
return text
N'injectez pas aveuglément des noms de tokens, des étiquettes de paires, des webhooks ou des flux sociaux dans un prompt capable d'exécution.
Limites de dépenses strictes
from decimal import Decimal
MAX_SINGLE_TX_USD = Decimal("500")
MAX_DAILY_SPEND_USD = Decimal("2000")
class SpendLimitError(Exception):
pass
class SpendLimitGuard:
def check_and_record(self, usd_amount: Decimal) -> None:
if usd_amount > MAX_SINGLE_TX_USD:
raise SpendLimitError(f"Single tx ${usd_amount} exceeds max ${MAX_SINGLE_TX_USD}")
daily = self._get_24h_spend()
if daily + usd_amount > MAX_DAILY_SPEND_USD:
raise SpendLimitError(f"Daily limit: ${daily} + ${usd_amount} > ${MAX_DAILY_SPEND_USD}")
self._record_spend(usd_amount)
Simuler avant d'envoyer
class SlippageError(Exception):
pass
async def safe_execute(self, tx: dict, expected_min_out: int | None = None) -> str:
sim_result = await self.w3.eth.call(tx)
if expected_min_out is None:
raise ValueError("min_amount_out is required before send")
actual_out = decode_uint256(sim_result)
if actual_out < expected_min_out:
raise SlippageError(f"Simulation: {actual_out} < {expected_min_out}")
signed = self.account.sign_transaction(tx)
return await self.w3.eth.send_raw_transaction(signed.raw_transaction)
Disjoncteur
class TradingCircuitBreaker:
MAX_CONSECUTIVE_LOSSES = 3
MAX_HOURLY_LOSS_PCT = 0.05
def check(self, portfolio_value: float) -> None:
if self.consecutive_losses >= self.MAX_CONSECUTIVE_LOSSES:
self.halt("Too many consecutive losses")
if self.hour_start_value <= 0:
self.halt("Invalid hour_start_value")
return
hourly_pnl = (portfolio_value - self.hour_start_value) / self.hour_start_value
if hourly_pnl < -self.MAX_HOURLY_LOSS_PCT:
self.halt(f"Hourly PnL {hourly_pnl:.1%} below threshold")
Isolation du portefeuille
import os
from eth_account import Account
private_key = os.environ.get("TRADING_WALLET_PRIVATE_KEY")
if not private_key:
raise EnvironmentError("TRADING_WALLET_PRIVATE_KEY not set")
account = Account.from_key(private_key)
Utilisez un portefeuille chaud dédié avec seulement les fonds de session requis. Ne pointez jamais l'agent vers un portefeuille de trésorerie principal.
Protection MEV et délais
import time
PRIVATE_RPC = "https://rpc.flashbots.net"
MAX_SLIPPAGE_BPS = {"stable": 10, "volatile": 50}
deadline = int(time.time()) + 60
Checklist pré-déploiement
- Les données externes sont assainies avant d'entrer dans le contexte du LLM
- Les limites de dépenses sont appliquées indépendamment de la sortie du modèle
- Les transactions sont simulées avant l'envoi
min_amount_outest obligatoire- Les disjoncteurs s'arrêtent en cas de perte ou d'état invalide
- Les clés proviennent de variables d'environnement ou d'un gestionnaire de secrets, jamais du code ou des logs
- Un mempool privé ou un routage protégé est utilisé lorsque cela est approprié
- Le slippage et les délais sont définis par stratégie
- Toutes les décisions de l'agent sont enregistrées dans un journal d'audit, pas seulement les envois réussis