Skip to content

트레이싱

이 페이지는 AI 에이전트를 위한 포괄적인 트레이싱 기능을 제공하는 트레이싱 기능에 대한 세부 정보를 포함합니다.

기능 개요

트레이싱 기능은 에이전트 실행에 대한 상세 정보를 캡처하는 강력한 모니터링 및 디버깅 도구입니다. 포함하는 정보는 다음과 같습니다:

  • 전략 실행
  • LLM 호출
  • 도구 호출
  • 에이전트 그래프 내 노드 실행

이 기능은 에이전트 파이프라인의 주요 이벤트를 가로채어 구성 가능한 메시지 처리기로 전달하는 방식으로 작동합니다. 이 처리기들은 트레이스 정보를 로그 파일 또는 파일 시스템의 다른 유형 파일과 같은 다양한 대상으로 출력할 수 있으며, 이를 통해 개발자는 에이전트 동작에 대한 통찰력을 얻고 문제를 효과적으로 해결할 수 있습니다.

이벤트 흐름

  1. 트레이싱 기능은 에이전트 파이프라인의 이벤트를 가로챕니다.
  2. 이벤트는 구성된 메시지 필터를 기반으로 필터링됩니다.
  3. 필터링된 이벤트는 등록된 메시지 처리기로 전달됩니다.
  4. 메시지 처리기는 이벤트를 포맷하고 각 대상에 출력합니다.

구성 및 초기화

기본 설정

트레이싱 기능을 사용하려면 다음이 필요합니다:

  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
├── 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 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 서버-센트 이벤트(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 문서

트레이싱 기능은 다음 핵심 구성 요소를 가진 모듈식 아키텍처를 따릅니다:

  1. Tracing: 에이전트 파이프라인의 이벤트를 가로채는 주요 기능 클래스.
  2. TraceFeatureConfig: 기능 동작을 사용자 지정하기 위한 구성 클래스.
  3. 메시지 처리기: 트레이스 이벤트를 처리하고 출력하는 구성 요소:

FAQ 및 문제 해결

다음 섹션에는 트레이싱 기능과 관련된 자주 묻는 질문과 답변이 포함되어 있습니다.

에이전트 실행의 특정 부분만 트레이스하려면 어떻게 해야 합니까?

messageFilter 속성을 사용하여 이벤트를 필터링합니다. 예를 들어, LLM 호출만 트레이스하려면:

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모델이 반환한 하나 이상의 응답입니다.
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입니다.