DirectChatTransport — HTTP 없이 에이전트와 직접 통신
DirectChatTransport — HTTP 없이 에이전트와 직접 통신
DirectChatTransport는 Agent와 in-process로 직접 통신하는 트랜스포트예요. HTTP를 거치지 않고요. 다음과 같은 상황에서 유용해요:
- 서버 사이드 렌더링 시나리오
- 네트워크 없이 테스트하기
- 단일 프로세스 애플리케이션
출처: 문서
본문
Agent와 in-process로 직접 통신하는 트랜스포트예요. HTTP를 거치지 않고요. 다음과 같은 상황에서 유용해요:
- 서버 사이드 렌더링 시나리오
- 네트워크 없이 테스트하기
- 단일 프로세스 애플리케이션
DefaultChatTransport가 API 엔드포인트에 HTTP 요청을 보내는 것과 달리, DirectChatTransport는 에이전트의 stream() 메서드를 직접 호출하고 결과를 UI 메시지 스트림으로 변환해요.
import { useChat } from '@ai-sdk/react';
import { DirectChatTransport, ToolLoopAgent } from 'ai';
__PROVIDER_IMPORT__;
const agent = new ToolLoopAgent({
model: __MODEL__,
instructions: 'You are a helpful assistant.',
});
export default function Chat() {
const { messages, sendMessage, status } = useChat({
transport: new DirectChatTransport({ agent }),
});
// ... render chat UI
}
Import
import { DirectChatTransport } from "ai"
생성자 (Constructor)
파라미터
agent:Agent(필수) — 응답 생성에 사용할 Agent 인스턴스. 각 메시지에 대해 에이전트가stream()으로 호출돼요.options:CALL_OPTIONS(선택) — 에이전트를 호출할 때 넘길 옵션. 에이전트를 만들 때 정의한 에이전트 특정 옵션이에요.originalMessages:UIMessage[](선택) — 원본 메시지. 제공하면 영속 모드로 간주되고 응답 메시지에 메시지 ID가 제공돼요.generateMessageId:IdGenerator(선택) — 응답 메시지의 메시지 ID를 생성해요. 제공하지 않으면 응답 메시지에 메시지 ID가 설정되지 않아요.messageMetadata:(options: { part: TextStreamPart }) => METADATA | undefined(선택) — 클라이언트로 보낼 메시지 메타데이터를 추출해요.start와finish이벤트에서 호출돼요.sendReasoning:boolean(선택) — reasoning 부분을 클라이언트로 보낼지 여부. 기본값은 true.sendSources:boolean(선택) — source 부분을 클라이언트로 보낼지 여부. 기본값은 false.sendFinish:boolean(선택) — finish 이벤트를 클라이언트로 보낼지 여부. 추가 데이터를 보내는 추가 streamText 호출을 사용한다면 false로 설정하세요. 기본값은 true.sendStart:boolean(선택) — 메시지 start 이벤트를 클라이언트로 보낼지 여부. 추가 streamText 호출을 사용하고 메시지 start 이벤트를 이미 보냈다면 false로 설정하세요. 기본값은 true.onError:(error: unknown) => string(선택) — 에러를 처리합니다 (예: 로깅). 기본값은() => 'An error occurred.'. 데이터 스트림에 포함할 에러 메시지를 반환해요.
메서드
sendMessages()
메시지를 에이전트로 보내고 스트리밍 응답을 반환해요. 이 메서드는 UI 메시지를 검증하고 모델 메시지로 변환하며, 에이전트의 stream() 메서드를 호출하고 결과를 UI 메시지 스트림으로 반환해요.
const stream = await transport.sendMessages({
chatId: 'chat-123',
trigger: 'submit-message',
messages: [...],
abortSignal: controller.signal,
});
chatId:string— 채팅 세션의 고유 식별자.trigger:'submit-message' | 'regenerate-message'— 메시지 제출 유형 — 새 메시지 또는 재생성.messageId:string | undefined— 재생성할 메시지의 ID, 새 메시지면 undefined.messages:UIMessage[]— 대화 기록을 나타내는 UI 메시지 배열.abortSignal:AbortSignal | undefined— 필요 시 요청을 중단하는 신호.headers:Record<string, string> | Headers(선택) — 추가 헤더 (DirectChatTransport는 무시).body:object(선택) — 추가 body 속성 (DirectChatTransport는 무시).metadata:unknown(선택) — 커스텀 메타데이터 (DirectChatTransport는 무시).
반환값
Promise<ReadableStream<UIMessageChunk>>를 반환해요 — 채팅 UI가 처리할 수 있는 UI 메시지 청크의 스트림이에요.
reconnectToStream()
직접 트랜스포트는 재연결할 영속 서버 측 스트림이 없으므로 재연결을 지원하지 않아요.
반환값
항상 Promise<null>을 반환해요.
예시
기본 사용
import { useChat } from '@ai-sdk/react';
import { DirectChatTransport, ToolLoopAgent } from 'ai';
import { openai } from '@ai-sdk/openai';
const agent = new ToolLoopAgent({
model: openai('gpt-6-astra'),
instructions: 'You are a helpful assistant.',
});
export default function Chat() {
const { messages, sendMessage, status } = useChat({
transport: new DirectChatTransport({ agent }),
});
return (
<div>
{messages.map(message => (
<div key={message.id}>
{message.role === 'user' ? 'User: ' : 'AI: '}
{message.parts.map((part, index) =>
part.type === 'text' ? <span key={index}>{part.text}</span> : null,
)}
</div>
))}
<button onClick={() => sendMessage({ text: 'Hello!' })}>Send</button>
</div>
);
}
에이전트 도구와 함께
import { useChat } from '@ai-sdk/react';
import { DirectChatTransport, ToolLoopAgent, tool } from 'ai';
import { openai } from '@ai-sdk/openai';
import { z } from 'zod';
const weatherTool = tool({
description: 'Get the current weather',
inputSchema: z.object({
location: z.string().describe('The city and state'),
}),
execute: async ({ location }) => {
return `The weather in ${location} is sunny and 72°F.`;
},
});
const agent = new ToolLoopAgent({
model: openai('gpt-6-astra'),
instructions: 'You are a helpful assistant with access to weather data.',
tools: { weather: weatherTool },
});
export default function Chat() {
const { messages, sendMessage } = useChat({
transport: new DirectChatTransport({ agent }),
});
// ... render chat UI with tool results
}
커스텀 에이전트 옵션과 함께
import { useChat } from '@ai-sdk/react';
import { DirectChatTransport, ToolLoopAgent } from 'ai';
import { openai } from '@ai-sdk/openai';
const agent = new ToolLoopAgent<{ userId: string }>({
model: openai('gpt-6-astra'),
prepareCall: ({ options, ...rest }) => ({
...rest,
providerOptions: {
openai: { user: options.userId },
},
}),
});
export default function Chat({ userId }: { userId: string }) {
const { messages, sendMessage } = useChat({
transport: new DirectChatTransport({
agent,
options: { userId },
}),
});
// ... render chat UI
}
Reasoning과 함께
import { useChat } from '@ai-sdk/react';
import { DirectChatTransport, ToolLoopAgent } from 'ai';
import { openai } from '@ai-sdk/openai';
const agent = new ToolLoopAgent({
model: openai('o1-preview'),
});
export default function Chat() {
const { messages, sendMessage } = useChat({
transport: new DirectChatTransport({
agent,
sendReasoning: true,
}),
});
return (
<div>
{messages.map(message => (
<div key={message.id}>
{message.parts.map((part, index) => {
if (part.type === 'text') {
return <p key={index}>{part.text}</p>;
}
if (part.type === 'reasoning') {
return (
<pre key={index} style={{ opacity: 0.6 }}>
{part.text}
</pre>
);
}
return null;
})}
</div>
))}
</div>
);
}
더 알아보기 (Learn more)
- useChat — 채팅 훅
- createUIMessageStream — UI 메시지 스트림 만들기