SpyBara
Go Premium

agent-sdk/sessions.md 2026-05-07 22:59 UTC to 2026-05-08 22:00 UTC

324 added, 0 removed.

2026
Sun 31 06:39 Sat 30 06:23 Fri 29 06:38 Thu 28 06:37 Wed 27 06:42 Tue 26 06:33 Sun 24 06:25 Sat 23 06:18 Fri 22 06:33 Thu 21 06:36 Wed 20 06:35 Tue 19 06:34 Mon 18 23:59 Sun 17 01:01 Fri 15 22:58 Thu 14 17:02 Wed 13 23:01 Tue 12 22:57 Mon 11 23:00 Sun 10 23:03 Sat 9 04:57 Fri 8 22:00 Thu 7 22:59 Tue 5 23:00 Mon 4 22:58 Sat 2 18:14 Fri 1 18:19

์„ธ์…˜์œผ๋กœ ์ž‘์—…ํ•˜๊ธฐ

์„ธ์…˜์ด ์—์ด์ „ํŠธ ๋Œ€ํ™” ๊ธฐ๋ก์„ ์–ด๋–ป๊ฒŒ ์œ ์ง€ํ•˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์ด์ „ ์‹คํ–‰์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ ์œ„ํ•ด continue, resume, fork๋ฅผ ์–ธ์ œ ์‚ฌ์šฉํ• ์ง€์— ๋Œ€ํ•ด ์•Œ์•„๋ด…๋‹ˆ๋‹ค.

์„ธ์…˜์€ ์—์ด์ „ํŠธ๊ฐ€ ์ž‘์—…ํ•˜๋Š” ๋™์•ˆ SDK๊ฐ€ ๋ˆ„์ ํ•˜๋Š” ๋Œ€ํ™” ๊ธฐ๋ก์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ํ”„๋กฌํ”„ํŠธ, ์—์ด์ „ํŠธ๊ฐ€ ์ˆ˜ํ–‰ํ•œ ๋ชจ๋“  ๋„๊ตฌ ํ˜ธ์ถœ, ๋ชจ๋“  ๋„๊ตฌ ๊ฒฐ๊ณผ, ๊ทธ๋ฆฌ๊ณ  ๋ชจ๋“  ์‘๋‹ต์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. SDK๋Š” ์ด๋ฅผ ์ž๋™์œผ๋กœ ๋””์Šคํฌ์— ๊ธฐ๋กํ•˜๋ฏ€๋กœ ๋‚˜์ค‘์— ๋Œ์•„์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์„ธ์…˜์œผ๋กœ ๋Œ์•„๊ฐ„๋‹ค๋Š” ๊ฒƒ์€ ์—์ด์ „ํŠธ๊ฐ€ ์ด์ „์˜ ์ „์ฒด ์ปจํ…์ŠคํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค. ์ด๋ฏธ ์ฝ์€ ํŒŒ์ผ, ์ด๋ฏธ ์ˆ˜ํ–‰ํ•œ ๋ถ„์„, ์ด๋ฏธ ๋‚ด๋ฆฐ ๊ฒฐ์ •๋“ค์ด ๋ชจ๋‘ ์žˆ์Šต๋‹ˆ๋‹ค. ํ›„์† ์งˆ๋ฌธ์„ ํ•  ์ˆ˜ ์žˆ๊ณ , ์ค‘๋‹จ์—์„œ ๋ณต๊ตฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‹œ๋„ํ•˜๊ธฐ ์œ„ํ•ด ๋ถ„๊ธฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ฐ€์ด๋“œ์—์„œ๋Š” ์•ฑ์— ๋งž๋Š” ์˜ฌ๋ฐ”๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์„ ํƒํ•˜๋Š” ๋ฐฉ๋ฒ•, ์„ธ์…˜์„ ์ž๋™์œผ๋กœ ์ถ”์ ํ•˜๋Š” SDK ์ธํ„ฐํŽ˜์ด์Šค, ์„ธ์…˜ ID๋ฅผ ์บก์ฒ˜ํ•˜๊ณ  resume ๋ฐ fork๋ฅผ ์ˆ˜๋™์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•, ๊ทธ๋ฆฌ๊ณ  ํ˜ธ์ŠคํŠธ ๊ฐ„์— ์„ธ์…˜์„ ์žฌ๊ฐœํ•  ๋•Œ ์•Œ์•„์•ผ ํ•  ์‚ฌํ•ญ์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

์ ‘๊ทผ ๋ฐฉ์‹ ์„ ํƒํ•˜๊ธฐ

ํ•„์š”ํ•œ ์„ธ์…˜ ์ฒ˜๋ฆฌ์˜ ์–‘์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ˜•ํƒœ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์„ธ์…˜ ๊ด€๋ฆฌ๋Š” ์ปจํ…์ŠคํŠธ๋ฅผ ๊ณต์œ ํ•ด์•ผ ํ•˜๋Š” ์—ฌ๋Ÿฌ ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋ณด๋‚ผ ๋•Œ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ๋‹จ์ผ query() ํ˜ธ์ถœ ๋‚ด์—์„œ ์—์ด์ „ํŠธ๋Š” ์ด๋ฏธ ํ•„์š”ํ•œ ๋งŒํผ ๋งŽ์€ ํ„ด์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ๊ถŒํ•œ ํ”„๋กฌํ”„ํŠธ์™€ AskUserQuestion์€ ๋ฃจํ”„ ๋‚ด์—์„œ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค (ํ˜ธ์ถœ์„ ์ข…๋ฃŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค).

๊ตฌ์ถ• ์ค‘์ธ ๊ฒƒ ์‚ฌ์šฉํ•  ๊ฒƒ
์ผํšŒ์„ฑ ์ž‘์—…: ๋‹จ์ผ ํ”„๋กฌํ”„ํŠธ, ํ›„์† ์—†์Œ ์ถ”๊ฐ€ ์ž‘์—… ์—†์Œ. ๋‹จ์ผ query() ํ˜ธ์ถœ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
ํ•œ ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ๋‹ค์ค‘ ํ„ด ์ฑ„ํŒ… ClaudeSDKClient (Python) ๋˜๋Š” continue: true (TypeScript). SDK๊ฐ€ ID ์ฒ˜๋ฆฌ ์—†์ด ์„ธ์…˜์„ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.
ํ”„๋กœ์„ธ์Šค ์žฌ์‹œ์ž‘ ํ›„ ์ค‘๋‹จํ•œ ์ง€์ ์—์„œ ๊ณ„์†ํ•˜๊ธฐ continue_conversation=True (Python) / continue: true (TypeScript). ๋””๋ ‰ํ† ๋ฆฌ์˜ ๊ฐ€์žฅ ์ตœ๊ทผ ์„ธ์…˜์„ ์žฌ๊ฐœํ•˜๋ฉฐ, ID๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
ํŠน์ • ๊ณผ๊ฑฐ ์„ธ์…˜ ์žฌ๊ฐœํ•˜๊ธฐ (๊ฐ€์žฅ ์ตœ๊ทผ์ด ์•„๋‹Œ) ์„ธ์…˜ ID๋ฅผ ์บก์ฒ˜ํ•˜๊ณ  resume์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
์›๋ณธ์„ ์žƒ์ง€ ์•Š๊ณ  ๋Œ€์ฒด ์ ‘๊ทผ ๋ฐฉ์‹ ์‹œ๋„ํ•˜๊ธฐ ์„ธ์…˜์„ ํฌํฌํ•ฉ๋‹ˆ๋‹ค.
์ƒํƒœ ๋น„์ €์žฅ ์ž‘์—…, ๋””์Šคํฌ์— ์•„๋ฌด๊ฒƒ๋„ ๊ธฐ๋กํ•˜๊ณ  ์‹ถ์ง€ ์•Š์Œ (TypeScript๋งŒ ํ•ด๋‹น) persistSession: false๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์„ธ์…˜์€ ํ˜ธ์ถœ ๊ธฐ๊ฐ„ ๋™์•ˆ๋งŒ ๋ฉ”๋ชจ๋ฆฌ์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. Python์€ ํ•ญ์ƒ ๋””์Šคํฌ์— ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

Continue, resume, fork

Continue, resume, fork๋Š” query()์— ์„ค์ •ํ•˜๋Š” ์˜ต์…˜ ํ•„๋“œ์ž…๋‹ˆ๋‹ค (Python์˜ ClaudeAgentOptions, TypeScript์˜ Options).

Continue์™€ resume์€ ๋ชจ๋‘ ๊ธฐ์กด ์„ธ์…˜์„ ์„ ํƒํ•˜๊ณ  ์—ฌ๊ธฐ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ฐจ์ด์ ์€ ํ•ด๋‹น ์„ธ์…˜์„ ์ฐพ๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค:

  • Continue๋Š” ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ์˜ ๊ฐ€์žฅ ์ตœ๊ทผ ์„ธ์…˜์„ ์ฐพ์Šต๋‹ˆ๋‹ค. ์•„๋ฌด๊ฒƒ๋„ ์ถ”์ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์•ฑ์ด ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ๋Œ€ํ™”๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
  • Resume์€ ํŠน์ • ์„ธ์…˜ ID๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ID๋ฅผ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์„ธ์…˜์ด ์žˆ์„ ๋•Œ (์˜ˆ: ๋‹ค์ค‘ ์‚ฌ์šฉ์ž ์•ฑ์˜ ์‚ฌ์šฉ์ž๋‹น ํ•˜๋‚˜) ๋˜๋Š” ๊ฐ€์žฅ ์ตœ๊ทผ์ด ์•„๋‹Œ ์„ธ์…˜์œผ๋กœ ๋Œ์•„๊ฐ€๊ณ  ์‹ถ์„ ๋•Œ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

Fork๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค: ์›๋ณธ์˜ ๊ธฐ๋ก ๋ณต์‚ฌ๋ณธ์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ์ƒˆ ์„ธ์…˜์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์›๋ณธ์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐฉํ–ฅ์„ ์‹œ๋„ํ•˜๋ฉด์„œ ๋Œ์•„๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์„ ์œ ์ง€ํ•˜๋ ค๋ฉด fork๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ž๋™ ์„ธ์…˜ ๊ด€๋ฆฌ

๋‘ SDK ๋ชจ๋‘ ํ˜ธ์ถœ ๊ฐ„์— ์„ธ์…˜ ์ƒํƒœ๋ฅผ ์ถ”์ ํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋ฏ€๋กœ ID๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ „๋‹ฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋‹จ์ผ ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ๋‹ค์ค‘ ํ„ด ๋Œ€ํ™”์— ์ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Python: ClaudeSDKClient

ClaudeSDKClient๋Š” ์„ธ์…˜ ID๋ฅผ ๋‚ด๋ถ€์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. client.query()์— ๋Œ€ํ•œ ๊ฐ ํ˜ธ์ถœ์€ ์ž๋™์œผ๋กœ ๋™์ผํ•œ ์„ธ์…˜์„ ๊ณ„์†ํ•ฉ๋‹ˆ๋‹ค. client.receive_response()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ˜„์žฌ ์ฟผ๋ฆฌ์˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ˜๋ณตํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ๋Š” ๋น„๋™๊ธฐ ์ปจํ…์ŠคํŠธ ๊ด€๋ฆฌ์ž๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด ์˜ˆ์ œ๋Š” ๋™์ผํ•œ client์— ๋Œ€ํ•ด ๋‘ ๊ฐœ์˜ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋Š” ์—์ด์ „ํŠธ์—๊ฒŒ ๋ชจ๋“ˆ์„ ๋ถ„์„ํ•˜๋„๋ก ์š”์ฒญํ•˜๊ณ , ๋‘ ๋ฒˆ์งธ๋Š” ํ•ด๋‹น ๋ชจ๋“ˆ์„ ๋ฆฌํŒฉํ† ๋งํ•˜๋„๋ก ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๋‘ ํ˜ธ์ถœ ๋ชจ๋‘ ๋™์ผํ•œ ํด๋ผ์ด์–ธํŠธ ์ธ์Šคํ„ด์Šค๋ฅผ ํ†ต๊ณผํ•˜๋ฏ€๋กœ ๋‘ ๋ฒˆ์งธ ์ฟผ๋ฆฌ๋Š” ๋ช…์‹œ์ ์ธ resume ๋˜๋Š” ์„ธ์…˜ ID ์—†์ด ์ฒซ ๋ฒˆ์งธ์˜ ์ „์ฒด ์ปจํ…์ŠคํŠธ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค:

import asyncio
from claude_agent_sdk import (
    ClaudeSDKClient,
    ClaudeAgentOptions,
    AssistantMessage,
    ResultMessage,
    TextBlock,
)


def print_response(message):
    """Print only the human-readable parts of a message."""
    if isinstance(message, AssistantMessage):
        for block in message.content:
            if isinstance(block, TextBlock):
                print(block.text)
    elif isinstance(message, ResultMessage):
        cost = (
            f"${message.total_cost_usd:.4f}"
            if message.total_cost_usd is not None
            else "N/A"
        )
        print(f"[done: {message.subtype}, cost: {cost}]")


async def main():
    options = ClaudeAgentOptions(
        allowed_tools=["Read", "Edit", "Glob", "Grep"],
    )

    async with ClaudeSDKClient(options=options) as client:
        # First query: client captures the session ID internally
        await client.query("Analyze the auth module")
        async for message in client.receive_response():
            print_response(message)

        # Second query: automatically continues the same session
        await client.query("Now refactor it to use JWT")
        async for message in client.receive_response():
            print_response(message)


asyncio.run(main())

Python SDK ์ฐธ์กฐ์—์„œ ClaudeSDKClient์™€ ๋…๋ฆฝํ˜• query() ํ•จ์ˆ˜๋ฅผ ์–ธ์ œ ์‚ฌ์šฉํ• ์ง€์— ๋Œ€ํ•œ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

TypeScript: continue: true

์•ˆ์ •์ ์ธ TypeScript SDK (์ด ๋ฌธ์„œ ์ „์ฒด์—์„œ ์‚ฌ์šฉ๋˜๋Š” query() ํ•จ์ˆ˜, ๋•Œ๋•Œ๋กœ V1์ด๋ผ๊ณ  ๋ถˆ๋ฆผ)๋Š” Python์˜ ClaudeSDKClient์™€ ๊ฐ™์€ ์„ธ์…˜ ๋ณด์œ  ํด๋ผ์ด์–ธํŠธ ๊ฐ์ฒด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ๊ฐ ํ›„์† query() ํ˜ธ์ถœ์—์„œ continue: true๋ฅผ ์ „๋‹ฌํ•˜๋ฉด SDK๊ฐ€ ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ์˜ ๊ฐ€์žฅ ์ตœ๊ทผ ์„ธ์…˜์„ ์ฐพ์•„ ์žฌ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ID ์ถ”์ ์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ์˜ˆ์ œ๋Š” ๋‘ ๊ฐœ์˜ ๋ณ„๋„ query() ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋Š” ์ƒˆ ์„ธ์…˜์„ ๋งŒ๋“ค๊ณ , ๋‘ ๋ฒˆ์งธ๋Š” continue: true๋ฅผ ์„ค์ •ํ•˜์—ฌ SDK๊ฐ€ ๋””์Šคํฌ์˜ ๊ฐ€์žฅ ์ตœ๊ทผ ์„ธ์…˜์„ ์ฐพ์•„ ์žฌ๊ฐœํ•˜๋„๋ก ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. ์—์ด์ „ํŠธ๋Š” ์ฒซ ๋ฒˆ์งธ ํ˜ธ์ถœ์˜ ์ „์ฒด ์ปจํ…์ŠคํŠธ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค:

import { query } from "@anthropic-ai/claude-agent-sdk";

// First query: creates a new session
for await (const message of query({
  prompt: "Analyze the auth module",
  options: { allowedTools: ["Read", "Glob", "Grep"] }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}

// Second query: continue: true resumes the most recent session
for await (const message of query({
  prompt: "Now refactor it to use JWT",
  options: {
    continue: true,
    allowedTools: ["Read", "Edit", "Write", "Glob", "Grep"]
  }
})) {
  if (message.type === "result" && message.subtype === "success") {
    console.log(message.result);
  }
}

query()์™€ ํ•จ๊ป˜ ์„ธ์…˜ ์˜ต์…˜ ์‚ฌ์šฉํ•˜๊ธฐ

์„ธ์…˜ ID ์บก์ฒ˜ํ•˜๊ธฐ

Resume๊ณผ fork์—๋Š” ์„ธ์…˜ ID๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ ๋ฉ”์‹œ์ง€์˜ session_id ํ•„๋“œ์—์„œ ์ฝ์Šต๋‹ˆ๋‹ค (Python์˜ ResultMessage, TypeScript์˜ SDKResultMessage). ์ด๋Š” ์„ฑ๊ณต ๋˜๋Š” ์˜ค๋ฅ˜์™€ ๊ด€๊ณ„์—†์ด ๋ชจ๋“  ๊ฒฐ๊ณผ์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. TypeScript์—์„œ ID๋Š” ์ดˆ๊ธฐ SystemMessage์˜ ์ง์ ‘ ํ•„๋“œ๋กœ๋„ ๋” ์ผ์ฐ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. Python์—์„œ๋Š” SystemMessage.data ๋‚ด์— ์ค‘์ฒฉ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage


async def main():
session_id = None

async for message in query(
prompt="Analyze the auth module and suggest improvements",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Glob", "Grep"],
),
):
if isinstance(message, ResultMessage):
session_id = message.session_id
if message.subtype == "success":
print(message.result)

print(f"Session ID: {session_id}")
return session_id


session_id = asyncio.run(main())

ID๋กœ ์žฌ๊ฐœํ•˜๊ธฐ

์„ธ์…˜ ID๋ฅผ resume์— ์ „๋‹ฌํ•˜์—ฌ ํŠน์ • ์„ธ์…˜์œผ๋กœ ๋Œ์•„๊ฐ‘๋‹ˆ๋‹ค. ์—์ด์ „ํŠธ๋Š” ์„ธ์…˜์ด ์ค‘๋‹จ๋œ ๊ณณ์—์„œ ์ „์ฒด ์ปจํ…์ŠคํŠธ๋กœ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ์žฌ๊ฐœํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ์ด์œ :

  • ์™„๋ฃŒ๋œ ์ž‘์—…์— ๋Œ€ํ•ด ํ›„์† ์กฐ์น˜ํ•˜๊ธฐ. ์—์ด์ „ํŠธ๊ฐ€ ์ด๋ฏธ ๋ฌด์–ธ๊ฐ€๋ฅผ ๋ถ„์„ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ํŒŒ์ผ์„ ๋‹ค์‹œ ์ฝ์ง€ ์•Š๊ณ  ํ•ด๋‹น ๋ถ„์„์— ๋”ฐ๋ผ ์กฐ์น˜ํ•˜๊ธฐ๋ฅผ ์›ํ•ฉ๋‹ˆ๋‹ค.
  • ์ œํ•œ์—์„œ ๋ณต๊ตฌํ•˜๊ธฐ. ์ฒซ ๋ฒˆ์งธ ์‹คํ–‰์ด error_max_turns ๋˜๋Š” error_max_budget_usd๋กœ ๋๋‚ฌ์Šต๋‹ˆ๋‹ค (๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ ์ฐธ์กฐ). ๋” ๋†’์€ ์ œํ•œ์œผ๋กœ ์žฌ๊ฐœํ•ฉ๋‹ˆ๋‹ค.
  • ํ”„๋กœ์„ธ์Šค ์žฌ์‹œ์ž‘ํ•˜๊ธฐ. ์ข…๋ฃŒ ์ „์— ID๋ฅผ ์บก์ฒ˜ํ–ˆ์œผ๋ฉฐ ๋Œ€ํ™”๋ฅผ ๋ณต์›ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์ด ์˜ˆ์ œ๋Š” ์„ธ์…˜ ID ์บก์ฒ˜ํ•˜๊ธฐ์˜ ์„ธ์…˜์„ ํ›„์† ํ”„๋กฌํ”„ํŠธ๋กœ ์žฌ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ์žฌ๊ฐœํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์—์ด์ „ํŠธ๋Š” ์ด๋ฏธ ์ด์ „ ๋ถ„์„์„ ์ปจํ…์ŠคํŠธ์— ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค:

# Earlier session analyzed the code; now build on that analysis
async for message in query(
prompt="Now implement the refactoring you suggested",
options=ClaudeAgentOptions(
resume=session_id,
allowed_tools=["Read", "Edit", "Write", "Glob", "Grep"],
),
):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)

๋จธ์‹  ๊ฐ„ ๋˜๋Š” ์„œ๋ฒ„๋ฆฌ์Šค ํ™˜๊ฒฝ์—์„œ ์„ธ์…˜์„ ์žฌ๊ฐœํ•˜๋ ค๋ฉด SessionStore ์–ด๋Œ‘ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋žœ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๊ณต์œ  ์Šคํ† ๋ฆฌ์ง€๋กœ ๋ฏธ๋Ÿฌ๋งํ•ฉ๋‹ˆ๋‹ค.

๋Œ€์ฒด ๋ฐฉ์•ˆ์„ ํƒ์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด ํฌํฌํ•˜๊ธฐ

ํฌํ‚น์€ ์›๋ณธ์˜ ๊ธฐ๋ก ๋ณต์‚ฌ๋ณธ์œผ๋กœ ์‹œ์ž‘ํ•˜์ง€๋งŒ ๊ทธ ์ง€์ ์—์„œ ๋ถ„๊ธฐํ•˜๋Š” ์ƒˆ ์„ธ์…˜์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ํฌํฌ๋Š” ์ž์‹ ์˜ ์„ธ์…˜ ID๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค. ์›๋ณธ์˜ ID์™€ ๊ธฐ๋ก์€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‘ ๊ฐœ์˜ ๋…๋ฆฝ์ ์ธ ์„ธ์…˜์„ ๋ณ„๋„๋กœ ์žฌ๊ฐœํ•  ์ˆ˜ ์žˆ๋Š” ๋‘ ๊ฐœ์˜ ์„ธ์…˜ ID๋กœ ๋๋‚ฉ๋‹ˆ๋‹ค.

์ด ์˜ˆ์ œ๋Š” ์„ธ์…˜ ID ์บก์ฒ˜ํ•˜๊ธฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค: session_id์—์„œ ์ธ์ฆ ๋ชจ๋“ˆ์„ ์ด๋ฏธ ๋ถ„์„ํ–ˆ์œผ๋ฉฐ JWT ์ค‘์‹ฌ ์Šค๋ ˆ๋“œ๋ฅผ ์žƒ์ง€ ์•Š๊ณ  OAuth2๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋ธ”๋ก์€ ์„ธ์…˜์„ ํฌํฌํ•˜๊ณ  ํฌํฌ์˜ ID (forked_id)๋ฅผ ์บก์ฒ˜ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ๋ธ”๋ก์€ ์›๋ณธ session_id๋ฅผ ์žฌ๊ฐœํ•˜์—ฌ JWT ๊ฒฝ๋กœ๋ฅผ ๊ณ„์†ํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ๋‘ ๊ฐœ์˜ ์„ธ์…˜ ID๊ฐ€ ๋‘ ๊ฐœ์˜ ๋ณ„๋„ ๊ธฐ๋ก์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค:

# Fork: branch from session_id into a new session
forked_id = None
async for message in query(
prompt="Instead of JWT, implement OAuth2 for the auth module",
options=ClaudeAgentOptions(
resume=session_id,
fork_session=True,
),
):
if isinstance(message, ResultMessage):
forked_id = message.session_id  # The fork's ID, distinct from session_id
if message.subtype == "success":
print(message.result)

print(f"Forked session: {forked_id}")

# Original session is untouched; resuming it continues the JWT thread
async for message in query(
prompt="Continue with the JWT approach",
options=ClaudeAgentOptions(resume=session_id),
):
if isinstance(message, ResultMessage) and message.subtype == "success":
print(message.result)

ํ˜ธ์ŠคํŠธ ๊ฐ„์— ์žฌ๊ฐœํ•˜๊ธฐ

์„ธ์…˜ ํŒŒ์ผ์€ ์ด๋ฅผ ๋งŒ๋“  ๋จธ์‹ ์— ๋กœ์ปฌ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํ˜ธ์ŠคํŠธ (CI ์›Œ์ปค, ์ž„์‹œ ์ปจํ…Œ์ด๋„ˆ, ์„œ๋ฒ„๋ฆฌ์Šค)์—์„œ ์„ธ์…˜์„ ์žฌ๊ฐœํ•˜๋ ค๋ฉด ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค:

  • ์„ธ์…˜ ํŒŒ์ผ ์ด๋™ํ•˜๊ธฐ. ์ฒซ ๋ฒˆ์งธ ์‹คํ–‰์—์„œ ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl์„ ์œ ์ง€ํ•˜๊ณ  resume์„ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ์ƒˆ ํ˜ธ์ŠคํŠธ์˜ ๋™์ผํ•œ ๊ฒฝ๋กœ๋กœ ๋ณต์›ํ•ฉ๋‹ˆ๋‹ค. cwd๊ฐ€ ์ผ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์„ธ์…˜ ์žฌ๊ฐœ์— ์˜์กดํ•˜์ง€ ์•Š๊ธฐ. ํ•„์š”ํ•œ ๊ฒฐ๊ณผ (๋ถ„์„ ์ถœ๋ ฅ, ๊ฒฐ์ •, ํŒŒ์ผ diff)๋ฅผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒํƒœ๋กœ ์บก์ฒ˜ํ•˜๊ณ  ์ƒˆ ์„ธ์…˜์˜ ํ”„๋กฌํ”„ํŠธ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ข…์ข… ํŠธ๋žœ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ์ฃผ๋ณ€์— ๋ฐฐ์†กํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋” ๊ฒฌ๊ณ ํ•ฉ๋‹ˆ๋‹ค.

๋‘ SDK ๋ชจ๋‘ ๋””์Šคํฌ์˜ ์„ธ์…˜์„ ์—ด๊ฑฐํ•˜๊ณ  ๋ฉ”์‹œ์ง€๋ฅผ ์ฝ๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค: TypeScript์˜ listSessions() ๋ฐ getSessionMessages(), Python์˜ list_sessions() ๋ฐ get_session_messages(). ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ •์˜ ์„ธ์…˜ ์„ ํƒ๊ธฐ, ์ •๋ฆฌ ๋กœ์ง ๋˜๋Š” ํŠธ๋žœ์Šคํฌ๋ฆฝํŠธ ๋ทฐ์–ด๋ฅผ ๊ตฌ์ถ•ํ•ฉ๋‹ˆ๋‹ค.

๋‘ SDK ๋ชจ๋‘ ๊ฐœ๋ณ„ ์„ธ์…˜์„ ์กฐํšŒํ•˜๊ณ  ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๋„ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค: Python์˜ get_session_info(), rename_session(), tag_session(), ๊ทธ๋ฆฌ๊ณ  TypeScript์˜ getSessionInfo(), renameSession(), tagSession(). ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํƒœ๊ทธ๋ณ„๋กœ ์„ธ์…˜์„ ๊ตฌ์„ฑํ•˜๊ฑฐ๋‚˜ ์ธ๊ฐ„์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ์ œ๋ชฉ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๊ด€๋ จ ๋ฆฌ์†Œ์Šค