Claude Blog 5 min

Building effective agent automations

🔗 https://claude.dev/blog/building-effective-agent-automations/

📌 【Anthropic 官方指南】讓排程 AI 代理不再悄悄失靈

TL;DR:Claude Managed Agents 參考實作教你打造會記錄進度、會老實說「這次沒讀到什麼」的排程代理。

排程代理最怕的不是明顯報錯,而是「悄悄」出錯:存取權限過期了沒人發現,使用者的偏好設定沒被遵守,結果往往要等到有人發現漏訊才會察覺。這正是 Anthropic 這篇文章想解決的問題。

🤔 背景:簡單的自動化,難做得「穩」

Anthropic 在文中指出,隨著 AI 加速工作節奏,團隊越來越常靠簡單的 agent automation(依排程在背景蒐集資訊、主動回報重點)來跟上進度。但這類自動化很難做得可靠:代理可能悄悄失去某個資料來源的存取權卻沒人發現,或是沒有遵循使用者的偏好設定。

🧩 六個元件撐起一套參考實作

Anthropic 用 Claude Managed Agents(beta)打造了一個參考實作,定期讀取像 Slack 頻道、GitHub pull request 這類自訂來源,追蹤「從上次執行後有什麼變化」,再把結果寫到指定的目的地(如 Slack)。整套設計拆成六個元件:

  • Sources(來源):列出要讀取地點的清單,預設是 Slack 頻道與 GitHub PR,清單放在使用者的偏好設定檔裡,可擴充到其他來源。
  • Destination(目的地):代理可以寫入的地方,範例是固定發到某個 Slack 頻道,每次執行發一篇帶日期的貼文。
  • Agent(代理本體):agent.md 裡定義的模型、工具與執行步驟,每次執行照步驟跑完就停止。
  • Schedule(排程):用 cron 排程定期觸發,整個流程跑在 Anthropic 的基礎設施上,不需要使用者的機器保持開機。
  • Memory(記憶):使用者的偏好設定,以及代理自己的書籤、帳本、筆記與執行紀錄。
  • Guardrails(防護機制):凡是只讀取的地方一律設為唯讀權限,且每次執行設有花費上限。

在憑證管理上,Managed Agents 把真正的密鑰放在 vault 裡,跑在沙盒之外:呼叫 GitHub 走 MCP server,由沙盒外的 proxy 依網址比對找出對應憑證;呼叫 Slack 則是在沙盒內用 bash 搭配 curl,沙盒裡只會看到像 $SLACK_BOT_TOKEN 這樣的佔位符,請求離開沙盒時才會被平臺換成真正的 token,且只換給允許的網域。

針對「讀取窗口」,文章點出一個常見錯誤:如果代理每次只抓「過去 24 小時」,執行得晚會漏東西,執行得早又會重複回報。參考實作改用「書籤」機制:每個來源各自記錄「讀到的最新一筆項目的時間戳」,存在跨執行保留、且每次執行都會掛載進沙盒的記憶體資料夾 /mnt/memory/ 裡,下一次執行就從書籤接續讀取,窗口會隨上次執行時間自動伸縮。

文章也處理「讀取失敗」與「誤判沒新消息」之間的落差:如果某個 MCP server 當掉或 token 過期,這次執行依然會啟動,只是少了那個來源的工具,而代理看不到任何來自那個來源的內容就可能誤報「沒有新消息」。agent.md 裡訂了三條規則來避免這個問題:來源失敗時書籤原地不動、用其他來源的內容照常發出當次簡報、並在簡報最後加一行寫明「這次讀不到哪個來源」,讓讀者知道有缺漏。

在「確認貼文真的送出」這件事上也有一套防呆設計:代理會先檢查頻道最近的訊息裡是否已經有今天的標題,避免重複發文;貼文只有在 Slack 回傳 “ok”: true 並帶出訊息 ts 時才算真正送出;帳本與書籤也只有在確認送出後才會更新。如果結果不明確,代理會把這次執行標記成「可能已發送」,其他狀態維持不變,避免漏報或重複發送。代理在記憶體裡替每次執行留一筆紀錄,狀態依序標記成「發文中」「已發文(含訊息 ID)」或「可能已發文」。

怎麼用:這個參考實作需要先準備一個 Slack app(可用提供的 manifest 建立)與一個 GitHub token。設定檔包含 agent.md(模型、工具、指令)、deployment.md(排程、時區、預算、輸入訊息)、environment.yaml(網路白名單)、兩個 memory_store yaml 檔(偏好設定與狀態)、vault.yaml(憑證所在的 vault),以及 claude-lock.json(寫入資源 ID 的記錄檔)。流程上先用 ant apply vault.yaml 建立 vault,再用 TypeScript SDK 把像 Slack bot token 這樣的憑證加進 vault,然後把 vault ID 填進 deployment.md 裡。文中也提到可以在 Claude Code 裡執行一行指令,透過 claude-api skill 依本文說明互動式完成設定。

⚠️ 目前仍是 beta

Anthropic 把 Claude Managed Agents 標註為 beta,功能與設定方式仍可能調整。整套設計目前也只示範了 Slack 與 GitHub 兩種來源,接其他系統需要自己擴充。

🎯 實務啟示

如果你也在打造會定期執行、會主動回報的 AI 代理,這篇文章提供三個值得直接套用的工程模式:一是用「每來源書籤」取代「固定時間窗口」,避免漏訊或重複回報;二是貼文前先查重、送出後才更新狀態記錄,確保一次執行只對應一次結果;三是讓失敗的來源「靜音但不裝沒事」,在簡報裡老實寫出哪裡沒讀到,而不是讓讀者誤以為今天真的沒事發生。

🔗 來源

#Anthropic #Claude #AIAgents #Automation #MCP #AgenticAI #DevOps #Slack #GitHub #ManagedAgents

原始資料 Claude Blog · 收集於 2026-10-09
來源原標題
Building effective agent automations
機構
Anthropic
原始標籤
Best practices
原始連結
https://claude.dev/blog/building-effective-agent-automations/

摘要原文

As AI accelerates our work, it's getting harder to keep up. At Anthropic, simple agent automations are frequently used to help. They often run on a schedule, gather context in the background, and proactively tell us what we need to know. But it’s difficult to build effective agent automations: they can lose access to a source without anyone noticing or fail to follow our preferences. Using Claude Managed Agents (beta), we built a reference implementation that reads custom sources (e.g., Slack and GitHub repos) on a schedule, tracks what changed since the last run, and posts what you need to know (e.g., to Slack). In this article, we walk through each step, share a reference implementation, and provide a command to run in Claude Code that configures the agent for you. GET THE CODE The reference implementation is here . For an interactive walkthrough, run the command below in Claude Code. The claude-api skill can help set up the agent following the guidance in this article: PROMPT Copy /claude-api managed-agents-onboard https://claude.dev/blog/building-effective-agent-automations/ For this reference implementation, you need a Slack app ( create it from the manifest ) and a GitHub token . The provided files (shown below) are configuration for Claude API resources, including the agent, its environment, memory stores, vault, and deployment. CODE Text Copy 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, and run records ├── vault.yaml the vault that holds the credentials ├── claude-lock.json resource IDs, written by ant apply └── slack/manifest.yaml one bot app ant apply , a command in the ant CLI, reads these files, creates the resources in your Claude API workspace (where the platform stores and runs them), and records the IDs in claude-lock.json . We'll use this command in the sections below. Once configured, the automation runs on a schedule on Anthropic's infrastructure, so nothing has to stay running on your machine. OVERVIEW The agent we’ll build has six components, covered in this order: Sources - A named list of places to read Destination - One place the agent may write Agent - The model, tools, and run steps in agent.md Schedule - A cron schedule Memory - Your preferences and the agent's own memory Guardrails - Read-only access wherever the agent only reads, and a spending cap per run SOURCES The agent reads two default sources: Slack channels and GitHub pull requests. The channels and repos are listed in your preferences file. The template can be extended to use other sources. Give the agent its own, scoped credentials With Managed Agents , credentials live in vaults . The agent can reference these credentials but the real values stay in the vault, outside the sandbox where Claude's code runs (see here and here ): MCP servers (GitHub). The agent calls MCP tools through a proxy that runs outside the sandbox. The proxy finds the vault credential whose URL matches the server’s. The shell (Slack). The agent calls the Slack API with curl using the bash tool inside the sandbox. The sandbox only holds an opaque placeholder, $SLACK_BOT_TOKEN . As the request leaves the sandbox, the platform swaps in the real token for hosts you allow. Create the vault using the ant CLI and the template file in the repo: CODE Shell Copy ant apply vault.yaml This creates the vault in your Claude API workspace, where the platform stores it, and records its ID in claude-lock.json . Then add each credential to the vault with the TypeScript SDK . Here is an example showing addition of the Slack credential: CODE TypeScript Copy 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 }, }, }); After creating the vault and adding each credential, attach the vault to the deployment. Copy the vault ID from claude-lock.json into vault_ids in the deployment file, deployment.md . Read from where you left off A common mistake is asking the agent to read a fixed window like " the last 24 hours ." A late run leaves a gap and an early run repeats items. Instead, give the agent a bookmark per source. At the end of each run, the agent writes the timestamp of the newest item it read from each source to one file, bookmarks.json , with an entry per source: "slack": "2026-09-14T13:02:11Z" . The next run starts from those bookmarks, so its window stretches or shrinks to cover everything since the last run. The bookmarks live in the memory store called state : a folder of text files that the platform mounts into every run's sandbox under /mnt/memory/ and keeps between runs. The agent reads and writes it with its ordinary file tools, and the instructions in agent.md tell it how. Don't mistake a failed read for a quiet day If an MCP server is down or its token has expired, the run still starts, just without that server's tools. The session logs an error, but the agent sees nothing from that source and reports "nothing new." Three rules in agent.md help fix this. When a source fails, the agent will: keep the source’s bookmark where it is, write the brief from the other sources, and end the brief with one line naming what it couldn't read ("pull requests unavailable this run"), so the reader is made aware. DESTINATION Our template posts to one Slack channel, with a dated post each time it runs. The agent posts to Slack using the bash tool in its sandbox, using the same bot token it reads with. Nothing has to approve the post. The agent sends it with a bash command, and the built-in bash tool runs without asking for approval by default. slack.com is also on the allowlist of the agent's environment , the sandbox it runs in. The post is one request: CODE Shell Copy 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 ..."}' Confirm the post landed before recording it Once a post is confirmed, the agent updates its ledger of reported items and its bookmarks. If those records don't match what was actually posted, two things can go wrong. If the agent records a post that never landed, the bookmarks move on and those items are never reported. If it posts again because it isn't sure the first post landed, readers get the same brief twice. Three rules in agent.md prevent this. First, the agent looks for today's title in the channel's recent messages and doesn't post if the edition is already there. Second, the post counts as sent only if Slack returns "ok": true and a message ts. Third, the agent updates the ledger and bookmarks only after that confirmation. If the result is unclear, it marks the run "maybe posted" and changes nothing else, so nothing is lost. The agent keeps a run record in its memory store ( runs/<date>.md ). It marks the run "posting" before the post, then "posted" with the message ID, or "maybe posted." AGENT In Claude Managed Agents, an agent is a versioned configuration: a model, a system prompt, and tools. Each run follows its run steps and stops. In our reference implementation, the agent configuration is agent.md : CODE Markdown Copy --- name: Daily brief model: claude-sonnet-5-5 mcp_servers: - type: url name: github url: https://api.githubcopilot.

由 claude-code/sonnet 自動生成