스트리밍
Agents SDK는 모델과 기타 실행 단계의 출력을 점진적으로 전달할 수 있습니다. 스트리밍은 UI를 반응성 있게 유지하고, 전체 최종 결과를 기다리지 않고 사용자에게 업데이트할 수 있게 합니다.
스트리밍 활성화
섹션 제목: “스트리밍 활성화”Runner.run()에 { stream: true } 옵션을 전달하여 전체 결과 대신 스트리밍 객체를 받습니다:
import { Agent, run } from '@openai/agents';
const agent = new Agent({ name: 'Storyteller', instructions: 'You are a storyteller. You will be given a topic and you will tell a story about it.',});
const result = await run(agent, 'Tell me a story about a cat.', { stream: true,});스트리밍이 활성화되면 반환된 stream은 AsyncIterable 인터페이스를 구현합니다. 각 전달된 이벤트는 실행 중에 일어난 일을 설명하는 객체입니다. 스트림은 에이전트 실행의 서로 다른 부분을 설명하는 세 가지 이벤트 유형 중 하나를 방출합니다. 대부분의 애플리케이션은 모델의 텍스트만 필요하므로, 스트림은 이를 위한 헬퍼를 제공합니다.
텍스트 출력 가져오기
섹션 제목: “텍스트 출력 가져오기”stream.toTextStream()을 호출하여 방출된 텍스트의 스트림을 얻습니다. compatibleWithNodeStreams가 true이면 반환값은 일반 Node.js Readable입니다. 이를 process.stdout 또는 다른 대상으로 바로 파이프할 수 있습니다.
import { Agent, run } from '@openai/agents';
const agent = new Agent({ name: 'Storyteller', instructions: 'You are a storyteller. You will be given a topic and you will tell a story about it.',});
const result = await run(agent, 'Tell me a story about a cat.', { stream: true,});
result .toTextStream({ compatibleWithNodeStreams: true, }) .pipe(process.stdout);프로미스 stream.completed는 실행과 보류 중인 모든 콜백이 완료되면 resolve됩니다. 더 이상 출력이 없음을 보장하려면 항상 이를 await 하세요.
모든 이벤트 수신
섹션 제목: “모든 이벤트 수신”for await 루프를 사용하여 도착하는 각 이벤트를 검사할 수 있습니다. 유용한 정보에는 저수준 모델 이벤트, 에이전트 전환, 그리고 SDK 특정 실행 정보가 포함됩니다:
import { Agent, run } from '@openai/agents';
const agent = new Agent({ name: 'Storyteller', instructions: 'You are a storyteller. You will be given a topic and you will tell a story about it.',});
const result = await run(agent, 'Tell me a story about a cat.', { stream: true,});
for await (const event of result) { // these are the raw events from the model if (event.type === 'raw_model_stream_event') { console.log(`${event.type} %o`, event.data); } // agent updated events if (event.type === 'agent_updated_stream_event') { console.log(`${event.type} %s`, event.agent.name); } // Agent SDK specific events if (event.type === 'run_item_stream_event') { console.log(`${event.type} %o`, event.item); }}스트리밍된 예제를 참조하면 순수 텍스트 스트림과 원문 이벤트 스트림을 모두 출력하는 완전한 스크립트를 볼 수 있습니다.
이벤트 유형
섹션 제목: “이벤트 유형”스트림은 세 가지 서로 다른 이벤트 유형을 방출합니다:
raw_model_stream_event
섹션 제목: “raw_model_stream_event”type RunRawModelStreamEvent = { type: 'raw_model_stream_event'; data: ResponseStreamEvent;};예:
{ "type": "raw_model_stream_event", "data": { "type": "output_text_delta", "delta": "Hello" }}run_item_stream_event
섹션 제목: “run_item_stream_event”type RunItemStreamEvent = { type: 'run_item_stream_event'; name: RunItemStreamEventName; item: RunItem;};핸드오프 페이로드 예:
{ "type": "run_item_stream_event", "name": "handoff_occurred", "item": { "type": "handoff_call", "id": "h1", "status": "completed", "name": "transfer_to_refund_agent" }}agent_updated_stream_event
섹션 제목: “agent_updated_stream_event”type RunAgentUpdatedStreamEvent = { type: 'agent_updated_stream_event'; agent: Agent<any, any>;};예:
{ "type": "agent_updated_stream_event", "agent": { "name": "Refund Agent" }}스트리밍 중 휴먼인더루프 (HITL)
섹션 제목: “스트리밍 중 휴먼인더루프 (HITL)”스트리밍은 실행을 일시 중지하는 핸드오프(예: 도구 승인 필요)와 호환됩니다. 스트림 객체의 interruption 필드는 인터럽션(중단 처리)을 노출하며, 각 인터럽션에 대해 state.approve() 또는 state.reject()를 호출하여 실행을 계속할 수 있습니다. { stream: true }로 다시 실행하면 스트리밍 출력이 재개됩니다.
import { Agent, run } from '@openai/agents';
const agent = new Agent({ name: 'Storyteller', instructions: 'You are a storyteller. You will be given a topic and you will tell a story about it.',});
let stream = await run( agent, 'What is the weather in San Francisco and Oakland?', { stream: true },);stream.toTextStream({ compatibleWithNodeStreams: true }).pipe(process.stdout);await stream.completed;
while (stream.interruptions?.length) { console.log( 'Human-in-the-loop: approval required for the following tool calls:', ); const state = stream.state; for (const interruption of stream.interruptions) { const approved = confirm( `Agent ${interruption.agent.name} would like to use the tool ${interruption.name} with "${interruption.arguments}". Do you approve?`, ); if (approved) { state.approve(interruption); } else { state.reject(interruption); } }
// Resume execution with streaming output stream = await run(agent, state, { stream: true }); const textStream = stream.toTextStream({ compatibleWithNodeStreams: true }); textStream.pipe(process.stdout); await stream.completed;}사용자와 상호작용하는 더 완전한 예제는
human-in-the-loop-stream.ts입니다.
- 모든 출력이 플러시되었음을 보장하려면 종료 전에
stream.completed를 기다리세요 - 초기
{ stream: true }옵션은 제공된 그 호출에만 적용됩니다.RunState로 다시 실행하는 경우 옵션을 다시 지정해야 합니다 - 애플리케이션이 텍스트 결과에만 관심이 있다면 개별 이벤트 객체를 처리하지 않도록
toTextStream()을 사용하는 것이 좋습니다
스트리밍과 이벤트 시스템을 사용하면 에이전트를 채팅 인터페이스, 터미널 애플리케이션 또는 사용자가 점진적 업데이트의 이점을 얻는 모든 곳에 통합할 수 있습니다.