AI/LLM/Agent 개발 — anthropic SDK로 production-grade Agent 만들기 · 퀴즈

7 문항 · Bloom: Understand:1, Apply:1, Analyze:2, Evaluate:1, Create:2

Q1 Apply mcq_single

anthropic Python SDK의 Messages API로 single-turn 호출을 만들 때, OpenAI/Spring AI ChatClient와 비교해 가장 두드러지는 구조적 차이는 무엇인가요?

정답: B
anthropic SDK는 system을 top-level 파라미터로 두고, max_tokens는 기본값이 없어 반드시 명시해야 합니다. 반면 OpenAI는 system을 messages 안 role='system'으로 두고 max_tokens 기본값을 가집니다.
오답 해설:
  • A. 그건 OpenAI 스타일입니다. anthropic은 system을 별도 top-level로 분리합니다.
  • C. anthropic의 role은 'user'/'assistant' 두 종류입니다. 'human'/'ai'는 LangChain 추상화의 명칭과 혼동한 것입니다.
  • D. fluent builder는 Spring AI ChatClient의 패턴이고, anthropic Python SDK는 명시적 dict/kwargs 호출을 사용합니다.
Q2 Understand true_false

cache_control: {'type':'ephemeral'} 블록을 system 텍스트에 붙이면 system 부분만 캐시되고, 그 뒤 messages 안의 정적 RAG context는 같은 호출에서는 캐시 대상이 될 수 없다.

정답: B
False입니다. cache breakpoint는 system뿐 아니라 messages, tools 어디에도 둘 수 있고 한 호출에 최대 4개까지 누적적으로 적용됩니다. 큰 RAG context는 messages 첫 user 블록에 cache_control을 붙여 캐싱하는 것이 흔한 패턴입니다. '캐시 = conversation history' 또는 '캐시 = system 전용'이라는 인식이 가장 흔한 오해입니다.
오답 해설:
  • A. True로 답했다면 prompt caching의 적용 범위를 system에만 국한된다고 오해한 것입니다. 실제로는 system/messages/tools 모두에 cache_control 블록을 둘 수 있습니다.
Q3 Analyze mcq_single

다음 응답 usage가 주어졌을 때, 이번 호출의 캐시 동작에 대한 가장 정확한 해석은? `usage = {input_tokens: 200, cache_creation_input_tokens: 0, cache_read_input_tokens: 3000, output_tokens: 400}`

정답: B
cache_read_input_tokens=3000은 이전 5분 TTL 안에 만들어진 캐시를 그대로 읽어 ~10% 단가로 청구된다는 뜻이고, input_tokens=200은 cache breakpoint 뒤에 새로 추가된 동적 부분(예: 사용자 새 질문)입니다. 이는 가장 이상적인 cache hit 패턴입니다.
오답 해설:
  • A. cache_read_input_tokens가 3000으로 이미 잡혀 있어 hit입니다. miss라면 이 값이 0이어야 합니다.
  • C. cache_creation=0은 '이번 호출이 새로 캐시를 만들지 않았다'는 뜻일 뿐, 이미 만들어진 캐시를 읽고 있으므로 정상입니다.
  • D. cache breakpoint 이전이 바뀌면 cache_read가 0이 되고 cache_creation이 다시 발생합니다. 동적 데이터는 breakpoint 뒤에 두는 것이 정상 패턴입니다.
Q4 Analyze mcq_multi

직접 구현한 agent loop를 production에 올리기 전에 반드시 챙겨야 하는 안전장치를 3개 고르시오.

정답: A, B, C
정답 3개 — A: max_iterations(보통 10) 없이 두면 도구를 잘못 정의할 때 무한 호출로 비용 폭발합니다. B: stop_reason은 'end_turn'/'tool_use'/'max_tokens' 등이며 'end_turn'(또는 'tool_use'가 아님)일 때 루프를 종료해야 합니다. C: 도구 에러를 그냥 raise하면 agent가 회복할 기회를 잃으니 is_error=True로 메시지화해 LLM이 보고 다른 도구나 사과 응답을 만들 수 있게 합니다.
오답 해설:
  • D. parallel tool_use 응답은 모든 tool_use 블록을 실행해 한 번에 tool_result 배열로 묶어 보내는 것이 정상 패턴입니다. 일부만 실행하면 LLM이 누락된 결과를 기다리며 이상 동작합니다.
  • E. tool_choice='any'를 항상 강제하면 사용자가 단순 인사만 해도 도구를 부르려 시도해 오작동합니다. 기본값 'auto'가 production 디폴트입니다.
Q5 Create short_answer

사용자 자연어 요청을 받아 SQLite DB에서 고객 정보를 조회하는 도구 1개(`lookup_customer`)를 정의해야 합니다. anthropic tools 스키마(JSON Schema 기반) 한 항목을 작성하고, OpenAI function calling 스키마와 메시지 형식 측면에서 다른 점 1가지를 함께 설명하세요.

채점 기준:
  • tools 항목에 name, description, input_schema 세 키가 모두 있다 (1pt)
  • input_schema는 type='object', properties에 customer_id 같은 string 필드와 required 배열을 명시한다 (1pt)
  • description이 LLM이 도구 선택 근거로 읽힐 만큼 구체적이다 (예: 'Look up a customer by ID and return name/email/tier as JSON.') (1pt)
  • OpenAI와의 차이를 1개 이상 정확히 짚는다: 예) OpenAI는 {type:'function', function:{name, parameters}} 한 단계 wrapping이 더 있다 / OpenAI는 input_schema 대신 parameters 키를 쓴다 / OpenAI tool 결과는 role='tool' 메시지, anthropic은 role='user'+content type='tool_result' (1pt)
  • OpenAI와 anthropic이 '같다'고만 적으면 0점 — 메시지 형식과 스키마 wrapping이 다르다는 점을 명시해야 한다 (감점 기준)
Q6 Evaluate mcq_single

사내 운영 도구 팀이 다음 조건의 agent를 만듭니다: (1) Claude만 사용 확정, (2) 도구 12개 예정, (3) 추후 multi-agent 분기는 검토 대상, (4) 디버깅이 쉬워야 함. C3에서 직접 구현한 50줄 agent loop를 기준점으로 할 때 가장 합리적인 다음 단계는?

정답: C
조건 (1) anthropic 확정 = 모델 lock 비용 이미 수용, (2) 도구 12개 = 직접 구현 boilerplate가 늘어나 SDK 이득, (4) 디버깅 쉬움 = 얇은 추상화 선호 — 세 조건 모두 Claude Agent SDK 방향을 가리킵니다. multi-agent 분기는 '검토 대상'일 뿐 확정이 아니므로 LangGraph는 과한 선택입니다.
오답 해설:
  • A. LangGraph는 추상화가 두꺼워 디버깅 비용이 큽니다. multi-agent가 확정되지 않은 시점에서는 과투자입니다.
  • B. LlamaIndex는 RAG/index 중심 framework로 운영 도구 호출 agent에는 맞지 않는 보완재입니다.
  • D. 도구 2~3개라면 합리적이지만 12개 규모에서는 직접 구현의 boilerplate가 디버깅 비용을 오히려 키웁니다. 'lock-in 위험'을 모든 의사결정의 단일 기준으로 삼는 것은 잘못된 휴리스틱입니다.
Q7 Create short_answer

S3에서 만든 Typer single-file CLI에 anthropic SDK + tool use를 얹어 'PR diff를 받아 변경 파일을 요약하는 agent'를 capstone으로 설계한다고 가정합시다. (a) 도구 2개의 name/description을 정하고, (b) max_iterations 값과 그 근거, (c) read-only 원칙을 깨지 않기 위한 안전 가드 1개를 적으세요.

채점 기준:
  • (a) 도구 2개 모두 read-only로 정의 — 예: list_changed_files(diff_path), read_file(path) 같이 부작용 없는 함수 (2pt)
  • (a) 각 도구 description이 LLM이 선택 근거로 쓸 수 있게 구체적이다 (예: 'Return list of file paths changed in the given unified diff.') (1pt)
  • (b) max_iterations 값(3~10 범위)과 그 근거 제시 — 예: '도구 2개 × 파일 수만큼 read 호출 가능 → 5 iterations로 시작, 도구 호출 비용 모니터링 후 조정' (1pt)
  • (c) 안전 가드 1개 명시 — 예: write_file 도구를 추가하지 않음 / Path를 작업 디렉토리 prefix로 검증 / tool_result 내용을 4000자로 truncate해 prompt injection 위험 축소 / 사용자 입력을 그대로 shell에 넣지 않음 (1pt)
  • 단순히 'C5의 코드를 그대로 쓰면 된다'는 답변은 시나리오 적용이 없으므로 절반 점수 (감점 기준)