azure-ai-contentsafety-ts について
Azure AI Content Safetyを利用するTypeScript開発者向けのスキルです。テキストと画像の分析、カスタムブロックリスト管理、RESTクライアント設定や重大度に基づくモデレーションを扱います。
主な機能
- 01有害コンテンツのテキスト分析
- 02有害コンテンツの画像分析
- 03カスタムテキストブロックリスト管理
- 04重大度の出力レベル設定
- 05APIキーまたはAzure認証情報の利用
活用シーン
- 01ユーザー投稿テキストの確認
- 02アップロード画像のスクリーニング
- 03分野固有の禁止語句の適用
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill azure-ai-contentsafety-tsインストール後、Claude Code で/azure-ai-contentsafety-tsを入力して読み込まれたか確認します。
詳細
Azure AI Content Safety REST SDK for TypeScript
カスタマイズ可能なブロックリストを使用して、有害なコンテンツが含まれていないかテキストと画像を分析します。
インストール
npm install @azure-rest/ai-content-safety @azure/identity @azure/core-auth
環境変数
CONTENT_SAFETY_ENDPOINT=https://<resource>.cognitiveservices.azure.com
CONTENT_SAFETY_KEY=<api-key>
認証
重要:これは REST クライアントです。ContentSafetyClient はクラスではなく、関数です。
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 } from "@azure/identity";
const client = ContentSafetyClient(
process.env.CONTENT_SAFETY_ENDPOINT!,
new DefaultAzureCredential()
);
テキストの分析
import ContentSafetyClient, { isUnexpected } from "@azure-rest/ai-content-safety";
const result = await client.path("/text:analyze").post({
body: {
text: "Text content to analyze",
categories: ["Hate", "Sexual", "Violence", "SelfHarm"],
outputType: "FourSeverityLevels" // or "EightSeverityLevels"
}
});
if (isUnexpected(result)) {
throw result.body;
}
for (const analysis of result.body.categoriesAnalysis) {
console.log(`${analysis.category}: severity ${analysis.severity}`);
}
画像の分析
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}: severity ${analysis.severity}`);
}
Blob URL
const result = await client.path("/image:analyze").post({
body: {
image: { blobUrl: "https://storage.blob.core.windows.net/container/image.png" }
}
});
ブロックリストの管理
ブロックリストの作成
const result = await client
.path("/text/blocklists/{blocklistName}", "my-blocklist")
.patch({
contentType: "application/merge-patch+json",
body: {
description: "Custom blocklist for prohibited terms"
}
});
if (isUnexpected(result)) {
throw result.body;
}
console.log(`Created: ${result.body.blocklistName}`);
ブロックリストへの項目の追加
const result = await client
.path("/text/blocklists/{blocklistName}:addOrUpdateBlocklistItems", "my-blocklist")
.post({
body: {
blocklistItems: [
{ text: "prohibited-term-1", description: "First blocked term" },
{ text: "prohibited-term-2", description: "Second blocked term" }
]
}
});
if (isUnexpected(result)) {
throw result.body;
}
for (const item of result.body.blocklistItems ?? []) {
console.log(`Added: ${item.blocklistItemId}`);
}
ブロックリストを使用した分析
const result = await client.path("/text:analyze").post({
body: {
text: "Text that might contain blocked terms",
blocklistNames: ["my-blocklist"],
haltOnBlocklistHit: false
}
});
if (isUnexpected(result)) {
throw result.body;
}
// Check blocklist matches
if (result.body.blocklistsMatch) {
for (const match of result.body.blocklistsMatch) {
console.log(`Blocked: "${match.blocklistItemText}" from ${match.blocklistName}`);
}
}
ブロックリストの一覧表示
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}`);
}
ブロックリストの削除
await client.path("/text/blocklists/{blocklistName}", "my-blocklist").delete();
有害カテゴリ
| カテゴリ | API 用語 | 説明 |
|---|---|---|
| ヘイトと公平性 | Hate | アイデンティティグループを標的とする差別的な言葉 |
| 性的コンテンツ | Sexual | 性的コンテンツ、ヌード、ポルノ |
| 暴力 | Violence | 身体的危害、武器、テロリズム |
| 自傷行為 | SelfHarm | 自傷行為、自殺、摂食障害 |
重大度レベル
| レベル | リスク | 推奨される対応 |
|---|---|---|
| 0 | 安全 | 許可 |
| 2 | 低 | 確認するか、警告付きで許可 |
| 4 | 中 | ブロックするか、人による確認を必須にする |
| 6 | 高 | 直ちにブロック |
出力タイプ:
FourSeverityLevels(デフォルト):0、2、4、6 を返しますEightSeverityLevels:0~7 を返します
コンテンツモデレーションヘルパー
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 analyses = result.body.categoriesAnalysis;
const expected = ["Hate", "SelfHarm", "Sexual", "Violence"];
if (!Array.isArray(analyses) || expected.some(category =>
!analyses.some(c => c.category === category && Number.isInteger(c.severity) && c.severity! >= 0 && c.severity! <= 7))) {
throw new Error("Incomplete moderation assessment");
}
const flaggedCategories = analyses
.filter(c => c.severity! > maxAllowedSeverity)
.map(c => c.category!);
const maxSeverity = Math.max(
...analyses.map(c => c.severity!)
);
const blocklistMatches = (result.body.blocklistsMatch ?? [])
.map(m => m.blocklistItemText!);
return {
isAllowed: flaggedCategories.length === 0 && blocklistMatches.length === 0,
flaggedCategories,
maxSeverity,
blocklistMatches
};
}
API エンドポイント
| 操作 | メソッド | パス |
|---|---|---|
| テキストの分析 | POST | /text:analyze |
| 画像の分析 | POST | /image:analyze |
| ブロックリストの作成/更新 | PATCH | /text/blocklists/{blocklistName} |
| ブロックリストの一覧表示 | GET | /text/blocklists |
| ブロックリストの削除 | DELETE | /text/blocklists/{blocklistName} |
| ブロックリスト項目の追加 | POST | /text/blocklists/{blocklistName}:addOrUpdateBlocklistItems |
| ブロックリスト項目の一覧表示 | GET | /text/blocklists/{blocklistName}/blocklistItems |
| ブロックリスト項目の削除 | POST | /text/blocklists/{blocklistName}:removeBlocklistItems |
主な型
import ContentSafetyClient, {
isUnexpected,
AnalyzeTextParameters,
AnalyzeImageParameters,
TextCategoriesAnalysisOutput,
ImageCategoriesAnalysisOutput,
TextBlocklist,
TextBlocklistItem
} from "@azure-rest/ai-content-safety";
ベストプラクティス
- 必ず isUnexpected() を使用する - エラー処理のための型ガードです
- 適切なしきい値を設定する - カテゴリによって必要なしきい値が異なる場合があります
- ドメイン固有の用語にはブロックリストを使用する - カスタムルールで AI 検出を補完します
- モデレーションの判断を記録する - コンプライアンスのために監査証跡を保持します
- エッジケースに対応する - 空のテキスト、非常に長いテキスト、サポートされていない画像形式
使用する場合
このスキルは、概要に記載されたワークフローやアクションを実行する際に適用できます。
制限事項
- このスキルは、タスクが上記の説明の範囲に明確に一致する場合にのみ使用してください。
- 出力を、環境固有の検証、テスト、専門家による確認の代わりとして扱わないでください。
- 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、作業を中断して確認を求めてください。
重大度 0 はモデルの結果であり、安全性を証明するものではありません。アプリケーションに合わせてしきい値とエスカレーションを調整してください。分析が行われていない場合やサービス障害が発生した場合、そのコンテンツは未評価のままです。プライベートなコンテンツをクラウドに送信することについて許可を得てください。また、公開ログにエラーの生の内容やブロックリストに登録されたテキストを出力しないでください。
コメント
Markdown 対応