세션
세션은 Agents SDK에 영구 메모리 계층을 제공합니다. Session 인터페이스를 구현하는 객체를 Runner.run에 제공하면 나머지는 SDK가 처리합니다. 세션이 있으면 러너가 자동으로 다음 작업을 수행합니다.
- 이전에 저장된 대화 항목을 가져와 다음 턴 앞에 추가합니다.
- 각 실행이 완료된 후 새로운 사용자 입력과 어시스턴트 출력을 저장합니다.
- 새로운 사용자 텍스트로 러너를 호출하거나 인터럽션(중단 처리)된
RunState에서 재개하는 경우에도 이후 턴에서 세션을 계속 사용할 수 있도록 유지합니다.
따라서 수동으로 toInputList()를 호출하거나 턴 사이의 기록을 이어 붙일 필요가 없습니다. TypeScript SDK는 Conversations API용 OpenAIConversationsSession과 로컬 개발용 MemorySession이라는 두 가지 구현을 제공합니다. 두 구현 모두 Session 인터페이스를 공유하므로 자체 스토리지 백엔드를 연결할 수 있습니다. Conversations API 이외의 구현 아이디어는 examples/memory/ 아래의 세션 백엔드 코드 예제(Prisma, 파일 기반 등)를 살펴보세요. OpenAI Responses 모델을 사용하는 경우 세션을 OpenAIResponsesCompactionSession으로 래핑하면 responses.compact를 통해 저장된 대화 기록을 자동으로 축소할 수 있습니다.
팁: 이 페이지의
OpenAIConversationsSession코드 예제를 실행하려면 SDK가 Conversations API를 호출할 수 있도록OPENAI_API_KEY환경 변수를 설정하거나 세션을 생성할 때apiKey를 제공하세요.
SDK가 클라이언트 측 메모리를 관리하도록 하려면 세션을 사용하세요. 이미 conversationId 또는 previousResponseId와 함께 OpenAI 서버 관리 상태를 사용하고 있다면 일반적으로 동일한 대화 기록에 세션을 추가로 사용할 필요가 없습니다.
빠른 시작
섹션 제목: “빠른 시작”OpenAIConversationsSession을 사용하여 메모리를 Conversations API와 동기화하거나 다른 Session 구현으로 교체할 수 있습니다.
import { Agent, OpenAIConversationsSession, run } from '@openai/agents';
const agent = new Agent({ name: 'TourGuide', instructions: 'Answer with compact travel facts.',});
// Any object that implements the Session interface works here. This example uses// the built-in OpenAIConversationsSession, but you can swap in a custom Session.const session = new OpenAIConversationsSession();
const firstTurn = await run(agent, 'What city is the Golden Gate Bridge in?', { session,});console.log(firstTurn.finalOutput); // "San Francisco"
const secondTurn = await run(agent, 'What state is it in?', { session });console.log(secondTurn.finalOutput); // "California"동일한 세션 인스턴스를 재사용하면 에이전트가 매 턴 전에 전체 대화 기록을 수신하고 새 항목이 자동으로 저장됩니다. 다른 Session 구현으로 전환할 때 별도의 코드 변경은 필요하지 않습니다.
로컬 데모, 테스트 또는 프로세스 로컬 채팅 상태에는 OpenAI와 통신하지 않고 동일한 인터페이스를 제공하는 MemorySession을 사용할 수 있습니다.
import { Agent, MemorySession, run } from '@openai/agents';
const agent = new Agent({ name: 'TourGuide', instructions: 'Answer with compact travel facts.',});
const session = new MemorySession();const result = await run(agent, 'What city is the Golden Gate Bridge in?', { session,});
console.log(result.finalOutput);OpenAIConversationsSession 생성자 옵션:
| 옵션 | 타입 | 설명 |
|---|---|---|
conversationId | string | 대화를 지연 생성하는 대신 기존 대화를 재사용합니다. |
client | OpenAI | 사전 구성된 OpenAI 클라이언트를 전달합니다. |
apiKey | string | 내부 OpenAI 클라이언트를 생성할 때 사용하는 API 키입니다. |
baseURL | string | OpenAI 호환 엔드포인트의 기본 URL입니다. |
organization | string | 요청에 사용할 OpenAI 조직 ID입니다. |
project | string | 요청에 사용할 OpenAI 프로젝트 ID입니다. |
MemorySession 생성자 옵션:
| 옵션 | 타입 | 설명 |
|---|---|---|
sessionId | string | 로그 또는 테스트에 사용할 고정 식별자입니다. 기본적으로 자동 생성됩니다. |
initialItems | AgentInputItem[] | 기존 기록을 사용하여 세션을 초기화합니다. |
logger | Logger | 디버그 출력에 사용할 로거를 재정의합니다. |
MemorySession은 모든 데이터를 로컬 프로세스 메모리에 저장하므로 프로세스가 종료되면 초기화됩니다.
세션을 생성하기 전에 대화 ID를 미리 생성해야 한다면 startOpenAIConversationsSession(client?)을 사용하고 반환된 ID를 conversationId로 전달하세요.
핵심 세션 동작
섹션 제목: “핵심 세션 동작”러너의 세션 사용 방식
섹션 제목: “러너의 세션 사용 방식”- 각 실행 전에 세션 기록을 가져와 새 턴의 입력과 병합한 후 결합된 목록을 에이전트에 전달합니다.
- 비스트리밍 실행 후에는
session.addItems()를 한 번 호출하여 원래 사용자 입력과 최신 턴의 모델 출력을 모두 저장합니다. - 스트리밍 실행의 경우 사용자 입력을 먼저 기록하고 턴이 완료되면 스트리밍된 출력을 추가합니다.
RunResult.state에서 재개할 때 승인 또는 기타 인터럽션(중단 처리)을 위해 동일한session을 계속 전달하세요. 재개된 턴은 입력을 다시 준비하지 않고 메모리에 추가됩니다.
출력 가드레일이 최종 함수 도구 결과를 거부하면 러너는 거부된 원문 결과를 새 세션 기록에 추가하지 않습니다. 러너는 인식된 함수 호출 및 결과 쌍에 대해 안전하게 재실행할 수 있는 자리표시자를 저장하고, 소유권을 입증할 수 없는 출력은 저장하지 않고 모호한 현재 응답 접미사를 생략합니다. 이러한 보호 기능은 외부 도구의 부수 효과를 되돌리거나 애플리케이션이 세션 파이프라인 외부에 저장한 데이터를 삭제하지 않습니다.
기록 검사 및 편집
섹션 제목: “기록 검사 및 편집”세션은 간단한 CRUD 도우미를 제공하므로 ‘실행 취소’, ‘채팅 지우기’ 또는 감사 기능을 구축할 수 있습니다.
import { OpenAIConversationsSession } from '@openai/agents';import type { AgentInputItem } from '@openai/agents-core';
// Replace OpenAIConversationsSession with any other Session implementation that// supports get/add/pop/clear if you store history elsewhere.const session = new OpenAIConversationsSession({ conversationId: 'conv_123', // Resume an existing conversation if you have one.});
const history = await session.getItems();console.log(`Loaded ${history.length} prior items.`);
const followUp: AgentInputItem[] = [ { type: 'message', role: 'user', content: [{ type: 'input_text', text: 'Let’s continue later.' }], },];await session.addItems(followUp);
const undone = await session.popItem();
if (undone?.type === 'message') { console.log(undone.role); // "user"}
await session.clearSession();session.getItems()는 저장된 AgentInputItem[]를 반환합니다. popItem()을 호출하면 마지막 항목이 제거되며, 에이전트를 다시 실행하기 전에 사용자가 내용을 수정할 때 유용합니다.
커스텀 스토리지 및 병합 동작
섹션 제목: “커스텀 스토리지 및 병합 동작”자체 스토리지 사용
섹션 제목: “자체 스토리지 사용”Session 인터페이스를 구현하여 Redis, DynamoDB, SQLite 또는 다른 데이터스토어에 메모리를 저장할 수 있습니다. 비동기 메서드 5개만 구현하면 됩니다.
import { Agent, run } from '@openai/agents';import { randomUUID } from '@openai/agents-core/_shims';import { getLogger } from '@openai/agents-core';import type { AgentInputItem, Session } from '@openai/agents-core';
/** * Minimal example of a Session implementation; swap this class for any storage-backed version. */export class CustomMemorySession implements Session { private readonly sessionId: string; private readonly logger: ReturnType<typeof getLogger>;
private items: AgentInputItem[];
constructor( options: { sessionId?: string; initialItems?: AgentInputItem[]; logger?: ReturnType<typeof getLogger>; } = {}, ) { this.sessionId = options.sessionId ?? randomUUID(); this.items = options.initialItems ? options.initialItems.map(cloneAgentItem) : []; this.logger = options.logger ?? getLogger('openai-agents:memory-session'); }
async getSessionId(): Promise<string> { return this.sessionId; }
async getItems(limit?: number): Promise<AgentInputItem[]> { if (limit === undefined) { const cloned = this.items.map(cloneAgentItem); this.logger.debug( `Getting items from memory session (${this.sessionId}): ${JSON.stringify(cloned)}`, ); return cloned; } if (limit <= 0) { return []; } const start = Math.max(this.items.length - limit, 0); const items = this.items.slice(start).map(cloneAgentItem); this.logger.debug( `Getting items from memory session (${this.sessionId}): ${JSON.stringify(items)}`, ); return items; }
async addItems(items: AgentInputItem[]): Promise<void> { if (items.length === 0) { return; } const cloned = items.map(cloneAgentItem); this.logger.debug( `Adding items to memory session (${this.sessionId}): ${JSON.stringify(cloned)}`, ); this.items = [...this.items, ...cloned]; }
async popItem(): Promise<AgentInputItem | undefined> { if (this.items.length === 0) { return undefined; } const item = this.items[this.items.length - 1]; const cloned = cloneAgentItem(item); this.logger.debug( `Popping item from memory session (${this.sessionId}): ${JSON.stringify(cloned)}`, ); this.items = this.items.slice(0, -1); return cloned; }
async clearSession(): Promise<void> { this.logger.debug(`Clearing memory session (${this.sessionId})`); this.items = []; }}
function cloneAgentItem<T extends AgentInputItem>(item: T): T { return structuredClone(item);}
const agent = new Agent({ name: 'MemoryDemo', instructions: 'Remember the running total.',});
// Using the above custom memory session implementation hereconst session = new CustomMemorySession({ sessionId: 'session-123-4567',});
const first = await run(agent, 'Add 3 to the total.', { session });console.log(first.finalOutput);
const second = await run(agent, 'Add 4 more.', { session });console.log(second.finalOutput);커스텀 세션을 사용하면 보존 정책을 적용하거나, 암호화를 추가하거나, 각 대화 턴에 메타데이터를 첨부한 후 저장할 수 있습니다.
커스텀 영속성의 원자성 및 멱등성 보장
섹션 제목: “커스텀 영속성의 원자성 및 멱등성 보장”기록을 업데이트하고 작업 식별자를 원자적으로 기록할 수 있는 백엔드에서는 선택적 SessionHistoryTransactionAwareSession 인터페이스를 구현하세요. 이 인터페이스의 applyHistoryTransaction(...) 메서드는 고정된 operationId와 다음 두 가지 트랜잭션 형식 중 하나를 받습니다.
append_items는 기록 항목 그룹을 추가합니다.replace_suffix는 현재 저장된 접미사가 예상된 기록 접미사와 여전히 일치할 때만 이를 교체합니다.
작업 식별자와 기록 변경 사항을 동일한 백엔드 트랜잭션에 저장하세요. 동일한 트랜잭션에서 작업 식별자가 반복되면 해당 작업을 두 번 적용하지 않고 성공해야 합니다. 다른 내용으로 식별자를 재사용하거나 예상 접미사가 변경된 후 replace_suffix를 적용하면 기록을 변경하지 않고 실패해야 합니다. 이를 통해 러너는 재시도 및 재개 가능한 출력 가드레일 흐름에서 저장된 출력을 안전하게 조정할 수 있습니다.
MemorySession은 참조 구현으로 이 계약을 구현합니다. 기존 Session 구현은 이 인터페이스 없이도 계속 유효하지만 트랜잭션 인식 영속성 경로는 사용하지 않습니다.
실행 컨텍스트를 사용한 커스텀 세션 범위 지정
섹션 제목: “실행 컨텍스트를 사용한 커스텀 세션 범위 지정”커스텀 세션에서 스토리지 라우팅 또는 메타데이터를 위해 활성 RunContext가 필요한 경우 RunContextAwareSession<TContext>를 구현하고 acceptsRunContext를 true로 설정하세요. 러너는 스트리밍 영속성 및 재개된 실행을 포함하여 실행 중의 모든 기록 작업에 동일한 컨텍스트 인스턴스를 전달합니다. Session만 구현하는 세션은 기존 메서드 시그니처를 유지하며 추가 인수 없이 호출됩니다.
import { Agent, run, type AgentInputItem, type RunContext, type RunContextAwareSession,} from '@openai/agents';
type TenantContext = { tenantId: string;};
class TenantSession implements RunContextAwareSession<TenantContext> { readonly acceptsRunContext = true; private readonly itemsByTenant = new Map<string, AgentInputItem[]>();
async getSessionId(): Promise<string> { return 'shared-tenant-session'; }
async getItems( limit?: number, runContext?: RunContext<TenantContext>, ): Promise<AgentInputItem[]> { const items = this.getTenantItems(runContext); return limit === undefined ? [...items] : items.slice(-limit); }
async addItems( items: AgentInputItem[], runContext?: RunContext<TenantContext>, ): Promise<void> { this.getTenantItems(runContext).push(...items); }
async popItem( runContext?: RunContext<TenantContext>, ): Promise<AgentInputItem | undefined> { return this.getTenantItems(runContext).pop(); }
async clearSession(runContext?: RunContext<TenantContext>): Promise<void> { this.itemsByTenant.set(this.getTenantId(runContext), []); }
private getTenantItems( runContext: RunContext<TenantContext> | undefined, ): AgentInputItem[] { const tenantId = this.getTenantId(runContext); const items = this.itemsByTenant.get(tenantId) ?? []; this.itemsByTenant.set(tenantId, items); return items; }
private getTenantId( runContext: RunContext<TenantContext> | undefined, ): string { if (!runContext) { throw new Error('TenantSession requires a run context.'); } return runContext.context.tenantId; }}
const agent = new Agent<TenantContext>({ name: 'Assistant', instructions: 'Reply concisely.',});const session = new TenantSession();
await run(agent, 'Remember that my favorite color is green.', { context: { tenantId: 'tenant-a' }, session,});
await run(agent, 'What is my favorite color?', { context: { tenantId: 'tenant-a' }, session,});OpenAIResponsesCompactionSession은 실행 컨텍스트를 기본 세션에 전달하지 않습니다. 이러한 기능을 함께 사용하는 경우 컨텍스트 범위마다 하나의 압축 세션 인스턴스를 유지하세요.
기록과 새 항목의 병합 방식 제어
섹션 제목: “기록과 새 항목의 병합 방식 제어”AgentInputItem 배열을 실행 입력으로 전달할 때는 저장된 기록과 결정론적으로 병합할 수 있도록 sessionInputCallback을 제공하세요. 러너는 기존 기록을 불러오고 모델 호출 전에 콜백을 호출한 다음 반환된 배열을 해당 턴의 전체 입력으로 모델에 전달합니다. 이 훅은 오래된 항목을 잘라내거나, 도구 결과의 중복을 제거하거나, 모델에 표시할 컨텍스트만 강조하는 데 적합합니다.
import { Agent, OpenAIConversationsSession, run } from '@openai/agents';import type { AgentInputItem } from '@openai/agents-core';
const agent = new Agent({ name: 'Planner', instructions: 'Track outstanding tasks before responding.',});
// Any Session implementation can be passed here; customize storage as needed.const session = new OpenAIConversationsSession();
const todoUpdate: AgentInputItem[] = [ { type: 'message', role: 'user', content: [ { type: 'input_text', text: 'Add booking a hotel to my todo list.' }, ], },];
await run(agent, todoUpdate, { session, // function that combines session history with new input items before the model call sessionInputCallback: (history, newItems) => { const recentHistory = history.slice(-8); return [...recentHistory, ...newItems]; },});문자열 입력의 경우 러너가 기록을 자동으로 병합하므로 콜백은 선택 사항입니다. 콜백은 턴 입력이 이미 항목 배열인 경우에만 실행됩니다.
conversationId 또는 previousResponseId도 사용하는 경우 콜백 결과에 현재 턴의 새 항목을 하나 이상 유지하세요. 이러한 서버 관리형 API는 현재 턴의 변경분에 의존합니다. 콜백이 새 항목을 모두 제거하면 SDK는 빈 변경분을 전송하는 대신 원래의 새 입력을 복원하고 경고를 기록합니다.
재개 가능한 실행
섹션 제목: “재개 가능한 실행”승인 및 재개 가능한 실행 처리
섹션 제목: “승인 및 재개 가능한 실행 처리”휴먼인더루프 (HITL) 흐름에서는 승인을 기다리기 위해 실행을 일시 중지하는 경우가 많습니다.
import { Agent, MemorySession, Runner } from '@openai/agents';
const agent = new Agent({ name: 'Trip Planner', instructions: 'Plan trips and ask for approval before booking anything.',});
const runner = new Runner();const session = new MemorySession();
const result = await runner.run(agent, 'Search the itinerary', { session,});
if (result.interruptions?.length) { // ... collect user feedback, then resume the agent in a later turn. for (const interruption of result.interruptions) { result.state.approve(interruption); }
const continuation = await runner.run(agent, result.state, { session }); console.log(continuation.finalOutput);}이전 RunState에서 재개하면 단일 대화 기록을 유지하기 위해 새 턴이 동일한 메모리 레코드에 추가됩니다. 대부분의 휴먼인더루프 (HITL) 승인 체크포인트는 RunState를 통해 왕복 처리되며, 세션은 전체 대화 기록을 완전하게 유지합니다.
승인된 함수 도구 결과가 최종 출력이 될 수 있는 경우 출력 가드레일은 더 엄격한 경계를 적용합니다. 현재 RunState 스키마는 SDK가 소유권을 입증할 수 있는 경우 현재 응답에서 생성된 항목의 정확한 소유권을 기록하므로, 출력을 포함하는 지원 대상 승인 체크포인트에서 세션 기록을 그대로 유지한 채 재개할 수 있습니다. SDK는 이후 모델, 도구 또는 세션에서 부수 효과가 발생하기 전에 해당 소유권을 검증합니다. 소유권이 누락되거나 유효하지 않거나 모호한 이전 스냅샷 및 체크포인트는 여전히 안전한 방식으로 실패합니다. SDK가 이 상태를 보고하면 안전한 입력으로 새 실행을 시작하세요. 원문 항목을 재실행하여 우회하지 마세요.
고급: 기록 압축
섹션 제목: “고급: 기록 압축”OpenAI Responses 기록 자동 압축
섹션 제목: “OpenAI Responses 기록 자동 압축”OpenAIResponsesCompactionSession은 모든 Session을 데코레이팅하며 OpenAI Responses API를 사용하여 저장된 긴 기록을 더 짧고 동등한 대화 항목 목록으로 교체합니다. 저장된 각 턴이 끝나면 러너는 최신 responseId를 runCompaction에 전달하며, 결정 훅이 true를 반환하면 responses.compact가 호출됩니다. compactionMode에 따라 요청은 최신 Responses API 체인 또는 세션의 현재 항목으로 구성됩니다. 기본 트리거는 사용자 항목이 아닌 항목이 10개 이상 누적되면 압축을 수행합니다. 토큰 수 또는 커스텀 휴리스틱을 기준으로 결정하려면 shouldTriggerCompaction을 재정의하세요. 압축이 완료되면 데코레이터는 기본 세션을 지우고 축소된 항목 목록으로 다시 작성합니다. 다른 서버 관리형 기록 흐름을 사용하는 OpenAIConversationsSession과 함께 사용하지 마세요.
import { Agent, MemorySession, OpenAIResponsesCompactionSession, run,} from '@openai/agents';
const agent = new Agent({ name: 'Support', instructions: 'Answer briefly and keep track of prior context.', model: 'gpt-5.4',});
// Wrap any Session to trigger responses.compact once history grows beyond your threshold.const session = new OpenAIResponsesCompactionSession({ // You can pass any Session implementation except OpenAIConversationsSession underlyingSession: new MemorySession(), // (optional) The model used for calling responses.compact API model: 'gpt-5.4', // (optional) your custom logic here shouldTriggerCompaction: ({ compactionCandidateItems }) => { return compactionCandidateItems.length >= 12; },});
await run(agent, 'Summarize order #8472 in one sentence.', { session });await run(agent, 'Remind me of the shipping address.', { session });
// Compaction runs automatically after each persisted turn. You can also force it manually.await session.runCompaction({ force: true });OpenAIResponsesCompactionSession 생성자 옵션:
| 옵션 | 타입 | 설명 |
|---|---|---|
client | OpenAI | responses.compact에 사용되는 OpenAI 클라이언트입니다. |
underlyingSession | Session | 압축된 항목으로 지우고 다시 작성할 기본 세션 스토어입니다. 데모에서는 기본적으로 인메모리 세션을 사용하며 OpenAIConversationsSession을 사용할 수 없습니다. |
model | OpenAI.ResponsesModel | 압축 요청에 사용되는 모델입니다. 기본값은 SDK의 현재 기본 OpenAI 모델입니다. |
compactionMode | 'auto' | 'previous_response_id' | 'input' | 압축에서 서버 응답 체인 또는 로컬 입력 항목 중 어느 것을 사용할지 제어합니다. |
shouldTriggerCompaction | (context) => boolean | Promise<boolean> | responseId, compactionMode, 후보 항목 및 현재 세션 항목을 기반으로 하는 커스텀 트리거 훅입니다. |
이미 Responses API 응답 ID를 사용하여 턴을 연결하고 있다면 compactionMode: 'previous_response_id'가 유용합니다. compactionMode: 'input'은 현재 세션 항목으로 압축 요청을 다시 구성하며, 응답 체인을 사용할 수 없거나 기본 세션의 내용을 단일 진실 공급원으로 사용하려는 경우 유용합니다.
runCompaction(args) 옵션:
| 옵션 | 타입 | 설명 |
|---|---|---|
responseId | string | previous_response_id 모드에 사용할 최신 Responses API 응답 ID입니다. |
compactionMode | 'auto' | 'previous_response_id' | 'input' | 구성된 모드를 호출별로 선택적으로 재정의합니다. |
store | boolean | 마지막 실행이 서버 상태를 저장했는지 나타냅니다. |
force | boolean | shouldTriggerCompaction을 우회하고 즉시 압축합니다. |
OpenAIResponsesCompactionSession은 동일한 래퍼 인스턴스를 통해 실행된 변경 작업을 직렬화합니다. runCompaction(), addItems(), popItem(), clearSession() 호출은 호출 순서대로 실행되며, 작업이 거부된 후에도 큐가 계속 처리되므로 이후 래퍼 변경 작업이 교체 또는 롤백 작업과 섞이지 않습니다. 교체 또는 롤백에 성공하면 래퍼의 캐시된 기록이 기본 세션과 일치하게 유지됩니다. 교체와 복원에 모두 실패하면 계속하기 전에 기본 세션을 복구하세요. 이러한 순서 보장은 다른 래퍼 인스턴스 또는 underlyingSession의 직접 변경과 조정되지 않으므로 애플리케이션에서 이러한 접근 경로를 조정하세요.
자동 압축은 실행이 읽어 온 기록 스냅샷의 소유권을 계속 보유하는지도 확인합니다. 자동 압축이 시작되기 전에 다른 작업이 래퍼의 기록을 변경하면 SDK는 최신 기록을 보존하고 해당 압축 시도를 건너뜁니다. 이후 실행 또는 명시적인 runCompaction() 호출로 업데이트된 기록을 압축할 수 있습니다.
지연 시간이 짧은 스트리밍을 위한 수동 압축
섹션 제목: “지연 시간이 짧은 스트리밍을 위한 수동 압축”압축은 기본 세션을 지우고 다시 작성하므로 SDK는 스트리밍 실행을 완료하기 전에 압축이 끝날 때까지 기다립니다. 압축 작업이 무거우면 마지막 출력 토큰 이후에도 result.completed가 몇 초 동안 대기 상태로 유지될 수 있습니다. 지연 시간이 짧은 스트리밍 또는 더 빠른 턴 전환이 필요하다면 자동 압축을 비활성화하고 턴 사이 또는 유휴 시간에 직접 runCompaction을 호출하세요.
import { Agent, MemorySession, OpenAIResponsesCompactionSession, run,} from '@openai/agents';
const agent = new Agent({ name: 'Support', instructions: 'Answer briefly and keep track of prior context.', model: 'gpt-5.4',});
// Disable auto-compaction to avoid delaying stream completion.const session = new OpenAIResponsesCompactionSession({ underlyingSession: new MemorySession(), shouldTriggerCompaction: () => false,});
const result = await run(agent, 'Share the latest ticket update.', { session, stream: true,});
// Wait for the streaming run to finish before compacting.await result.completed;
// Choose force based on your own thresholds or heuristics, between turns or during idle time.await session.runCompaction({ force: true });언제든지 runCompaction({ force: true })를 호출하여 보관 또는 핸드오프 전에 기록을 축소할 수 있습니다. 압축 결정을 추적하려면 DEBUG=openai-agents:openai:compaction으로 디버그 로그를 활성화하세요.