에이전트 구축하기
에이전트 구축하기 (ToolLoopAgent)
도구를 쓰는 애플리케이션을 만들다 보면 "모델이 도구를 여러 번 순서대로 호출하며 복잡한 작업을 끝내는" 흐름을 반복해서 구현하게 돼요. ToolLoopAgent는 LLM 설정·도구·행동을 재사용 가능한 컴포넌트로 캡슐화하고, 그 에이전트 루프를 알아서 처리해요. 에이전트를 한 번 정의해 앱 곳곳에서 재사용하는 게 목표예요.
출처: 공식문서
본문
에이전트 만들기
ToolLoopAgent 클래스를 인스턴스화해 정의해요. generateText/streamText와 같은 설정을 모두 받아요.
import { ToolLoopAgent } from 'ai';
const myAgent = new ToolLoopAgent({
model: "xai/grok-4.6",
instructions: 'You are a helpful assistant.',
tools: {
// Your tools here
},
});
- 모델·시스템 지침 —
model과instructions로 에이전트의 역할과 전문성을 정해요. - 도구 —
tools로 작업을 수행할 도구를 제공할 수 있어요. - 컨텍스트와 에이전트 상태 —
runtimeContext를 에이전트의 공유 런타임 상태로 사용해요. 에이전트 루프를 관통하며prepareStep, 라이프사이클 콜백, 최종 결과에서 접근할 수 있어요. 도구가 자격 증명이나 범위 제한 권한 같은 서버 측 값이 필요하면toolsContext로 넘기고 도구의contextSchema로 선언해요.prepareStep에서 반환한 모델 호출 설정은 현재 스텝에만 적용되고, 이후 스텝은 다른 오버라이드를 반환하지 않으면 에이전트의 최상위 설정을 사용해요.
실험용 샌드박스와 도구 승인
에이전트 도구가 명령어나 코드 실행 환경을 필요로 하면 experimental_sandbox를 넘겨요. 샌드박스는 호출 단위 값이라 generate(), stream(), 또는 에이전트 UI 스트림 헬퍼에서 제공해야 해요. 참고로 샌드박스 설명이 모델 프롬프트에 자동 추가되지 않으니, 모델이 환경을 알아야 한다면 직접 포함시켜야 해요. 또 샌드박스를 넘긴다고 도구 자체가 샌드박스되는 건 아니고, 도구가 명시적으로 샌드박스에 작업을 위임해야 해요.
도구 실행 전 승인도 요구할 수 있어요. toolApproval로 도구별 승인 정책을 설정하면(예: runCode: 'user-approval') 수동 승인 UI로 이어져요. 자동 승인·거부, 동적 정책 함수, useChat 통합에 대해서는 Tool Approvals 문서를 참고하면 돼요.
루프 제어
기본적으로 에이전트는 20스텝 동안 실행돼요 (stopWhen: isStepCount(20)). 각 스텝에서 모델은 텍스트를 생성하거나 도구를 호출해요. 텍스트를 생성하면 에이전트가 완료되고, 도구를 호출하면 AI SDK가 그 도구를 실행한 뒤 다음 생성으로 이어져요. stopWhen을 바꿔 더 많은 스텝을 허용할 수 있고, isStepCount(50)처럼 숫자를 늘리거나 커스텀 조건과 배열로 조합할 수 있어요.
루프는 다음 조건 중 하나가 만족될 때까지 계속돼요.
tool-calls가 아닌 finish reason이 반환되거나- 호출된 도구에
execute함수가 없거나 - 도구 호출에 승인이 필요하거나
- 정지 조건이 충족되거나
도구 선택과 구조화 출력
toolChoice로 도구 사용을 제어할 수 있어요. 'required'(도구 사용 강제), 'none'(도구 비활성), 'auto'(기본, 모델이 결정)를 쓰고, { type: 'tool', toolName: 'weather' }처럼 특정 도구를 강제할 수도 있어요. 구조화 출력은 Output.object({ schema })로 스키마를 정의하면 generate() 결과의 output에서 타입 있는 값을 받아요.
시스템 지침으로 행동 정의하기
instructions로 에이전트의 행동·성격·제약을 정의해요. 모든 상호작용의 컨텍스트를 세우고 사용자 질문에 어떻게 응답하고 도구를 어떻게 쓰는지 안내하죠. 간단한 역할·전문성 정의부터, 보안 취약점 우선 검토 같은 세부 행동 지침, 쇼핑몰 고객지원 규칙 같은 제약, 검색·문서 도구 사용법 지침, 마크다운 형식·2인칭 문체 같은 형식·스타일 지침까지 다양하게 쓸 수 있어요.
에이전트 사용하기
정의한 에이전트는 세 가지 방식으로 사용할 수 있어요.
generate()— 일회성 텍스트 생성.const result = await myAgent.generate({ prompt })후result.text로 접근.stream()— 스트리밍 응답.result.textStream을 순회.createAgentUIStreamResponse()— 클라이언트 앱용 API 응답 생성. API 라우트에서uiMessages와 함께 호출하면 useChat 기반 UI와 바로 연결돼요.
라이프사이클 콜백과 타입 안전성
에이전트는 onStart, onStepStart, onToolExecutionStart, onToolExecutionEnd, onStepEnd, onEnd 콜백을 제공해 로깅·관찰성·디버깅·커스텀 텔레메트리에 쓸 수 있어요. 콜백은 생성자(에이전트 전역 추적)와 generate()/stream() 호출(호출별 추적) 양쪽에 정의할 수 있고, 둘 다 있으면 생성자 콜백이 먼저 실행된 뒤 메서드 콜백이 실행돼요.
타입 안전성도 신경 써요. InferAgentUIMessage<typeof myAgent>로 에이전트의 UIMessage 타입을 추론해 UI 컴포넌트나 영속화에 쓰고, 클라이언트에서는 useChat<MyAgentUIMessage>()로 메시지와 도구에 대한 완전한 타입을 얻을 수 있어요.