AI 에이전트 전환: Anthropic SDK 0.100–0.102에서 삭제할 Cloudflare 코드

Anthropic SDK 0.100–0.102의 Managed Agents, outcomes, 웹훅을 Cloudflare Workers·Durable Objects 스택에 적용할 때 삭제할 코드와 남겨야 할 재시도·비용 제어 계층을 실제 운영 마이그레이션 기준으로 정리합니다.

Saturday, September 5, 2026Omid Saffari
AI 에이전트 전환: Anthropic SDK 0.100–0.102에서 삭제할 Cloudflare 코드

Anthropic Python SDK는 5월 6일 0.100.0, 5월 11일 0.101.0, 5월 13일 0.102.0을 잇달아 내놓았습니다. 불과 8일 사이 세 차례 릴리스되면서 Managed Agents는 결과 평가(outcomes), 웹훅, 멀티 에이전트 오케스트레이션을 내장한 호스팅형 AI 에이전트 런타임이 됐습니다. 제가 Cloudflare에서 운영 중인 6개 Durable Object 스택을 놓고 client.beta.managed_agents.sessions.create()가 무엇을 대체하는지 따져본 결과, 솔직한 답은 워크플로 두 단계에 흩어진 재시도·폴링 코드 약 280줄입니다. 나머지는 그대로 둡니다.

SDK 0.100–0.102에서 AI 에이전트 기능은 무엇이 달라졌나

세 번의 릴리스가 나온 기간은 단 8일입니다. 그 사이 Python SDK의 표면적은 직전 6개월보다 더 크게 바뀌었습니다. 운영 환경을 anthropic==0.99.x에 고정해 둔 팀이라면 한 번의 스프린트 동안 Managed Agents 런타임 전체를 놓친 셈입니다.

**v0.100.0(2026년 5월 6일)**에서는 beta 네임스페이스에 멀티 에이전트, outcomes, 웹훅 지원과 vault 검증이 추가됐습니다. 핵심 형태는 이렇습니다. client.beta.managed_agents.sessions.create(thread=..., outcome=..., metadata=...)를 호출하면 session_id가 반환되고 Anthropic 인프라에서 비동기로 실행됩니다. 이제 오케스트레이션 루프를 직접 운영하지 않아도 됩니다.

**v0.101.0(2026년 5월 11일)**에서는 Claude Platform on AWS용 AWS 클라이언트가 추가됐고, 모든 쿡북 예제의 모델이 claude-sonnet-4-5-20250929로 바뀌었습니다. Bedrock을 사용한다면 필요한 버전은 이것입니다. ANTHROPIC_BEDROCK_SERVICE_TIER 환경 변수 지원(default/flex/priority)은 0.100이 아니라 이 버전에 들어왔습니다.

**v0.102.0(2026년 5월 13일)**에서는 BetaManagedAgentsSearchResultBlock 타입, 프롬프트 캐시 beta의 캐시 진단, Pydantic 이터레이터 즉시 검증이 추가됐습니다. 블록 타입 인터페이스는 여전히 바뀌는 중이며, 제가 아직 멀티 에이전트 코드를 옮기지 않는 가장 큰 이유도 바로 이것입니다.

대표 기능은 outcomes입니다. 루브릭을 작성하면 별도의 평가 에이전트가 결과를 채점하고, 통과할 때까지 에이전트가 다시 실행됩니다. Anthropic 내부 평가에 따르면 일반적인 프롬프팅 루프보다 작업 성공률이 최대 +10포인트 높았고, docx 생성은 +8.4%, pptx 생성은 +10.1% 개선됐습니다. 제 Critic Durable Object에서 확인한 결과와도 흐름이 같습니다. 평가 메모를 반영해 한 번만 다시 프롬프트해도 대략 모델을 한 등급 올린 만큼 품질이 좋아집니다.

다른 한 축은 웹훅입니다. Claude Console에 등록한 URL로 8가지 세션 이벤트가 전송됩니다. session.status_run_started, session.status_idled, session.status_rescheduled, session.status_terminated, session.thread_created, session.thread_idled, session.thread_terminated, 그리고 가장 중요한 session.outcome_evaluation_ended입니다. 서명 시크릿은 whsec_… 형식이며 생성할 때 한 번만 표시됩니다. 검증에는 client.webhooks.unwrap(payload, signature, secret)을 사용합니다.

멀티 에이전트 오케스트레이션도 함께 나왔지만, 리서치 프리뷰 접근 권한을 별도로 신청해야 합니다. 아직 이 기능을 켜지 않는 이유는 뒤에서 설명하겠습니다.

비개발 창업자가 알아야 할 변화

이제 Anthropic이 에이전트를 대신 실행합니다. 루브릭을 작성하면 됩니다. 예를 들어 “글이 2,000단어를 충족하고, 1차 출처 3개를 인용하며, de-AI 정규식을 통과했는가?”라고 정해 두면 Anthropic의 평가 에이전트가 결과를 검토하고 통과할 때까지 다시 실행합니다. 엔지니어가 재시도 루프를 직접 만들 필요가 없어집니다.

비용에는 두 가지 영향이 있습니다. 첫째, 코드베이스에서 수작업 재시도 루프가 줄어 시니어 엔지니어가 이를 유지보수하는 시간도 감소합니다. 둘째, Anthropic 세션 내부의 재시도는 늘어나며, 각각 토큰 비용에 더해 세션 시간당 $0.08이 부과됩니다. 실제로 이득인지는 세션이 얼마나 오래 실행되는지에 전적으로 달려 있습니다.

현실적으로 보면, 팀이 v1 에이전트 제품을 출시하는 단계라면 Managed Agents는 시니어 엔지니어가 직접 작성해야 할 오케스트레이션 코드의 약 40%를 대체합니다. 이미 제품을 출시했다면 대체 범위는 더 작지만, 웹훅만으로도 어딘가에 거의 확실히 남아 있는 폴링 루프를 없앨 수 있습니다.

이번 주 CTO에게 물어볼 질문은 이것입니다. “아직도 완료 여부를 폴링하고 있나요, 아니면 session.outcome_evaluation_ended로 전환했나요?” 답이 “폴링 중”이라면 반나절짜리 리팩터링으로 인프라 비용과 요청 지연 시간을 한 번에 낮출 수 있습니다.

현재 운영 중인 Cloudflare 스택

무엇을 삭제할 수 있는지 설명하려면 먼저 현재 아키텍처를 봐야 합니다. Cloudflare Workers에서 구동되는 Hono 기반 Worker 하나(ES2021 타깃, Static Assets 바인딩)가 퍼블리셔 루틴별 Durable Object 6개의 앞단을 맡습니다. Editorial, Discovery, Writer, Distribution, Maintenance, Manager가 있고, 관리자 UI를 지원하는 일곱 번째 객체 ManualIntake가 따로 있습니다.

각 루틴은 6개의 Cloudflare Workflows 중 하나를 통해 실행됩니다. PublishWorkflow, WriteArticle, PublishArticle, EnrichIdea, DiscoverIdeas, DistributeArticle입니다. 가장 많은 일을 하는 PublishWorkflow는 검증, 근거화, 생성, 정제, 저장, 인덱싱, 커버, 발행으로 이어지는 8개의 멱등 단계로 구성됩니다. 모든 I/O 단계는 다음 코드로 감쌉니다.

TypeScript
const result = await step.do(
  "generate-article",
  { retries: { limit: 3, backoff: "exponential" } },
  async () => env.WRITER.generate(brief)
);

D1은 기준 상태를 보관합니다(editorial_brief.status 전이: dispatcheddraftingpublished / failed). Vectorize는 블록별 임베딩을 처리합니다(Gemini-2 768d, 비대칭 검색 형식). 모든 유료 모델 호출은 단일 관문인 callAi(env, ctx, runner)를 거칩니다. 이 함수는 비용 집계를 위해 agent_id, workflow_instance_id, idea_id와 함께 ai_call_log에 기록하고, 일일 $20 및 인스턴스당 $1 한도를 강제합니다.

이 아키텍처는 앞서 정리한 6-DO 구성입니다. Managed Agents 마이그레이션에서 중요한 것은 재시도 로직의 위치입니다. 두 군데에 있습니다.

  1. 워크플로 단계 재시도(저렴하며, 기반 호출이 성공하면 무료): 네트워크 순간 장애, 레이트 리밋, 업스트림 제공자의 일시적인 5xx를 처리합니다.
  2. clean.ts에 직접 작성한 평가 후 재시도 루프: Writer를 실행하고 Critic으로 평가한 뒤, score < 0.75이면 Critic 메모를 넣어 다시 프롬프트합니다. 최대 3번 시도합니다.

Managed Agents가 대체하는 것은 두 번째입니다. 첫 번째는 유지합니다.

SDK 0.100으로 삭제할 수 있는 280줄

src/worker/workflows/publish/clean.ts의 평가 후 재시도 루프는 outcomes로 가장 깔끔하게 대응됩니다. 현재 오케스트레이션 코드는 약 120줄입니다. Writer를 호출하고, editorial_brief.rubric_md에 저장된 루브릭으로 Critic을 실행하고, 점수를 파싱하고, 임계값에 따라 분기하고, 메모를 시스템 블록으로 붙여 다시 프롬프트하는 과정을 최대 3회 반복합니다. Critic 자체도 Durable Object 코드 80줄을 더 차지합니다(hibernation 훅, 루브릭 이력용 인스턴스별 SQLite, 시도별 멱등성 키). callAi.ts의 시도별 ai_call_log 집계에도 40줄이 더 필요합니다. 각 시도를 따로 기록한 뒤 대시보드에서 다시 합쳐야 하기 때문입니다.

이 세 블록은 Managed Agents 호출 하나로 줄어듭니다.

TypeScript
const session = await anthropic.beta.managedAgents.sessions.create({
  thread: { messages: [{ role: "user", content: brief.body_md }] },
  outcome: {
    rubric: brief.rubric_md,
    evaluator: "claude-sonnet-4-5-20250929"
  },
  metadata: { brief_id: brief.id, workflow_instance: ctx.instanceId }
});
return { session_id: session.id, status: "pending" };

이것이 전부입니다. 세션은 Anthropic 측에서 완료될 때까지 비동기로 실행됩니다. outcome 매개변수가 기존 Critic DO의 역할을 맡습니다. 별도의 평가 에이전트가 루브릭에 따라 결과를 채점하고, 통과할 때까지 기본 에이전트를 다시 실행합니다.

추가할 코드는 하나뿐입니다. /api/admin/webhooks/managed-agents 경로에서 whsec_… 서명을 검증하고, event.type === "session.outcome_evaluation_ended"인 이벤트를 분기 처리해 결과를 D1에 기록합니다.

TypeScript
app.post("/api/admin/webhooks/managed-agents", async (c) => {
  const raw = await c.req.text();
  const event = await anthropic.webhooks.unwrap(
    raw, c.req.header("anthropic-signature")!, c.env.WEBHOOK_SECRET
  );

  if (event.type !== "session.outcome_evaluation_ended") {
    return c.json({ ok: true });
  }

  await c.env.DB.update(editorial_brief).set({
    status: event.outcome.passed ? "published" : "failed",
    body_md: event.result.body,
    session_cost_usd: event.session.usage.total_cost_usd
  }).where(eq(editorial_brief.id, event.session.metadata.brief_id));

  return c.json({ ok: true });
});

서명 검증과 멱등성(brief_id 기준)을 갖춘 코드 40줄이면 충분합니다.

순변경: 오케스트레이션 코드 240줄 감소. wrangler.json에서 Durable Object 바인딩 1개 감소. 마이그레이션 파일 1개 감소. 웹훅 처리 코드 40줄 추가. Cloudflare Secrets Store에 시크릿 1개 추가.

GET /api/admin/workflows/:id/status의 폴링 엔드포인트는 계속 작동합니다. 다만 이제 env.PUBLISH_WORKFLOW.get(id).status()가 아니라 웹훅이 채운 D1에서 세션 상태를 읽습니다. UI는 바뀌지 않습니다. 관리자 대시보드도 차이를 알 필요가 없습니다.

다른 모든 I/O 단계의 step.do 재시도 래퍼는 유지합니다. 커버 이미지 생성, Vercel 재검증, Cloudflare 캐시 삭제는 outcome 루브릭의 도움을 받지 못하지만, Workflows의 재실행 안전형 단계 캐싱에서는 모두 이점을 얻습니다. 잘 작동하는 부분까지 걷어낼 이유는 없습니다.

유지해야 할 단 하나의 파일과 규모가 커질수록 비용 계산이 뒤집히는 이유

callAi.ts는 유지합니다. 일일 $20 한도와 인스턴스당 $1 한도도 그대로입니다. 직접 호출하든, AI Gateway를 통하든, Managed Agents를 통하든 모든 유료 모델 호출은 이 관문을 거칩니다.

이 지점이 중요한 이유는 과금 구조에 있습니다. Managed Agents에는 표준 요율의 토큰 비용에 더해 세션 시간당 $0.08, 그리고 웹 검색 1000회당 $10이 부과됩니다. 제가 운영하는 규모에서는 퍼블리셔 루틴 6개가 실행될 때마다 각각 글 1개를 처리하고 세션당 약 3분이 걸리므로, 토큰 비용 외 세션 시간 비용은 글 1개당 약 $0.004입니다. 무시할 만한 수준입니다.

분기점은 세션이 길어질 때 찾아옵니다. 4시간짜리 Anthropic Skills 세션은 토큰 비용과 별도로 런타임에만 $0.32가 듭니다. 이런 세션을 하루 50개 실행하면 토큰 비용을 빼고도 세션 시간 요금만 월 $480입니다. 웹 검색 대기열에서 1시간을 기다리는 다단계 리서치 세션이라면 이전에는 없던 $0.08이 발생합니다. 다운스트림 서비스를 기다리며 유휴 상태인 시간도 과금됩니다(Anthropic 문서에는 밀리초 단위로 계산된다고 되어 있지만, 그동안 미터는 계속 돌아갑니다).

이 관문은 Managed Agents 대시보드에 없는 하드 상한을 강제합니다. 대시보드는 세션 비용을 사후에 보여줍니다. 반면 callAi.ts는 사전 추정치가 일일 한도를 넘을 것으로 보이면 세션이 시작되기 전에 워크플로 도중 NonRetryableError를 던집니다.

사전 추정은 보수적으로 계산합니다.

TypeScript
async function estimateSessionCost(brief: Brief): Promise<number> {
  const tokenEstimate = brief.body_md.length / 3.5;
  const inputCost = (tokenEstimate / 1_000_000) * 3.0;
  const outputCost = (tokenEstimate * 1.5 / 1_000_000) * 15.0;
  const sessionHourEstimate = (brief.expected_minutes / 60) * 0.08;
  const safetyMargin = 1.4;
  return (inputCost + outputCost + sessionHourEstimate) * safetyMargin;
}

세션 시간당 비용 계산은 1인 엔지니어 환경에서 가장 빨리 어긋나는 부분입니다. 상한이 없으면 runaway 에이전트 하나만으로도 알아차리기 전에 하루 예산을 소진합니다. 루브릭이 지나치게 엄격할 때 outcome 재시도 루프가 바로 그런 동작을 부추길 수 있습니다. 실제로 겪어본 문제입니다.

관문은 남겨야 합니다. sessions.create()도 이 경로를 통과시키고, 세션 시작 전에 사전 추정치를 기록합니다. 세션이 종료되면 웹훅 페이로드의 event.session.usage.total_cost_usd와 실제 비용을 대조합니다.

아직 미루는 마이그레이션: 멀티 에이전트 오케스트레이션

멀티 에이전트 오케스트레이션은 Anthropic Dev Day의 대표 기능입니다. 리드 에이전트가 작업을 나누고, 각자 모델·프롬프트·툴을 가진 전문 서브에이전트에게 하위 작업을 맡깁니다. 서브에이전트들은 공유 파일시스템에서 병렬로 일하고 리드가 결과를 종합합니다. 이론상으로는 지금 제 Manager DO가 하는 일과 정확히 같습니다. Writer, Discovery, Distribution에 DO RPC로 병렬 전달하고, 각 객체는 자체 SQLite 상태를 가지며, R2 + D1을 공유 “파일시스템”처럼 사용합니다.

제가 보류하는 이유는 세 가지입니다.

첫째, API 변경이 잦습니다. 멀티 에이전트 오케스트레이션은 리서치 프리뷰 단계이며 별도의 접근 요청이 필요합니다. BetaManagedAgentsSearchResultBlock은 0.102에서야 추가됐습니다. 멀티 에이전트 결과의 블록 타입 인터페이스도 계속 바뀌고 있습니다. 지금 옮기면 앞으로 2~3번의 SDK 릴리스가 나올 때마다 통합 코드를 다시 작성해야 합니다. 웹훅 인터페이스는 0.100에서 안정됐지만, 멀티 에이전트 쪽은 여전히 움직이고 있습니다.

둘째, 공유 파일시스템은 세션 전용이며 일시적입니다. Managed Agents 세션 내부의 공유 파일시스템은 세션이 끝나면 사라집니다. R2와 D1은 모든 루틴에서 지속되고, 어떤 Worker에서도 조회할 수 있으며, 세션이 중단돼도 남습니다. 공유 파일시스템이 영속성을 갖추거나 R2를 세션 샌드박스에 직접 마운트할 수 있을 때까지는 제 워크로드에 기능 후퇴입니다.

셋째, Anthropic의 리드/서브에이전트 분리 방식에는 정해진 틀이 있습니다. 리드 에이전트 역할이 고정됩니다. 제 Editorial DO는 퍼블리셔 루틴이 실행되는 날에는 리드지만, 관리자 UI가 브리프를 보내고 Editorial이 파이프라인 중간에 합류하는 날에는 동료 역할입니다. 호스팅 추상화에 맞추려고 유용한 비대칭 구조를 평평하게 만들게 됩니다.

공유 파일시스템이 영속적이고 세션 간에도 이어지거나, R2를 샌드박스에 마운트할 수 있게 되면 판단이 달라집니다. 그때는 마이그레이션이 매력적입니다. 지금은 업그레이드가 아니라 개선 없는 교체에 가깝습니다.

SDK 0.100–0.102 마이그레이션 체크리스트

  1. SDK 버전 고정

    Bash
    uv add anthropic@0.102.0

    아직 uv를 사용하지 않는다면 pip install anthropic==0.102.0을 실행합니다. Bedrock 때문에 0.101에서 멈춰야 하는 특별한 이유가 없다면 0.100과 0.101은 건너뜁니다.

  2. Claude Console에 웹훅 등록

    Claude Console → Settings → Webhooks → New endpoint로 이동합니다. https://your-worker.example.com/api/admin/webhooks/managed-agents를 지정하고, 생성할 때 한 번만 표시되는 whsec_… 시크릿을 복사합니다. Cloudflare Secrets Store에 저장합니다. SDK 0.101을 통해 Claude Platform on AWS를 사용한다면 AWS Secrets Manager에 저장해도 됩니다.

  3. 웹훅 route 추가

    /api/admin/webhooks/managed-agents 라우트를 만듭니다. client.webhooks.unwrap(payload, signature, secret)으로 서명을 검증합니다. 이 헬퍼는 v0.95.x에서 도입됐고 0.100에서 안정화됐습니다. unwrap 호출 하나가 HMAC, 타임스탬프 허용 오차, 이벤트 타입 파싱을 모두 처리합니다. HMAC 검증을 직접 구현하지 마십시오. 타임스탬프 편차 허용 구간이 생각보다 단순하지 않습니다.

  4. evaluator 단계 전환

    sessions.create()의 평가 후 재시도 루프를 outcome={rubric: brief.rubric_md, evaluator: "claude-sonnet-4-5-20250929"}로 바꿉니다. Critic DO와 재시도 오케스트레이션은 제거합니다. 루브릭은 계속 D1에 저장합니다. 루브릭 컬럼의 중요성은 줄어드는 것이 아니라 오히려 커집니다.

  5. D1 기반 조회로 폴링 전환

    상태 엔드포인트가 이제 D1에서 읽도록 바꿉니다. 키는 event.session.metadata.brief_id이며, sessions.create()metadata에 넣은 다른 연결 키가 있다면 그것을 써도 됩니다. 웹훅이 쓰고 상태 엔드포인트가 읽습니다. 더 이상 workflow.status()를 왕복 호출할 필요가 없습니다.

  6. 비용 관문 유지

    callAi.ts는 유지합니다. 세션 비용을 사전에 추정하고, 일일 한도를 넘는다면 NonRetryableError를 던집니다. 웹훅 핸들러에서 event.session.usage의 완료 후 실제 비용을 기록합니다. 매주 사전 추정치와 실제 비용을 대조하고, 차이가 25%를 넘으면 안전 여유분을 조정합니다.

  7. 위험이 가장 낮은 루틴부터 테스트

    제 경우 공개 결과물이 없어 마이그레이션이 잘못돼도 영향이 적은 Discovery부터 시작했습니다. 기존 경로와 병렬로 72시간 실행하고 결과 차이를 확인합니다. 그런 다음에만 Writer를 옮깁니다.

기존 Anthropic Bedrock 구성에서 SDK 0.100을 사용할 수 있나요?

가능합니다. 다만 전용 AWS 클라이언트는 0.101에서 추가됐습니다. Bedrock을 사용한다면 0.100보다 높은 버전으로 올리십시오. SDK 0.101에는 0.100에 없는 ANTHROPIC_BEDROCK_SERVICE_TIER 환경 변수 지원(default/flex/priority)도 추가됐습니다.

웹훅이 streaming response API를 완전히 대체하나요?

아닙니다. 웹훅은 세션 수명주기 이벤트(started, idled, terminated, outcome-evaluation-ended)에 반응합니다. 스트리밍 응답은 계속 messages.create(stream=True)와 일반 델타 프로토콜을 통해 전달됩니다. 웹훅은 “오래 실행되는 세션이 끝나면 알려 달라”는 용도이고, 스트리밍은 “토큰이 생성되는 대로 보여 달라”는 용도입니다.

서명 secret의 실제 형식은 무엇이며 어떻게 검증하나요?

형식은 whsec_…이며 Console에서 생성할 때 한 번만 표시됩니다. client.webhooks.unwrap(raw_body, signature_header, secret)으로 검증하면 HMAC, 타임스탬프 허용 오차, 이벤트 타입 파싱을 한 번에 처리할 수 있습니다. 원본 시크릿을 로그에 남기지 마십시오. 쿼리 매개변수로 전달해서도 안 됩니다. Cloudflare Secrets Store 또는 이에 준하는 서비스를 사용합니다.

Managed Agents 없이 Messages API만으로 outcomes 평가를 실행할 수 있나요?

불가능합니다. outcome={rubric, evaluator}sessions.create()에서만 쓸 수 있는 Managed Agents 전용 매개변수입니다. Messages API로 같은 기능을 직접 만들 수는 있습니다. 지금 제 Critic DO가 하는 방식입니다. 하지만 오케스트레이션 지연을 감수하고 코드를 직접 유지보수해야 합니다. 그 부담을 없애는 것이 Managed Agents의 핵심입니다.

Managed Agents 세션 안에서도 prompt caching이 적용되나요?

적용됩니다. 캐시 적중 시 입력 비용을 최대 90% 줄입니다. 프롬프트 캐시 beta의 캐시 진단 기능은 0.102에서 추가됐으므로, 이제 응답 페이로드에서 캐시 적중률을 확인할 수 있습니다.

Discovery 마이그레이션에는 오후 한 번, Writer에는 한 번 더면 충분합니다. 0.102.0으로 고정하고 웹훅을 등록하십시오. Critic DO는 삭제하고 비용 관문은 유지합니다.

마지막 업데이트

2026년 9월 5일

카테고리Build

Google에서 이 사이트를 우선하기

Google 검색에서 omidsaffari.com을 선호 소스로 추가

omidsaffari.com을 선호 소스로 지정하면 Google이 Top Stories, AI Overviews, AI Mode에서 우선적으로 보여 줍니다.

Build의 다른 글

Build 글 전체 보기
뉴스레터

매주 일요일, 한 통의 편지. 뜨거운 의견이 아닌, 돌아가는 시스템.

AI 벤처 포트폴리오 운영에서 나오는 빌드 로그, 가동 중인 시스템, 현장 노트.

주간 발행. 스팸 없음. 언제든 해지 가능합니다.