SDK REST Azure AI Content Safety pour TypeScript
Analysez du texte et des images pour détecter du contenu nuisible avec des listes de blocage personnalisables.
Installation
npm install @azure-rest/ai-content-safety @azure/identity @azure/core-auth
Variables d'environnement
CONTENT_SAFETY_ENDPOINT=https://<resource>.cognitiveservices.azure.com
CONTENT_SAFETY_KEY=<api-key>
AZURE_TOKEN_CREDENTIALS=prod # Requis uniquement si DefaultAzureCredential est utilisé en production
Authentification
Important : ceci est un client REST. ContentSafetyClient est une fonction, pas une classe.
Clé API
import ContentSafetyClient from "@azure-rest/ai-content-safety";
import { AzureKeyCredential } from "@azure/core-auth";
const client = ContentSafetyClient(
process.env.CONTENT_SAFETY_ENDPOINT!,
new AzureKeyCredential(process.env.CONTENT_SAFETY_KEY!)
);
DefaultAzureCredential
import ContentSafetyClient from "@azure-rest/ai-content-safety";
import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity";
// Dev local : DefaultAzureCredential. Production : définissez AZURE_TOKEN_CREDENTIALS=prod ou AZURE_TOKEN_CREDENTIALS=<specific_credential>
const credential = new DefaultAzureCredential({requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"]});
// Ou utilisez une identifiant spécifique directement en production :
// Voir https://learn.microsoft.com/javascript/api/overview/azure/identity-readme?view=azure-node-latest#credential-classes
// const credential = new ManagedIdentityCredential();
const client = ContentSafetyClient(
process.env.CONTENT_SAFETY_ENDPOINT!,
credential
);
Analyser du texte
import ContentSafetyClient, { isUnexpected } from "@azure-rest/ai-content-safety";
const result = await client.path("/text:analyze").post({
body: {
text: "Contenu textuel à analyser",
categories: ["Hate", "Sexual", "Violence", "SelfHarm"],
outputType: "FourSeverityLevels" // ou "EightSeverityLevels"
}
});
if (isUnexpected(result)) {
throw result.body;
}
for (const analysis of result.body.categoriesAnalysis) {
console.log(`${analysis.category}: sévérité ${analysis.severity}`);
}
Analyser une image
Contenu Base64
import { readFileSync } from "node:fs";
const imageBuffer = readFileSync("./image.png");
const base64Image = imageBuffer.toString("base64");
const result = await client.path("/image:analyze").post({
body: {
image: { content: base64Image }
}
});
if (isUnexpected(result)) {
throw result.body;
}
for (const analysis of result.body.categoriesAnalysis) {
console.log(`${analysis.category}: sévérité ${analysis.severity}`);
}
URL Blob
const result = await client.path("/image:analyze").post({
body: {
image: { blobUrl: "https://storage.blob.core.windows.net/container/image.png" }
}
});
Gestion des listes de blocage
Créer une liste de blocage
const result = await client
.path("/text/blocklists/{blocklistName}", "my-blocklist")
.patch({
contentType: "application/merge-patch+json",
body: {
description: "Liste de blocage personnalisée pour les termes interdits"
}
});
if (isUnexpected(result)) {
throw result.body;
}
console.log(`Créée : ${result.body.blocklistName}`);
Ajouter des éléments à une liste de blocage
const result = await client
.path("/text/blocklists/{blocklistName}:addOrUpdateBlocklistItems", "my-blocklist")
.post({
body: {
blocklistItems: [
{ text: "prohibited-term-1", description: "Premier terme bloqué" },
{ text: "prohibited-term-2", description: "Deuxième terme bloqué" }
]
}
});
if (isUnexpected(result)) {
throw result.body;
}
for (const item of result.body.blocklistItems ?? []) {
console.log(`Ajouté : ${item.blocklistItemId}`);
}
Analyser avec une liste de blocage
const result = await client.path("/text:analyze").post({
body: {
text: "Texte qui pourrait contenir des termes bloqués",
blocklistNames: ["my-blocklist"],
haltOnBlocklistHit: false
}
});
if (isUnexpected(result)) {
throw result.body;
}
// Vérifier les correspondances de liste de blocage
if (result.body.blocklistsMatch) {
for (const match of result.body.blocklistsMatch) {
console.log(`Bloqué : "${match.blocklistItemText}" depuis ${match.blocklistName}`);
}
}
Lister les listes de blocage
const result = await client.path("/text/blocklists").get();
if (isUnexpected(result)) {
throw result.body;
}
for (const blocklist of result.body.value ?? []) {
console.log(`${blocklist.blocklistName}: ${blocklist.description}`);
}
Supprimer une liste de blocage
await client.path("/text/blocklists/{blocklistName}", "my-blocklist").delete();
Catégories de contenu nuisible
| Catégorie | Terme API | Description |
|---|---|---|
| Discours haineux et équité | Hate |
Langage discriminatoire ciblant les groupes d'identité |
| Contenu sexuel | Sexual |
Contenu sexuel, nudité, pornographie |
| Violence | Violence |
Dommages physiques, armes, terrorisme |
| Automutilation | SelfHarm |
Automutilation, suicide, troubles alimentaires |
Niveaux de sévérité
| Niveau | Risque | Action recommandée |
|---|---|---|
| 0 | Sûr | Autoriser |
| 2 | Faible | Examiner ou autoriser avec avertissement |
| 4 | Moyen | Bloquer ou demander un examen manuel |
| 6 | Élevé | Bloquer immédiatement |
Types de sortie :
FourSeverityLevels(par défaut) : renvoie 0, 2, 4, 6EightSeverityLevels: renvoie 0-7
Assistant de modération de contenu
import ContentSafetyClient, {
isUnexpected,
TextCategoriesAnalysisOutput
} from "@azure-rest/ai-content-safety";
interface ModerationResult {
isAllowed: boolean;
flaggedCategories: string[];
maxSeverity: number;
blocklistMatches: string[];
}
async function moderateContent(
client: ReturnType<typeof ContentSafetyClient>,
text: string,
maxAllowedSeverity = 2,
blocklistNames: string[] = []
): Promise<ModerationResult> {
const result = await client.path("/text:analyze").post({
body: { text, blocklistNames, haltOnBlocklistHit: false }
});
if (isUnexpected(result)) {
throw result.body;
}
const flaggedCategories = result.body.categoriesAnalysis
.filter(c => (c.severity ?? 0) > maxAllowedSeverity)
.map(c => c.category!);
const maxSeverity = Math.max(
...result.body.categoriesAnalysis.map(c => c.severity ?? 0)
);
const blocklistMatches = (result.body.blocklistsMatch ?? [])
.map(m => m.blocklistItemText!);
return {
isAllowed: flaggedCategories.length === 0 && blocklistMatches.length === 0,
flaggedCategories,
maxSeverity,
blocklistMatches
};
}
Points d'accès API
| Opération | Méthode | Chemin |
|---|---|---|
| Analyser du texte | POST | /text:analyze |
| Analyser une image | POST | /image:analyze |
| Créer/Mettre à jour une liste de blocage | PATCH | /text/blocklists/{blocklistName} |
| Lister les listes de blocage | GET | /text/blocklists |
| Supprimer une liste de blocage | DELETE | /text/blocklists/{blocklistName} |
| Ajouter des éléments à une liste de blocage | POST | /text/blocklists/{blocklistName}:addOrUpdateBlocklistItems |
| Lister les éléments d'une liste de blocage | GET | /text/blocklists/{blocklistName}/blocklistItems |
| Supprimer des éléments d'une liste de blocage | POST | /text/blocklists/{blocklistName}:removeBlocklistItems |
Types clés
import ContentSafetyClient, {
isUnexpected,
AnalyzeTextParameters,
AnalyzeImageParameters,
TextCategoriesAnalysisOutput,
ImageCategoriesAnalysisOutput,
TextBlocklist,
TextBlocklistItem
} from "@azure-rest/ai-content-safety";
Bonnes pratiques
- Toujours utiliser isUnexpected() - Garde de type pour la gestion des erreurs
- Définir des seuils appropriés - Les catégories différentes peuvent nécessiter des seuils de sévérité différents
- Utiliser les listes de blocage pour les termes spécifiques au domaine - Complémenter la détection par IA avec des règles personnalisées
- Journaliser les décisions de modération - Conserver une trace d'audit pour la conformité
- Gérer les cas limites - Texte vide, texte très long, formats d'image non supportés