← Start here · Module 5A · 25 slides

Module 5A · Architecture & Agents

모든 에이전트 시스템의 핵심은 ~20줄 agent loop 하나뿐입니다. 나머지(Claude Code, Cursor, 커스텀 에이전트)는 그 위에 얹은 "두꺼운 하니스"예요. 이 모듈은 그 패턴들의 서베이입니다.

📊 원본 슬라이드: ksetp.netlify.app/agents · 칩(슬라이드 N)이 덱의 번호와 같습니다.

5A.0 · 오리엔테이션 — 모듈 지도와 어휘 Slide 1–4

이 모듈은 새 알고리즘이 아니라 패턴 서베이예요. 목표는 두 가지 — 에이전트 시스템의 모양을 알아보는 눈과, 그걸 설명할 공통 어휘.

앞으로 나올 9가지(루프 · Claude Code · 서브에이전트 · 메모리 · 라우팅 · 캐싱 · 롱러닝 · 컴퓨터 유즈 · 안전)는 전부 한 개의 루프 위에 얹거나 그 루프에 도구를 더 꽂는 레이어일 뿐입니다. 먼저 그 지도를 보고, 용어부터 손에 익혀요 — 뒤 섹션들이 이 단어들을 계속 다시 씁니다.

Everything in this module wraps one core loop

flowchart TB subgraph WRAP["the harness — everything else"] direction LR SUB["subagents"] MEM["memory scopes"] ROUTE["model routing"] CACHE["prompt caching"] ASYNC["long-running / async"] CU["computer use"] SAFE["safety: gates + limits"] end WRAP --> CORE["the agent loop
~20 lines"] classDef core fill:#11271a,stroke:#3fb950,color:#e6edf3,stroke-width:2px; classDef io fill:#0d1f33,stroke:#58a6ff,color:#e6edf3; classDef data fill:#2a2410,stroke:#d29322,color:#e6edf3; classDef danger fill:#2d1215,stroke:#f85149,color:#e6edf3; class SUB,MEM,CU io; class ROUTE,CACHE,ASYNC data; class SAFE danger; class CORE core;
핵심 어휘 — 5묶음으로
  • 엔진: agent(루프로 도구를 부르는 프로그램) · agentic loop(모델→도구→결과→반복) · harness(루프 둘레의 통제 코드) · tool registry(쓸 수 있는 도구 목록) · dispatcher(도구 이름 → 실제 함수 연결)
  • 위임: subagent(자식 Claude 세션) · task tool(서브에이전트를 띄우는 도구) · context isolation(자식 작업이 부모 창을 안 더럽힘)
  • 통제: permission gate(도구 실행 전 허용/확인/차단) · hook(도구 호출 전후에 끼우는 자동 훅)
  • 비용·성능: router(난이도별 모델 선택) · fallback(1차 실패 시 2차) · ensemble(여럿 돌려 최선 택) · cache_control: ephemeral(정적 prefix 5분 캐시)
  • 비전: computer use(화면을 API처럼 다룸) · vision tool(스크린샷을 보고 다음 행동 결정)
🗺️ 이 모듈을 관통하는 한 문장: "에이전트는 새 모델이 아니라 루프 + 하니스다." 그래서 지능은 모델에, 통제는 하니스에 — 이 배치를 모든 패턴에서 반복해서 확인하게 됩니다.

이 모듈 전체를 관통하는 핵심 주장은?

9가지 패턴은 전부 같은 ~20줄 루프 위의 레이어예요. 그래서 "모양 알아보기"가 목표죠 — 새로운 시스템을 만나도 "아, 이건 루프에 메모리를 붙이고 / 도구를 더 꽂고 / 게이트를 씌운 것"으로 환원해서 읽을 수 있게 됩니다.

5A.1 · The agent loop — the engine Slide 5

Claude에 messages+tools 전송 → tool call 디스패치 → 결과 append → end_turn까지 반복.

The whole engine — a single while-loop

flowchart LR A["messages + tools
to Claude"] --> B{"stop_reason?"} B -->|tool_use| C["run the tool"] C --> D["append result to messages"] D --> A B -->|end_turn| E["done"] classDef core fill:#11271a,stroke:#3fb950,color:#e6edf3,stroke-width:2px; classDef decision fill:#241a2e,stroke:#a371f7,color:#e6edf3; classDef io fill:#0d1f33,stroke:#58a6ff,color:#e6edf3; classDef done fill:#11271a,stroke:#3fb950,color:#e6edf3; class A core; class B decision; class C,D io; class E done;
messages = [{"role": "user", "content": question}]
while True:
    reply = client.messages.create(model=..., tools=TOOLS, messages=messages)
    messages.append({"role": "assistant", "content": reply.content})
    if reply.stop_reason != "tool_use":
        break                                   # end_turn → 끝
    for call in tool_calls(reply):              # 모델이 요청한 도구들 실행
        result = dispatch(call.name, call.input)
        messages.append({"role": "user",
                         "content": [{"type": "tool_result",
                                      "tool_use_id": call.id, "content": result}]})

Module 3의 Level 3에서 본 바로 그 루프예요. 이 ~20줄이 엔진이고, 화려한 에이전트는 모두 이 위에 UI·권한·도구를 덧댄 것뿐입니다.

🧩 "thick harness"가 뭔가: 엔진(loop)은 얇습니다. 진짜 제품이 되려면 그 둘레에 도구 레지스트리 · 권한 게이트 · 메모리 · 에러 복구 · UI를 둘러야 해요. 이 둘레가 두꺼울수록 "프레임워크"가 됩니다. 핵심: 지능은 모델에, 통제는 하니스에 있습니다.

"agent"의 가장 정확한 정의는?

에이전트는 새 모델이 아니라 제어 구조예요. "모델 호출 → 도구 실행 → 결과 append → 반복"이라는 루프가 본질이고, 모델은 매 턴 "다음에 뭘 할지"만 정합니다. 그래서 ~20줄로 충분합니다.

5A.2 · What is Claude Code, actually? Slide 6

기본 루프 + UI 레이어 + 권한 게이트 + ~25개 내장 도구 + MCP 도구 레지스트리 + 멀티스코프 메모리.

🏗️ 비유: 엔진(agent loop)은 같고, Claude Code는 그 위에 계기판(UI), 안전벨트(권한 게이트), 공구함(25개 도구)을 붙인 완성차예요. 지금 당신이 타고 있는 그 차입니다.

The layers stacked on the loop

flowchart TB UI["UI layer
streaming, diffs, prompts"] --> PERM["permission gate
read ok, write confirm, exec sandbox"] PERM --> LOOP["the agent loop (~20 lines)"] LOOP --> TOOLS["~25 built-in tools
read, edit, bash, search"] LOOP --> MCP["MCP registry
external tools on demand"] LOOP --> MEM["multi-scope memory
conversation to world"] classDef core fill:#11271a,stroke:#3fb950,color:#e6edf3,stroke-width:2px; classDef io fill:#0d1f33,stroke:#58a6ff,color:#e6edf3; classDef decision fill:#241a2e,stroke:#a371f7,color:#e6edf3; classDef data fill:#2a2410,stroke:#d29322,color:#e6edf3; class LOOP core; class UI,TOOLS,MCP io; class PERM decision; class MEM data;

핵심 통찰: Claude Code가 특별한 건 모델이 달라서가 아니라, 엔진 둘레의 하니스가 두껍기 때문이에요. 같은 엔진에 더 얇은 하니스를 붙이면 당신만의 에이전트가 됩니다.

Claude Code가 단순 챗봇과 근본적으로 다른 지점은?

차이는 모델이 아니라 하니스예요. 챗봇은 텍스트만 내놓지만, Claude Code는 그 텍스트를 도구 호출로 받아 파일을 고치고 셸을 돌립니다. 그 힘을 권한 게이트가 통제하죠.

5A.3 · Subagents — recursion for agents Slide 7

제한된 도구셋·전용 system prompt로 자식 Claude 세션을 띄움 → 컨텍스트 격리·전문화.

부모는 자식이 한 일의 요약만 받습니다 → 병렬 처리 + 재귀적 분해. 큰 일을 작은 독립 작업으로 쪼개 여럿에게 동시에 맡기는 셈이에요(42의 fork()/프로세스 분할과 비슷한 감각).

One parent fans work out, gets summaries back

flowchart TB P["parent agent
full context"] --> C1["subagent A
narrow tools + own prompt"] P --> C2["subagent B
narrow tools + own prompt"] P --> C3["subagent C
narrow tools + own prompt"] C1 -.summary only.-> P C2 -.summary only.-> P C3 -.summary only.-> P classDef core fill:#11271a,stroke:#3fb950,color:#e6edf3,stroke-width:2px; classDef io fill:#0d1f33,stroke:#58a6ff,color:#e6edf3; class P core; class C1,C2,C3 io;
🪟 왜 "요약만" 돌려받나 — 컨텍스트 보호: 자식이 파일 50개를 읽어도 부모 창에는 결론 한 단락만 들어옵니다. 덕분에 부모의 컨텍스트가 잡음으로 차오르지 않아요. 이게 서브에이전트의 진짜 이득 — 병렬성보다 컨텍스트 격리가 더 큽니다.

서브에이전트를 쓰는 가장 큰 이점은?

서브에이전트는 컨텍스트 격리 + 전문화가 핵심이에요. 넓은 탐색은 자식에게 맡기고 부모는 결론만 받아 큰 그림을 유지합니다. 토큰은 오히려 더 쓰지만(여러 세션), 부모 창이 안 더러워지는 대가로 충분히 남는 장사죠.

5A.4 · Memory — what persists, where Slide 8

"무엇을 어디까지 기억하나"를 5단계 스코프로 나눕니다 — 좁은 휘발성부터 넓은 영속까지.

Memory Scopes (5)
  • conversation — 현재 세션의 메시지들 (가장 좁고 휘발성)
  • session — 로그인 지속 동안 유지
  • user — 사용자별 영속 선호 (재방문해도 남음)
  • project — 레포 컨벤션 (CLAUDE.md 같은 파일)
  • world — 벡터 스토어·지식베이스 (= Module 4의 RAG, 가장 넓음)

Five scopes, narrow & volatile to wide & persistent

flowchart LR A["conversation
this session"] --> B["session
while logged in"] B --> C["user
persistent prefs"] C --> D["project
repo conventions (CLAUDE.md)"] D --> E["world
vector store / knowledge base"] classDef io fill:#0d1f33,stroke:#58a6ff,color:#e6edf3; classDef data fill:#2a2410,stroke:#d29322,color:#e6edf3; class A,B,C io; class D,E data;
🔁 2편과 4편이 여기서 만난다: 2편에서 "API는 stateless"라 했죠 — 이 스코프들이 바로 그 stateless 위에 우리가 얹는 기억 장치입니다. 그리고 가장 넓은 world 스코프는 새 개념이 아니라 Module 4의 RAG를 "기억"에 그대로 적용한 거예요.

가장 넓은 world 스코프는 어떻게 구현될까요?

world 메모리 = RAG를 기억에 적용한 것이에요. 사실을 chunk·embed해 저장하고, 필요할 때 top-K로 검색해 붙입니다. 모델 가중치는 학습 때 고정되고, context window 무한 확장은 Module 4 첫 섹션의 4가지 이유(Scale·Cost·Latency·Accuracy)에 부딪혀요.

5A.5 · Patterns: routing · caching · async · progress Slide 9–12

프로덕션 에이전트가 비용·지연·신뢰성을 잡는 네 가지 반복 패턴.

Four patterns
  • Multi-Model Routing — 싼 모델(Haiku)을 분류기로 써서 적절한 모델로 라우팅 → 비용 한정
  • Prompt Caching — 정적 system prefix를 cacheable로 표시 → 5분 윈도우 내 반복 비용 ~90%↓
  • Long-Running Tasks — 백그라운드 잡·예약 wake-up·webhook으로 비동기. 일시정지 중 상태를 어디 둘지 결정
  • Progress Streaming — 각 단계서 사람이 읽을 이벤트 emit, 전송계층과 분리, 종료는 done/error

Multi-model routing — a cheap model triages first

flowchart LR Q(["incoming request"]) --> H["cheap model (Haiku)
classify difficulty"] H -->|simple| S["answer with Haiku
fast, cheap"] H -->|hard| B["escalate to a bigger model
(Sonnet / Opus)"] classDef core fill:#11271a,stroke:#3fb950,color:#e6edf3,stroke-width:2px; classDef io fill:#0d1f33,stroke:#58a6ff,color:#e6edf3; classDef done fill:#11271a,stroke:#3fb950,color:#e6edf3; classDef data fill:#2a2410,stroke:#d29322,color:#e6edf3; class H core; class Q io; class S done; class B data;
💸 Prompt caching, 한 번 더: 매 요청에 똑같이 들어가는 긴 system 프롬프트·도구 정의를 캐시로 표시하면, 5분 윈도우 안의 다음 호출들은 그 부분을 재처리하지 않고 재사용해요. 같은 토큰을 매번 새로 계산하지 않으니 반복 비용이 ~90%까지 떨어집니다. 정적인 부분은 앞에, 변하는 부분은 뒤에 두는 게 캐시 적중의 핵심.

Long-running tasks — pause, persist, resume

flowchart LR T["long task starts"] --> Wk["do a chunk of work"] Wk --> P{"need to wait?
API, human, timer"} P -->|no| Wk P -->|yes| Sv["persist state, release the worker"] Sv -.webhook / scheduled wake-up.-> Wk classDef core fill:#11271a,stroke:#3fb950,color:#e6edf3,stroke-width:2px; classDef io fill:#0d1f33,stroke:#58a6ff,color:#e6edf3; classDef decision fill:#241a2e,stroke:#a371f7,color:#e6edf3; classDef data fill:#2a2410,stroke:#d29322,color:#e6edf3; class Wk core; class T io; class P decision; class Sv data;

멀티모델 라우팅에서 값싼 Haiku를 "분류기"로 먼저 두는 이유는?

라우팅의 목적은 비용 상한이에요. 대부분의 요청은 쉬운데, 그걸 전부 Opus로 처리하면 낭비죠. 싼 모델이 먼저 난이도를 보고, 진짜 어려운 것만 비싼 모델로 escalate 합니다.

prompt caching 효과를 극대화하려면 프롬프트를 어떻게 배치해야 할까요?

캐시는 접두(prefix) 단위로 적중해요. 앞부분이 매번 똑같아야 그 구간을 재사용합니다. 그래서 정적인 system·도구 정의를 앞에 고정하고, 변하는 사용자 입력을 뒤로 미는 게 핵심이에요.

5A.6 · Computer use & Safety Slide 13–14

화면이 곧 API. 스크린샷 + 마우스/키보드로 API 없는 자동화. 단, 권한·한도가 필수.

① 스키마 — 모델은 행동을 정할 뿐, 실행은 안 한다

computer use는 서버 정의 내장 도구(계약을 Anthropic이 소유)라, 우리가 스키마를 쓰지 않아요. beta 헤더버전 타입만 선언하면 모델이 모든 action을 이미 압니다.

client.beta.messages.create(
    betas=["computer-use-2025-01-24"],       # ← beta 헤더
    tools=[{
        "type": "computer_20250124",         # ← 버전 타입 (스키마는 서버가 소유)
        "name": "computer",
        "display_width_px": 1280, "display_height_px": 800,
        "display_number": 1,
    }],
    messages=[...],
)

Actions(모델이 고름): screenshot · left_click · right_click · double_click · mouse_move · left_click_drag · type · key · hold_key · scroll · wait · cursor_position. 모델의 응답은 좌표가 담긴 tool_use예요:

{ "type": "tool_use", "name": "computer",
  "input": { "action": "left_click", "coordinate": [612, 348] } }

② 실행 루프 — 세 주체: 환경 · 하니스 · API

flowchart LR subgraph ENV["Environment — you own it"] VM["container / VM
Linux desktop"] end subgraph APP["Your harness — the loop"] CAP["capture screenshot
(PNG)"] EXE["execute action
via xdotool"] end subgraph API["Anthropic API"] CL["Claude decides the
next action from pixels"] end VM --> CAP --> CL --> EXE --> VM classDef data fill:#2a2410,stroke:#d29322,color:#e6edf3; classDef io fill:#0d1f33,stroke:#58a6ff,color:#e6edf3; classDef core fill:#11271a,stroke:#3fb950,color:#e6edf3,stroke-width:2px; class VM data; class CAP,EXE io; class CL core;

Claude는 당신 기계를 절대 만지지 않아요결정만 합니다. 스크린샷을 보내면 action이 담긴 tool_use를 돌려주고, 그걸 당신의 하니스xdotool로 실행 → 다시 스크린샷 → Claude가 도구를 그만 부를 때까지 반복. 5A.1의 그 루프와 똑같되 "도구"가 마우스·키보드일 뿐이에요.

⚖️ 대가를 알고 쓰기: 매 턴 스크린샷이라 느리고 vision 토큰을 많이 먹고, UI가 조금만 바뀌어도 깨지기 쉽습니다(brittle). 원칙: API나 accessibility tree가 있으면 그걸 먼저, computer use는 "다른 길이 없을 때"의 최후 수단.
🛡️ Safety = 권한 게이트 + 하드 리밋. 읽기는 항상 허용, 파괴적 작업은 확인, 실행은 샌드박스. 그리고 스텝 예산·토큰 캡·시간 데드라인·scope 제한으로 폭주를 막습니다.

Two layers of defense — gate every action, cap the whole run

flowchart TB A["agent proposes an action"] --> G{"permission gate"} G -->|read| OK["allow"] G -->|write / delete| Ask["ask human first"] G -->|exec| Sand["run in sandbox"] OK --> L{"hard limits
steps, tokens, time"} Ask --> L Sand --> L L -->|within budget| Next["continue loop"] L -->|exceeded| Stop["halt the run"] classDef decision fill:#241a2e,stroke:#a371f7,color:#e6edf3; classDef io fill:#0d1f33,stroke:#58a6ff,color:#e6edf3; classDef done fill:#11271a,stroke:#3fb950,color:#e6edf3; classDef danger fill:#2d1215,stroke:#f85149,color:#e6edf3; class A,Ask,Sand io; class G,L decision; class OK,Next done; class Stop danger;

에이전트가 무한 루프로 비용 폭탄이 되는 걸 막는 1차 방어선은?

능력(자율성)과 안전은 트레이드오프예요. 모델을 믿기보다, 코드로 강제하는 한도가 폭주를 막습니다. 파괴적 작업엔 사람 확인(human-in-the-loop)도 함께.

권한 게이트에서 "읽기/쓰기/실행"을 다르게 다루는 이유는?

핵심은 되돌릴 수 있는가예요. 읽기는 부작용이 없으니 자유롭게, 파일 삭제·셸 실행은 돌이키기 어렵고 외부에 영향을 주니 확인·샌드박스로 감쌉니다. 위험도에 비례한 마찰이 좋은 설계죠.

5A.7 · Project: build a data-analyst agent Slide 17–21

SQLite 위 read-only SQL 도구 3개로 agent loop를 시연하는 스타터(안전 패턴 2개 기구현).

Safety patterns already in the starter
  • 구조적으로 read-only인 DB(안전 패턴 1) — 쓰기 도구를 아예 안 줌
  • max-steps 예산(안전 패턴 2) — 루프가 N스텝 넘으면 강제 종료

The data-analyst loop you'll wire up

flowchart LR U(["natural-language question"]) --> Ag["agent loop"] Ag -->|list_tables| DB[("read-only SQLite")] Ag -->|describe_table| DB Ag -->|run_query| DB DB -.rows.-> Ag Ag --> Ans(["answer in plain language"]) classDef core fill:#11271a,stroke:#3fb950,color:#e6edf3,stroke-width:2px; classDef io fill:#0d1f33,stroke:#58a6ff,color:#e6edf3; classDef data fill:#2a2410,stroke:#d29322,color:#e6edf3; classDef done fill:#11271a,stroke:#3fb950,color:#e6edf3; class Ag core; class U io; class DB data; class Ans done;

코드 읽기 ① — 함수 이름 지도 (전체 모양부터)

스타터(agent-app.zip)의 런타임은 파일 둘 — agent.py(루프+CLI) · tools.py(도구 3개 + 라우터). 함수는 7개지만 모든 길은 answer_turn() 하나로 모여요. 아래 지도가 재생되며 하나씩 나타납니다(우측 위 ▶ 다시 재생).

flowchart TD MAIN["__main__"] -->|arg| A1["answer_turn(messages)"] MAIN -->|no arg| REPL["repl()"] REPL --> A1 A1 --> CREATE["messages.create()
SYSTEM + messages + TOOLS"] CREATE --> CHECK{"tool_use block?"} CHECK -->|no| RET["return final text"] CHECK -->|yes| DISP["dispatch(name, input)"] DISP --> APP["append tool_result"] APP --> CREATE DISP --> LT["list_tables()"] DISP --> DT["describe_table(table)"] DISP --> RQ["run_query(sql)"] LT --> CONN["_connect() · mode=ro"] DT --> CONN RQ --> CONN classDef core fill:#11271a,stroke:#3fb950,color:#e6edf3,stroke-width:2px; classDef io fill:#0d1f33,stroke:#58a6ff,color:#e6edf3; classDef decision fill:#241a2e,stroke:#a371f7,color:#e6edf3; classDef data fill:#2a2410,stroke:#d29322,color:#e6edf3; classDef done fill:#11271a,stroke:#3fb950,color:#e6edf3; class A1 core; class CHECK decision; class CONN data; class RET done; class MAIN,REPL,CREATE,DISP,APP,LT,DT,RQ io;

엔진 = answer_turn() — 네 동작의 반복

def answer_turn(messages: list) -> str:
    for _ in range(MAX_STEPS):                    # 스텝 예산 = 폭주 방지
        resp = client.messages.create(model=MODEL, system=SYSTEM,
                                      messages=messages, tools=TOOLS)
        messages.append({"role": "assistant", "content": resp.content})
        tool_calls = [b for b in resp.content if b.type == "tool_use"]
        if not tool_calls:                        # 도구 안 부름 → 끝(end_turn)
            return "".join(b.text for b in resp.content if b.type=="text").strip()
        results = [{"type": "tool_result", "tool_use_id": c.id,
                    "content": dispatch(c.name, c.input)} for c in tool_calls]
        messages.append({"role": "user", "content": results})   # 결과 되먹임

묻기 → (도구 없으면 종료) → dispatch로 실행 → 결과 append → 반복. 출구는 딱 둘: 도구를 안 부를 때(정상 end_turn) / MAX_STEPS 소진(안전 정지).

코드 읽기 ② — 실제 질문이 루프를 도는 모습

질문 "지난 분기 매출 top 3 제품?" — 데이터 최신일(2026-05-31) 기준 "지난 분기" = 2026 Q1. 루프가 5바퀴 돕니다(예산 12 중).

sequenceDiagram participant L as answer_turn() loop participant API as messages.create() participant DB as data.db (mode=ro) Note over L: 1 · orient L->>API: create(messages, TOOLS) API-->>L: tool_use list_tables L->>DB: dispatch to list_tables() DB-->>L: customers, order_items, orders, products Note over L: 2 · schema L->>API: create() API-->>L: tool_use x3 describe_table L->>DB: dispatch to describe_table() DB-->>L: columns + sample rows Note over L: 3 · find "now" L->>API: create() API-->>L: tool_use run_query MAX(order_date) L->>DB: dispatch to run_query() DB-->>L: 2026-05-31 Note over L: 4 · the real query L->>API: create() API-->>L: tool_use run_query top-3 revenue Q1 L->>DB: dispatch to run_query() DB-->>L: Robot Vacuum / Cookware Set / Scented Candle Note over L: 5 · answer L->>API: create() API-->>L: end_turn (text, no tool_use) Note over L: return final answer
🔎 루프의 모양은 코드가, 루프 안의 행동은 프롬프트가 정합니다. 1·2바퀴가 늘 스키마 탐색인 건 코드가 아니라 SYSTEM 프롬프트가 "먼저 list_tables → describe_table 하라"고 시켜서예요. 그리고 messages는 매 바퀴 tool_use + tool_result 두 블록씩 자라며 — 이게 곧 멀티턴 기억(5A.4)입니다.
🚀 Beyond — Managed Agents (beta, 슬라이드 23): 소유 모델 역전 — Anthropic이 루프를 실행하고, 당신은 도구 정의 + 이벤트 스트림 반응만 합니다. 수동 메시지 리스트 관리가 사라지고 멀티턴 세션이 무료로 제공돼요.

이 데이터분석 에이전트에 run_query(SELECT 전용)만 주고 run_sql(임의 실행)을 안 주는 이유는?

가장 튼튼한 안전장치는 위험한 도구를 애초에 안 주는 것이에요(안전 패턴 1). 모델이 아무리 헷갈려도 줄 수 있는 도구가 SELECT뿐이면 DROP/UPDATE는 불가능합니다. 프롬프트 경고보다 확실하죠.

스타터: agent-app.zip다운로드

5A.8 · 한눈에 정리 — 루프 하나 + 그 위의 레이어들 Slide 13–14

이 모듈 전체를 한 그림으로: ~20줄 루프가 엔진이고, 나머지는 전부 그 둘레에 덧댄 레이어예요.

The agent loop, drawn — everything else wraps it

flowchart TB subgraph CORE["the agent loop — the engine"] direction LR MSG["messages + tools"] --> API["messages.create()"] API --> SR{"stop_reason?"} SR -->|tool_use| RUN["dispatch → run the tool"] RUN --> APP["append tool_result"] APP --> MSG SR -->|end_turn| DONE(["final answer"]) end SUB["subagents
recursion + context isolation"] -.-> CORE MEM["memory
conversation → world"] -.-> CORE RT["routing
cheap decides, dear executes"] -.-> CORE CA["prompt caching
static prefix, ~90% cheaper"] -.-> CORE ASY["long-running
background · callbacks · batch"] -.-> CORE SAFE["safety
permission gates + hard limits"] -.-> CORE classDef core fill:#11271a,stroke:#3fb950,color:#e6edf3,stroke-width:2px; classDef io fill:#0d1f33,stroke:#58a6ff,color:#e6edf3; classDef decision fill:#241a2e,stroke:#a371f7,color:#e6edf3; classDef done fill:#11271a,stroke:#3fb950,color:#e6edf3; classDef data fill:#2a2410,stroke:#d29322,color:#e6edf3; classDef danger fill:#2d1215,stroke:#f85149,color:#e6edf3; class API core; class MSG,RUN,APP,SUB,MEM io; class SR decision; class DONE done; class RT,CA,ASY data; class SAFE danger;
배운 것 8가지
  • ① agent loop — 모델→도구→결과→반복, ~20줄 엔진
  • ② Claude Code — 그 루프 + UI·권한·~25도구·MCP·메모리(두꺼운 하니스)
  • ③ subagents — 자식 세션에 위임 → 컨텍스트 격리·전문화·병렬
  • ④ memory scopes — conversation·session·user·project·world
  • ⑤ routing — 싼 모델이 난이도 판정, 비싼 모델은 진짜 어려운 것만
  • ⑥ prompt caching — 정적 prefix를 캐시 → 반복 호출 비용 ~90%↓
  • ⑦ long-running — 백그라운드·콜백·batch로 한 요청을 넘어서는 일 처리
  • ⑧ safety — 권한 게이트(허용/확인/샌드박스) + 하드 리밋(스텝·토큰·시간)
🧭 모양 알아보기 완성: 이제 어떤 에이전트 제품을 봐도 "이건 루프에 어떤 레이어를 덧댄 거지?"로 분해해 읽을 수 있어요. 다음 Module 6 · Production은 이걸 신뢰할 수 있게 만드는 법(평가·가드레일·보안)을 다룹니다.

라우팅(⑤)과 캐싱(⑥)을 함께 쓰면 비용에 특히 좋은 이유는?

둘은 서로 다른 축을 공격해요. 라우팅은 어떤 모델로 보낼까(호출 단가↓), 캐싱은 같은 prefix를 다시 계산하지 말자(반복 비용↓). 겹쳐 쓰면 비싼 호출의 반복분까지 줄어 비용 상한이 두 겹으로 눌립니다.