Tool Invocation 결과 누락 오류

Tool Invocation 결과 누락 오류 (Tool Invocation Missing Result Error)

generateText()나 streamText()를 쓸 때 "ToolInvocation must have a result" 오류가 나는 상황을 다루는 문서예요. execute 함수가 없는 도구를 호출했을 때 이 오류가 나며, 도구 결과를 서버에서 처리하거나 클라이언트에서 반드시 제공해야 한다는 게 핵심이에요.

출처: 문서

본문

문제 (Issue)

generateText() 또는 streamText()를 사용할 때, execute 함수가 없는 도구가 호출되면 "ToolInvocation must have a result" 오류가 발생할 수 있습니다.

원인 (Cause)

execute 함수가 없는 도구를 정의하고, 다른 수단(예: useChat의 onToolCall이나 addToolOutput 함수)으로 결과를 제공하지 않으면 오류가 발생합니다.

도구가 호출될 때마다 모델은 대화를 계속하기 전에 결과를 받을 것을 기대합니다. 결과가 없으면 모델은 도구 호출이 성공했는지 실패했는지 판단할 수 없고 대화 상태가 유효하지 않게 됩니다.

해결 방법 (Solution)

도구 결과를 처리하는 방법은 두 가지가 있습니다:

  1. execute 함수가 있는 도구를 사용한 서버 측 실행:
const tools = {
  weather: tool({
    description: 'Get the weather in a location',
    inputSchema: z.object({
      location: z
        .string()
        .describe('The city and state, e.g. "San Francisco, CA"'),
    }),
    execute: async ({ location }) => {
      // Fetch and return weather data
      return { temperature: 72, conditions: 'sunny', location };
    },
  }),
};
  1. useChat를 사용한 클라이언트 측 실행(execute 함수 생략)에서는 addToolOutput으로 결과를 반드시 제공해야 합니다:
import { useChat } from '@ai-sdk/react';
import {
  DefaultChatTransport,
  lastAssistantMessageIsCompleteWithToolCalls,
} from 'ai';

const { messages, sendMessage, addToolOutput } = useChat({
  // Automatically submit when all tool results are available
  sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,

  // Handle tool calls in onToolCall
  onToolCall: async ({ toolCall }) => {
    if (toolCall.toolName === 'getLocation') {
      try {
        const result = await getLocationData();

        // Important: Don't await inside onToolCall to avoid deadlocks
        addToolOutput({
          tool: 'getLocation',
          toolCallId: toolCall.toolCallId,
          output: result,
        });
      } catch (err) {
        // Important: Don't await inside onToolCall to avoid deadlocks
        addToolOutput({
          tool: 'getLocation',
          toolCallId: toolCall.toolCallId,
          state: 'output-error',
          errorText: 'Failed to get location',
        });
      }
    }
  },
});
// For interactive UI elements:
const { messages, sendMessage, addToolOutput } = useChat({
  transport: new DefaultChatTransport({ api: '/api/chat' }),
  sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
});

// Inside your JSX, when rendering tool calls:
<button
  onClick={() =>
    addToolOutput({
      tool: 'myTool',
      toolCallId, // must provide tool call ID
      output: {
        /* your tool result */
      },
    })
  }
>
  Confirm
</button>;

경고: 서버에서든 클라이언트에서든 도구를 처리하든, 대화가 계속되기 전에 각 도구 호출에는 대응하는 결과가 있어야 합니다.

더 알아보기 (Learn more)

전체 사이트맵