convertToModelMessages() — UI 메시지를 모델 메시지로 변환
convertToModelMessages() — UI 메시지를 모델 메시지로 변환
convertToModelMessages 함수는 useChat 훅의 UI 메시지 배열을 ModelMessage 객체 배열로 변환하는 데 사용해요. 이 ModelMessage 객체들은 streamText 같은 AI 코어 함수와 호환돼요. 서버 쪽 라우트 핸들러에서 UI 메시지를 다시 모델로 보낼 때 사용해요.
출처: 문서
본문
convertToModelMessages 함수는 useChat 훅의 UI 메시지 배열을 ModelMessage 객체 배열로 변환하는 데 사용해요. 이 ModelMessage 객체들은 streamText 같은 AI 코어 함수와 호환돼요.
import {
convertToModelMessages,
createUIMessageStreamResponse,
streamText,
toUIMessageStream,
} from 'ai';
__PROVIDER_IMPORT__;
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: __MODEL__,
messages: await convertToModelMessages(messages),
});
return createUIMessageStreamResponse({
stream: toUIMessageStream({ stream: result.stream }),
});
}
Import
import { convertToModelMessages } from "ai"
API 시그니처
파라미터
messages:Message[]— 변환할 useChat 훅의 UI 메시지 배열.options:{ tools?: ToolSet, ignoreIncompleteToolCalls?: boolean, convertDataPart?: (part: DataUIPart) => TextPart | FilePart | undefined }— 선택적 구성 객체. 멀티모달 도구 응답을 활성화하려면 도구를 제공하세요. 결과 없는 도구 호출을 건너뛰려면ignoreIncompleteToolCalls를 true로 설정하세요 (기본값: false). 커스텀 데이터 part를 모델 호환 콘텐츠로 변환하려면convertDataPart를 사용하세요.
반환값
ModelMessage 객체 배열로 resolve되는 Promise를 반환해요.
Promise<ModelMessage[]>:Promise— ModelMessage 객체 배열로 resolve되는 Promise.
rawInput 필드 (deprecated)
output-error 상태의 도구 part는 도구 인자를 input에 저장해야 해요. 레거시 rawInput 필드는 영속된 메시지에 대해 계속 지원되지만, convertToModelMessages는 정의된 값을 만나면 AI SDK deprecation 경고를 내보내요.
두 필드가 모두 존재할 때 input이 non-nullish이면 우선해요. 하위 호환을 위해 input이 null 또는 undefined일 때는 rawInput이 대체값으로 남아요. rawInput이 제거될 다음 메이저 버전 전에 저장된 메시지를 input으로 마이그레이션하세요.
도구 승인 상태 (Tool Approval States)
convertToModelMessages는 UI 메시지를 후속 generateText 또는 streamText 호출을 위한 ModelMessage로 다시 변환할 때 도구 승인 상태를 보존해요.
- 승인 메타데이터가 있는 도구 part는
tool-approval-request콘텐츠 part를 만들어요.approval.requestReason은 있을 때 요청reason으로 전달돼요. approval-responded상태의 도구 part도tool-approval-response콘텐츠 part가 돼요. 별도의 응답reason은 있을 때 전달돼요.- 자동 승인 메타데이터는
approval.isAutomatic을tool-approval-requestpart로 전달해 보존돼요. - 거부된 도구 승인은
output: { type: 'execution-denied', reason?: string }을 가진 합성tool-result도 만들어, 모델이 완전한 도구 라이프사이클을 받고 다음 단계에서 거부에 응답할 수 있게 해요.
멀티모달 도구 응답 (Multi-modal Tool Responses)
convertToModelMessages 함수는 멀티모달 콘텐츠를 반환할 수 있는 도구를 지원해요. 이미지 같은 비텍스트 콘텐츠를 반환해야 하는 도구에 유용해요.
import { tool } from 'ai';
__PROVIDER_IMPORT__;
import { z } from 'zod';
const screenshotTool = tool({
inputSchema: z.object({}),
execute: async () => 'imgbase64',
toModelOutput: ({ output }) => [
{ type: 'file-data', data: output, mediaType: 'image/png' },
],
});
const result = streamText({
model: __MODEL__,
messages: convertToModelMessages(messages, {
tools: {
screenshot: screenshotTool,
},
}),
});
도구는 선택적 toModelOutput 메서드를 구현해 결과를 멀티모달 콘텐츠로 변환할 수 있어요. 콘텐츠는 콘텐츠 part의 배열이며, 각 part는 type (예: 'text', 'image')과 해당 데이터를 가져요.
커스텀 데이터 part 변환 (Custom Data Part Conversion)
convertToModelMessages 함수는 사용자 메시지에 첨부된 커스텀 데이터 part 변환을 지원해요. 사용자가 메시지에 추가 컨텍스트(URL, 코드 파일, JSON 구성)를 포함해야 할 때 유용해요.
기본 사용
기본적으로 사용자 메시지의 데이터 part는 변환 중 필터링돼요. 이들을 포함하려면 데이터 part를 모델이 이해할 수 있는 텍스트나 파일 part로 변환하는 convertDataPart 콜백을 제공하세요:
import {
convertToModelMessages,
createUIMessageStreamResponse,
streamText,
toUIMessageStream,
} from 'ai';
type CustomUIMessage = UIMessage<
never,
{
url: { url: string; title: string; content: string };
'code-file': { filename: string; code: string; language: string };
}
>;
export async function POST(req: Request) {
const { messages } = await req.json();
const result = streamText({
model: __MODEL__,
messages: convertToModelMessages<CustomUIMessage>(messages, {
convertDataPart: part => {
// URL 첨부를 텍스트로 변환
if (part.type === 'data-url') {
return {
type: 'text',
text: `[Reference: ${part.data.title}](${part.data.url})\n\n${part.data.content}`,
};
}
// 코드 파일 첨부 변환
if (part.type === 'data-code-file') {
return {
type: 'text',
text: `\`\`\`${part.data.language}\n// ${part.data.filename}\n${part.data.code}\n\`\`\``,
};
}
// 그 외의 데이터 part는 무시
},
}),
});
return createUIMessageStreamResponse({
stream: toUIMessageStream({ stream: result.stream }),
});
}
사용 사례
URL 콘텐츠 첨부 — 사용자가 메시지에 URL을 첨부할 수 있게 하고, 콘텐츠를 모델을 위해 가져와 형식화하는 예:
// 클라이언트 쪽
sendMessage({
parts: [
{ type: 'text', text: 'Analyze this article' },
{
type: 'data-url',
data: {
url: 'https://example.com/article',
title: 'Important Article',
content: '...',
},
},
],
});
코드 파일을 컨텍스트로 포함 — 사용자가 대화에서 코드 파일을 참조할 수 있게 하는 예:
convertDataPart: part => {
if (part.type === 'data-code-file') {
return {
type: 'text',
text: `\`\`\`${part.data.language}\n${part.data.code}\n\`\`\``,
};
}
};
선택적 포함 — 텍스트나 파일 모델 메시지 part를 반환한 데이터 part만 포함되고, 다른 데이터 part는 모두 무시돼요.
const result = convertToModelMessages<
UIMessage<
unknown,
{
url: { url: string; title: string };
code: { code: string; language: string };
note: { text: string };
}
>
>(messages, {
convertDataPart: part => {
if (part.type === 'data-url') {
return {
type: 'text',
text: `[${part.data.title}](${part.data.url})`,
};
}
// data-code와 data-node는 무시
},
});
타입 안전성
제네릭 파라미터는 커스텀 데이터 part에 대한 완전한 타입 안전성을 보장해요:
type MyUIMessage = UIMessage<
unknown,
{
url: { url: string; content: string };
config: { key: string; value: string };
}
>;
// TypeScript는 part.data의 정확한 형태를 알아요
convertToModelMessages<MyUIMessage>(messages, {
convertDataPart: part => {
if (part.type === 'data-url') {
// part.data는 { url: string; content: string }로 타입화됨
return { type: 'text', text: part.data.url };
}
// 이 part를 건너뛰려면 undefined 반환
},
});
더 알아보기 (Learn more)
- useChat — 채팅 훅
- createUIMessageStream — UI 메시지 스트림 만들기