Skip to content

프론트엔드 액션 (Frontend Actions)

에이전트가 앱에서 직접 행동하게 하기

프론트엔드 액션은 에이전트가 호출하는 도구로, 서버가 아니라 브라우저에서 코드를 실행해요. 모델이 호출을 결정하면, 여러분의 핸들러가 테마를 바꾸거나, 화면을 이동하거나, 요소를 강조하거나, 앱 데이터를 갱신하고, 그 결과가 다시 에이전트로 흘러갑니다.

이 액션은 도구 기반 생성형 UI와 같은 훅인 useFrontendTool을 사용해요. 차이는 무엇을 넘겨주느냐에 있는데, UI를 그리는 render 대신(혹은 곁들여서) 코드를 실행하는 handler를 넘겨준다는 점이죠.

프론트엔드 액션은 Crews와 Flows 모두에서 동작해요. copilotkit.actions를 LLM 호출에 바인딩하는 에이전트라면 누구나 호출할 수 있습니다.

프론트엔드 액션 만들기

아래 예시는 에이전트가 요청에 따라 앱을 다크 모드로 전환하게 해줍니다.

1단계 — 프론트엔드에서 액션 등록하기

useFrontendToolhandler와 함께 호출해요. 이 핸들러는 에이전트가 도구를 호출했을 때 브라우저에서 실행되고, 반환하는 문자열이 다시 에이전트에게 전달됩니다.

"use client";
import { useFrontendTool } from "@copilotkit/react-core/v2";
import { z } from "zod";

useFrontendTool({
  agentId: "assistant",
  name: "set_theme",
  description: "Switch the app between light and dark mode.",
  parameters: z.object({
    theme: z.enum(["light", "dark"]),
  }),
  followUp: false,
  handler: async ({ theme }) => {
    document.documentElement.dataset.theme = theme; // runs in the browser
    return `Theme set to ${theme}.`;
  },
});

각 인자를 살펴볼게요.

  • name — 모델이 호출하는 도구 이름입니다(set_theme).
  • description — 도구가 무엇을 하는지 짧게 설명합니다. 모델은 이 설명을 읽고 언제 도구를 호출할지 판단하므로 구체적으로 적어야 해요. 생략하면 모델은 이름만 보고 짐작할 수밖에 없습니다.
  • parameters — 모델이 제공해야 하는 인자를 설명하는 zod 스키마입니다. CopilotKit은 이를 도구의 JSON 스키마로 바꾸고 들어오는 호출을 검증해요.
  • handler(args) — 파싱된 인자와 함께 브라우저에서 실행됩니다. 부수 효과(테마 설정, 이동, 상태 갱신)를 여기서 처리하고, 반환하는 문자열이 도구 결과로 에이전트에게 전달돼요.
  • followUp: false — 액션이 실행된 뒤 에이전트가 다음 턴을 진행하지 않게 막습니다. 액션 후 에이전트가 응답하길 원하면 생략하거나 true로 설정하세요.

2단계 — 백엔드에서 프론트엔드 도구 바인딩하기

에이전트는 자기에게 주어진 도구만 호출할 수 있어요. Flow에서 프론트엔드에 등록된 도구를 *self.state.copilotkit.actions로 LLM tools 목록에 넘겨주세요.

from crewai.flow.flow import Flow, start
from litellm import acompletion
from ag_ui_crewai.sdk import copilotkit_stream, CopilotKitState

class AssistantFlow(Flow[CopilotKitState]):
    @start()
    async def chat(self):
        response = await copilotkit_stream(
            await acompletion(
                model="openai/gpt-4o",
                messages=[
                    {"role": "system", "content": "Help the user. Use the tools available to control the app."},
                    *self.state.messages,
                ],
                tools=[*self.state.copilotkit.actions],  # tools the frontend registered
                parallel_tool_calls=False,
                stream=True,
            )
        )
        message = response.choices[0].message
        self.state.messages.append(message)

self.state.copilotkit.actions에는 useFrontendTool로 등록된 모든 프론트엔드 액션의 도구 정의가 담겨 있어요. 이걸 LLM tools 목록에 펼쳐 넣어야 에이전트가 브라우저 쪽 액션을 호출할 수 있습니다. copilotkit_stream은 도구 호출을 포함한 응답을 프론트엔드로 스트리밍하고, CopilotKit이 그에 맞는 핸들러를 실행해요.

3단계 — Flow 서빙하기

Flow를 add_crewai_flow_fastapi_endpoint(...)로 AG-UI 위에 노출하고 프론트엔드 개요에서와 마찬가지로 CopilotKit 런타임에 등록합니다. 둘 다 실행되면, 어시스턴트에게 "다크 모드로 바꿔줘"라고 말하는 것만으로 set_theme이 호출되고 페이지가 바뀝니다.

액션 vs 생성형 UI

useFrontendTool은 스펙트럼의 양쪽 끝을 모두 다루며, 도구마다 원하는 쪽을 고르면 돼요.

제공하는 것 동작
handler 브라우저에서 코드를 실행합니다(프론트엔드 액션)
render 도구 호출에 대한 UI를 그립니다(생성형 UI)

둘 중 하나만 제공해도 되고, 둘 다 제공해도 됩니다. handlerrender를 곁들이면 액션을 수행하면서 동시에 UI를 그려요. 에이전트 액션의 결과만 표시하는 render 전용 도구는 도구 기반 생성형 UI를 참고하세요.

관련 문서