콘텐츠로 이동

스트리밍

Agents SDK는 모델과 기타 실행 단계의 출력을 점진적으로 전달할 수 있습니다. 스트리밍은 UI를 반응적으로 유지하고 사용자 업데이트 전에 최종 결과 전체를 기다리지 않도록 합니다.

Runner.run(){ stream: true } 옵션을 전달하면 전체 결과 대신 스트리밍 객체를 얻습니다:

Enabling streaming
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,
});

스트리밍이 활성화되면 반환된 streamAsyncIterable 인터페이스를 구현합니다. 각 발생 이벤트는 실행 중에 무슨 일이 일어났는지를 설명하는 객체입니다. 스트림은 에이전트 실행의 서로 다른 부분을 설명하는 세 가지 이벤트 타입 중 하나를 내보냅니다. 대부분의 애플리케이션은 모델의 텍스트만 원하므로, 스트림은 이를 위한 헬퍼를 제공합니다.

발생한 텍스트의 스트림을 얻으려면 stream.toTextStream()을 호출하세요. compatibleWithNodeStreamstrue이면 반환값은 일반 Node.js Readable입니다. 이를 process.stdout 또는 다른 대상으로 바로 파이프할 수 있습니다.

Logging out the text as it arrives
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 특화 실행 정보 등이 있습니다:

Listening to all events
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);
}
}

완전한 스크립트는 스트리밍 예제를 참고하세요. 일반 텍스트 스트림과 원문 이벤트 스트림을 모두 출력합니다.

스트림은 세 가지 다른 이벤트 타입을 내보냅니다:

type RunRawModelStreamEvent = {
type: 'raw_model_stream_event';
data: ResponseStreamEvent;
};

예:

{
"type": "raw_model_stream_event",
"data": {
"type": "output_text_delta",
"delta": "Hello"
}
}
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"
}
}
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 }로 다시 실행하면 스트리밍 출력이 재개됩니다.

Handling human approval while streaming
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.rawItem.name} with "${interruption.rawItem.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()을 사용하는 것이 좋습니다.

스트리밍과 이벤트 시스템을 사용하면 에이전트를 채팅 인터페이스, 터미널 애플리케이션 또는 사용자가 점진적 업데이트의 이점을 얻는 모든 곳에 통합할 수 있습니다.