> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dify.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# センシティブコンテンツ審査

> このドキュメントは AI によって自動翻訳されています。不正確な部分がある場合は、[英語版](/en/cloud/use-dify/workspace/api-extension/moderation-api-extension) を参照してください。

このモジュールは、アプリケーション内でエンドユーザーが入力したコンテンツと LLM が出力したコンテンツを審査するために使用され、2 つの拡張ポイントタイプに分かれています。

## 拡張ポイント

* `app.moderation.input`：エンドユーザー入力コンテンツ審査拡張ポイント
  * エンドユーザーが渡した変数内容と会話型アプリケーションの会話入力内容を審査するために使用されます。
* `app.moderation.output`：LLM 出力コンテンツ審査拡張ポイント
  * LLM が出力したコンテンツを審査するために使用されます。
  * LLM の出力がストリーミングの場合、出力内容は 100 文字を 1 セグメントとして API にリクエストされ、出力内容が長い場合の審査の遅延を可能な限り回避します。

### app.moderation.input

Chatflow、Agent、チャットアシスタントなどのアプリケーションで **コンテンツ審査 > 入力コンテンツを審査** が有効になっている場合、Dify は対応するカスタム API に以下の HTTP POST リクエストを送信します：

#### Request Body

```
{
    "point": "app.moderation.input", // 拡張ポイントタイプ、ここでは app.moderation.input に固定
    "params": {
        "app_id": string,  // アプリケーション ID
        "inputs": {  // エンドユーザーが渡した変数値、key は変数名、value は変数値
            "var_1": "value_1",
            "var_2": "value_2",
            ...
        },
        "query": string | null  // エンドユーザーの現在の会話入力内容、会話型アプリケーションの固定パラメータ。
    }
}
```

**例**：

```
{
    "point": "app.moderation.input",
    "params": {
        "app_id": "61248ab4-1125-45be-ae32-0ce91334d021",
        "inputs": {
            "var_1": "私のマイナンバーは 1234-5678-9012 です。",
            "var_2": "私の電話番号は 090-1234-5678 です。"
        },
        "query": "アカウント情報を更新してください。"
    }
}
```

#### API レスポンス仕様

```
{
    "flagged": bool,  // 検証ルールに違反しているかどうか
    "action": string, // アクション、direct_output は事前設定された回答を直接出力; overridden は入力変数値を上書き
    "preset_response": string,  // 事前設定された回答（action=direct_output の場合にのみ返される）
    "inputs": {  // エンドユーザーが渡した変数値、key は変数名、value は変数値（action=overridden の場合にのみ返される）
        "var_1": "value_1",
        "var_2": "value_2",
        ...
    },
    "query": string | null  // 上書きされたエンドユーザーの現在の会話入力内容、会話型アプリケーションの固定パラメータ。（action=overridden の場合にのみ返される）
}
```

**例**：

* `action=direct_output`
  ```
  {
      "flagged": true,
      "action": "direct_output",
      "preset_response": "Your content violates our usage policy."
  }
  ```
* `action=overridden`
  ```
  {
      "flagged": true,
      "action": "overridden",
      "inputs": {
          "var_1": "私のマイナンバーは ****-****-**** です。",
          "var_2": "私の電話番号は ***-****-**** です。"
      },
      "query": "アカウント情報を更新してください。"
  }
  ```

### app.moderation.output

Chatflow、Agent、チャットアシスタントなどのアプリケーションで **コンテンツ審査 > 出力コンテンツを審査** が有効になっている場合、Dify は対応するカスタム API に以下の HTTP POST リクエストを送信します：

#### Request Body

```
{
    "point": "app.moderation.output", // 拡張ポイントタイプ、ここでは app.moderation.output に固定
    "params": {
        "app_id": string,  // アプリケーション ID
        "text": string  // LLM 応答内容。LLM の出力がストリーミングの場合、ここでは 100 文字を 1 セグメントとした内容。
    }
}
```

**例**：

```
{
    "point": "app.moderation.output",
    "params": {
        "app_id": "61248ab4-1125-45be-ae32-0ce91334d021",
        "text": "私のマイナンバーは 1234-5678-9012 です。"
    }
}
```

#### API レスポンス

```
{
    "flagged": bool,  // 検証ルールに違反しているかどうか
    "action": string, // アクション、direct_output は事前設定された回答を直接出力; overridden は入力変数値を上書き
    "preset_response": string,  // 事前設定された回答（action=direct_output の場合にのみ返される）
    "text": string  // 上書きされた LLM 応答内容。（action=overridden の場合にのみ返される）
}
```

**例**：

* `action=direct_output`
  ```
  {
      "flagged": true,
      "action": "direct_output",
      "preset_response": "Your content violates our usage policy."
  }
  ```
* `action=overridden`
  ```
  {
      "flagged": true,
      "action": "overridden",
      "text": "私のマイナンバーは ****-****-**** です。"
  }
  ```

## コードサンプル

以下は、Cloudflare にデプロイ可能な `src/index.ts` コードの一部です。（Cloudflare の完全な使用方法については [このドキュメント](/ja/cloud/use-dify/workspace/api-extension/cloudflare-worker) を参照してください）

コードの動作原理はキーワードマッチングを行い、Input（ユーザーが入力したコンテンツ）および Output（大規模モデルが返したコンテンツ）をフィルタリングすることです。ユーザーは必要に応じてマッチングロジックを変更できます。

```
import { Hono } from "hono";
import { bearerAuth } from "hono/bearer-auth";
import { z } from "zod";
import { zValidator } from "@hono/zod-validator";
import { generateSchema } from '@anatine/zod-openapi';

type Bindings = {
  TOKEN: string;
};

const app = new Hono<{ Bindings: Bindings }>();

// API フォーマット検証 ⬇️
const schema = z.object({
  point: z.union([
    z.literal("ping"),
    z.literal("app.external_data_tool.query"),
    z.literal("app.moderation.input"),
    z.literal("app.moderation.output"),
  ]), // Restricts 'point' to two specific values
  params: z
    .object({
      app_id: z.string().optional(),
      tool_variable: z.string().optional(),
      inputs: z.record(z.any()).optional(),
      query: z.any(),
      text: z.any()
    })
    .optional(),
});


// Generate OpenAPI schema
app.get("/", (c) => {
  return c.json(generateSchema(schema));
});

app.post(
  "/",
  (c, next) => {
    const auth = bearerAuth({ token: c.env.TOKEN });
    return auth(c, next);
  },
  zValidator("json", schema),
  async (c) => {
    const { point, params } = c.req.valid("json");
    if (point === "ping") {
      return c.json({
        result: "pong",
      });
    }
    // ⬇️ impliment your logic here ⬇️
    // point === "app.external_data_tool.query"
    else if (point === "app.moderation.input"){
    // 入力チェック ⬇️
    const inputkeywords = ["入力フィルターテスト1", "入力フィルターテスト2", "入力フィルターテスト3"];

    if (inputkeywords.some(keyword => params.query.includes(keyword))) 
      {
      return c.json({
        "flagged": true,
        "action": "direct_output",
        "preset_response": "入力に違法コンテンツが含まれています。別の質問で試してください!"
      });
    } else {
      return c.json({
        "flagged": false,
        "action": "direct_output",
        "preset_response": "入力は正常です"
      });
    }
    // 入力チェック完了 
    }
    
    else {
      // 出力チェック ⬇️
      const outputkeywords = ["出力フィルターテスト1", "出力フィルターテスト2", "出力フィルターテスト3"]; 

  if (outputkeywords.some(keyword => params.text.includes(keyword))) 
    {
      return c.json({
        "flagged": true,
        "action": "direct_output",
        "preset_response": "出力にセンシティブコンテンツが含まれており、システムによってフィルタリングされました。別の質問で試してください!"
      });
    }
  
  else {
    return c.json({
      "flagged": false,
      "action": "direct_output",
      "preset_response": "出力は正常です"
    });
  };
    }
    // 出力チェック完了 
  }
);

export default app;

```
