호출 옵션 설정

호출 옵션 설정 (Configuring Call Options)

호출 옵션(call options)으로 에이전트에 타입 안전한 구조화된 입력을 전달하는 방법을 설명하는 문서예요. 특정 요청에 따라 어떤 에이전트 설정이든 동적으로 수정할 수 있어요.

출처: 문서

본문

호출 옵션은 에이전트에 타입 안전한 구조화된 입력을 전달할 수 있게 해 줘요. 특정 요청에 따라 에이전트 설정을 동적으로 수정하는 데 사용하세요.

왜 호출 옵션을 사용하나요? (Why Use Call Options?)

런타임 입력에 따라 에이전트 동작을 바꿔야 할 때 필요해요:

  • 동적 컨텍스트 추가 (Add dynamic context) - 검색된 문서, 사용자 선호도, 세션 데이터를 프롬프트에 주입해요
  • 모델 동적 선택 (Select models dynamically) - 요청 복잡성에 따라 더 빠르거나 더 강력한 모델을 선택해요
  • 요청별 툴 구성 (Configure tools per request) - 검색 툴에 사용자 위치를 전달하거나 툴 동작을 조정해요
  • 프로바이더 옵션 커스터마이즈 (Customize provider options) - reasoning effort, temperature, 기타 프로바이더별 설정을 지정해요

호출 옵션이 없으면 여러 에이전트를 만들거나 에이전트 밖에서 설정 로직을 처리해야 해요.

동작 방식 (How It Works)

호출 옵션을 세 단계로 정의해요:

  1. 스키마 정의 - callOptionsSchema로 받아들일 입력을 지정해요
  2. prepareCall로 구성 - 그 입력을 사용해 에이전트 설정을 수정해요
  3. 런타임에 옵션 전달 - generate() 또는 stream()을 호출할 때 옵션을 제공해요

기본 예제 (Basic Example)

런타임에 에이전트의 프롬프트에 사용자 컨텍스트를 추가해요:

import { ToolLoopAgent } from 'ai';
__PROVIDER_IMPORT__;
import { z } from 'zod';

const supportAgent = new ToolLoopAgent({
  model: __MODEL__,
  callOptionsSchema: z.object({
    userId: z.string(),
    accountType: z.enum(['free', 'pro', 'enterprise']),
  }),
  instructions: 'You are a helpful customer support agent.',
  prepareCall: ({ options, ...settings }) => ({
    ...settings,
    instructions:
      settings.instructions +
      `\nUser context:
- Account type: ${options.accountType}
- User ID: ${options.userId}

Adjust your response based on the user's account level.`,
  }),
});

// Call the agent with specific user context
const result = await supportAgent.generate({
  prompt: 'How do I upgrade my account?',
  options: {
    userId: 'user_123',
    accountType: 'free',
  },
});

이제 options 매개변수는 필수이며 타입 검사가 돼요. 제공하지 않거나 잘못된 타입을 전달하면 TypeScript가 오류를 내요.

에이전트 설정 수정 (Modifying Agent Settings)

prepareCall을 사용해 어떤 에이전트 설정이든 수정할 수 있어요. 변경하려는 설정만 반환하면 돼요.

동적 모델 선택 (Dynamic Model Selection)

요청 특성에 따라 모델을 선택해요:

import { ToolLoopAgent } from 'ai';
__PROVIDER_IMPORT__;
import { z } from 'zod';

const agent = new ToolLoopAgent({
  model: __MODEL__, // Default model
  callOptionsSchema: z.object({
    complexity: z.enum(['simple', 'complex']),
  }),
  prepareCall: ({ options, ...settings }) => ({
    ...settings,
    model:
      options.complexity === 'simple'
        ? 'openai/gpt-6-luna'
        : 'openai/gpt-6-astra',
  }),
});

// Use faster model for simple queries
await agent.generate({
  prompt: 'What is 2+2?',
  options: { complexity: 'simple' },
});

// Use more capable model for complex reasoning
await agent.generate({
  prompt: 'Explain quantum entanglement',
  options: { complexity: 'complex' },
});

동적 툴 구성 (Dynamic Tool Configuration)

런타임 입력에 따라 툴을 구성해요:

import { openai } from '@ai-sdk/openai';
import { ToolLoopAgent } from 'ai';
__PROVIDER_IMPORT__;
import { z } from 'zod';

const newsAgent = new ToolLoopAgent({
  model: __MODEL__,
  callOptionsSchema: z.object({
    userCity: z.string().optional(),
    userRegion: z.string().optional(),
  }),
  tools: {
    web_search: openai.tools.webSearch(),
  },
  prepareCall: ({ options, ...settings }) => ({
    ...settings,
    tools: {
      web_search: openai.tools.webSearch({
        searchContextSize: 'low',
        userLocation: {
          type: 'approximate',
          city: options.userCity,
          region: options.userRegion,
          country: 'US',
        },
      }),
    },
  }),
});

await newsAgent.generate({
  prompt: 'What are the top local news stories?',
  options: {
    userCity: 'San Francisco',
    userRegion: 'California',
  },
});

프로바이더별 옵션 (Provider-Specific Options)

프로바이더 설정을 동적으로 구성해요:

import { OpenAILanguageModelResponsesOptions } from '@ai-sdk/openai';
import { ToolLoopAgent } from 'ai';
import { z } from 'zod';

const agent = new ToolLoopAgent({
  model: 'openai/gpt-6-astra',
  callOptionsSchema: z.object({
    taskDifficulty: z.enum(['low', 'medium', 'high']),
  }),
  prepareCall: ({ options, ...settings }) => ({
    ...settings,
    providerOptions: {
      openai: {
        reasoningEffort: options.taskDifficulty,
      } satisfies OpenAILanguageModelResponsesOptions,
    },
  }),
});

await agent.generate({
  prompt: 'Analyze this complex scenario...',
  options: { taskDifficulty: 'high' },
});

고급 패턴 (Advanced Patterns)

검색 증강 생성 (Retrieval Augmented Generation / RAG)

관련 컨텍스트를 가져와 프롬프트에 주입해요:

import { ToolLoopAgent } from 'ai';
__PROVIDER_IMPORT__;
import { z } from 'zod';

const ragAgent = new ToolLoopAgent({
  model: __MODEL__,
  callOptionsSchema: z.object({
    query: z.string(),
  }),
  prepareCall: async ({ options, ...settings }) => {
    // Fetch relevant documents (this can be async)
    const documents = await vectorSearch(options.query);

    return {
      ...settings,
      instructions: `Answer questions using the following context:

${documents.map(doc => doc.content).join('\n\n')}`,
    };
  },
});

await ragAgent.generate({
  prompt: 'What is our refund policy?',
  options: { query: 'refund policy' },
});

prepareCall 함수는 비동기일 수 있어서, 에이전트를 구성하기 전에 데이터를 가져올 수 있어요.

여러 수정 결합 (Combining Multiple Modifications)

여러 설정을 함께 수정해요:

import { ToolLoopAgent } from 'ai';
__PROVIDER_IMPORT__;
import { z } from 'zod';

const agent = new ToolLoopAgent({
  model: __MODEL__,
  callOptionsSchema: z.object({
    userRole: z.enum(['admin', 'user']),
    urgency: z.enum(['low', 'high']),
  }),
  tools: {
    readDatabase: readDatabaseTool,
    writeDatabase: writeDatabaseTool,
  },
  prepareCall: ({ options, ...settings }) => ({
    ...settings,
    // Upgrade model for urgent requests
    model: options.urgency === 'high' ? __MODEL__ : settings.model,
    // Limit tools based on user role
    activeTools:
      options.userRole === 'admin'
        ? ['readDatabase', 'writeDatabase']
        : ['readDatabase'],
    // Adjust instructions
    instructions: `You are a ${options.userRole} assistant.
${options.userRole === 'admin' ? 'You have full database access.' : 'You have read-only access.'}`,
  }),
});

await agent.generate({
  prompt: 'Update the user record',
  options: {
    userRole: 'admin',
    urgency: 'high',
  },
});

createAgentUIStreamResponse와 함께 사용 (Using with createAgentUIStreamResponse)

API 라우트를 통해 호출 옵션을 에이전트에 전달해요:

import { createAgentUIStreamResponse } from 'ai';
import { myAgent } from '@/ai/agents/my-agent';

export async function POST(request: Request) {
  const { messages, userId, accountType } = await request.json();

  return createAgentUIStreamResponse({
    agent: myAgent,
    messages,
    options: {
      userId,
      accountType,
    },
  });
}

다음 단계 (Next Steps)

더 알아보기 (Learn more)