mcpField
A
azure-ai-contentsafety-ts

azure-ai-contentsafety-ts

github.com/sickn33その他48.7k80 回インストール今日更新
リポジトリ

azure-ai-contentsafety-ts について

Azure AI Content Safetyを利用するTypeScript開発者向けのスキルです。テキストと画像の分析、カスタムブロックリスト管理、RESTクライアント設定や重大度に基づくモデレーションを扱います。

主な機能

  1. 01有害コンテンツのテキスト分析
  2. 02有害コンテンツの画像分析
  3. 03カスタムテキストブロックリスト管理
  4. 04重大度の出力レベル設定
  5. 05APIキーまたはAzure認証情報の利用

活用シーン

  1. 01ユーザー投稿テキストの確認
  2. 02アップロード画像のスクリーニング
  3. 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";

ベストプラクティス

  1. 必ず isUnexpected() を使用する - エラー処理のための型ガードです
  2. 適切なしきい値を設定する - カテゴリによって必要なしきい値が異なる場合があります
  3. ドメイン固有の用語にはブロックリストを使用する - カスタムルールで AI 検出を補完します
  4. モデレーションの判断を記録する - コンプライアンスのために監査証跡を保持します
  5. エッジケースに対応する - 空のテキスト、非常に長いテキスト、サポートされていない画像形式

使用する場合

このスキルは、概要に記載されたワークフローやアクションを実行する際に適用できます。

制限事項

  • このスキルは、タスクが上記の説明の範囲に明確に一致する場合にのみ使用してください。
  • 出力を、環境固有の検証、テスト、専門家による確認の代わりとして扱わないでください。
  • 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、作業を中断して確認を求めてください。

重大度 0 はモデルの結果であり、安全性を証明するものではありません。アプリケーションに合わせてしきい値とエスカレーションを調整してください。分析が行われていない場合やサービス障害が発生した場合、そのコンテンツは未評価のままです。プライベートなコンテンツをクラウドに送信することについて許可を得てください。また、公開ログにエラーの生の内容やブロックリストに登録されたテキストを出力しないでください。

コメント