출처: https://claude.dev/blog/building-effective-agent-automations/ (Lance Martin, CJ Avilla · 2026년 10월 8일)
AI 덕분에 일은 빨라졌지만, 쏟아지는 정보를 따라가기는 오히려 더 어려워졌어요. Anthropic 내부에서는 이 문제를 간단한 에이전트 자동화로 풀고 있다고 해요. 일정에 맞춰 실행되고, 백그라운드에서 맥락을 모은 뒤, 알아야 할 것을 먼저 알려 주는 방식이에요.
다만 이런 자동화를 제대로 만들기는 쉽지 않아요. 아무도 모르는 사이에 소스 접근이 끊기거나, 사용자가 정한 선호를 따르지 않는 일이 흔하거든요. 원문 저자들은 Claude Managed Agents(베타)로 참조 구현을 만들었어요. Slack 채널과 GitHub 저장소 같은 소스를 일정에 맞춰 읽고, 지난 실행 이후 바뀐 것을 추적해, 알아야 할 내용을 Slack에 게시하는 에이전트예요. 이 글에서는 그 구현을 단계별로 따라가며 각 단계의 함정을 살펴봐요.
이 글의 다이어그램은 모두 원문 claude.dev Blog에서 가져왔어요.
코드 받기
참조 구현은 anthropics/claude-quickstarts 저장소에 있어요. Claude Code에서 아래 명령을 실행하면 claude-api 스킬이 이 글의 가이드를 따라 대화형으로 에이전트 설정을 도와줘요.
/claude-api managed-agents-onboard https://claude.dev/blog/building-effective-agent-automations/참조 구현을 돌리려면 두 가지가 필요해요.
- Slack 앱 (manifest로 생성)
- GitHub 토큰
저장소에 담긴 파일은 에이전트, 실행 환경, 메모리 스토어, 볼트, 배포 같은 Claude API 리소스의 설정이에요.
daily-brief/
├── agent.md model, tools, instructions
├── deployment.md schedule, time zone, budget, input message
├── environment.yaml network allowlist
├── memory_store_preferences.yaml user preferences
├── memory_store_state.yaml the agent's bookmarks, ledger, notes, run records
├── vault.yaml the vault that holds the credentials
├── claude-lock.json resource IDs, written by ant apply
└── slack/manifest.yaml one bot appant CLI의 ant apply 명령이 이 파일들을 읽어 Claude API 워크스페이스에 리소스를 만들고, 생성된 ID를 claude-lock.json에 기록해요. 한 번 설정하면 자동화는 Anthropic 인프라에서 일정대로 돌기 때문에 내 컴퓨터를 켜 둘 필요가 없어요.
전체 구조: 여섯 가지 구성 요소
에이전트는 여섯 부분으로 이루어져 있고, 아래 순서대로 살펴봐요.
- Sources: 읽을 곳의 이름 목록
- Destination: 에이전트가 쓸 수 있는 단 한 곳
- Agent:
agent.md에 담긴 모델, 도구, 실행 단계 - Schedule: cron 일정
- Memory: 사용자 선호와 에이전트 자신의 기억
- Guardrails: 읽기만 하는 곳은 읽기 전용 권한, 실행당 비용 상한

출처: claude.dev Blog
Sources: 어디서 읽을까
기본 소스는 Slack 채널과 GitHub 풀 리퀘스트 두 가지예요. 읽을 채널과 저장소는 preferences 파일에 적고, 템플릿을 확장하면 다른 소스도 붙일 수 있어요.

출처: claude.dev Blog
에이전트 전용 자격 증명을 범위를 좁혀 주기
Managed Agents에서 자격 증명은 볼트(vault)에 보관해요. 에이전트는 자격 증명을 참조만 하고, 실제 값은 Claude의 코드가 실행되는 샌드박스 바깥의 볼트에 남아요 (참고 1, 참고 2).
- MCP 서버 (GitHub): 샌드박스 밖 프록시를 거쳐 MCP 도구 호출, 프록시가 서버 URL과 일치하는 볼트 자격 증명을 선택
- 셸 (Slack): 샌드박스 안 bash 도구에서 curl로 Slack API 호출, 샌드박스에는 불투명한 자리표시자
$SLACK_BOT_TOKEN만 존재, 요청이 샌드박스를 떠날 때 허용한 호스트에 한해 플랫폼이 실제 토큰으로 교체
볼트는 저장소의 템플릿 파일과 ant CLI로 만들어요.
ant apply vault.yaml이 명령은 워크스페이스에 볼트를 만들고 ID를 claude-lock.json에 기록해요. 이어서 TypeScript SDK로 자격 증명을 하나씩 추가해요. 아래는 Slack 자격 증명을 추가하는 예시예요.
const vaultId = process.env.VAULT_ID!; // the vault's ID, from claude-lock.json
await client.beta.vaults.credentials.create(vaultId, {
display_name: "SLACK_BOT_TOKEN",
auth: {
type: "environment_variable",
secret_name: "SLACK_BOT_TOKEN",
secret_value: process.env.SLACK_BOT_TOKEN!,
networking: { type: "limited", allowed_hosts: ["slack.com"] },
injection_location: { header: true },
},
});자격 증명을 다 넣었다면 claude-lock.json의 볼트 ID를 배포 파일 deployment.md의 vault_ids에 옮겨 적어 배포에 연결해요.
고정 시간 창 대신 북마크에서 이어 읽기
흔한 실수는 에이전트에게 "최근 24시간"처럼 고정된 시간 창을 읽게 하는 거예요. 실행이 늦으면 빈틈이 생기고, 일찍 돌면 같은 항목을 또 보고하게 돼요.
대신 소스마다 북마크를 둬요. 실행이 끝날 때 에이전트는 소스별로 마지막으로 읽은 가장 최신 항목의 시각을 bookmarks.json 한 파일에 기록해요 (예: "slack": "2026-09-14T13:02:11Z"). 다음 실행은 이 북마크에서 시작하므로, 읽는 범위가 지난 실행 이후 전체에 맞춰 자연스럽게 늘거나 줄어요.
북마크는 state라는 메모리 스토어에 저장돼요. 플랫폼이 매 실행의 샌드박스에 /mnt/memory/로 마운트하고 실행 사이에도 유지하는 텍스트 파일 폴더예요. 에이전트는 평범한 파일 도구로 읽고 쓰며, 방법은 agent.md의 지시문에 적혀 있어요.
읽기 실패를 "조용한 하루"로 착각하지 않기
MCP 서버가 내려갔거나 토큰이 만료돼도 실행 자체는 시작돼요. 해당 서버의 도구만 빠진 채로요. 세션 로그에는 오류가 남지만, 에이전트 입장에서는 그 소스에서 아무것도 보이지 않으니 "새 소식 없음"이라고 보고해 버려요.
agent.md의 세 가지 규칙이 이를 막아요. 소스 하나가 실패하면 에이전트는 다음처럼 움직여요.
- 그 소스의 북마크는 그대로 둠
- 나머지 소스로 브리프 작성
- 브리프 끝에 읽지 못한 소스를 한 줄로 명시 ("pull requests unavailable this run")
Destination: 어디에 쓸까
템플릿은 Slack 채널 한 곳에, 실행할 때마다 날짜가 붙은 글을 하나씩 게시해요.

출처: claude.dev Blog
에이전트는 읽을 때 쓴 것과 같은 봇 토큰으로, 샌드박스 안의 bash 도구를 써서 Slack에 게시해요. 게시를 승인하는 단계는 없어요. 기본 내장 bash 도구는 승인 없이 실행되고, slack.com은 에이전트가 도는 샌드박스인 environment의 허용 목록에 들어 있거든요. 게시는 요청 한 번이에요.
curl -s https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
-H "Content-Type: application/json; charset=utf-8" \
-d '{"channel": "C0123456789", "text": "Daily brief, Tue Sep 15 ..."}'기록하기 전에 게시가 실제로 됐는지 확인하기
게시가 확인되면 에이전트는 보고한 항목의 원장(ledger)과 북마크를 갱신해요. 이 기록이 실제 게시 내용과 어긋나면 두 가지 문제가 생겨요.
- 게시되지 않은 글을 기록한 경우: 북마크만 앞으로 가서 해당 항목이 영영 보고되지 않음
- 첫 게시 성공 여부를 몰라 다시 게시한 경우: 독자가 같은 브리프를 두 번 받음
agent.md의 세 가지 규칙이 이를 막아요. 먼저 채널의 최근 메시지에서 오늘 제목을 찾아, 이미 있으면 게시하지 않아요. 다음으로 Slack이 "ok": true와 메시지 ts를 돌려줄 때만 게시된 것으로 쳐요. 마지막으로 그 확인이 끝난 뒤에만 원장과 북마크를 갱신해요. 결과가 불분명하면 실행을 "maybe posted"로 표시하고 다른 것은 건드리지 않으니, 잃어버리는 항목이 없어요.
에이전트는 메모리 스토어에 실행 기록(runs/<date>.md)도 남겨요. 게시 전에는 "posting", 성공하면 메시지 ID와 함께 "posted", 불확실하면 "maybe posted"로 표시해요.
Agent: 모델과 실행 규칙
Claude Managed Agents에서 agent는 모델, 시스템 프롬프트, 도구로 이루어진 버전 관리되는 설정이에요. 실행마다 정해진 단계를 따르고 끝나면 멈춰요.

출처: claude.dev Blog
참조 구현의 에이전트 설정은 agent.md예요.
---
name: Daily brief
model: claude-sonnet-5-5
mcp_servers:
- type: url
name: github
url: https://api.githubcopilot.com/mcp/
tools:
- type: agent_toolset_20260401
configs:
- name: web_search
enabled: false
- name: web_fetch
enabled: false
- type: mcp_toolset
mcp_server_name: github
default_config:
permission_policy:
type: always_allow
---
[Eight numbered run steps; the full text is in agent.md in the repo.]frontmatter에는 에이전트 이름, 모델, 도구, MCP 서버가, 본문에는 지시문이 들어가요. MCP 도구는 기본적으로 승인을 요구하는데 백그라운드 실행에는 승인해 줄 사람이 없어요. 그래서 GitHub 도구 모음은 always_allow로 두고, 대신 GitHub 토큰을 읽기 전용으로 발급해요.
브리프는 짧게
agent.md의 4단계는 Claude가 간결하게 쓰도록 이끌어요. 핵심은 이래요.
- 독자가 오늘 행동하거나, 곧 내릴 결정이 바뀌는 항목만 한 줄 차지
- 애매하면 제외, 대부분의 날은 몇 개, 아예 없는 날도 있음
- "12 open reviews" 같은 개수는 항목이 아님, 막혀 있는 것만 링크
- 원장에 있고 아직 열린 항목은 "still waiting, day 3"처럼 표시한 한 줄로만 이어 감, 닫힌 항목은 언급 없이 제외
- preferences 파일에서 은퇴시킨 주제는 다시 꺼내지 않음
4. Decide. An item earns a line when the reader would act on it today, or it changes a decision they are about to make. When unsure, leave it out.
게시 직전에 열린 항목을 다시 확인하기
소스를 읽은 시점과 게시하는 시점 사이에도 상황은 바뀌어요. 그래서 agent.md의 5단계는 게시 직전에 보고할 모든 항목의 실시간 상태를 다시 확인하게 해요.
- 그사이 해결됨: 제외
- 아직 열려 있지만 바뀜: 해당 줄 수정
- 확인 불가: 제외하고 실행 기록의 cuts에 기록
- 링크: 손으로 조합하지 않고 소스의 링크 필드(PR의 html_url, Slack permalink)에서 복사
원문은 이 원칙을 이렇게 표현해요.
One stale "still waiting on you" costs more trust than ten missing items, so never hedge an item's status: assert it or drop it.
낡은 "아직 답을 기다리고 있어요" 하나가 빠진 항목 열 개보다 신뢰를 더 깎는다는 뜻이에요. 상태를 얼버무리지 말고, 확신하거나 빼라는 거죠.
Schedule: 언제 실행할까
Claude Managed Agents에서 에이전트는 설정 파일일 뿐이고, 실제 실행은 deployment가 맡아요. 배포에는 에이전트, 환경, 매 실행의 첫 메시지가 들어가고, 일정·볼트·메모리 스토어·예산도 함께 담겨요. 일정이 될 때마다 플랫폼은 새 에이전트 세션을 시작해요.

출처: claude.dev Blog
템플릿의 배포 설정은 deployment.md이고, 본문이 첫 메시지가 돼요.
---
name: Daily brief
agent: ./agent.md
environment_id: ./environment.yaml
schedule:
type: cron
expression: "32 7 * * 1-5"
timezone: America/New_York
vault_ids: [vlt_...] # the vault you create under Sources
resources:
- path: ./memory_store_preferences.yaml
access: read_only
instructions: The reader's preferences. Re-read them every run. Never write here.
- path: ./memory_store_state.yaml
access: read_write
instructions: Your state. Bookmarks, ledger, notes, proposals, and run records.
---
Write today's brief.
The reader's time zone is America/New_York. Work out every date in that zone.
Follow your run steps in order.
Today's edition is titled "Daily brief, <weekday> <month> <day>".아래 명령은 파일에 경로로 적힌 에이전트, 환경, 메모리 스토어와 함께 배포를 만들어요.
ant apply deployment.md일정을 기다리지 않고 시험해 보려면 claude-lock.json의 ID로 ant beta:deployments run --deployment-id <id>를 실행해 수동으로 돌리면 돼요.
날짜는 사용자 시간대로 계산하기
에이전트가 서버 시간대로 날짜를 계산하는 바람에 오늘 아침을 "어제"라고 부르는 버그가 흔해요. deployment.md에서 timezone 필드는 실행 시각을 정하고, 본문 두 번째 줄은 날짜를 어느 시간대로 계산할지 에이전트에게 알려 줘요.
Memory: 무엇을 기억할까
실행은 매번 이전 기억이 없는 새 샌드박스에서 시작돼요. 기억이 없으면 피드백이 남지 않고, 반대로 낡은 기억은 에이전트를 헷갈리게 해요. 이미 해결된 항목을 여전히 대기 중이라고 보고하거나, 아직 열린 항목을 "이미 보고했다"며 빼 버리는 식이에요.

출처: claude.dev Blog
템플릿은 /mnt/memory/ 아래에 마운트되는 메모리 스토어 두 개를 둬요.
| 스토어 | 소유·권한 | 담는 내용 |
|---|---|---|
preferences | 사용자 소유, 에이전트는 읽기 전용 | 읽을 채널·저장소, 제외할 것, 길이 상한, 목적지, 중단 시점 |
state | 에이전트 소유, 읽기·쓰기 | 북마크, 보고 원장, 실행별 기록, preferences 변경 제안, 소스별 동작 메모 ("returns only the newest 50 items") |
ant apply deployment.md는 preferences 스토어만 만들고 그 안의 파일은 만들지 않아요. 첫 실행 전에 저장소의 scripts/seed-preferences.sh로 preferences.md를 넣어 둬야 해요.
매 실행 시작 때 선호를 새로 읽기
선호 사항을 프롬프트에 복사해 넣어 두면, 이미 바꾼 규칙을 계속 적용하는 문제가 생겨요. 에이전트가 매번 파일을 새로 읽게 하고, 파일을 읽지 못하면 기본값으로 돌지 말고 멈춰서 알리게 해요.
보고한 항목은 원장에 남기고, 변화를 보고하기
에이전트는 보고한 모든 항목을 원장 ledger.md에 기록해 브리프가 같은 말을 반복하지 않게 해요. 각 줄에는 보고 날짜, 출처, 바뀌지 않는 ID(Slack 메시지 타임스탬프나 PR 번호), 마지막으로 알려진 상태가 들어가요.
2026-09-09 slack:C0123456789 1788963600.000100 refund thread: customer waiting on a decision
2026-09-11 github 481 review blocked, day 2 (still waiting)
2026-09-11 slack:C0234567891 1789117333.000300 enterprise escalation: owner named, in progressGuardrails: 어디까지 허용할까
이 자동화는 일정에 따라 백그라운드에서 돌기 때문에, 에이전트가 할 수 있는 일과 쓸 수 있는 비용에 한도를 둬요.

출처: claude.dev Blog
할 수 있는 일 제한하기
에이전트는 다른 사람이 쓴 메시지와 이슈를 읽고, 그 텍스트가 지시로 해석될 수 있어요. 그러니 에이전트가 그 지시를 따르더라도 할 수 있는 일이 적게 만들어야 해요. 예제에서는 GitHub 토큰과 preferences 스토어가 읽기 전용이고, 환경은 허용 목록의 호스트에만 접근해요.
심어진 지시가 브리프 내용을 바꿀 수는 있어요. 에이전트가 실행 사이에 남기는 메모를 통해서도요. 하지만 GitHub에 쓰거나 사용자 규칙을 고칠 수는 없어요. 예외는 Slack이에요. 같은 토큰으로 게시까지 하므로, 봇은 읽거나 게시해야 하는 채널에만 초대해요.
비용 상한은 실제 실행 데이터로 정하기
비용 상한은 폭주하는 비용을 막아 줘요. 처음에는 평소 실행 비용의 3~5배로 시작하고, 실제 수치를 보면서 줄여 가요. 상한에 닿은 실행은 실패하지 않고 일시 정지하기 때문에, 상한이 너무 낮으면 브리프가 그냥 조용해진 것처럼 보여요.
상한은 deployment.md의 budget이에요. 실행마다 전액이 주어지고, 한도에 닿은 실행은 budget_reached 중단 사유와 함께 멈춰요.
budget:
type: limit
max_list_cost:
amount: "500" # a string, in cents: "500" is $5.00
currency: USD마무리: 여섯 가지 규칙
참조 구현은 결국 여섯 가지 규칙으로 요약돼요.
- 고정 시간 창이 아니라 북마크에서 각 소스 읽기
- 읽기 실패는 조용한 하루가 아니라 "읽을 수 없음"으로 보고
- 게시 직전에 모든 항목 재확인
- Slack이 확인해 줄 때만 게시 완료로 간주, 그 뒤에 북마크와 원장 갱신
- 에이전트가 수정할 수 없는 스토어에서 매 실행마다 선호 다시 읽기
- 읽기만 하는 곳은 읽기 전용 권한, 실행당 비용 상한 설정
Claude Code로 이 가이드를 직접 따라가 볼 수도 있어요. 먼저 Claude Code를 업데이트하고, claude-api 스킬을 실행해요.
claude update/claude-api managed-agents-onboard https://claude.dev/blog/building-effective-agent-automations/스킬이 이 글을 읽고 설정을 제안한 뒤, 프로젝트의 agents/ 폴더에 파일을 쓰고 ant apply로 리소스를 만들어 줘요. 어디까지나 출발점이니, 내 소스·목적지·메모리 선호에 맞게 고쳐 쓰면 돼요.
원문: Lance Martin, CJ Avilla, Building effective agent automations, claude.dev Blog (2026년 10월 8일)
