byteforce

CPN 한국어 자습서 · Claude Certified Developer — Foundations Prep

2-9 · 누적 디버그 과제

네 개 층에 심어진 버그, 찾아 고치기

Cumulative debug task — identify each bug, then write the corrected version

모듈 2에서 다룬 스키마 설계 · 스트리밍 · 컨텍스트 구성 · 메모리, 네 가지를 한 번에 점검하는 누적 디버그 과제입니다. 아래 에이전트 구현에는 층마다 하나씩, 모두 네 개의 버그가 심어져 있습니다. 먼저 어느 층에서 무엇이 어긋나는지 짚어 보고, 그다음 고친 버전을 직접 써 봅니다.

이 장에서 배우는 것What you'll learn

약 18분
1

한 구현에 심어진 네 층의 버그 — 스키마 · 스트리밍 · 컨텍스트 · 메모리

2

실패 증상을 보고 어느 층의 문제인지 짚어 내는 법

3

도구 설명이 모호할 때 도구 선택이 어긋나는 이유

4

스트리밍 커밋을 stop_seen으로 잠그고 사고 블록을 지키는 이유

5

여러 tool_result하나의 사용자 메시지로 모으는 구조

6

지난 세션을 통째로 이어 붙일 때 컨텍스트 창이 넘치는 문제와 해결

먼저 짚고 갈 용어
에이전트 루프 (agent loop)
모델의 응답을 받아 도구를 실행하고, 그 결과를 다시 모델에 돌려주기를 반복하는 코드 구조. 이 반복이 end_turn이 나올 때까지 이어진다.
스트리밍 (streaming)
응답을 한 번에 받지 않고 이벤트 조각 단위로 이어 받아 조립하는 방식. 조각이 다 도착하면 message_stop 이벤트가 온다.
tool_use · tool_result
모델이 도구를 호출하겠다고 표시하는 블록이 tool_use, 그 도구의 실행 결과를 다시 모델에 돌려주는 블록이 tool_result. 둘은 짝을 이뤄야 한다.
사고 블록 (thinking block)
확장 사고에서 모델이 답을 내기 전에 만드는 추론 블록. 다음 요청에 서명(signature)과 함께 그대로 되돌려 보내야 하며, 이를 되돌리기 규칙이라 한다.
컨텍스트 창 (context window)
한 요청에서 모델이 한 번에 읽을 수 있는 토큰의 최대 한도. 여기를 넘으면 model_context_window_exceeded 오류가 난다.
stop_reason
응답이 왜 끝났는지 알려 주는 값. 도구 호출 없이 답이 끝났으면 end_turn이 온다.

이 과제가 점검하는 것

Cumulative debug task

이 과제는 새로운 내용을 배우는 자리가 아니라, 모듈 2에서 익힌 것들이 실제 코드에서 어떻게 어긋나는지 확인하는 자리입니다. 버그는 모두 네 개이고, 서로 다른 네 층에 하나씩 들어 있습니다.

과제는 두 단계로 나뉩니다. 1단계에서는 네 개의 버그가 각각 어느 층에 있는지 짚고, 런타임에 무엇을 일으키는지 한 문장으로 적어 봅니다. 2단계에서는 고친 코드를 직접 써 보고, 그 수정이 무엇을 바꾸는지 이름을 붙여 봅니다.

쉽게 말하면

에이전트 하나에 성격이 다른 실수 네 개를 일부러 심어 두고, 그것을 찾아 고치는 연습입니다. 실무에서 층마다 자주 만나는 실수를 한 번에 복습하는 셈입니다.

버그가 심어진 구현

The buggy implementation

아래는 도구를 호출하는 에이전트 한 개의 전체 구현입니다. 겉보기에는 정상적으로 돌아가는 코드처럼 보이지만, 네 층에 각각 하나씩 결함이 들어 있습니다. 먼저 코드를 천천히 읽어 두세요.

BUGGY IMPLEMENTATION — 네 개의 층이 한 파일에

agent.py · buggy
# --- TOOL DEFINITIONS ---
tools = [
  {
    "name": "get_customer_data",
    "description": "Gets data.",
    "input_schema": {"type":"object","properties":{"id":{"type":"string"}},"required":["id"]}
  }
]

# --- AGENT LOOP ---
def run_agent(user_request, session_history):
  messages = session_history + [{"role":"user","content":user_request}]
  while True:
    blocks = {}
    stop_seen = False
    with client.messages.stream(
      model=model, max_tokens=4096, tools=tools, messages=messages,
      thinking={"type": "adaptive"}
    ) as stream:
      for event in stream:
        if event.type == "content_block_start":
          blocks[event.index] = init_block(event)
        elif event.type == "content_block_delta":
          apply_delta(blocks[event.index], event.delta)
        elif event.type == "message_stop":
          stop_seen = True
    assistant_content = [b for b in assemble(blocks) if b["type"] != "thinking"]
    messages.append({"role":"assistant","content": assistant_content})
    response = finalize(blocks)
    if response.stop_reason == "end_turn":
      return response
    for block in response.content:
      if block.type == "tool_use":
        result = execute_tool(block.name, block.input)
        messages.append({"role":"user","content":[{"type":"tool_result",
                "tool_use_id":block.id,"content":result}]})

# --- MEMORY ---
def build_session_history(prior_sessions):
  # Concatenating all prior session transcripts in-context
  full_history = []
  for session in prior_sessions:
    full_history.extend(session["messages"])
  return full_history

버그를 찾을 때는 층마다 코드의 어느 부분을 봐야 하는지 먼저 정리해 두면 도움이 됩니다. 아래 표는 각 층이 코드에서 어디에 해당하는지 짚어 줍니다. 무엇이 잘못됐는지는 아직 적혀 있지 않으니, 표를 길잡이 삼아 직접 진단해 보세요.

FOUR LAYERS → CODE — 층과 코드 위치

스키마 층tools 정의의 description — 도구가 무엇을 하는지 적는 자리입니다.
스트리밍 층스트림 이벤트를 조립한 뒤 assistant_content를 만들어 messages에 커밋하는 부분입니다.
컨텍스트 층for block in response.content 루프에서 tool_result를 사용자 메시지로 만들어 붙이는 부분입니다.
메모리 층build_session_history — 지난 세션 기록을 다음 요청 앞에 쌓는 부분입니다.

1단계 · 어느 층의 버그인지 짚기

Stage 1 · Identify each bug

이제 직접 진단할 차례입니다. 네 개의 버그마다 어느 층에 속하는지 이름을 붙이고, 그 버그가 런타임에 무엇을 일으키는지 한 문장으로 적어 보세요. 아래 칸에 먼저 써 본 뒤, 모범 답안을 열어 맞춰 보면 됩니다.

2단계 · 고친 버전 쓰기

Stage 2 · Write the corrected version

이번에는 앞에서 짚은 네 개의 버그를 고친 코드로 써 볼 차례입니다. 결함마다 고친 부분을 적고, 그 수정이 무엇을 바꾸는지 함께 적어 보세요. 다 쓴 뒤 모범 답안을 열어 맞춰 봅니다.

주의 · WATCH OUT
기억할 점

스스로 점검 — 층별로 짚어 보기

Checkpoint · Self-assess by layer

정답을 먼저 떠올려 본 뒤 골라 보세요. 맞히면 설명이 나옵니다. 네 문항은 각각 한 층씩을 다룹니다.

Q1도구 설명이 "Gets data."인 것은 어느 층의 버그이고, 런타임에 무엇을 일으킬까요?

Q2스트리밍 층에서 assistant_content를 기록에 붙이기 전에 stop_seen을 확인하지 않으면 무슨 일이 생길까요?

Q3여러 tool_resultfor 루프 안에서 각각 별도의 사용자 메시지로 붙이면 컨텍스트 층에서 무엇이 문제가 될까요?

Q4메모리 층에서 build_session_history가 지난 세션 기록을 전부 이어 붙이면 세션이 쌓일수록 무엇이 일어날까요?

MEMBER SESSION REQUIRED · REGISTRATION IS FREE

여기부터는 등록한 분에게 열립니다.

전 코스는 계속 무료입니다. 등록하면 이 코스의 남은 38개 레슨을 끝까지 읽을 수 있습니다.

등록하고 이어서 읽기

이미 등록하셨다면 그때 쓰신 이메일을 넣어 주세요.