Skip to content

プロンプトインジェクション

プロンプトインジェクションは、Nekro AgentプラグインがAIの動作に影響を与え、コンテキスト情報を提供したり、役割をカスタマイズしたりするための重要なメカニズムの一つです。AIのメインプロンプト(システムプロンプト)に動的にコンテンツを追加することで、プラグインはAIの思考方向と応答スタイルを誘導できます。

プロンプトインジェクションとは?

AIがユーザーと対話する前に、システムは通常、指示、コンテキスト情報、役割定義などのコンテンツを含むメインプロンプトを構築します。プロンプトインジェクションにより、プラグインはこの構築プロセス中に、セッション関連のプラグイン固有情報をメインプロンプトに動的に「注入」できます。

その目的は以下の通りです:

  • コンテキストの提供: 現在のセッションの特定の状態、ユーザーの過去の設定、プラグインが収集した関連情報などをAIに通知します。
  • 機能/役割の付与: プラグインが提供する特定のツールを使用するようAIに指示したり、特定の役割を演じるよう指示したりします(例:「あなたは現在、役立つ天気予報士です」)。
  • ルール/制約の設定: AIの動作に対するいくつかの指導原則や制限条件を確立します。

プロンプトインジェクションメソッドの登録

プラグインは @plugin.mount_prompt_inject_method() デコレータを通じて非同期関数を登録し、この関数は注入が必要なプロンプトコンテンツを生成する役割を担います。

python
from nekro_agent.api.schemas import AgentCtx
from nekro_agent.api import core

@plugin.mount_prompt_inject_method(
    name="status_awareness_prompt", # インジェクションメソッドの名前、デバッグと識別に使用
    description="現在のセッション状態情報と利用可能なツールプロンプトをAIに注入します。"
)
async def inject_status_prompt(_ctx: AgentCtx) -> str:
    """メインプロンプトに注入する必要のある文字列を生成して返します。

    Returns:
        str: 注入されるプロンプトテキスト。
    """
    # 例: プラグインストレージから現在のセッション状態情報を取得
    current_status = await plugin.store.get(chat_key=_ctx.from_chat_key, store_key="current_channel_status")
    
    prompt_parts = []
    
    if current_status:
        prompt_parts.append(f"現在の状態プロンプト: セッション状態は現在 '{current_status}' です。")
    else:
        prompt_parts.append("現在の状態プロンプト: セッション状態は不明またはデフォルト状態です。")

    # 例: AIが使用できるプラグインツールを通知(より複雑なツール説明はサンドボックスメソッドのドキュメントを通じて提供)
    prompt_parts.append("「get_weather(city)」ツールを使用して天気をクエリできます。")
    prompt_parts.append("「set_reminder(time_desc,message)」ツールを使用してリマインダーを設定できます。")

    # 最終的な注入プロンプト
    injected_prompt = "\n".join(prompt_parts)
    core.logger.debug(f"セッション {_ctx.from_chat_key} に注入されたプロンプト: \n{injected_prompt}")
    
    return injected_prompt

重要なポイント:

  • インジェクションメソッドは非同期関数(async def)である必要があります。
  • AgentCtx オブジェクトをパラメータとして受け取り、そこからセッション情報を取得できます。
  • 文字列を返す必要があり、この文字列はAIのメインプロンプトに連結されます。
  • namedescription パラメータは、このインジェクションメソッドを識別するために使用されます。

いつ実行されるか?

プロンプトインジェクションメソッドは、通常、以下の状況で呼び出されます:

  • ユーザーがAIと対話する前の各回

効果的なインジェクションプロンプトの設計

優れたインジェクションプロンプトは、プラグインの有用性とAIのパフォーマンスを大幅に向上させることができます。以下に、基本的な設計原則をいくつか示します:

  1. 簡潔明瞭: 注入されるコンテンツは、短く、明確で、AIが理解しやすいものであるべきです。冗長さや不要な複雑さを避けてください。
  2. 高関連性: 現在のセッション、現在のユーザー、またはプラグインのコア機能と密接に関連する情報のみを注入してください。無関係な情報はAIの処理負担を増加させ、誤解を招く可能性さえあります。
  3. 構造化: 複数の情報を注入する場合、特定のプレフィックス、改行、箇条書きなどの一貫した形式を使用して、AIが異なる情報フラグメントを区別しやすくしてください。
  4. 動的生成: AgentCtx とプラグインストレージからの情報を最大限に活用し、現在のコンテキストに最も適したプロンプトコンテンツを動的に生成してください。
  5. 明確な指示(必要な場合): AIに特定のツールを使用させたり、特定の動作に従わせたい場合、プロンプトで明確な指示を与えることができます。ただし、より複雑なツール使用指示はサンドボックスメソッドのドキュメント文字列に配置する必要があります。
  6. 競合の回避: あなたのインジェクションプロンプトが他のプラグインやシステムレベルのプロンプトと競合したり、曖昧さを引き起こしたりしないように注意してください。
  7. 反復とテスト: プロンプトエンジニアリングは、継続的な試行と最適化を必要とするプロセスであることが多いです。実際のテストを通じてインジェクションプロンプトの有効性をテストし、AIのフィードバックに基づいて調整してください。

例:シンプルなロールプレイングプロンプト

python
@plugin.mount_prompt_inject_method(name="role_play_prompt")
async def inject_role_prompt(_ctx: AgentCtx) -> str:
    # プラグイン設定に役割定義があると仮定
    role_description = plugin.config.ROLE_PLAY_CHARACTER 
    if role_description:
        return f"次の役割を演じてください: {role_description}。ユーザーとコミュニケーションする際、この役割の特性と口調を維持してください。"
    return "" # 役割が設定されていない場合は、何も注入しない

慎重に設計されたプロンプトインジェクションを通じて、プラグインがAIとより賢く連携し、ユーザーにスムーズでパーソナライズされたエクスペリエンスを提供できるようになります。