매일 아침 Slack 채널과 GitHub PR을 훑어 오늘 챙길 일만 알려 주는 에이전트는 만들기 쉬워 보입니다. 그런데 막상 돌려 보면 토큰이 만료돼 한 소스를 못 읽었는데도 “새 소식 없음"이라고 보내거나, 같은 요약을 두 번 올리거나, 이미 해결된 일을 아직 남았다고 알립니다. 사람이 지켜보지 않는 자동화라 이런 실패가 조용히 쌓입니다. Anthropic이 공개한 예제를 따라가며 이런 실패를 막는 장치를 정리합니다.

한눈에 보기

  • Claude Managed Agents(베타)로 Slack과 GitHub를 일정에 맞춰 읽고, 지난 실행 이후 바뀐 것만 Slack에 올리는 참고 구현을 공개했습니다.
  • 구성은 소스, 게시 위치, 에이전트, 일정, 메모리, 가드레일로 나뉩니다.
  • 원문이 마지막에 정리한 규칙은 여섯 가지입니다. 고정 기간 대신 소스별 북마크로 읽기, 못 읽은 소스를 조용한 날로 보고하지 않기, 게시 직전 모든 항목 재확인, Slack이 확인한 뒤에만 북마크와 원장 갱신, 에이전트가 고칠 수 없는 저장소에서 선호를 매번 다시 읽기, 읽기만 하는 곳은 읽기 전용 권한과 실행당 비용 상한입니다.

원문은 어떤 글인가

Lance Martin과 CJ Avilla가 2026년 10월 8일에 쓴 글이고 읽는 데 9분쯤 걸립니다. 참고 구현 저장소의 설정 파일을 하나씩 설명하면서 단계마다 자주 생기는 실패를 짚습니다. 정기 보고나 모니터링을 에이전트로 자동화하려는 개발자라면 설정 예시를 그대로 가져다 쓸 수 있습니다. 원문: Building effective agent automations

전체 구조와 설정 파일

참고 구현은 설정 파일 묶음입니다. agent.md, deployment.md, environment.yaml, 메모리 저장소 두 개, 자격 증명을 담는 vault.yaml 이 들어 있습니다. ant CLI의 ant apply 가 이 파일을 읽어 Claude API 워크스페이스에 리소스를 만들고, 만든 리소스 ID를 claude-lock.json 에 적습니다. 그 뒤로는 Anthropic 인프라에서 일정대로 돌기 때문에 내 컴퓨터를 켜 둘 필요가 없습니다. Claude Code에서 /claude-api managed-agents-onboard 에 원문 URL을 붙여 실행하면 이 설정 과정을 대화로 안내받을 수 있습니다.

아래 그림은 구성 요소가 어떻게 이어지는지 보여 줍니다.

에이전트 자동화 구성도: Schedule이 Agent를 깨우고 Sources를 읽어 Already posted 확인 후 Destination에 게시하며 아래 Memory에서 State는 읽고 쓰고 Preferences는 읽기만 하는 구조

그림 1. Schedule(일정)이 Agent를 깨우고, Agent는 Sources(소스)를 읽어 Already posted?(이미 올렸나) 확인을 거쳐 Destination(게시 위치)에 올립니다. 아래 Memory에서 State는 에이전트가 쓰는 기록, Preferences는 독자(Reader)가 쓰고 에이전트는 읽기만 하는 선호입니다. 점선 Guardrails는 턴·시간·비용 상한과 누군가 지켜보는 heartbeat 같은 안전장치입니다. 출처: 원문 .

소스: 북마크로 읽고, 실패를 숨기지 않는다

자격 증명은 vault라는 보관소에 두고, 에이전트는 진짜 토큰 값을 보지 못합니다. GitHub 쪽은 샌드박스 밖 프록시가 MCP 호출에 토큰을 붙입니다. Slack은 샌드박스 안에서 curl로 부르는데 샌드박스에는 $SLACK_BOT_TOKEN 이라는 자리표시자만 있습니다. 요청이 허용된 호스트로 나가는 순간 플랫폼이 진짜 토큰으로 바꿔 넣습니다.

“지난 24시간"처럼 기간을 못 박아 읽게 하면 문제가 생깁니다. 실행이 늦게 뜬 날은 그 사이 항목을 놓치고, 일찍 뜬 날은 어제 본 항목을 또 올립니다. 예제는 대신 소스별 북마크를 씁니다. 실행이 끝날 때 소스마다 읽은 가장 최신 항목의 타임스탬프를 bookmarks.json 에 적고, 다음 실행은 거기서부터 읽습니다. 이 파일은 실행마다 /mnt/memory/ 에 연결되는 state 메모리 저장소에 있습니다.

MCP 서버가 죽었거나 토큰이 만료된 경우는 더 조용히 틀어집니다. 실행 자체는 시작되고 세션 로그에 에러도 남지만 그 소스의 도구가 빠진 채라 에이전트 눈에는 아무 일도 없던 날로 보입니다. 그러면 “새 소식 없음"이 올라갑니다. 원문은 agent.md 에 규칙 세 개를 넣어 이를 막습니다.

flowchart TD
  A["소스 읽기"] --> B{"읽기 성공"}
  B -->|"예"| C["새 항목 반영<br/>북마크 전진"]
  B -->|"아니오"| D["북마크 그대로 둠"]
  D --> E["다른 소스로<br/>브리프 작성"]
  E --> F["끝에 못 읽은 소스<br/>한 줄 명시"]

북마크를 그대로 두니 다음 실행이 놓친 구간을 다시 읽습니다. 마지막 한 줄은 독자에게 오늘이 조용한 날이었는지, 못 읽은 날이었는지 알려 줍니다.

게시: Slack이 확인해 준 다음에만 기록한다

에이전트는 bash 도구로 Slack API에 curl 요청 한 번을 보내 게시하고 중간에 승인 절차는 없습니다. 그래서 장부와 실제 채널이 어긋나기 쉽습니다. 실패한 게시를 성공으로 적으면 북마크가 앞으로 가 버려 그 항목은 다시는 보고되지 않습니다. 반대로 성공했는지 몰라 한 번 더 올리면 독자는 같은 브리프를 두 번 받습니다.

예제는 이 순서를 고정합니다. 채널 최근 메시지에 오늘 제목이 이미 있으면 올리지 않고, Slack 응답에 "ok": true 와 메시지 ts가 함께 와야 보낸 것으로 칩니다. 원장과 북마크는 이 확인이 끝난 다음에 고칩니다. 실행 기록 runs/<date>.md 의 상태와 그 뒤 처리는 이렇게 이어집니다.

stateDiagram-v2
    state "posting" as posting
    state "posted" as posted
    state "maybe posted" as maybe
    [*] --> posting
    posting --> posted : ok와 ts 확인
    posting --> maybe : 결과 불확실
    posted --> [*] : 원장·북마크 갱신
    maybe --> [*] : 다른 기록은 그대로

결과가 불확실하면 maybe posted로만 표시하고 아무것도 바꾸지 않으니, 최악의 경우에도 항목을 잃지 않습니다.

에이전트, 일정, 메모리

Managed Agents에서 에이전트는 모델과 시스템 프롬프트, 도구를 묶은 설정이고 버전으로 관리됩니다. 예제는 claude-sonnet-5-5 를 쓰고 웹 검색과 웹 페치를 껐습니다. MCP 도구는 원래 호출마다 승인을 받는데 무인 실행에서는 눌러 줄 사람이 없습니다. 그래서 GitHub 도구는 always_allow 로 열어 두고, 그 대신 GitHub 토큰 자체를 읽기 전용으로 만들었습니다.

실행 단계는 여덟 개이고 원문은 그중 두 단계를 발췌해 보여 줍니다. 하나는 고르기입니다. 독자가 오늘 움직이거나 곧 내릴 결정이 달라지는 항목만 남기고, 애매하면 뺍니다. “열린 리뷰 12건” 같은 숫자는 항목으로 치지 않습니다. 다른 하나는 게시 직전 재확인입니다. 에이전트가 읽는 동안에도 PR은 병합되고 스레드는 정리됩니다. 그래서 올릴 항목마다 원본을 다시 열어, 해결됐으면 빼고 아직 열려 있지만 바뀌었으면 그 줄을 고칩니다. 확인이 안 되는 항목은 빼고 실행 기록에 따로 적습니다. 링크는 손으로 조립하지 않고 원본의 링크 필드에서 복사합니다.

일정은 배포(deployment)가 맡습니다. 예제는 cron 32 7 * * 1-5 와 America/New_York 시간대로 평일 아침에 돕니다. 서버 시간대로 날짜를 계산하면 오늘 아침을 “어제"라고 부르는 버그가 생기므로, 첫 메시지에 독자의 시간대를 따로 알려 줍니다.

메모리 저장소는 두 개입니다. preferences는 독자가 쓰고 에이전트는 읽기만 합니다. 읽을 채널과 저장소, 뺄 것, 길이 상한이 여기 들어가고, 에이전트는 실행마다 이 파일을 새로 읽습니다. 못 읽으면 기본값으로 돌지 말고 멈춰서 알려야 합니다. ant apply deployment.md 는 저장소만 만들고 파일은 만들지 않으니, 첫 실행 전에 scripts/seed-preferences.sh 로 preferences.md를 넣어 둡니다. state는 에이전트가 읽고 씁니다. 북마크와 실행 기록, 이미 보고한 항목의 원장 ledger.md 에 더해 선호 변경 제안과 소스별 동작 메모도 여기에 남깁니다. 원장에는 항목마다 보고한 날과 출처, 그리고 Slack 메시지 타임스탬프나 PR 번호처럼 바뀌지 않는 ID와 마지막 상태를 적습니다.

가드레일: 권한과 예산

이 에이전트는 남이 쓴 메시지와 이슈를 읽고, 그 안의 문장이 지시처럼 읽힐 수 있습니다. 그래서 따랐을 때 할 수 있는 일을 줄여 둡니다. GitHub 토큰과 preferences 저장소는 읽기 전용이고 환경은 허용 목록에 있는 호스트에만 연결됩니다. 심어진 지시로 브리프 내용이 바뀔 수는 있고, 실행 사이에 남기는 state 메모를 거쳐 영향이 이어질 수도 있습니다. 그래도 GitHub에 쓰거나 선호 규칙을 고치는 데까지는 가지 못합니다. Slack은 같은 토큰으로 게시까지 하므로 봇을 꼭 필요한 채널에만 초대합니다.

비용 상한은 평소 실행 비용의 3-5배로 잡고, 실제 수치가 쌓이면 줄여 나갑니다. 예제의 "500" 은 센트 단위라 $5.00입니다. 상한에 닿은 실행은 에러 없이 budget_reached 로 멈춥니다. 상한을 너무 낮게 잡으면 브리프가 그냥 한산한 날처럼 보이니 주의해야 합니다.

인사이트

여기서부터는 원문이 아니라 이 블로그의 해석입니다.

  1. 북마크, 게시 확인 후 기록, maybe posted는 데이터 엔지니어에게 익숙한 증분 적재의 워터마크와 커밋 순서 그대로입니다. 에이전트 자동화도 ETL 작업처럼 “어디까지 처리했나"를 바깥에 남기고, 쓰기가 확정된 뒤에만 그 표시를 옮겨야 다시 돌려도 안전합니다.

  2. “애매하면 빼라”, “확인 못 하면 빼라"는 규칙은 보고 에이전트의 신뢰를 지키는 쪽으로 기울어 있습니다. 사내 데이터 이상 탐지 알림을 만들 때도 놓친 항목 몇 개보다 틀린 알림 하나가 채널을 음소거하게 만든다는 점을 기준으로 삼을 만합니다.

  3. 선호 파일은 에이전트가 고치지 못하고 변경을 제안만 하게 한 설계가 눈에 띕니다. 규칙과 상태를 다른 저장소로 나누고 쓰기 권한을 떼어 두면, 프롬프트 주입이 있어도 규칙 자체는 오염되지 않습니다. 다만 원문이 밝히듯 state 메모는 에이전트가 쓰는 곳이라, 주입된 내용이 다음 실행으로 넘어갈 여지는 남습니다. 운영한다면 state 메모를 가끔 사람이 열어 보는 편이 좋겠습니다.

바로 해볼 것

  • 지금 돌리는 정기 리포트나 알림 자동화가 “최근 N시간"을 읽는지 확인합니다. 그렇다면 마지막 처리 시각을 저장해 그 이후부터 읽도록 바꿀 수 있는지 봅니다.
  • 소스 하나를 일부러 끊어 보고, 자동화가 “변경 없음"이라고 보내는지 못 읽었다고 알리는지 확인합니다.
  • claude update 후 /claude-api managed-agents-onboard 에 원문 URL을 붙여 실행하고 제안된 설정 파일을 내 소스와 채널에 맞게 고쳐 봅니다.

원문: Building effective agent automations