다중 턴 세션과 스트리밍 입력

다중 턴 세션과 스트리밍 입력

이 항목에서는 Cortex Code Agent SDK에 프롬프트를 보내는 주요 방법을 설명해요: query()가 세션 수명 주기를 관리하도록 할 때의 단일 프롬프트 쿼리, 점진적 프롬프트 전달을 위한 스트리밍 입력, 교환 간에 컨텍스트를 유지하는 대화형 대화를 위한 다중 턴 세션.

출처: Multi-turn sessions and streaming input

본문

입력 패턴

SDK는 세 가지 입력 패턴을 제공해요.

모드 사용 시기 API
단일 프롬프트 입력 query()로 프롬프트 하나를 보내고 SDK가 세션 수명 주기를 관리하게 함. 에이전트가 ResultMessage를 만들 때까지 출력은 계속 스트리밍돼요. TypeScript와 Python 모두의 query()
스트리밍 입력 단일 프롬프트 문자열 대신 async 이터러블에서 사용자 메시지를 점진적으로 전송 TypeScript와 Python 모두의 query(), TypeScript의 Query.streamInput() 추가
다중 턴 세션 대화형 대화: 여러 프롬프트 전송, 컨텍스트 유지, 세션 수명 주기 제어 createCortexCodeSession()(TypeScript) 또는 CortexCodeSDKClient(Python)

단일 프롬프트 쿼리

query() 함수는 SDK를 사용하는 가장 간단한 방법이에요. 단일 프롬프트 문자열 또는 SDK 사용자 메시지의 async 이터러블을 보낼 수 있으며, 에이전트가 ResultMessage를 만들 때까지 이벤트를 스트리밍해요. 이 모드에서 "단일 프롬프트"는 입력 패턴을 가리키며, 출력은 여전히 정상적으로 스트리밍돼요.

import { query } from "cortex-code-agent-sdk";

for await (const message of query({
  prompt: "Explain how the auth module works",
  options: { cwd: process.cwd() },
})) {
  if (message.type === "assistant") {
    for (const block of message.content) {
      if (block.type === "text") process.stdout.write(block.text);
    }
  }
}
import asyncio
from cortex_code_agent_sdk import query, AssistantMessage, CortexCodeAgentOptions

async def main():
    async for message in query(
        prompt="Explain how the auth module works",
        options=CortexCodeAgentOptions(cwd="."),
    ):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if hasattr(block, "text"):
                    print(block.text, end="")

asyncio.run(main())

query() 함수는 전체 세션 수명 주기를 관리해요. 세션을 만들고, 프롬프트를 보내고, 이벤트를 생성하고, 결과가 도착하거나 이터레이터가 소진되면 세션을 닫아요.

이것은 maxTurns/max_turns와 다릅니다. 단일 프롬프트 쿼리는 여전히 에이전트가 구성한 턴 한도의 적용을 받아 필요한 만큼 내부 턴을 가지도록 허용해요. maxTurns: 1 또는 max_turns=1을 설정하는 것은 에이전트를 하나의 내부 턴으로 제한하고 error_max_turns 결과를 만들어낼 수 있는 별도의 제약이에요.

다중 턴 세션

여러 교환을 요구하는 대화에는 세션을 사용해요. 에이전트는 턴 간에 컨텍스트를 유지하므로, 이후 프롬프트는 이전 턴에서 읽은 파일, 수행한 분석, 논의한 주제를 참조할 수 있어요.

import { createCortexCodeSession } from "cortex-code-agent-sdk";

const session = await createCortexCodeSession({ cwd: process.cwd() });

// First turn
await session.send("Read the database connection module");
for await (const event of session.stream()) {
  if (event.type === "assistant") {
    for (const b of event.content) {
      if (b.type === "text") process.stdout.write(b.text);
    }
  }
  if (event.type === "result") break;
}

// Second turn -- context from the first turn is preserved
await session.send("What error handling patterns does it use?");
for await (const event of session.stream()) {
  if (event.type === "assistant") {
    for (const b of event.content) {
      if (b.type === "text") process.stdout.write(b.text);
    }
  }
  if (event.type === "result") break;
}

await session.close();
from cortex_code_agent_sdk import CortexCodeSDKClient, CortexCodeAgentOptions, AssistantMessage, ResultMessage

async with CortexCodeSDKClient(CortexCodeAgentOptions(cwd=".")) as client:
    # First turn
    await client.query("Read the database connection module")
    async for msg in client.receive_response():
        if isinstance(msg, AssistantMessage):
            for block in msg.content:
                if hasattr(block, "text"):
                    print(block.text, end="")

    # Second turn -- context from the first turn is preserved
    await client.query("What error handling patterns does it use?")
    async for msg in client.receive_response():
        if isinstance(msg, AssistantMessage):
            for block in msg.content:
                if hasattr(block, "text"):
                    print(block.text, end="")

세션 수명 주기

  • createCortexCodeSession(options)를 호출해 세션을 시작해요. 이것은 CLI 프로세스를 생성해요.
  • session.send(prompt)를 호출해 사용자 메시지를 보내요.
  • 응답을 받으려면 session.stream()을 반복해요. result 이벤트를 보면 반복을 중지해요.
  • 추가 턴에 대해 2~3단계를 반복해요.
  • 세션을 끝내고 프로세스를 정리하려면 session.close()를 호출해요.
  • CortexCodeSDKClient를 만들고 connect()를 호출하거나(async with 사용) 사용자 메시지를 보내려면 client.query(prompt)를 호출해요.
  • client.receive_response()를 반복해 ResultMessage를 포함한 메시지를 받아요.
  • 추가 턴에 대해 2~3단계를 반복해요.
  • client.disconnect()를 호출하거나 async with 블록이 종료되도록 해요.

이전 세션 계속하기

이전 세션의 대화를 재개할 수 있어요. 에이전트는 이전 대화 기록을 로드하고 중단한 지점부터 계속해요.

import { createCortexCodeSession } from "cortex-code-agent-sdk";

// Continue the most recent conversation
const session = await createCortexCodeSession({
  cwd: process.cwd(),
  continue: true,
});

await session.send("What were we working on?");
for await (const event of session.stream()) {
  if (event.type === "result") break;
}
await session.close();
from cortex_code_agent_sdk import CortexCodeSDKClient, CortexCodeAgentOptions

# Continue the most recent conversation
async with CortexCodeSDKClient(
    CortexCodeAgentOptions(continue_conversation=True)
) as client:
    await client.query("What were we working on?")
    async for msg in client.receive_response():
        pass  # process messages

ID로 특정 세션을 재개할 수도 있어요.

const session = await createCortexCodeSession({
  cwd: process.cwd(),
  resume: "previous-session-id",
});
async with CortexCodeSDKClient(
    CortexCodeAgentOptions(resume="previous-session-id")
) as client:
    ...

세션 포크(Fork)하기

포킹은 기존 세션의 전체 대화 기록으로 시작하는 새 세션을 만들어요. 원래 세션은 수정되지 않아요. 원래 대화를 잃지 않고 대안 접근 방식을 탐색하는 데 유용해요.

import { createCortexCodeSession } from "cortex-code-agent-sdk";

const forked = await createCortexCodeSession({
  cwd: process.cwd(),
  resume: "previous-session-id",
  forkSession: true,
});

await forked.send("Let's try a different approach");
for await (const event of forked.stream()) {
  if (event.type === "result") break;
}
await forked.close();
from cortex_code_agent_sdk import CortexCodeSDKClient, CortexCodeAgentOptions

async with CortexCodeSDKClient(
    CortexCodeAgentOptions(resume="previous-session-id", fork_session=True)
) as client:
    await client.query("Let's try a different approach")
    async for msg in client.receive_response():
        pass  # process messages

턴 중단(Interrupt)

애플리케이션은 에이전트가 턴을 처리하는 동안 중단을 요청할 수 있어요. 이것은 CLI에서 Esc를 누르는 것과 같은 효과가 있어요. 세션은 추가 프롬프트를 위해 유지돼요.

직접 중단 호출

interrupt() 메서드를 호출해 직접 중단 요청을 보내요.

import { createCortexCodeSession } from "cortex-code-agent-sdk";

const session = await createCortexCodeSession({ cwd: process.cwd() });

await session.send("Analyze every file in this large codebase");

// Interrupt after 10 seconds
setTimeout(() => session.interrupt(), 10_000);

for await (const event of session.stream()) {
  if (event.type === "result") break;
}

// Session is still alive -- send another prompt
await session.send("Just summarize the top-level structure instead");
for await (const event of session.stream()) {
  if (event.type === "result") break;
}

await session.close();
import asyncio
from cortex_code_agent_sdk import CortexCodeSDKClient, CortexCodeAgentOptions, ResultMessage

async with CortexCodeSDKClient(CortexCodeAgentOptions(cwd=".")) as client:
    await client.query("Analyze every file in this large codebase")

    # Interrupt after 10 seconds
    async def interrupt_later():
        await asyncio.sleep(10)
        await client.interrupt()

    asyncio.create_task(interrupt_later())

    async for msg in client.receive_response():
        pass

    # Session is still alive -- send another prompt
    await client.query("Just summarize the top-level structure instead")
    async for msg in client.receive_response():
        pass

Abort controller / abort 이벤트

세션 생성 시 중단 신호를 전달할 수도 있어요. 신호가 발생하면 SDK가 자동으로 같은 중단 요청을 보내요.

import { createCortexCodeSession } from "cortex-code-agent-sdk";

const controller = new AbortController();

const session = await createCortexCodeSession({
  cwd: process.cwd(),
  abortController: controller,
});

await session.send("Analyze every file in this large codebase");

// Trigger interrupt from anywhere
setTimeout(() => controller.abort(), 10_000);

for await (const event of session.stream()) {
  if (event.type === "result") break;
}
await session.close();
import asyncio
from cortex_code_agent_sdk import CortexCodeSDKClient, CortexCodeAgentOptions

abort_event = asyncio.Event()

async with CortexCodeSDKClient(
    CortexCodeAgentOptions(cwd=".", abort_event=abort_event)
) as client:
    await client.query("Analyze every file in this large codebase")

    # Trigger interrupt from anywhere
    async def trigger_abort():
        await asyncio.sleep(10)
        abort_event.set()

    asyncio.create_task(trigger_abort())

    async for msg in client.receive_response():
        pass

주의 TypeScript에서는 중단 요청을 트리거하는 abort() 메서드가 있는 AbortController를 전달해요. Python에서는 중단 요청을 트리거하는 set() 메서드가 있는 asyncio.Event를 전달해요. 두 경우 모두 중단 후 세션은 유지돼요.

법적 고지

Model and Service Pass-Through Terms에 제공된 모델을 사용하도록 Cortex Code를 구성하는 경우, 해당 모델 사용은 해당 페이지의 모델에 대한 약관도 추가로 적용돼요.

입력 및 출력의 데이터 분류는 다음 표에 명시되어 있어요.

입력 데이터 분류 출력 데이터 분류 지정
사용 데이터 고객 데이터 Covered AI Features [1]

[1] AI 약관 및 허용 가능한 사용 정책에서 사용되는 정의된 용어를 나타내요.

추가 정보는 Snowflake AI 및 ML을 참고하세요.

더 알아보기