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