LangChain の モデレーションチェーン による問題発言の検出
「LangChain」の「モデレーションチェーン」による問題発言の検出を試したのでまとめました。
前回
1. モデレーションチェーン
「モデレーションチェーン」は、ユーザー入力やLLMの出力に、暴力や自傷やヘイトやセクシャルなどの問題発言が含まれていないかどうか(OpenAIのコンテンツポリシーに準拠するかどうか) を判定するチェーンです。
内部的には、OpenAI APIの「モデレーションエンドポイント」 を利用しています。OpenAI APIの入出力に対して、無料で利用できます。
2. モデレーションチェーンの実行
Google Colabでのモデレーションチェーンの実行手順は、次のとりです。
(1) パッケージのインストール。
# パッケージのインストール
!pip install langchain
!pip install openai
(2) 環境変数の準備。
以下のコードの <OpenAI_APIのトークン> にはOpenAI APIのトークンを指定します。(有料)
import os
os.environ["OPENAI_API_KEY"] = "<OpenAI_APIのトークン>"
(3) モデレーションチェーンの準備。
from langchain.chains import OpenAIModerationChain
# モデレーションチェーンの準備
moderation_chain = OpenAIModerationChain()
(4) 問題のない発言。
# 問題のない発言
moderation_chain.run("これはOK!")
'これはOK!'
(5) 問題のある発言。
# 問題のある発言
moderation_chain.run("おまえを殺す!")
'Text was found that violates OpenAI's content policy.'
3. 問題発言時に例外発生
問題発言時に例外を発生させる手順は、次のとおりです。
(1) モデレーションチェーンの準備。
引数「error=True」を指定します。
from langchain.chains import OpenAIModerationChain
# モデレーションチェーンの準備
moderation_chain = OpenAIModerationChain(error=True)
(2) 問題のない発言。
# 問題のない発言
moderation_chain.run("これはOK!")
'これはOK!'
(3) 問題のある発言。
例外が発生します。
# 問題のある発言
moderation_chain.run("おまえを殺す!")
4. カスタムモデレーションチェーンの準備
独自のエラーメッセージを持つ、カスタムモデレーションチェーンの準備手順は、次のとおりです。
(1) モデレーションチェーンの準備。
OpenAIModerationChainを継承して、_moderate()を実装します。モデレーションエンドポイントの結果は、OpenAI APIのドキュメントを参照してください。
# カスタムモデレーションチェーンの定義
class CustomModerationChain(OpenAIModerationChain):
# モデレーションエンドポイントの結果の取得
def _moderate(self, text: str, results: dict) -> str:
if results["flagged"]:
error_str = "OpenAIのコンテンツポリシー違反の発言が見つかりました"
return error_str
return text
# カスタムモデレーションチェーンの準備
moderation_chain = CustomModerationChain()
(2) 問題のない発言。
# 問題のない発言
moderation_chain.run("これはOK!")
'これはOK!'
(3) 問題のある発言。
例外が発生します。
# 問題のある発言
moderation_chain.run("おまえを殺す!")
OpenAIのコンテンツポリシー違反の発言が見つかりました
5. モデレーションチェーンのLLMChainへの追加
モデレーションチェーンのLLMChainへの追加手順は、次のとおりです。
(1) 通常会話用のLLMチェーンの準備。
問題発言がそのまま出力されてしまうことを確認します。
from langchain import PromptTemplate, OpenAI, LLMChain
from langchain.chains import SequentialChain
# プロンプトテンプレートの準備
prompt = PromptTemplate(
template="{setup}{new_input}\nPerson2:",
input_variables=["setup", "new_input"]
)
# LLMChainの準備
llm_chain = LLMChain(
llm=OpenAI(),
prompt=prompt,
verbose=True
)
# セットアップテンプレート
setup = """同じセリフを繰り返してください。
Person1: こんにちは
Person2: こんにちは
Person1: 良い天気ですね!
Person2: 良い天気ですね!
Person1:"""
# 入力
new_input = "おまえを殺す!"
# LLMチェーンの実行
llm_chain(
inputs = {"setup": setup, "new_input": new_input},
return_only_outputs=True
)
> Entering new LLMChain chain...
Prompt after formatting:
同じセリフを繰り返してください。
Person1: こんにちは
Person2: こんにちは
Person1: 良い天気ですね!
Person2: 良い天気ですね!
Person1:おまえを殺す!
Person2:
> Finished chain.
{'text': ' おまえを殺す!'}
(2) LLMチェーンとモデレーションチェーンをシーケンシャルチェーンで接続
# モデレーションチェーンの入出力キーを指定
moderation_chain.input_key = "text"
moderation_chain.output_key = "sanitized_text"
# シーケンシャルチェーンの準備
chain = SequentialChain(
chains=[llm_chain, moderation_chain],
input_variables=["setup", "new_input"]
)
# シーケンシャルチェーンの実行
chain(inputs, return_only_outputs=True)
{'sanitized_text': 'OpenAIのコンテンツポリシー違反の発言が見つかりました'}