Tools
agent designer.
The advanced mode of the agent SDK wizard: the same steps with every setting, written to agent.yaml, with agent.py to load it. Nothing here calls an API or leaves your browser.
The agent designer needs a wider screen.
Use the simple wizard, or open this page on a computer.
agent
Model family, effort, thinking, and what the system prompt starts from.
Families, not dated model IDs: the SDK picks the current model. Leave effort on default unless you have a reason. Adaptive thinking lets recent models decide how much to think; a fixed budget is mainly for older models.
Your text replaces the system prompt completely.
options: # Model family: the SDK picks the current model. model: "sonnet" system_prompt: "You track developments in our field. Cite every source you use."
generated files
# agent.yaml: settings for agent.py, made with the weclaudecode agent designer.# ${NAME} values are filled in from the environment when agent.py starts. Never paste secrets here.options: # Model family: the SDK picks the current model. model: "sonnet" system_prompt: "You track developments in our field. Cite every source you use." # Tools: allowed ones run without asking; disallowed ones are removed from the model's context. allowed_tools: ["WebSearch", "WebFetch", "Read", "Agent"] # Subagents the main agent can hand work to through the Agent tool. agents: "summariser": description: "Condenses one long source into five bullet points." prompt: "Summarise the source you are given in five bullet points. Keep every number and date exact." tools: ["Read"] model: "haiku" # Limits, working folder, settings files and skills. max_turns: 12 max_budget_usd: 1# The prompt agent.py sends.prompt: "What changed in our field this week?"
# pip install "claude-agent-sdk==0.2.163" "pyyaml==6.0.3"# Settings live in agent.yaml next to this file. In-process tools and hooks live here, because they are code.import os, re, sysfrom pathlib import Pathimport anyioimport yamlfrom claude_agent_sdk import ClaudeAgentOptions, query, AgentDefinitionfrom claude_agent_sdk import AssistantMessage, ResultMessage, TextBlock, ToolUseBlockENV_REF = re.compile(r"\$\{([A-Z_][A-Z0-9_]*)\}")def expand(value): # Fills in ${NAME} from the environment, and stops before the agent starts if one is missing. def sub(m): name = m.group(1) if name not in os.environ: sys.exit(f"agent.yaml needs {name}: set it in the environment") return os.environ[name] return ENV_REF.sub(sub, value)def load_config(path): cfg = yaml.safe_load(Path(path).read_text()) # Only MCP env, headers, url and stdio args may reference the environment; other text is used as written. for server in cfg["options"].get("mcp_servers", {}).values(): if "url" in server: server["url"] = expand(server["url"]) if "args" in server: server["args"] = [expand(a) for a in server["args"]] for field in ("env", "headers"): for key, value in server.get(field, {}).items(): server[field][key] = expand(value) return cfgcfg = load_config(Path(__file__).with_name("agent.yaml"))opts = cfg["options"]opts["agents"] = {name: AgentDefinition(**a) for name, a in opts["agents"].items()}options = ClaudeAgentOptions(**opts)def show(message): if isinstance(message, AssistantMessage): for block in message.content: if isinstance(block, TextBlock): print(block.text) elif isinstance(block, ToolUseBlock): print("->", block.name, block.input) elif isinstance(message, ResultMessage): cost = message.total_cost_usd or 0 print(f"\n[{message.subtype}: {message.num_turns} turns, ${cost:.4f}]")async def main(): async for message in query(prompt=cfg["prompt"], options=options): show(message)anyio.run(main)
ANTHROPIC_API_KEY
The files target the claude-agent-sdk Python package. Options change between releases, so check the SDK's own documentation before you ship.