feat(skills): add managed-agents knowledge skill
This commit is contained in:
parent
9b2012a3ba
commit
f3a3dcd997
2 changed files with 286 additions and 0 deletions
103
skills/managed-agents/SKILL.md
Normal file
103
skills/managed-agents/SKILL.md
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
---
|
||||
name: managed-agents
|
||||
description: |
|
||||
This skill should be used when the user asks about "managed agents",
|
||||
"Anthropic API agents", "cloud-hosted agents", "agent SDK",
|
||||
"deploying agents to the cloud", "serverless agents",
|
||||
"API-based agent deployment", "/v1/agents endpoint",
|
||||
"remote agent hosting", "agent as a service"
|
||||
version: 0.1.0
|
||||
---
|
||||
|
||||
## What are managed agents
|
||||
|
||||
Managed agents are Anthropic-hosted agent runtimes accessed via the Agent SDK
|
||||
(`@anthropic-ai/sdk` for TypeScript, `anthropic` for Python). Instead of running
|
||||
Claude Code locally, the agent runs on Anthropic's infrastructure with persistent
|
||||
sessions, tool access, and automatic scaling.
|
||||
|
||||
Key difference from local agents: managed agents don't have local filesystem
|
||||
access by default. They work through tools you define in code, not through
|
||||
Claude Code's built-in Read/Write/Bash tools.
|
||||
|
||||
## When to use managed agents vs local deployment
|
||||
|
||||
| Dimension | Managed Agents (API) | Local (Claude Code CLI) |
|
||||
|-----------|---------------------|------------------------|
|
||||
| Infrastructure | Anthropic-hosted | Your machine/server |
|
||||
| Filesystem | Via tools you define | Full local access |
|
||||
| MCP servers | Not available | Full MCP support |
|
||||
| Scaling | Automatic | Manual |
|
||||
| Cost model | Per-token API billing | Subscription or API key |
|
||||
| Best for | SaaS products, API integrations | Personal pipelines, file-heavy work |
|
||||
| Session persistence | Via API sessions | Via `--resume` / `--name` |
|
||||
|
||||
**Decision rule:** If your agents need local filesystem access, MCP servers, or
|
||||
run as part of a personal workflow → use local deployment (cron/launchd/systemd/Docker).
|
||||
If your agents are part of a product, need to scale, or don't need local files →
|
||||
use managed agents.
|
||||
|
||||
**Important limitation:** Managed agents cannot use MCP servers. If your agent
|
||||
system relies on MCP servers for Slack, GitHub, databases, or other integrations,
|
||||
use local deployment with Docker for isolation instead.
|
||||
|
||||
## SDK patterns
|
||||
|
||||
For concrete code patterns, see:
|
||||
`${CLAUDE_PLUGIN_ROOT}/skills/managed-agents/references/api-patterns.md`
|
||||
|
||||
## Session management
|
||||
|
||||
Managed agents support persistent sessions via the API:
|
||||
|
||||
```typescript
|
||||
// Create a new session
|
||||
const session = await client.agents.sessions.create({
|
||||
agent_id: "ag_...",
|
||||
system_prompt: "You are a research agent..."
|
||||
});
|
||||
|
||||
// Resume an existing session
|
||||
const response = await client.agents.sessions.messages.create({
|
||||
agent_id: "ag_...",
|
||||
session_id: session.id,
|
||||
messages: [{ role: "user", content: "Continue the analysis" }]
|
||||
});
|
||||
```
|
||||
|
||||
Sessions maintain conversation history and tool state across multiple
|
||||
interactions, similar to `claude --resume` for local agents.
|
||||
|
||||
## Budget and cost considerations
|
||||
|
||||
Managed agents bill per token at standard API rates. For cost control:
|
||||
|
||||
1. **Set max_tokens** on each request to cap output length
|
||||
2. **Use prompt caching** — cached input tokens cost 90% less
|
||||
3. **Batch non-urgent work** — batch API gives 50% discount
|
||||
4. **Monitor with Admin API** — if you have org access, use
|
||||
`/v1/organizations/usage_report/messages` with an Admin API key
|
||||
(`sk-ant-admin...`) for detailed cost breakdowns
|
||||
5. **Use `--max-budget-usd`** flag for local headless runs as a budget cap
|
||||
|
||||
Note: The Usage & Cost API requires an Admin API key and organization account.
|
||||
Individual accounts should estimate costs from token counts.
|
||||
|
||||
## Migration path: local → managed
|
||||
|
||||
1. Extract your agent's system prompt from `.claude/agents/[name].md`
|
||||
2. Convert tool access to SDK tool definitions
|
||||
3. Replace file-based memory with session persistence or external storage
|
||||
4. Replace MCP server integrations with direct API calls in tool handlers
|
||||
5. Test with the SDK before removing local deployment
|
||||
|
||||
This is a significant architectural change. Only migrate if you need API-based
|
||||
access or auto-scaling. Local deployment is simpler and cheaper for personal use.
|
||||
|
||||
## Getting started
|
||||
|
||||
For a guided setup: run `/agent-factory:build` and choose "Managed Agents"
|
||||
as the deployment target in Phase 6.
|
||||
|
||||
For manual setup: see the API patterns reference at
|
||||
`${CLAUDE_PLUGIN_ROOT}/skills/managed-agents/references/api-patterns.md`
|
||||
183
skills/managed-agents/references/api-patterns.md
Normal file
183
skills/managed-agents/references/api-patterns.md
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
# Managed Agents API Patterns
|
||||
|
||||
Code patterns for creating and managing agents via the Anthropic SDK.
|
||||
All examples use `@anthropic-ai/sdk` (TypeScript) with Python equivalents noted.
|
||||
|
||||
---
|
||||
|
||||
## Basic agent creation
|
||||
|
||||
```typescript
|
||||
import Anthropic from "@anthropic-ai/sdk";
|
||||
|
||||
const client = new Anthropic();
|
||||
|
||||
// Create an agent with tools
|
||||
const response = await client.messages.create({
|
||||
model: "claude-sonnet-4-6",
|
||||
max_tokens: 4096,
|
||||
system: "You are a research agent. Produce structured briefs.",
|
||||
tools: [
|
||||
{
|
||||
name: "web_search",
|
||||
description: "Search the web for information",
|
||||
input_schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
query: { type: "string", description: "Search query" }
|
||||
},
|
||||
required: ["query"]
|
||||
}
|
||||
}
|
||||
],
|
||||
messages: [
|
||||
{ role: "user", content: "Research the latest Claude Code features" }
|
||||
]
|
||||
});
|
||||
```
|
||||
|
||||
## Agent with persistent sessions
|
||||
|
||||
```typescript
|
||||
// Create a session-based agent
|
||||
const session = await client.agents.sessions.create({
|
||||
agent_id: "ag_your_agent_id",
|
||||
system_prompt: `You are a data analyst. You have access to the
|
||||
company database via the query tool. Always verify your findings
|
||||
before reporting.`,
|
||||
tools: [/* your tool definitions */]
|
||||
});
|
||||
|
||||
// First interaction
|
||||
const result1 = await client.agents.sessions.messages.create({
|
||||
agent_id: "ag_your_agent_id",
|
||||
session_id: session.id,
|
||||
messages: [{ role: "user", content: "Analyze Q1 revenue trends" }]
|
||||
});
|
||||
|
||||
// Continue the conversation (session remembers context)
|
||||
const result2 = await client.agents.sessions.messages.create({
|
||||
agent_id: "ag_your_agent_id",
|
||||
session_id: session.id,
|
||||
messages: [{ role: "user", content: "Now compare with Q4 of last year" }]
|
||||
});
|
||||
```
|
||||
|
||||
## Tool handling pattern
|
||||
|
||||
```typescript
|
||||
async function runAgentLoop(
|
||||
client: Anthropic,
|
||||
messages: Anthropic.MessageParam[],
|
||||
tools: Anthropic.Tool[]
|
||||
) {
|
||||
let response = await client.messages.create({
|
||||
model: "claude-sonnet-4-6",
|
||||
max_tokens: 4096,
|
||||
tools,
|
||||
messages
|
||||
});
|
||||
|
||||
while (response.stop_reason === "tool_use") {
|
||||
const toolUseBlocks = response.content.filter(
|
||||
(b): b is Anthropic.ToolUseBlock => b.type === "tool_use"
|
||||
);
|
||||
|
||||
const toolResults: Anthropic.ToolResultBlockParam[] = [];
|
||||
for (const toolUse of toolUseBlocks) {
|
||||
const result = await executeToolCall(toolUse.name, toolUse.input);
|
||||
toolResults.push({
|
||||
type: "tool_result",
|
||||
tool_use_id: toolUse.id,
|
||||
content: JSON.stringify(result)
|
||||
});
|
||||
}
|
||||
|
||||
messages.push({ role: "assistant", content: response.content });
|
||||
messages.push({ role: "user", content: toolResults });
|
||||
|
||||
response = await client.messages.create({
|
||||
model: "claude-sonnet-4-6",
|
||||
max_tokens: 4096,
|
||||
tools,
|
||||
messages
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
```
|
||||
|
||||
## Cost optimization with prompt caching
|
||||
|
||||
```typescript
|
||||
const response = await client.messages.create({
|
||||
model: "claude-sonnet-4-6",
|
||||
max_tokens: 1024,
|
||||
system: [
|
||||
{
|
||||
type: "text",
|
||||
text: longSystemPrompt, // cached — 90% cheaper on reuse
|
||||
cache_control: { type: "ephemeral" }
|
||||
}
|
||||
],
|
||||
messages: [{ role: "user", content: userQuery }]
|
||||
});
|
||||
```
|
||||
|
||||
## Error handling
|
||||
|
||||
```typescript
|
||||
try {
|
||||
const response = await client.messages.create(/* ... */);
|
||||
} catch (error) {
|
||||
if (error instanceof Anthropic.RateLimitError) {
|
||||
// Retry with exponential backoff
|
||||
await sleep(retryDelay);
|
||||
retryDelay *= 2;
|
||||
} else if (error instanceof Anthropic.APIError) {
|
||||
console.error(`API error ${error.status}: ${error.message}`);
|
||||
// Log for debugging, don't retry on 4xx
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Python equivalent
|
||||
|
||||
```python
|
||||
import anthropic
|
||||
|
||||
client = anthropic.Anthropic()
|
||||
|
||||
response = client.messages.create(
|
||||
model="claude-sonnet-4-6",
|
||||
max_tokens=4096,
|
||||
system="You are a research agent.",
|
||||
messages=[{"role": "user", "content": "Research topic X"}]
|
||||
)
|
||||
```
|
||||
|
||||
## Deployment pattern: scheduled managed agent
|
||||
|
||||
```typescript
|
||||
// Run as a scheduled job (e.g., via cron or cloud scheduler)
|
||||
async function dailyReport() {
|
||||
const client = new Anthropic();
|
||||
|
||||
const response = await runAgentLoop(
|
||||
client,
|
||||
[{ role: "user", content: "Generate the daily status report" }],
|
||||
reportTools
|
||||
);
|
||||
|
||||
// Extract and save the report
|
||||
const text = response.content
|
||||
.filter((b): b is Anthropic.TextBlock => b.type === "text")
|
||||
.map((b) => b.text)
|
||||
.join("\n");
|
||||
|
||||
await saveReport(text);
|
||||
}
|
||||
|
||||
dailyReport().catch(console.error);
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue