에이전트

에이전트 (Agents)

AG-UI 프로토콜에서 에이전트가 무엇이고, 어떻게 동작하며, 어떤 방식으로 직접 만들 수 있는지 설명해 드릴게요. 에이전트는 요청을 처리하고 응답을 만들어 내는 AG-UI 프로토콜의 핵심 구성 요소예요.

출처: 문서

본문

에이전트(Agent)는 AG-UI 프로토콜에서 요청을 처리하고 응답을 생성하는 핵심 구성 요소예요. 내부 구현이 어떻게 되어 있든 관계없이, 프런트엔드 애플리케이션이 일관된 인터페이스를 통해 AI 서비스와 통신할 수 있도록 표준화된 방식을 만들어 줍니다.

에이전트란 무엇인가요?

AG-UI에서 에이전트는 다음을 수행하는 클래스예요.

  1. 대화 상태와 메시지 히스토리를 관리합니다.
  2. 들어오는 메시지와 컨텍스트를 처리합니다.
  3. 이벤트 기반 스트리밍 인터페이스를 통해 응답을 생성합니다.
  4. 통신을 위한 표준화된 프로토콜을 따릅니다.

에이전트는 어떤 AI 서비스와도 연결되도록 구현할 수 있어요.

  • GPT-4나 Claude 같은 대규모 언어 모델(LLM)
  • 커스텀 AI 시스템
  • 검색 증강 생성(RAG) 시스템
  • 멀티 에이전트 시스템

에이전트 아키텍처

AG-UI의 모든 에이전트는 AbstractAgent 클래스를 상속받아요. 이 클래스는 다음을 위한 기반을 제공합니다.

  • 상태(state) 관리
  • 메시지 히스토리 추적
  • 이벤트 스트림 처리
  • 도구(tool) 사용
import { AbstractAgent } from "@ag-ui/client"

class MyAgent extends AbstractAgent {
  run(input: RunAgentInput): RunAgent {
    // Implementation details
  }
}

핵심 구성 요소

AG-UI 에이전트는 몇 가지 핵심 구성 요소로 이루어져 있어요.

  1. 설정(Configuration): 에이전트 ID, 스레드 ID, 초기 상태
  2. 메시지(Messages): 사용자와 어시스턴트 메시지로 구성된 대화 히스토리
  3. 상태(State): 상호작용 전반에 걸쳐 유지되는 구조화된 데이터
  4. 이벤트(Events): 클라이언트와 통신하기 위한 표준화된 메시지
  5. 도구(Tools): 에이전트가 외부 시스템과 상호작용할 때 사용하는 함수

에이전트 유형

AG-UI는 다양한 요구에 맞춘 여러 에이전트 구현을 제공해요.

AbstractAgent

모든 에이전트가 상속하는 기본 클래스예요. 핵심 이벤트 처리, 상태 관리, 메시지 히스토리를 다룹니다.

HttpAgent

HTTP를 통해 원격 AI 서비스에 연결하는 구체적인 구현이에요.

import { HttpAgent } from "@ag-ui/client"

const agent = new HttpAgent({
  url: "https://your-agent-endpoint.com/agent",
  headers: {
    Authorization: "Bearer your-api-key",
  },
})

커스텀 에이전트

AbstractAgent를 상속해 어떤 AI 서비스와도 통합되는 커스텀 에이전트를 만들 수 있어요.

class CustomAgent extends AbstractAgent {
  // Custom properties and methods

  run(input: RunAgentInput): RunAgent {
    // Implement the agent's logic
  }
}

에이전트 구현하기

기본 구현

커스텀 에이전트를 만들려면 AbstractAgent 클래스를 상속하고 필수 run 메서드를 구현하면 돼요.

import {
  AbstractAgent,
  RunAgent,
  RunAgentInput,
  EventType,
  BaseEvent,
} from "@ag-ui/client"
import { Observable } from "rxjs"

class SimpleAgent extends AbstractAgent {
  run(input: RunAgentInput): RunAgent {
    const { threadId, runId } = input

    return () =>
      new Observable<BaseEvent>((observer) => {
        // Emit RUN_STARTED event
        observer.next({
          type: EventType.RUN_STARTED,
          threadId,
          runId,
        })

        // Send a message
        const messageId = Date.now().toString()

        // Message start
        observer.next({
          type: EventType.TEXT_MESSAGE_START,
          messageId,
          role: "assistant",
        })

        // Message content
        observer.next({
          type: EventType.TEXT_MESSAGE_CONTENT,
          messageId,
          delta: "Hello, world!",
        })

        // Message end
        observer.next({
          type: EventType.TEXT_MESSAGE_END,
          messageId,
        })

        // Emit RUN_FINISHED event
        observer.next({
          type: EventType.RUN_FINISHED,
          threadId,
          runId,
        })

        // Complete the observable
        observer.complete()
      })
  }
}

에이전트의 기능

AG-UI 프로토콜의 에이전트는 정교한 AI 상호작용을 가능하게 하는 풍부한 기능을 제공해요.

양방향 통신

에이전트는 이벤트 스트림을 통해 프런트엔드 애플리케이션과 양방향 통신 채널을 구축해요. 이 덕분에 다음이 가능해집니다.

  • 글자 단위로 실시간 스트리밍되는 응답
  • 사용자와 AI 사이의 즉각적인 피드백 루프
  • 오래 걸리는 작업에 대한 진행 표시기
  • 양방향 구조화된 데이터 교환

도구 사용

에이전트는 도구를 사용해 작업을 수행하고 외부 리소스에 접근할 수 있어요. 중요한 점은 도구가 프런트엔드 애플리케이션에서 에이전트로 전달되어 정의된다는 거예요. 그래서 유연하고 확장 가능한 시스템이 됩니다.

// Tool definition
const confirmAction = {
  name: "confirmAction",
  description: "Ask the user to confirm a specific action before proceeding",
  parameters: {
    type: "object",
    properties: {
      action: {
        type: "string",
        description: "The action that needs user confirmation",
      },
      importance: {
        type: "string",
        enum: ["low", "medium", "high", "critical"],
        description: "The importance level of the action",
      },
      details: {
        type: "string",
        description: "Additional details about the action",
      },
    },
    required: ["action"],
  },
}

// Running an agent with tools from the frontend
agent.runAgent({
  tools: [confirmAction], // Frontend-defined tools passed to the agent
  // other parameters
})

도구는 일련의 이벤트를 통해 호출돼요.

  1. TOOL_CALL_START: 도구 호출의 시작을 알립니다.
  2. TOOL_CALL_ARGS: 도구 호출의 인자를 스트리밍합니다.
  3. TOOL_CALL_END: 도구 호출의 완료를 표시합니다.

그러면 프런트엔드 애플리케이션이 도구를 실행하고 결과를 에이전트에 다시 전달할 수 있어요. 이 양방향 흐름은 정교한 인간-인-더-루프(human-in-the-loop) 워크플로를 가능하게 해요. 그 과정에서:

  • 에이전트가 특정 작업을 수행하도록 요청할 수 있습니다.
  • 인간이 적절한 판단으로 그 작업을 실행할 수 있습니다.
  • 결과는 계속된 추론을 위해 에이전트에 피드백됩니다.
  • 에이전트는 과정에서 내려진 모든 결정을 인식하고 있습니다.

이 메커니즘은 AI와 인간이 협력하는 인터페이스를 구현할 때 특히 강력해요. 예를 들어 CopilotKit은 바로 이 패턴을 useCopilotAction 훅으로 활용하고 있어요. React 애플리케이션에서 도구를 정의하고 다루는 간단한 방법을 제공하죠.

도구 메커니즘을 통해 AI가 인간의 결정을 계속 인지하게 하면, 애플리케이션이 컨텍스트를 유지하고 사용자와 AI 어시스턴트 사이에 더 자연스러운 협업 경험을 만들 수 있어요.

상태 관리

에이전트는 상호작용 전반에 걸쳐 유지되는 구조화된 상태를 관리해요. 이 상태는:

  • STATE_DELTA 이벤트로 점진적으로 갱신될 수 있습니다.
  • STATE_SNAPSHOT 이벤트로 완전히 새로고침될 수 있습니다.
  • 에이전트와 프런트엔드 모두가 접근할 수 있습니다.
  • 사용자 선호도, 대화 컨텍스트, 애플리케이션 상태를 저장하는 데 쓰입니다.
// Accessing agent state
console.log(agent.state.preferences)

// State is automatically updated during agent runs
agent.runAgent().subscribe((event) => {
  if (event.type === EventType.STATE_DELTA) {
    // State has been updated
    console.log("New state:", agent.state)
  }
})

멀티 에이전트 협업

AG-UI는 에이전트 간 핸드오프(handoff)와 협업을 지원해요.

  • 에이전트가 다른 전문화된 에이전트에게 작업을 위임할 수 있습니다.
  • 여러 에이전트가 조정된 워크플로에서 함께 작업할 수 있습니다.
  • 상태와 컨텍스트가 에이전트 간에 전달될 수 있습니다.
  • 프런트엔드는 에이전트 전환 전반에 걸쳐 일관된 경험을 유지합니다.

예를 들어, 일반 어시스턴트 에이전트가 프로그래밍 도움이 필요할 때 전문화된 코딩 에이전트에게 핸드오프하면서 대화 컨텍스트와 특정 요구사항을 함께 넘겨줄 수 있어요.

인간-인-더-루프 워크플로

에이전트는 인간의 개입과 지원을 지원해요.

  • 에이전트가 특정 결정에 대해 인간의 입력을 요청할 수 있습니다.
  • 프런트엔드가 에이전트 실행을 일시 중지했다가 인간의 피드백 후 재개할 수 있습니다.
  • 전문가가 최종 확정 전에 에이전트 출력을 검토하고 수정할 수 있습니다.
  • 하이브리드 워크플로가 AI의 효율성과 인간의 판단을 결합합니다.

이를 통해 에이전트가 자율 시스템이 아니라 협력 파트너로서 동작하는 애플리케이션을 만들 수 있어요.

대화 메모리

에이전트는 대화 메시지의 전체 히스토리를 유지해요.

  • 과거 상호작용이 이후 응답에 영향을 줍니다.
  • 클라이언트와 서버 사이에 메시지 히스토리가 동기화됩니다.
  • 메시지는 텍스트, 구조화된 데이터, 참조 같은 풍부한 콘텐츠를 담을 수 있습니다.
  • 관련 정보에 집중하도록 컨텍스트 윈도우를 관리할 수 있습니다.
// Accessing message history
console.log(agent.messages)

// Adding a new user message
agent.messages.push({
  id: "msg_123",
  role: "user",
  content: "Can you explain that in more detail?",
})

메타데이터와 계측(Instrumentation)

에이전트는 내부 프로세스에 대한 메타데이터를 내보낼 수 있어요.

  • 커스텀 이벤트를 통한 추론 단계
  • 성능 지표와 타이밍 정보
  • 출처 인용과 참조 추적
  • 서로 다른 응답 옵션에 대한 신뢰도 점수

이 덕분에 프런트엔드는 에이전트의 의사결정 과정을 투명하게 보여주고, 사용자가 결론이 어떻게 도출됐는지 이해하도록 도울 수 있어요.

에이전트 사용하기

에이전트를 구현했거나 인스턴스화했다면 이렇게 사용해요.

// Create an agent instance
const agent = new HttpAgent({
  url: "https://your-agent-endpoint.com/agent",
})

// Add initial messages if needed
agent.messages = [
  {
    id: "1",
    role: "user",
    content: "Hello, how can you help me today?",
  },
]

// Run the agent
agent
  .runAgent({
    runId: "run_123",
    tools: [], // Optional tools
    context: [], // Optional context
  })
  .subscribe({
    next: (event) => {
      // Handle different event types
      switch (event.type) {
        case EventType.TEXT_MESSAGE_CONTENT:
          console.log("Content:", event.delta)
          break
        // Handle other events
      }
    },
    error: (error) => console.error("Error:", error),
    complete: () => console.log("Run complete"),
  })

에이전트 설정

에이전트는 생성자(constructor)를 통해 설정을 받아요.

interface AgentConfig {
  agentId?: string // Unique identifier for the agent
  description?: string // Human-readable description
  threadId?: string // Conversation thread identifier
  initialMessages?: Message[] // Initial messages
  initialState?: State // Initial state object
}

// Using the configuration
const agent = new HttpAgent({
  agentId: "my-agent-123",
  description: "A helpful assistant",
  threadId: "thread-456",
  initialMessages: [
    { id: "1", role: "system", content: "You are a helpful assistant." },
  ],
  initialState: { preferredLanguage: "English" },
})

에이전트 상태 관리

AG-UI 에이전트는 상호작용 전반에 걸쳐 상태를 유지해요.

// Access current state
console.log(agent.state)

// Access messages
console.log(agent.messages)

// Clone an agent with its state
const clonedAgent = agent.clone()

결론

에이전트는 AG-UI 프로토콜의 기반이에요. 프런트엔드 애플리케이션을 AI 서비스와 연결하는 표준화된 방법을 제공하죠. AbstractAgent 클래스를 구현하면 애플리케이션에 일관된 인터페이스를 유지하면서 어떤 AI 서비스와도 커스텀 통합을 만들 수 있어요.

이벤트 기반 아키텍처는 현대 AI 애플리케이션에 필수적인 실시간 스트리밍 상호작용을 가능하게 하고, 표준화된 프로토콜은 서로 다른 구현 간 호환성을 보장합니다.

더 알아보기 (Learn more)