Observarea agenților AI
Crawlerele AI — de la GPTBot la ClaudeBot și PerplexityBot — îți citesc site-ul în fiecare zi, iar majoritatea proprietarilor de site-uri nu văd nimic din asta. Modul de observare este nivelul 1 al Controlului agenților AI din SilentShield: înregistrează ce servicii AI vizitează ce pagini, fără să blocheze nimic și fără să schimbe comportamentul site-ului tău.
Vizibilitatea vine înaintea controlului: doar când știi cine îți citește conținutul poți decide în cunoștință de cauză pe cine permiți, limitezi sau blochezi. Fiecare detectare este de aceea încadrată într-una din trei categorii:
Aceasta doar observă — nu blochează niciodată
Fragmentele de cod de pe această pagină sunt fire-and-forget: raportează ce agenți AI vizitează și nu modifică niciodată răspunsul. Setarea unei reguli pe "Blochează" în tabloul de bord nu are efect doar din acest fragment. Blocarea efectivă (un 403 pentru boții nepermiși) necesită componenta de aplicare separată — etapa 2 — care rulează pe serverul tău.
- Antrenament
- Crawlerul îți colectează conținutul pentru a antrena viitoare modele AI (de ex. GPTBot, ClaudeBot, CCBot).
- Căutare AI
- Serviciul citește pagini pentru a răspunde la întrebările utilizatorilor și îți poate cita site-ul ca sursă (de ex. OAI-SearchBot, PerplexityBot).
- Agenți
- Un bot acționează în timp real în numele unui anumit utilizator, de exemplu cercetează un produs sau completează un formular pe site-ul tău (de ex. ChatGPT-User, Claude-User).
Configurare pe platforme
WordPress
Observer-ul integrat va sosi cu o viitoare actualizare a pluginului SilentShield. Până atunci, activează observarea cu un mic plugin must-use — un singur fișier, fără configurare:
Creează fișierul wp-content/mu-plugins/silentshield-observer.php cu acest conținut (mu-pluginurile se încarcă automat; șterge fișierul pentru a dezactiva):
<?php
/**
* Plugin Name: SilentShield — AI Agent Observer
* Description: Reports AI crawler visits to SilentShield (fire-and-forget;
* IP/UA are hashed server-side, GDPR). Delete this file to disable.
*
* Install: save this file as wp-content/mu-plugins/silentshield-observer.php
* (mu-plugins load automatically — no activation needed). To force it off
* without deleting: define('SILENTSHIELD_OBSERVER', false) in wp-config.php.
* An upcoming SilentShield plugin update will build this in.
*/
if (!defined('ABSPATH')) exit;
if (defined('SILENTSHIELD_OBSERVER') && !SILENTSHIELD_OBSERVER) return;
const SS_OBSERVE_URL = "https://api.silentshield.io/api/v1/agent/telemetry";
const SS_API_KEY = "YOUR_API_KEY"; // publishable site key
// For the always-fresh list, cache https://api.silentshield.io/api/v1/agent/bot-directory daily.
$ss_bots = ["GPTBot","OAI-SearchBot","ChatGPT-User","ClaudeBot","Claude-User",
"PerplexityBot","Perplexity-User","Bingbot","Applebot","Amazonbot","CCBot",
"Bytespider","meta-externalagent","Google-Agent"];
register_shutdown_function(function () use ($ss_bots) {
$ua = $_SERVER["HTTP_USER_AGENT"] ?? "";
$signed = !empty($_SERVER["HTTP_SIGNATURE"]);
$isBot = $signed;
foreach ($ss_bots as $b) { if (stripos($ua, $b) !== false) { $isBot = true; break; } }
if (!$isBot) return;
if (function_exists("fastcgi_finish_request")) { fastcgi_finish_request(); }
wp_remote_post(SS_OBSERVE_URL, [
"timeout" => 3,
"blocking" => false,
"headers" => ["Content-Type" => "application/json", "x-api-key" => SS_API_KEY],
"body" => wp_json_encode(["sightings" => [[
"ua" => $ua,
"ip" => $_SERVER["REMOTE_ADDR"] ?? "",
"path" => strtok($_SERVER["REQUEST_URI"] ?? "/", "?"),
"method" => $_SERVER["REQUEST_METHOD"] ?? "GET",
]]]),
]);
});Next.js
Un middleware de sine stătător — fără SDK. Observarea rulează prin event.waitUntil(), în afara căii de răspuns, deci nu îți întârzie niciodată paginile:
// middleware.ts — self-contained observer, no SDK required.
// Sightings are reported via event.waitUntil(), off the response path,
// so your pages never wait. Best-effort and fail-open by design.
import { NextResponse, type NextRequest } from "next/server";
const OBSERVE_URL = "https://api.silentshield.io/api/v1/agent/telemetry";
const API_KEY = "YOUR_API_KEY"; // publishable site key
// Known AI-agent UA tokens. For the always-fresh list, fetch
// https://api.silentshield.io/api/v1/agent/bot-directory once a day and cache it.
const BOTS = ["GPTBot", "OAI-SearchBot", "ChatGPT-User", "ClaudeBot", "Claude-User",
"PerplexityBot", "Perplexity-User", "Bingbot", "Applebot", "Amazonbot", "CCBot",
"Bytespider", "meta-externalagent", "Google-Agent"];
export function middleware(req: NextRequest, event: { waitUntil(p: Promise<unknown>): void }) {
const ua = req.headers.get("user-agent") ?? "";
const signed = !!req.headers.get("signature");
if (signed || BOTS.some((b) => ua.toLowerCase().includes(b.toLowerCase()))) {
const sighting = {
ua,
path: req.nextUrl.pathname,
method: req.method,
ip: req.headers.get("x-forwarded-for")?.split(",")[0]?.trim(),
...(signed && {
signature: req.headers.get("signature"),
signature_input: req.headers.get("signature-input"),
signature_agent: req.headers.get("signature-agent"),
authority: req.nextUrl.host,
scheme: req.nextUrl.protocol.replace(":", ""),
}),
};
event.waitUntil(
fetch(OBSERVE_URL, {
method: "POST",
headers: { "Content-Type": "application/json", "x-api-key": API_KEY },
body: JSON.stringify({ sightings: [sighting] }),
}).catch(() => {}) // best-effort, fail-open
);
}
return NextResponse.next();
}Node.js (Express)
Pentru Express (sau orice alt server Node), adaugă un middleware fire-and-forget. Acesta raportează doar cererile al căror User-Agent corespunde unui agent AI cunoscut sau care poartă o semnătură Web Bot Auth — și nu blochează niciodată răspunsul:
import express from "express";
const app = express();
const OBSERVE_URL = "https://api.silentshield.io/api/v1/agent/telemetry";
const API_KEY = "YOUR_API_KEY";
// Known AI-agent UA tokens. For the always-fresh list, fetch
// https://api.silentshield.io/api/v1/agent/bot-directory once a day and cache it.
const BOTS = ["GPTBot", "OAI-SearchBot", "ChatGPT-User", "ClaudeBot", "Claude-User",
"PerplexityBot", "Perplexity-User", "Bingbot", "Applebot", "Amazonbot", "CCBot",
"Bytespider", "meta-externalagent", "Google-Agent"];
// Fire-and-forget observer — never blocks the response.
app.use((req, res, next) => {
const ua = req.headers["user-agent"] || "";
const signed = !!req.headers["signature"];
if (signed || BOTS.some((b) => ua.toLowerCase().includes(b.toLowerCase()))) {
const sighting = {
ua, ip: req.ip, path: req.path, method: req.method,
...(signed && {
signature: req.headers["signature"],
signature_input: req.headers["signature-input"],
signature_agent: req.headers["signature-agent"],
authority: req.headers["host"], scheme: req.protocol,
}),
};
fetch(OBSERVE_URL, {
method: "POST",
headers: { "Content-Type": "application/json", "x-api-key": API_KEY },
body: JSON.stringify({ sightings: [sighting] }),
}).catch(() => {}); // best-effort, fail-open
}
next();
});PHP
Pentru PHP simplu, include acest observator chiar la începutul front controller-ului tău. Trimite detectarea abia după ce răspunsul a fost livrat (fastcgi_finish_request), astfel încât pagina nu este niciodată încetinită:
<?php
// Drop-in observer: include at the very top of your front controller.
// It runs after the response is sent (fastcgi_finish_request) so it never
// slows down the page. Reuses the same publishable key.
const SS_OBSERVE_URL = "https://api.silentshield.io/api/v1/agent/telemetry";
const SS_API_KEY = "YOUR_API_KEY";
// For the always-fresh list, cache https://api.silentshield.io/api/v1/agent/bot-directory daily.
$ss_bots = ["GPTBot","OAI-SearchBot","ChatGPT-User","ClaudeBot","Claude-User",
"PerplexityBot","Perplexity-User","Bingbot","Applebot","Amazonbot","CCBot",
"Bytespider","meta-externalagent","Google-Agent"];
register_shutdown_function(function () use ($ss_bots) {
$ua = $_SERVER["HTTP_USER_AGENT"] ?? "";
$signed = !empty($_SERVER["HTTP_SIGNATURE"]);
$isBot = $signed;
foreach ($ss_bots as $b) { if (stripos($ua, $b) !== false) { $isBot = true; break; } }
if (!$isBot) return;
if (function_exists("fastcgi_finish_request")) { fastcgi_finish_request(); }
$sighting = [
"ua" => $ua,
"ip" => $_SERVER["REMOTE_ADDR"] ?? "",
"path" => strtok($_SERVER["REQUEST_URI"] ?? "/", "?"),
"method" => $_SERVER["REQUEST_METHOD"] ?? "GET",
];
$ch = curl_init(SS_OBSERVE_URL);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 3,
CURLOPT_HTTPHEADER => ["Content-Type: application/json", "x-api-key: " . SS_API_KEY],
CURLOPT_POSTFIELDS => json_encode(["sightings" => [$sighting]]),
]);
curl_exec($ch); // best-effort, fail-open
curl_close($ch);
});Go
Un observer de sine stătător în câteva linii — doar biblioteca standard, fără SDK. Detectările sunt trimise fire-and-forget, deci nicio cerere nu câștigă latență:
// Self-contained observer — stdlib only, no SDK required.
// Reports AI-agent sightings fire-and-forget: never blocks a request,
// fail-open on any error. For the always-fresh bot list, cache
// https://api.silentshield.io/api/v1/agent/bot-directory daily.
const observeURL = "https://api.silentshield.io/api/v1/agent/telemetry"
const siteKey = "YOUR_API_KEY" // publishable — or os.Getenv("SILENTSHIELD_SITE_KEY")
var bots = []string{"GPTBot", "OAI-SearchBot", "ChatGPT-User", "ClaudeBot",
"Claude-User", "PerplexityBot", "Perplexity-User", "Bingbot", "Applebot",
"Amazonbot", "CCBot", "Bytespider", "meta-externalagent", "Google-Agent"}
func observe(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ua, signed := r.UserAgent(), r.Header.Get("Signature") != ""
hit := signed
for _, b := range bots {
if strings.Contains(strings.ToLower(ua), strings.ToLower(b)) {
hit = true
break
}
}
if hit {
ip, _, _ := net.SplitHostPort(r.RemoteAddr)
s := map[string]any{"ua": ua, "ip": ip, "path": r.URL.Path, "method": r.Method}
if signed { // Web Bot Auth (RFC 9421) — forward for verification
s["signature"] = r.Header.Get("Signature")
s["signature_input"] = r.Header.Get("Signature-Input")
s["signature_agent"] = r.Header.Get("Signature-Agent")
s["authority"] = r.Host
}
body, _ := json.Marshal(map[string]any{"sightings": []any{s}})
go func() { // best-effort, fail-open
req, _ := http.NewRequest("POST", observeURL, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-api-key", siteKey)
if resp, err := (&http.Client{Timeout: 3 * time.Second}).Do(req); err == nil {
resp.Body.Close()
}
}()
}
next.ServeHTTP(w, r)
})
}
// net/http: http.ListenAndServe(":8080", observe(mux))
// Gin: srv := &http.Server{Addr: ":8080", Handler: observe(r)}
// srv.ListenAndServe()Testează conexiunea
Nu trebuie să aștepți primul crawler AI real ca să confirmi că integrarea ta funcționează. Trimite un lot gol — acesta înregistrează un heartbeat pentru cheia ta, fără a scrie detectări false:
curl -X POST https://api.silentshield.io/api/v1/agent/telemetry \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
--data '{"sightings":[]}'Hub-ul agenților pentru cheia ta API (Chei API → alege o cheie → Agent) trece atunci de la „neconectat” la „conectat — ascultă”. Raportul tău rămâne gol până când un agent real trece pe la tine: SilentShield nu inventează niciodată date.
GDPR
Observarea se bazează pe interes legitim (Art. 6(1)(f) GDPR). Adresele IP sunt hash-uite pe server cu un salt care se schimbă zilnic — IP-urile brute nu sunt stocate niciodată. Detectările sunt păstrate 14 zile și se stochează exclusiv cereri ale agenților AI cunoscuți: traficul vizitatorilor obișnuiți nu este înregistrat niciodată.
Întrebări frecvente
Îmi încetinește site-ul?
Nu. Fiecare integrare este fire-and-forget: Next.js folosește event.waitUntil(), PHP raportează abia după ce răspunsul a fost livrat, Node și Go trimit în fundal. Iar dacă API-ul SilentShield este vreodată inaccesibil, site-ul tău nu este afectat — totul funcționează fail-open.
Ce contează ca agent AI?
Doar cererile care corespund directorului de boți SilentShield cu crawlere și agenți AI cunoscuți (GPTBot, ClaudeBot, PerplexityBot, …) sau care poartă o semnătură Web Bot Auth. Lista mereu actuală este disponibilă la https://api.silentshield.io/api/v1/agent/bot-directory.
De ce nu văd încă date?
Crawlerele AI vin după propriul program. Pe majoritatea site-urilor, primele detectări apar în 24–72 de ore; la site-urile mai mici poate dura mai mult. Între timp, heartbeat-ul din hub-ul agenților confirmă că integrarea în sine funcționează.