세션 실행 및 이어가기

세션 실행 및 이어가기 (Run and continue sessions)

세션은 에이전트의 구성, 대화, 저장된 작업을 시간에 걸쳐 유지해요. 같은 세션을 재사용해 후속 메시지를 보내고 작업을 이어갈 수 있어요.

출처: 문서

본문

세션과 턴 (Sessions and turns)

턴은 세션 안에서의 한 차례 작업 주기예요. 유휴(idle) 세션에 보낸 메시지는 새 턴을 시작하고, 활성 턴 중에 보낸 메시지는 그 턴을 안내해요.

턴은 비동기로 실행돼요. 애플리케이션은 스트리밍으로 진행 상황을 따라가거나, 웹훅으로 세션 상태 변경을 받을 수 있어요.

작업 시작하기 (Start work)

에이전트 구성과 초기 input으로 세션을 만들고, stream을 true로 설정하면 같은 요청에서 첫 번째 턴의 이벤트를 받을 수 있어요.

API 키와 SDK가 구성되면 이 예시를 실행해 스크립트를 만들고 실행해 보세요. OpenAI가 환경을 관리해요:

세션 만들고 첫 턴 스트리밍하기

import OpenAI from "openai";

const client = new OpenAI();
const events = await client.beta.agents.sessions.create({
  agent: {
    model: "gpt-6-astra",
    instructions: "Write clean code, run it, and report the actual output.",
  },
  environment: { type: "openai_hosted" },
  input:
    "Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output.",
  stream: true,
});
try {
  for await (const event of events) {
    console.log(JSON.stringify(event));
  }
} finally {
  events.controller.abort();
}
from openai import OpenAI

with OpenAI() as client:
    with client.beta.agents.sessions.create(
        agent={
            "model": "gpt-6-astra",
            "instructions": "Write clean code, run it, and report the actual output.",
        },
        environment={"type": "openai_hosted"},
        input="Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output.",
        stream=True,
    ) as events:
        for event in events:
            print(event.to_json(indent=None), flush=True)
import (
	"context"
	"fmt"

	"github.com/openai/openai-go/v3"
)

ctx := context.Background()
client := openai.NewClient()
events := client.Beta.Agents.Sessions.NewStreaming(ctx, openai.BetaAgentSessionNewParams{
	Agent: openai.BetaAgentSessionNewParamsAgent{
		Model:        openai.String("gpt-6-astra"),
		Instructions: openai.String("Write clean code, run it, and report the actual output."),
	},
	Environment: openai.EnvironmentParamUnion{OfParamOpenAIHosted: &openai.EnvironmentParamOpenAIHosted{}},
	Input: openai.BetaAgentSessionNewParamsInputUnion{
		OfString: openai.String("Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output."),
	},
})
defer events.Close()
if events.Err() != nil {
	panic(events.Err())
}
for events.Next() {
	event := events.Current()
	fmt.Println(event.RawJSON())
}
if err := events.Err(); err != nil {
	panic(err)
}
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.http.StreamResponse;
import com.openai.models.beta.agents.AgentSessionEvent;
import com.openai.models.beta.agents.EnvironmentParam;
import com.openai.models.beta.agents.sessions.SessionCreateParams;

OpenAIClient client = OpenAIOkHttpClient.fromEnv();
var json = new JsonMapper();
try (StreamResponse<AgentSessionEvent> events =
    client
        .beta()
        .agents()
        .sessions()
        .createStreaming(
            SessionCreateParams.builder()
                .agent(
                    SessionCreateParams.Agent.builder()
                        .model("gpt-6-astra")
                        .instructions("Write clean code, run it, and report the actual output.")
                        .build())
                .environment(EnvironmentParam.OpenAIHosted.builder().build())
                .input(
                    "Create tree.py, a Python script that prints a readable tree of the files"
                        + " in the current directory. Run it and show me the output.")
                .build())) {
  var iterator = events.stream().iterator();
  while (iterator.hasNext()) {
    var event = iterator.next();
    System.out.println(json.writeValueAsString(event));
  }
}
require "openai"
require "json"

client = OpenAI::Client.new
events = client.beta.agents.sessions.create_streaming(
  agent: {
    model: "gpt-6-astra",
    instructions: "Write clean code, run it, and report the actual output."
  },
  environment: { type: "openai_hosted" },
  input: "Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output."
)
begin
  events.each do |event|
    puts JSON.generate(event.to_h)
  end
ensure
  events.close
end
curl --no-buffer --fail-with-body https://api.openai.com/v1/agents/sessions \
  -H "OpenAI-Beta: agents=v1" \
  -H "Authorization: Bearer ***" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": {
      "model": "gpt-6-astra",
      "instructions": "Write clean code, run it, and report the actual output."
    },
    "environment": { "type": "openai_hosted" },
    "input": "Create tree.py, a Python script that prints a readable tree of the files in the current directory. Run it and show me the output.",
    "stream": true
  }'

session_id를 애플리케이션의 대화 상태와 함께 저장하세요. 후속 메시지를 보내고 그 대화의 저장된 작업을 검색하는 데 사용해요.

재사용 가능한 에이전트 설정은 Agents 구성을, 환경 선택은 Architecture를 참고하세요. environment.type: "none"인 세션은 초기 입력이 필요해요. 요청 필드는 Create session 레퍼런스에 나열돼 있어요.

진행 상황 따라가고 결과 처리하기 (Follow progress and handle outcomes)

에이전트가 작업하는 동안 이벤트가 출력과 변경 사항을 보고해요. 턴의 결과(완료, 실패, 취소)를 확인하세요. 유휴 세션만으로는 턴이 성공했음을 뜻하지 않아요.

agent.session.turn.completed, agent.session.turn.failed, 또는 agent.session.turn.cancelled를 찾아보세요. 에이전트의 출력도 확인하세요. 턴이 완료됐다고 모든 도구가 성공한 건 아니에요.

세션이 함수 결과나 환경 연결을 필요로 한다면 세션을 검색하고 required_actions를 확인하세요. 코드가 함수 호출을 처리하거나 환경을 연결해야 작업을 이어갈 수 있어요.

이벤트 유형과 페이로드는 Events and Items를 참고하세요.

작업 이어가거나 안내하기 (Continue or steer the work)

같은 세션에 또 다른 agent.session.input.message를 보내세요. 에이전트가 작업 중이면 그 메시지가 활성 턴을 안내하고, 세션이 유휴 상태면 기존 대화로 새 턴을 시작해요.

저장된 에이전트 변경 사항은 새 세션에만 적용돼요. 이 세션의 이후 턴에서 모델, 추론 노력, 서비스 티어를 바꾸려면 그 설정을 업데이트하세요.

대화의 세션 ID를 사용해 입력을 보내세요. 메시지를 보내기 전에 그 이벤트 스트림을 구독하면 애플리케이션이 턴의 초기 이벤트를 받을 수 있어요.

애플리케이션의 함수에 API 클라이언트, 세션 ID, 메시지를 전달하세요:

후속 메시지 보내기

// Pass your saved session ID and message to this helper.
async function sendMessage(client, sessionId, text) {
  await client.beta.agents.sessions.events.create(sessionId, {
    events: [
      {
        type: "agent.session.input.message",
        input: [
          {
            role: "user",
            content: [
              {
                type: "input_text",
                text,
              },
            ],
          },
        ],
      },
    ],
  });
}
# Pass your saved session ID and message to this helper.
def send_message(client: OpenAI, session_id: str, text: str) -> None:
    client.beta.agents.sessions.events.create(
        session_id,
        events=[
            {
                "type": "agent.session.input.message",
                "input": [
                    {
                        "role": "user",
                        "content": [
                            {
                                "type": "input_text",
                                "text": text,
                            }
                        ],
                    }
                ],
            }
        ],
    )
// Pass your saved session ID and message to this helper.
func sendMessage(ctx context.Context, client *openai.Client, sessionID, text string) error {
	return client.Beta.Agents.Sessions.Events.New(ctx,
		sessionID,
		openai.BetaAgentSessionEventNewParams{
			Events: []openai.AgentSessionInputParamUnion{
				{
					OfParamAgentSessionInputMessage: &openai.AgentSessionInputParamAgentSessionInputMessage{
						Input: []openai.AgentSessionInputMessageParam{
							{
								Content: []openai.InputContentParamUnion{
									{
										OfParamInputText: &openai.InputContentParamInputText{Text: text},
									},
								},
							},
						},
					},
				},
			},
		})
}
// Pass your saved session ID and message to this helper.
public static void sendMessage(OpenAIClient client, String sessionId, String text) {
  client
      .beta()
      .agents()
      .sessions()
      .events()
      .create(
          EventCreateParams.builder()
              .sessionId(sessionId)
              .addEvent(
                  AgentSessionInputParam.AgentSessionInputMessage.builder()
                      .addInput(
                          AgentSessionInputMessageParam.builder()
                              .addInputTextContent(text)
                              .build())
                      .build())
              .build());
}
# Pass your saved session ID and message to this helper.
def send_message(client, session_id, text)
  client.beta.agents.sessions.events.create(
    session_id,
    events: [
      {
        type: "agent.session.input.message",
        input: [
          {
            role: "user",
            content: [
              {
                type: "input_text",
                text: text
              }
            ]
          }
        ]
      }
    ]
  )
end
curl \
  "https://api.openai.com/v1/agents/sessions/$session_id/events" \
  -H "OpenAI-Beta: agents=v1" \
  -H "Authorization: Bearer ***" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "type": "agent.session.input.message",
        "input": [
          {
            "role": "user",
            "content": [
              {
                "type": "input_text",
                "text": "List the files in the current directory."
              }
            ]
          }
        ]
      }
    ]
  }'

보내기와 스트리밍을 함께 하는 예시는 Events and Items를 참고하세요.

저장된 작업 검색하기 (Retrieve saved work)

이벤트는 실시간 진행 상황을 보여 줘요. 아이템(item)은 완료된 응답을 포함한 저장된 메시지와 도구 호출이에요. 이전 작업을 표시하거나 턴이 끝난 후 결과를 확인하려면 아이템을 검색하세요:

세션 아이템 검색하기

// Pass your saved session ID to this helper.
async function listItems(client, sessionId) {
  return client.beta.agents.sessions.items.list(sessionId, {
    order: "asc",
    limit: 100,
  });
}
# Pass your saved session ID to this helper.
def list_items(client: OpenAI, session_id: str):
    return client.beta.agents.sessions.items.list(session_id, order="asc", limit=100)
// Pass your saved session ID to this helper.
func listItems(ctx context.Context, client *openai.Client, sessionID string) (*pagination.CursorPage[openai.AgentSessionItemUnion], error) {
	return client.Beta.Agents.Sessions.Items.List(ctx,
		sessionID,
		openai.BetaAgentSessionItemListParams{
			Order: "asc",
			Limit: openai.Int(100),
		})
}
// Pass your saved session ID to this helper.
public static ItemListPage listItems(OpenAIClient client, String sessionId) {
  return client
      .beta()
      .agents()
      .sessions()
      .items()
      .list(
          ItemListParams.builder()
              .sessionId(sessionId)
              .order(ItemListParams.Order.of("asc"))
              .limit(100L)
              .build());
}
# Pass your saved session ID to this helper.
def list_items(client, session_id)
  client.beta.agents.sessions.items.list(
    session_id,
    order: "asc",
    limit: 100
  )
end
curl \
  "https://api.openai.com/v1/agents/sessions/$session_id/items?order=asc&limit=100" \
  -H "OpenAI-Beta: agents=v1" \
  -H "Authorization: Bearer ***"

세션 상태와 턴 결과를 검사하려면 세션 관리를 참고하세요. 파일은 Files and artifacts로 검색하세요.

스트림은 놓친 이벤트를 재생하지 않아요. 연결이 끊긴 뒤에는 세션과 저장된 아이템을 검색해 작업을 복구하세요. 재연결 절차는 끊긴 스트림 복구하기를 참고하세요.

활성 턴 취소하기 (Cancel an active turn)

에이전트를 멈추고 싶을 때 현재 턴을 취소하세요. 세션과 이전 작업은 계속 사용할 수 있어요:

활성 턴 취소하기

// Pass your saved session ID to this helper.
async function cancelTurn(client, sessionId) {
  await client.beta.agents.sessions.events.create(sessionId, {
    events: [{ type: "agent.session.input.cancel" }],
  });
}
# Pass your saved session ID to this helper.
def cancel_turn(client: OpenAI, session_id: str) -> None:
    client.beta.agents.sessions.events.create(
        session_id, events=[{"type": "agent.session.input.cancel"}]
    )
// Pass your saved session ID to this helper.
func cancelTurn(ctx context.Context, client *openai.Client, sessionID string) error {
	return client.Beta.Agents.Sessions.Events.New(ctx,
		sessionID,
		openai.BetaAgentSessionEventNewParams{
			Events: []openai.AgentSessionInputParamUnion{
				{OfParamAgentSessionInputCancel: &openai.AgentSessionInputParamAgentSessionInputCancel{}},
			},
		})
}
// Pass your saved session ID to this helper.
public static void cancelTurn(OpenAIClient client, String sessionId) {
  client
      .beta()
      .agents()
      .sessions()
      .events()
      .create(
          EventCreateParams.builder()
              .sessionId(sessionId)
              .addEventAgentSessionInputCancel()
              .build());
}
# Pass your saved session ID to this helper.
def cancel_turn(client, session_id)
  client.beta.agents.sessions.events.create(
    session_id,
    events: [{ type: "agent.session.input.cancel" }]
  )
end
curl "https://api.openai.com/v1/agents/sessions/$session_id/events" \
  -H "OpenAI-Beta: agents=v1" \
  -H "Authorization: Bearer ***" \
  -H "Content-Type: application/json" \
  -d '{"events":[{"type":"agent.session.input.cancel"}]}'

더 알아보기 (Learn more)

  • Events and Items에서 이벤트 유형과 페이로드를 확인하세요.
  • 세션 관리에서 세션 상태 검사와 삭제 방법을 확인하세요.
  • 웹훅으로 세션 상태 변경을 받는 방법을 확인하세요.