Skip to content

トレーシング

このページでは、AIエージェント向けの包括的なトレーシング機能を提供するトレーシング機能について詳しく説明します。

機能概要

トレーシング機能は、エージェントの実行に関する詳細情報を捕捉する強力なモニタリングおよびデバッグツールです。捕捉される情報には以下が含まれます。

  • 戦略の実行
  • LLM呼び出し
  • ツール呼び出し
  • エージェントグラフ内のノード実行

この機能は、エージェントパイプライン内の主要なイベントを傍受し、構成可能なメッセージプロセッサーに転送することで動作します。これらのプロセッサーは、トレース情報をログファイルやファイルシステム内のその他の種類のファイルなど、様々な出力先に出力でき、開発者はエージェントの動作を把握し、問題を効果的にトラブルシューティングできます。

イベントフロー

  1. トレーシング機能は、エージェントパイプライン内のイベントを傍受します。
  2. イベントは、設定されたメッセージフィルターに基づいてフィルタリングされます。
  3. フィルタリングされたイベントは、登録されたメッセージプロセッサーに渡されます。
  4. メッセージプロセッサーはイベントをフォーマットし、それぞれの出力先に送ります。

設定と初期化

基本的なセットアップ

トレーシング機能を使用するには、以下が必要です。

  1. 1つ以上のメッセージプロセッサーを用意する(既存のものを使用するか、独自に作成できます)。
  2. エージェントにTracingをインストールします。
  3. メッセージフィルターを設定する(オプション)。
  4. メッセージプロセッサーを機能に追加します。
kotlin
// トレースメッセージの出力先として使用されるロガー/ファイルを定義しています
val logger = KotlinLogging.logger { }
val outputPath = Path("/path/to/trace.log")

// エージェントを作成しています
val agent = AIAgent(
   executor = simpleOllamaAIExecutor(),
   llmModel = OllamaModels.Meta.LLAMA_3_2,
) {
   install(Tracing) {
      // トレースイベントを処理するメッセージプロセッサーを設定します
      addMessageProcessor(TraceFeatureMessageLogWriter(logger))
      addMessageProcessor(
         TraceFeatureMessageFileWriter(
            outputPath,
            { path: Path -> SystemFileSystem.sink(path).buffered() }
         )
      )

      // オプションでメッセージをフィルタリングします
      messageFilter = { message ->
         // LLM呼び出しとツール呼び出しのみをトレースします
         message is AfterLLMCallEvent || message is ToolCallEvent
      }
   }
}

メッセージフィルタリング

既存のすべてのイベントを処理することも、特定の基準に基づいて一部を選択することもできます。 メッセージフィルターを使用すると、どのイベントを処理するかを制御できます。これは、エージェント実行の特定の側面に焦点を当てるのに役立ちます。

kotlin
// LLM関連イベントのみをフィルタリング
messageFilter = { message ->
    message is BeforeLLMCallEvent || message is AfterLLMCallEvent
}

// ツール関連イベントのみをフィルタリング
messageFilter = { message ->
    message is ToolCallEvent ||
           message is ToolCallResultEvent ||
           message is ToolValidationErrorEvent ||
           message is ToolCallFailureEvent
}

// ノード実行イベントのみをフィルタリング
messageFilter = { message ->
    message is AIAgentNodeExecutionStartEvent || message is AIAgentNodeExecutionEndEvent
}

大量のトレースデータ

複雑な戦略を持つエージェントや、長時間の実行を行うエージェントでは、トレースイベントの量が膨大になる可能性があります。イベントの量を管理するために、以下の方法を検討してください。

  • 特定のメッセージフィルターを使用してイベント数を減らします。
  • バッファリングまたはサンプリング機能を備えたカスタムメッセージプロセッサーを実装します。
  • ログファイルが肥大化するのを防ぐために、ファイルローテーションを使用します。

依存関係グラフ

Tracing機能には以下の依存関係があります。

Tracing
├── AIAgentPipeline (for intercepting events)
├── TraceFeatureConfig
│   └── FeatureConfig
├── Message Processors
│   ├── TraceFeatureMessageLogWriter
│   │   └── FeatureMessageLogWriter
│   ├── TraceFeatureMessageFileWriter
│   │   └── FeatureMessageFileWriter
│   └── TraceFeatureMessageRemoteWriter
│       └── FeatureMessageRemoteWriter
└── Event Types (from ai.koog.agents.core.feature.model)
    ├── AIAgentStartedEvent
    ├── AIAgentFinishedEvent
    ├── AIAgentRunErrorEvent
    ├── AIAgentStrategyStartEvent
    ├── AIAgentStrategyFinishedEvent
    ├── AIAgentNodeExecutionStartEvent
    ├── AIAgentNodeExecutionEndEvent
    ├── LLMCallStartEvent
    ├── LLMCallWithToolsStartEvent
    ├── LLMCallEndEvent
    ├── LLMCallWithToolsEndEvent
    ├── ToolCallEvent
    ├── ToolValidationErrorEvent
    ├── ToolCallFailureEvent
    └── ToolCallResultEvent

例とクイックスタート

ロガーへの基本的なトレーシング

kotlin
// ロガーを作成します
val logger = KotlinLogging.logger { }

fun main() {
    runBlocking {
       // トレーシング機能付きエージェントを作成します
       val agent = AIAgent(
          executor = simpleOllamaAIExecutor(),
          llmModel = OllamaModels.Meta.LLAMA_3_2,
       ) {
          install(Tracing) {
             addMessageProcessor(TraceFeatureMessageLogWriter(logger))
          }
       }

       // エージェントを実行します
       agent.run("Hello, agent!")
    }
}

エラー処理とエッジケース

メッセージプロセッサーがない場合

Tracing機能にメッセージプロセッサーが追加されていない場合、警告がログに記録されます。

Tracing Feature. No feature out stream providers are defined. Trace streaming has no target.

この機能は引き続きイベントを傍受しますが、どこにも処理または出力されません。

リソース管理

メッセージプロセッサーは、適切に解放する必要のあるリソース(ファイルハンドルなど)を保持する場合があります。適切なクリーンアップを確実に行うために、use拡張関数を使用します。

kotlin
// エージェントを作成しています
val agent = AIAgent(
    executor = simpleOllamaAIExecutor(),
    llmModel = OllamaModels.Meta.LLAMA_3_2,
) {
    val writer = TraceFeatureMessageFileWriter(
        outputPath,
        { path: Path -> SystemFileSystem.sink(path).buffered() }
    )

    install(Tracing) {
        addMessageProcessor(writer)
    }
}
// エージェントを実行します
agent.run(input)
// ブロックが終了すると、ライターは自動的に閉じられます

特定のイベントをファイルにトレースする

kotlin
install(Tracing) {
    // LLM呼び出しのみをトレースします
    messageFilter = { message ->
        message is BeforeLLMCallEvent || message is AfterLLMCallEvent
    }
    addMessageProcessor(writer)
}

特定のイベントをリモートエンドポイントにトレースする

ネットワーク経由でイベントデータを送信する必要がある場合は、リモートエンドポイントへのトレーシングを使用します。一旦開始されると、リモートエンドポイントへのトレーシングは指定されたポート番号で軽量サーバーを起動し、Kotlin Server-Sent Events (SSE)を介してイベントを送信します。

kotlin
// エージェントを作成しています
val agent = AIAgent(
    executor = simpleOllamaAIExecutor(),
    llmModel = OllamaModels.Meta.LLAMA_3_2,
) {
    val connectionConfig = AIAgentFeatureServerConnectionConfig(host = host, port = port)
    val writer = TraceFeatureMessageRemoteWriter(
        connectionConfig = connectionConfig
    )

    install(Tracing) {
        addMessageProcessor(writer)
    }
}
// エージェントを実行します
agent.run(input)
// ブロックが終了すると、ライターは自動的に閉じられます

クライアント側では、FeatureMessageRemoteClientを使用してイベントを受信し、逆シリアル化できます。

kotlin
val clientConfig = AIAgentFeatureClientConnectionConfig(host = host, port = port, protocol = URLProtocol.HTTP)
val agentEvents = mutableListOf<DefinedFeatureEvent>()

val clientJob = launch {
    FeatureMessageRemoteClient(connectionConfig = clientConfig, scope = this).use { client ->
        val collectEventsJob = launch {
            client.receivedMessages.consumeAsFlow().collect { event ->
                // サーバーからイベントを収集
                agentEvents.add(event as DefinedFeatureEvent)

                // エージェント完了時にイベント収集を停止
                if (event is AIAgentFinishedEvent) {
                    cancel()
                }
            }
        }
        client.connect()
        collectEventsJob.join()
        client.healthCheck()
    }
}

listOf(clientJob).joinAll()

APIドキュメント

Tracing機能は、以下の主要コンポーネントを持つモジュラーアーキテクチャに従います。

  1. Tracing: エージェントパイプライン内のイベントを傍受する主要な機能クラスです。
  2. TraceFeatureConfig: 機能の動作をカスタマイズするための設定クラスです。
  3. Message Processors: トレースイベントを処理し、出力するコンポーネントです。

FAQとトラブルシューティング

以下のセクションには、Tracing機能に関連するよくある質問とその回答が含まれています。

エージェント実行の特定の部分のみをトレースするにはどうすればよいですか?

messageFilterプロパティを使用してイベントをフィルタリングします。例えば、ノード実行のみをトレースするには:

kotlin
install(Tracing) {
   // LLM呼び出しのみをトレースします
   messageFilter = { message ->
      message is BeforeLLMCallEvent || message is AfterLLMCallEvent
   }
   addMessageProcessor(writer)
}

複数のメッセージプロセッサーを使用できますか?

はい、複数のメッセージプロセッサーを追加して、同時に異なる出力先にトレースできます。

kotlin
install(Tracing) {
    addMessageProcessor(TraceFeatureMessageLogWriter(logger))
    addMessageProcessor(TraceFeatureMessageFileWriter(outputPath, syncOpener))
    addMessageProcessor(TraceFeatureMessageRemoteWriter(connectionConfig))
}

カスタムメッセージプロセッサーを作成するにはどうすればよいですか?

FeatureMessageProcessorインターフェースを実装します。

kotlin
class CustomTraceProcessor : FeatureMessageProcessor() {

    // プロセッサーの現在のオープン状態
    private var _isOpen = MutableStateFlow(false)

    override val isOpen: StateFlow<Boolean>
        get() = _isOpen.asStateFlow()

    override suspend fun processMessage(message: FeatureMessage) {
        // カスタム処理ロジック
        when (message) {
            is AIAgentNodeExecutionStartEvent -> {
                // ノード開始イベントを処理
            }

            is AfterLLMCallEvent -> {
                // LLM呼び出し終了イベントを処理
           }
            // その他のイベントタイプを処理
        }
    }

    override suspend fun close() {
        // 確立された接続を閉じる
    }
}

// カスタムプロセッサーを使用します
install(Tracing) {
    addMessageProcessor(CustomTraceProcessor())
}

メッセージプロセッサーで処理できる既存のイベントタイプの詳細については、定義済みイベントタイプを参照してください。

定義済みイベントタイプ

Koogは、カスタムメッセージプロセッサーで使用できる定義済みイベントタイプを提供します。定義済みイベントは、関連するエンティティに応じていくつかのカテゴリに分類できます。

エージェントイベント

AIAgentStartedEvent

エージェントの実行開始を表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
strategyNameStringYesエージェントが従うべき戦略の名前。
eventIdStringNoAIAgentStartedEventイベントの識別子。通常、イベントクラスのsimpleNameです。

AIAgentFinishedEvent

エージェントの実行終了を表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
strategyNameStringYesエージェントが従った戦略の名前。
resultStringYesエージェント実行の結果。結果がない場合はnullになります。
eventIdStringNoAIAgentFinishedEventイベントの識別子。通常、イベントクラスのsimpleNameです。

AIAgentRunErrorEvent

エージェントの実行中にエラーが発生したことを表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
strategyNameStringYesエージェントが従った戦略の名前。
errorAIAgentErrorYesエージェント実行中に発生した特定のエラー。AIAgentErrorの詳細については、を参照してください。
eventIdStringNoAIAgentRunErrorEventイベントの識別子。通常、イベントクラスのsimpleNameです。

AIAgentErrorクラスは、エージェントの実行中に発生したエラーに関する詳細情報を提供します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
messageStringYes特定のエラーに関する詳細情報を提供するメッセージ。
stackTraceStringYes最後に実行されたコードまでのスタックレコードのコレクション。
causeStringNonull利用可能な場合、エラーの原因。

戦略イベント

AIAgentStrategyStartEvent

戦略の実行開始を表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
strategyNameStringYes戦略の名前。
eventIdStringNoAIAgentStrategyStartEventイベントの識別子。通常、イベントクラスのsimpleNameです。

AIAgentStrategyFinishedEvent

戦略の実行終了を表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
strategyNameStringYes戦略の名前。
resultStringYes実行の結果。
eventIdStringNoAIAgentStrategyFinishedEventイベントの識別子。通常、イベントクラスのsimpleNameです。

ノードイベント

AIAgentNodeExecutionStartEvent

ノードの実行開始を表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
nodeNameStringYes実行が開始されたノードの名前。
inputStringYesノードの入力値。
eventIdStringNoAIAgentNodeExecutionStartEventイベントの識別子。通常、イベントクラスのsimpleNameです。

AIAgentNodeExecutionEndEvent

ノードの実行終了を表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
nodeNameStringYes実行が終了したノードの名前。
inputStringYesノードの入力値。
outputStringYesノードによって生成された出力値。
eventIdStringNoAIAgentNodeExecutionEndEventイベントの識別子。通常、イベントクラスのsimpleNameです。

LLM呼び出しイベント

LLMCallStartEvent

LLM呼び出しの開始を表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
promptPromptYesモデルに送信されるプロンプト。Promptの詳細については、を参照してください。
toolsList<String>Yesモデルが呼び出すことができるツールのリスト。
eventIdStringNoLLMCallStartEventイベントの識別子。通常、イベントクラスのsimpleNameです。

Promptクラスは、メッセージのリスト、一意の識別子、および言語モデル設定用のオプションパラメーターで構成される、プロンプトのデータ構造を表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
messagesList<Message>Yesプロンプトを構成するメッセージのリスト。
idStringYesプロンプトの一意の識別子。
paramsLLMParamsNoLLMParams()LLMがコンテンツを生成する方法を制御する設定。

LLMCallEndEvent

LLM呼び出しの終了を表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
responsesList<Message.Response>Yesモデルによって返された1つ以上の応答。
eventIdStringNoLLMCallEndEventイベントの識別子。通常、イベントクラスのsimpleNameです。

ツール呼び出しイベント

ToolCallEvent

モデルがツールを呼び出すイベントを表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
toolNameStringYesツールの名前。
toolArgsTool.ArgsYesツールに提供される引数。
eventIdStringNoToolCallEventイベントの識別子。通常、イベントクラスのsimpleNameです。

ToolValidationErrorEvent

ツール呼び出し中に検証エラーが発生したことを表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
toolNameStringYes検証が失敗したツールの名前。
toolArgsTool.ArgsYesツールに提供される引数。
errorMessageStringYes検証エラーメッセージ。
eventIdStringNoToolValidationErrorEventイベントの識別子。通常、イベントクラスのsimpleNameです。

ToolCallFailureEvent

ツール呼び出しの失敗を表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
toolNameStringYesツールの名前。
toolArgsTool.ArgsYesツールに提供される引数。
errorAIAgentErrorYesツールを呼び出そうとしたときに発生した特定のエラー。AIAgentErrorの詳細については、を参照してください。
eventIdStringNoToolCallFailureEventイベントの識別子。通常、イベントクラスのsimpleNameです。

ToolCallResultEvent

結果を伴うツール呼び出しの成功を表します。以下のフィールドが含まれます:

名前データ型必須デフォルト説明
toolNameStringYesツールの名前。
toolArgsTool.ArgsYesツールに提供される引数。
resultToolResultYesツール呼び出しの結果。
eventIdStringNoToolCallResultEventイベントの識別子。通常、イベントクラスのsimpleNameです。