본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 06. 15. 05:26

명확한 Goal과 Eval로 에이전트를 움직이기 — Code with Claude Extended Tokyo에서 배운 것

요약

Anthropic의 'Code with Claude: Extended Tokyo' 이벤트 참가 후기로, 장시간 작동하는 에이전트를 효과적으로 제어하기 위한 전략을 다룹니다. 에이전트의 모호함을 줄이기 위해 구현 전 질문을 유도하고, 명확한 사양을 도출하는 워크플로우를 소개합니다.

핵심 포인트

  • 에이전트가 장시간 작업함에 따라 실수의 비용이 높아짐
  • 구현 전 에이전트가 사용자에게 질문하여 사양을 구체화해야 함
  • AskUserQuestion 툴을 활용해 인터뷰 형식으로 스펙 도출 가능
  • 모호한 프롬프트 대신 엣지 케이스와 타겟을 파악하는 과정이 필수적

Code with Claude のステージに掲げられた「Code w/ Claude」の看板

이치한(今半) 도시락, 마카롱, 무스, Bun의 고기만두…….

……라고 사진을 나열하고 있었더니, Slack에서 "식품 리뷰는 됐으니까!"라는 핀잔을 들어서, 이쯤에서 본론으로 들어가겠습니다 (웃음).

6월 11일, Anthropic의 "Code with Claude: Extended Tokyo" (본편 다음 날 개최된, 독립 개발자 및 초기 단계 창업자를 위한 확장판 이벤트)에 참가하고 왔습니다.

평소 Managed Agents를 다루고 있는 관계상, 이번에는 강연을 듣기보다 Workshop (핸즈온)을 우선하여 직접 손을 움직이는 전략으로 임했습니다.

당일 워크숍 교재는 anthropics/cwc-workshops에 공개되어 있습니다. Managed Agents 주변을 중심으로 돌아보고, 마지막에는 Agent Battle까지 참가했습니다 (본선 런은 회장에서 배포된 API 토큰이 제 손에 도착하는 것이 늦어져서...).

How we Claude Code — 장시간 에이전트와 함께하는 3가지 도구

오전은 Boris 님의 세션으로 시작되었고, 그 후에 참가한 것이 이 세션이었습니다. 출발점은 이 한 문장입니다.

"Agents now run for hours, not minutes and do more work than ever before."

登壇スライド「Agents now run for hours, not minutes and do more work than ever before.」

에이전트가 장시간·대량의 작업을 수행할 수 있게 된 만큼, 실수의 비용도 높아지고 있습니다. 그렇기에 소개된 것이 바로 "Three tools for working with long-running agents (장시간 작동하는 에이전트와 함께하는 3가지 도구)"입니다. 이를 Phase 1~3의 구현을 통해 체감하는 구성이었습니다.

① 모호함을 없애기 (Phase 1)

결론: 구현에 들어가기 전에, 에이전트가 먼저 질문하게 한다.

Bad/Good의 대비가 이해하기 쉬웠습니다.

프롬프트발생하는 현상
Bad"Create a bill-splitting app for friends for me."
Good"I'm not sure what my target audience is — can you help me brainstorm different ways I could take this?"

Phase 1의 PROMPT.MD

에서는 AskUserQuestion 툴을 명시함으로써, 인터뷰 형식으로 사양을 끌어낸 뒤 spec(사양)으로 떨어뜨리는 흐름을 만들고 있습니다. "누구를 위한 것인가?", "불균등한 결제는?"와 같은 질문이 차례차례 나오면서, 머릿속의 "어렴풋한 더치페이 앱"이 구체적인 사양서로 변해가는 경험이었습니다.

② 읽을 수 있는 계획을 만들기 (Phase 2)

결론: 계획은 Markdown이 아니라 HTML로 만든다.

Markdown (어제)HTML (오늘)
# Plan ## Scope ## Open questions 식의 평범한 불렛 포인트SCOPE / OPEN / FLOW 등을 카드 형식으로 구조화한 비주얼

HTML 계획은 모델의 사고 과정을 더 많이 포착할 수 있다는 것이 포인트입니다. Phase 2의 PROMPT.MD는 Phase 1의 사양을 읽고, 4가지 디자인 방향성을 각각 HTML 파일로 생성합니다. 코드를 작성하기 전에 여러 방향성을 나란히 놓고 비교할 수 있는 감각은, 하나의 안(案)에 얽매이기 쉬운 기존의 개발과는 상당히 달랐습니다.

③ 검증을 처음부터 포함하기 (Phase 3)

결론: 검증은 사후에 추가하는 것이 아니라, 설계와 동시에 생각하는 것이다.

3가지 원칙이 제시되었습니다.

  • Build for it from the start — 만들면서 검증을 생각한다
  • Modularize by verifiability — 독립적으로 검증할 수 있는 단위로 코드를 나눈다
  • Verify across the stack — 유닛(Unit) / 통합(Integration) / 비주얼 / 동작을 가로질러 검증한다

Phase 3에서는 Vite + React로 구현된 앱을 통해, 6가지 아이디어를 바탕으로 '검증 가능한 컴포넌트 설계 (Verifiable Component Design)'를 구체화했습니다.

#키워드개요
1DOM이 기계 판독 가능한 서피스 (Surface)data-verify-* 속성을 통해 컴포넌트의 상태를 외부에 공개한다
2검증 가능한 유닛 (Verifiable Unit)각 컴포넌트가 fixtures (재현 가능한 상태)와 invariants (충족해야 할 조건)를 선언한다
3독립된 렌더링 타겟 (Render Target)/verify/:unit/:fixture 경로를 통해 단 하나의 유닛만 마운트하여 관찰할 수 있다
4플러그형 검증기 (Pluggable Verifier)schema / invariants / dom-contract / a11y 4종류. 컴포넌트를 변경하지 않고 추가할 수 있다
5window.__verify에이전트용 API. manifest() / current() / runAll()을 제공한다
6판정은 단일 체계PASS / FAIL / BLOCKED / SKIP. 대시보드, 에이전트, CI가 동일한 코드 경로를 사용한다

data-verify-*라는 발상이 특히 흥미로웠는데, React의 useState는 JS 외부에서 읽을 수 없지만, 상태를 DOM 속성으로 써 내려가기만 하면 AI 에이전트가 document.querySelector로 가져올 수 있다는 이야기입니다. 내부 구현을 리팩터링(Refactoring)하더라도 DOM 속성만 유지한다면 검증이 깨지지 않는 설계입니다.

리포지토리는 phase-1-exploration (PROMPT.MD만 포함) / phase-2-planning (PROMPT.MD만 포함) / phase-3-verify (Vite + React 구현)의 3개 폴더 구성입니다.

이 세션의 마무리 멘트가 강렬한 인상을 남겼습니다.

"The work is no longer writing the code. The work is setting up the conditions in which the code gets written well."

登壇スライド「The work is no longer writing the code. The work is setting up the conditions in which the code gets written well.」

"코드를 작성하는 것 자체가 아니라, 코드가 잘 작성될 수 있는 조건을 설정하는 것이 업무가 되었다" —— 이론적으로는 알고 있다고 생각했지만, Phase 1~3의 흐름을 따라 직접 해보니 실감하며 깊이 이해하게 되었습니다. 다음 세션부터는 그 '조건을 설정하는 것'이 더욱 구체적인 형태로 나타납니다.

Managed Agents를 직접 움직이기

Ship your first Managed Agent

"새벽 2시에 p99 레이턴시(Latency)가 10배가 되었습니다. 자, 여기 있습니다"라는 가상의 긴급 시나리오로 핸즈온(Hands-on)이 시작됩니다. 주어진 agent.py에는 7개의 NotImplementedError가 나열되어 있었고, 이를 단 34줄로 채우기만 하면 되는 심플한 구성이었습니다.

흥미로웠던 점은 실행 장소의 분리입니다.

  • 에이전트 본체는 Anthropic의 클라우드 샌드박스(Sandbox)에서 동작한다.
  • 사용자의 로컬 환경에서는 get_metrics와 같은 도구들이 실행된다.
  • **이벤트 스트림(Event Stream)**이 양쪽을 연결하며, 에이전트 측은 "처리가 어디서 실행되고 있는지"를 의식하지 않는다.

이 방식의 실용적인 포인트는 사내 시스템을 외부에 공개하지 않고도 에이전트가 호출할 수 있다는 점입니다. 보통 에이전트에게 사내 API를 호출하게 하려면 VPN이나 인증 문제가 발생하지만, 이 모델에서는 로컬 도구가 아웃바운드(Outbound)로 이벤트 스트림에 연결하기만 하면 되므로 포트 개방이 필요하지 않습니다.

登壇スライド「The cloud agent calls a function on your laptop」(custom tool を SSE ストリーム経由でローカルの handle_tool が処理。インバウンド通信なし)

Agents that remember

캐치프레이즈는 "금붕어에서 동료로". 45분간 진행되는 핸즈온입니다.

초반 몇 분 동안 "에이전트가 아무것도 기억하지 못한다"는 것을 의도적으로 체감하게 만드는 설계가 훌륭했습니다. 그 후에 Memory Store 메커니즘이 등장합니다.

登壇スライド「Three layers(Session / Memory store / Dreaming)」

개념내용
Memory Store읽고 쓸 수 있는 영속적 스토리지 (Persistent Storage). 세션 (Session) 생성 시 어태치 (Attach) 함
여러 세션에 어태치동일한 스토어 (Store)를 다른 세션에 전달하면, 대화를 넘나들며 기억이 계승됨
기록 방식 지정 가능"무엇을 어떻게 기록할지"를 에이전트 (Agent)에게 지정할 수 있음
Dreaming과거 세션 (Session) 로그와 Memory Store를 입력으로 배치 처리 (Batch processing)하여, 정리된 새로운 Memory Store를 생성함 (리서치 프리뷰)

"기억시킨다"라고 하면 구현이 무거울 것 같지만, 실체는 스토어 (Store)를 어태치 (Attach) 하는 것뿐이었습니다 (엄밀히 말하면 agent toolset의 활성화가 필요하며, 참조 전용으로 만들고 싶은 스토어는 기억의 오염을 피하기 위해 read_only 사용이 권장됩니다). Dreaming은 과거 로그를 거슬러 올라가 정리할 수 있으므로, 나중에 "그 대화도 기억에 넣고 싶었다"라는 상황에서 효과적일 것 같습니다. Managed Agents 자체는 아직 베타/일부 리서치 프리뷰 단계이지만, 앞으로가 기대되는 기능이었습니다.

登壇スライド「How Dreaming works」(Input/Output memory store と Orchestrator・Subagent の構成)

evals를 "먼저" 작성하기

Evals for taste: Hill-climbing a slide-generation agent

"어쨌든 LLM에 맡긴다"라고 하기 전에, 먼저 평가 (evals)를 준비한다. 이번 이벤트를 통해 가장 반복적으로 등장한 발상이 이것이었으며, 이를 위한 전용 세션도 있었습니다. 주제는 **슬라이드를 생성하는 에이전트 (Agent)**로, 이를 평가 태스크군 (eval)으로 채점하며 키워 나가는 흐름입니다.

첫 번째 슬라이드에서 보여준 "evals가 없을 때 vs 있을 때"의 대비가 우선 납득이 갔습니다.

evalsセッションのスライド「Why are evals important?(Without evals / With evals)」

위 슬라이드의 요점을 나름대로 표로 정리하면 다음과 같습니다.

evals 없음evals 있음
상태갈피를 잡지 못하고 반응적인 루프 (Reactive loop)에 빠짐
구체적 내용문제가 운영 환경에서야 발견됨 / 하나의 버그를 고치면 다른 버그가 발생함 / 실제 피드백과 노이즈를 구분할 수 없음 / 개선인지 퇴보인지 "짐작만으로 확인"할 수밖에 없음

특히 와닿았던 점은 "성공이란 어떤 상태인가 (what does success look like?)를 evals가 강제적으로 언어화하게 만든다"는 점입니다. 모호한 상태로 만들기 시작하면 나중에 좋고 나쁨을 판단할 수 없게 되는데, 이는 앞서 언급한 "모호함을 없애기 (Phase 1)"와도 맥락이 이어지는 이야기였습니다.

evals는 프롬프트 엔지니어링 (Prompt Engineering) 라이프사이클의 일부로 자리 잡고 있었습니다.

Develop eval test cases (평가 태스크 만들기) → Write preliminary prompt (잠정 프롬프트 작성) → Run prompt against tasks (태스크에 대해 실행) → Refine prompt (개량) → Ship polished prompt (다듬어서 출시)

evalsセッションのスライド「Essential part of the prompt engineering lifecycle」

여기서 "Run ↔ Refine"을 뱅글뱅글 돌리는 반복 그 자체가 evals라는 정리입니다. 먼저 태스크 (평가)를 작성한 뒤에 프롬프트를 작성한다는 순서가 포인트이며, 목표 정의를 먼저 고정하기 때문에 개량의 좋고 나쁨이 흔들리지 않고 측정될 수 있다는 점에서 납득이 갔습니다.

채점자 (Grader)의 3가지 유형도 실무적이었습니다. 슬라이드에서는 다음과 같이 제시되었으며, 나중에 참고하기 위해 표로 정리해 둡니다.

evalsセッションのスライド「Graders(Code-based / Model-based / Human graders)」

Grader수법장점단점
Code-based문자열 일치, 정규 표현식, 퍼지 매칭 (Fuzzy matching), 유닛 테스트 (fail-to-pass), 정적 분석 (lint/type), 최종 상태 및 툴 호출 (Tool call) 체크빠름, 저렴함, 결정론적 (Deterministic)취약하며 뉘앙스를 담기 어려움
Model-based루브릭 (Rubric) 채점, 페어와이즈 비교 (Pairwise comparison), 다수 심사 합의유연함, 확장성 있음, 뉘앙스 대응 가능비결정론적 (Non-deterministic), 비용 발생, 캘리브레이션 (Calibration) 필요
HumanSME (전문가) 리뷰, 크라우드소싱 판정, 스팟 체크 추출, A/B 테스트유연함, 고품질, 뉘앙스 대응 가능느림, 고비용

「산술은 코드로, 판단은 LLM으로」라는 후술할 분업 이야기와 연결되지만, 채점도 마찬가지로 결정론적(Deterministic)으로 측정할 수 있는 것은 코드 기반(Code-based)으로 돌리고, 뉘앙스가 필요한 부분만 모델 기반(Model-based) / 인간(Human)에게 맡긴다——라는 비용 감각이 납득되었습니다. 이어서 다룰 Agent Battle의 --eval 역시, 결국 이 「먼저 태스크를 작성하고 빠르게 돌린다」는 발상의 구현판이었다는 것을 나중에 깨달았습니다.

툴 / Skill / Subagent로 분해하기

Tool, skill, or subagent? Decomposing an agent that outgrew its prompt

이 세션이 개인적으로 가장 와닿았습니다. 테마는 "너무 커져 버린 에이전트를 툴 / Skill / Subagent로 다시 분해하기"라는 이야기입니다.

핸즈온(Hands-on)에서 다룬 소재는 매일 아침 수백 행의 CSV 재고 데이터를 체크하여 공급업체(Supplier)를 선정하는 에이전트였습니다. 초기 상태는 다음과 같습니다.

  • system prompt: 402행
  • 툴(Tool) 수: 12개
  • CSV 전체 행이 통째로 컨텍스트(Context)에 포함됨
  • 공급업체 선정은 subagent에게 통째로 맡기고 산문(Prose)으로 답변

워크숍에서 제시된 측정치는 **488초 · 102회의 툴 호출 · 스코어 71%**였습니다. 솔직히 꽤나 힘든 수치입니다.

세션 내내 반복된 메시지는 이것이었습니다.

"Ranking suppliers is arithmetic, not judgment. Compute it in Python — do not reason about it in prose."
(공급업체 순위 지정은 산술이지 판단이 아닙니다. Python으로 계산하세요. 산문으로 추론하지 마세요.)

LLM에게 「생각하게」 해야 할 태스크와 「계산하게」 해야 할 태스크는 별개라는 이야기입니다. 공급업체의 순위 지정은 가격, 리드 타임(Lead time), 신뢰성에 가중치를 두어 더하기만 하면 되는 산술입니다. 그것을 LLM이 문장으로 추론하게 했던 것이 낭비였다——단순하지만, 다시금 언어화되어 전달되니 가슴에 와닿았습니다.

워크숍에서 제시된 개선 전후의 수치는 다음과 같습니다.

지표BeforeAfter
system prompt402행15행
...

가져온 판단 기준도 정리해 둡니다.

무엇에 맡길 것인가적절한 태스크
코드 실행 (Python 등)계산 · 집계 · 필터링 등의 산술 처리
Skill (프롬프트)정책이나 지식 참조 (필요할 때만 읽음)
Subagent독립된 목표를 가진 처리만

"subagent가 수치 하나를 반환할 뿐이라면, 그것은 subagent일 필요가 없다"라는 한마디도 인상적이었습니다.

「이것이 정말로 LLM이 생각해야 할 일인가?」를 먼저 eval 스코어로 확인한 뒤 분해해 나가는——이러한 흐름을 평소 개발에서도 당연하게 실천하고 싶습니다.

인도네시아의 「조문」을 쿼리 가능하게 만든 이야기

How I built a legal platform for 280 million people at the Claude Code Hackathon

워크숍 중간에 들었던 강연 중에서 특히 인상 깊었던 이야기를 하나 소개합니다.

Pasal.id(파살)는 인도네시아어로 「조문」을 의미합니다. 2억 8천만 명 인구 국가의 법령을 누구나 무료로 검색하고 참조할 수 있는 오픈 데이터베이스를 개인이 혼자서 만들었다는 프로젝트였습니다.

문제 의식이 매우 명확했습니다. 발표자에 따르면 인도네시아에는 1945년부터 현재까지 30만 건 이상의 법령이 있으며, 각 부처 사이트에 읽기 힘든 PDF나 이미지 스캔본 형태로 산재해 있다고 합니다. 포맷만 해도 21종류에 달합니다. 구조화되지 않은 정보는 찾을 수 없고, 인용할 수 없으며, AI에게 물어볼 수도 없다는 뜻입니다.

여기서 발표자가 깔끔하게 정리해 준 것이 「법령을 AI에게 물어보는 방법의 3단계」였습니다.

레벨접근 방식문제
Bad모델에게 직접 질문할루시네이션 (Hallucination), 지식 컷오프 (Knowledge Cutoff)
Better웹 검색 (Web Search)비구조화, 신뢰성 편차
Best구조화된 DB로의 쿼리 (MCP)

「AI 에이전트의 시대에는 모든 정보가 쿼리(Query) 가능해야 한다」라는 주장은 단순하지만, 역설적으로 말하면 쿼리할 수 없는 정보는 존재하지 않는 것과 같다는 뜻이기도 합니다.

개발 프로세스에서 Claude를 사용하는 방식도 인상적이었습니다. 「코드를 작성하게 하는 것」이 아니라 「함께 생각하는」 파트너로서 사용하며, 해커톤의 규칙 문서를 읽혀 브레인스토밍을 하고, 아키텍처에 대해 논의(Wall-hitting)하며, TASKS.md를 생성하고, 로고와 디자인 시스템까지 함께 만들었다고 합니다. 이 사용법은 개인적으로 더 따라 해보고 싶습니다.

데이터 파이프라인의 설계 사상도 흥미로웠습니다.

Scraping— 공식 PDF 다운로드
OCR— 이미지 스캔을 포함한 PDF의 텍스트화
Parsing— 텍스트를 법령 트리(장·조·항·호)로 변환. LLM을 사용하지 않는 결정론적 파서 (Deterministic Parser)
Verify— LLM을 「Auditor (감사자)」로 사용하여, 파서의 출력을 PDF와 대조하여 오류를 수정

인상적이었던 점은 「AI로 파서를 대체하는 것이 아니라, AI로 파서를 감사한다」는 설계였습니다. 법령 트리로의 변환 자체는 LLM을 사용하지 않는 결정론적 파서가 담당하고, LLM은 출력을 PDF와 대조하는 Auditor 역할을 수행합니다 (정확도의 토대는 코드 측에 있음).

나아가, 독자가 기사에서 오류를 보고하면 에이전트가 공식 PDF와 대조하여, 안전한 수정은 자동으로 적용하고 그 외의 것은 리뷰로 넘깁니다.

그리고 수정 사항은 하나씩 테스트 케이스가 되어, 사용될수록 파서가 성장해 나가는 구조였습니다.

마지막 슬라이드에 "Japan shares these same challenges"라고 적혀 있어 조금 뜨끔했습니다 (웃음). 일본의 법령 PDF도 이미지 스캔 형태가 많고, e-Gov가 있기는 하지만 에이전트가 쿼리하기 쉬운 형태인가 하면 솔직히 미묘합니다. 인도네시아에서 개인이 혼자서 해냈다면 일본에서도 할 수 있을 것입니다. —— 「해보고 싶다」는 생각이 솔직하게 들었습니다.

登壇スライド「What software does your country not have yet?」

Agent Battle

Agent Battle: Mine the most diamonds in 45 minutes

마지막은 Minecraft에서 다이아몬드 채굴 수를 겨루는 Agent Battle (교재는 anthropics/cwc-workshops의 agent-battle)이었습니다. 코드를 작성하는 것이 아니라, my_agent.py의 4가지 노브(Knob: model / system / skills / mcp_servers)를 어떻게 설정하느냐가 경기의 본질이었습니다.

登壇スライド「Your whole agent is a dict. Four levers(system / model / skills / mcp_servers)」

아키텍처는 Ship your first Managed Agent와 같은 발상으로, 로컬의 Mineflayer 봇이 클라우드의 Claude로 아웃바운드(Outbound) 연결을 시도하기 때문에 포트 개방은 필요하지 않습니다.

登壇スライド「The harness」(Anthropic cloud の Claude agent と、ローカルの mineflayer ボット/vanilla MC を MCP トンネルで接続)

여기서도 효과를 발휘한 것이 eval (평가)이었습니다. 경기 전에 --eval을 통해 다이아몬드 채굴의 전형적인 상황에 대한 에이전트의 판단을 채점할 수 있습니다. system 프롬프트가 비어 있는 상태에서도 7/10점을 받았습니다. Claude는 원래 Minecraft에 대한 지식을 가지고 있기 때문에, 아무것도 쓰지 않아도 7할은 맞춥니다. 나머지 3문제(철 곡괭이로 교체하기 / 다 캐면 이동하기 / tuff는 무시하기)가 system에 작성해야 할 힌트였습니다. eval은 30~60초 내외, 몇 엔 이하의 비용으로 돌릴 수 있으므로 가설을 저렴하게 여러 번 테스트할 수 있습니다.

본 경기(Run)에는 API 토큰이 필요했지만, 행사장 배포 토큰이 손에 닿는 시점이 늦어져 이번에는 eval을 파고드는 단계까지 진행했습니다. 본 경기는 다음 기회로 미룹니다.

요약

돌이켜보면, 이번에 얻은 핵심은 「명확한 Goal(목표)과 Eval(평가)로 에이전트를 움직인다」는 점 하나로 귀결됩니다. 성공의 정의(Goal)를 먼저 정하고, Eval로 측정하며 실행한다 —— 모든 세션이 결국 이 이야기로 이어졌습니다.

  • 먼저 모호함을 해결하고, 목표(Goal)를 확정하기 (How we Claude Code): 구현에 들어가기 전에 에이전트에게 질문을 던지게 하여, 사양(Specification)을 언어화한 뒤에 움직입니다. "코드를 쓰는 것보다, 코드가 잘 작성될 수 있는 조건을 정돈한다"라는 발상이 여기에 담겨 있었습니다.
  • Eval로 측정하며 반복하기: "성공이란 어떤 상태인가"를 먼저 Eval로 정의하고, 개선이나 분해 역시 Eval 점수로 확인한 뒤에 진행합니다. 산술적인 계산은 코드에 맡기고, 판단만을 LLM에 맡깁니다. 488초에서 100초로, 71%에서 92%로의 차이가 그 효과를 증명하고 있었습니다.

발표보다는 워크숍 중심으로 진행되었기에, 이 핵심 원칙이 깊이 와닿았습니다. 다음 기회에도 꼭 참여하고 싶습니다.

Discussion

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0