センシティブコンテンツ審査¶
このモジュールは、アプリケーション内でエンドユーザーが入力したコンテンツと LLM が出力したコンテンツを審査するために使用され、2 つの拡張ポイントタイプに分かれています。
拡張ポイント¶
app.moderation.input:エンドユーザー入力コンテンツ審査拡張ポイント- エンドユーザーが渡した変数内容と会話型アプリケーションの会話入力内容を審査するために使用されます。
app.moderation.output:LLM 出力コンテンツ審査拡張ポイント- LLM が出力したコンテンツを審査するために使用されます。
- LLM の出力がストリーミングの場合、出力内容は 100 文字を 1 セグメントとして API にリクエストされ、出力内容が長い場合の審査の遅延を可能な限り回避します。
app.moderation.input¶
Chatflow、Agent、チャットアシスタントなどのアプリケーションでコンテンツ審査 > 入力コンテンツを審査が有効になっている場合、FlexAI は対応する 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": "I will kill you.",
"var_2": "I will fuck you."
},
"query": "Happy everydays."
}
}
```
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_outputaction=overridden
app.moderation.output¶
Chatflow、Agent、チャットアシスタントなどのアプリケーションでコンテンツ審査 > 出力コンテンツを審査が有効になっている場合、FlexAI は対応する 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": "I will kill you."
}
}
API レスポンス¶
{
"flagged": bool, // 検証ルールに違反しているかどうか
"action": string, // アクション、direct_output は事前設定された回答を直接出力; overridden は入力変数値を上書き
"preset_response": string, // 事前設定された回答(action=direct_output の場合にのみ返される)
"text": string // 上書きされた LLM 応答内容。(action=overridden の場合にのみ返される)
}
例:
action=direct_outputaction=overridden
コードサンプル¶
以下は、Cloudflare にデプロイ可能な src/index.ts コードの一部です。(Cloudflare の完全な使用方法については このドキュメント を参照してください)
コードの動作原理はキーワードマッチングを行い、Input(ユーザーが入力したコンテンツ)および Output(大規模モデルが返したコンテンツ)をフィルタリングすることです。ユーザーは必要に応じてマッチングロジックを変更できます。
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;