콘텐츠로 이동

스트리밍

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.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() 을 사용하는 것이 좋습니다

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