Log in
Progress0 / 30 pages0%
VII.
Chapter 7 · Day 11 · 10 min read

Claude & Skills

Claude & Skills

Day 11 · The Welzin force multiplier

Every Welzin engineer works alongside Claude. Code review, scaffolding, debugging, customer-facing demos, internal automation - there is no role here that doesn't touch the model daily. The difference between an engineer who uses Claude and an engineer who operates Claude as a senior would is enormous: one writes 1.3× faster, the other writes 4× faster and gets better outputs.

This chapter is the operating manual. By the end of Day 11 you'll have built two real things - a Claude Code skill the rest of the team can install, and a custom agent using the Claude Agent SDK that does something useful for a customer workflow.


Outline

  1. The Claude product family - Web, API, Code, Agent SDK, when to use which
  2. Prompting as software engineering - system role, XML structure, examples, prefills
  3. Claude Code essentials - the CLI as an everyday tool
  4. Skills - the killer feature: anatomy, authoring, testing
  5. Tool use / function calling - letting Claude take actions
  6. Claude Agent SDK - building custom agents that aren't Claude Code
  7. Prompt caching - the single biggest cost lever
  8. Extended thinking - when to enable it, how to read the trace
  9. Memory and context management - the long-running session pattern
  10. The Welzin Claude stack - what we use, and what we don't

101 Primer

The Claude product family

Anthropic ships several surfaces. Pick the right one and your day gets shorter.

SurfaceWhat it isUse it when
claude.ai (Web)Chat UI + Projects + ArtifactsOne-off thinking, drafting, ad-hoc help
Claude CodeTerminal-native coding agentDaily engineering work in any repo
Anthropic APIDirect REST / SDK accessShipping LLM features in product code
Claude Agent SDKHigher-level library to build agentic appsCustom long-running agents, tool-heavy workflows
Claude in IDE (VS Code, JetBrains)Code suggestions + chat in editorInline completions, quick rewrites

Default rule: Claude Code in the terminal for engineering, API for product, Agent SDK for shipping agentic workflows to customers.

Models inside any of these surfaces:

  • Claude Haiku - cheapest, fastest. Classification, extraction, routing. Use whenever quality is "good enough."
  • Claude Sonnet - the workhorse. Default for product reasoning steps.
  • Claude Opus - the strongest. Hard reasoning, agentic planning, long-context tasks. Use when quality > cost.

When in doubt, prototype on Sonnet, profile, drop to Haiku where you can, lift to Opus where you must.

Prompting Claude, specifically

Claude responds well to a particular style. The non-negotiables:

1. Use a system prompt. Set role, constraints, and the one thing you must never do.

text
You are an extraction agent for customer-support emails. You only output JSON
matching the provided schema. You never include prose, markdown, or
explanation. If a field is missing, return null - never invent.

2. Use XML tags to delimit inputs. Claude is trained to attend to XML structure.

xml
<email>
  <from>jane@acme.com</from>
  <body>
    Hey team, my dashboard is showing stale data since this morning...
  </body>
</email>

<task>Extract the customer's intent and a one-line summary.</task>

3. Prefill the assistant turn for shape control. If you want JSON, start the assistant's reply with {:

python
messages = [
  {"role": "user", "content": "..."},
  {"role": "assistant", "content": "{"},   # the prefill
]
# Claude will continue from `{`, almost guaranteed to produce valid JSON

Note: Claude's API has a built-in tool_choice and structured output via tools - prefer that over prefills for production code. Prefills shine for ad-hoc scripts and prompt engineering.

4. Give examples (few-shot) when the format is non-obvious. Two well-chosen examples beat a paragraph of description.

5. Tell Claude to think. For non-trivial reasoning, an explicit <thinking>...</thinking> step before the answer raises quality:

text
Before you give your final answer, write your reasoning inside <thinking>
tags. Then give the answer inside <answer> tags. Only the contents of
<answer> will be shown to the user.

(For Sonnet/Opus, you can also enable extended thinking - see below.)

Claude Code as an everyday tool

Claude Code is the terminal agent you'll use for almost everything in this bootcamp. Start it with claude in any directory.

The mental model: Claude Code is a senior engineer who just walked into your repo. It has full access to your tools (read, edit, bash, search, the works) and follows the conventions in your CLAUDE.md. You're the staff engineer guiding it - high-leverage prompts, code review, course corrections.

A few habits that compound:

  • Write a CLAUDE.md at the repo root with project conventions, the tech stack, "never do X" rules, common commands. Claude reads it on every session.
  • Use /clear between unrelated tasks. Fresh context = better outputs.
  • Use /agents to dispatch parallel subagents for independent work (search, large analysis, parallel builds).
  • Trust but verify. Always review diffs before commits. The output is high-quality; it is not infallible.
  • Treat the terminal like pair-programming, not an oracle. Push back. Ask "why?". Course-correct.

Skills - the killer feature

A skill is a markdown file that teaches Claude how to do a specific task in your codebase or workflow. When Claude detects the task, it loads the skill and follows it.

This is the difference between asking Claude "deploy this to staging" every time (it guesses, sometimes wrong) versus having a deploy-staging skill that captures: the exact CLI, the env vars, the smoke-test URL, the rollback step, the Slack channel to ping. Once the skill exists, every engineer (and every Claude session) gets it for free.

Anatomy

markdown
---
name: deploy-staging
description: Use when the user asks to deploy the API to staging. Walks
  through the build, push, deploy, smoke-test, and notify steps.
---

# Deploy API to staging

## Preconditions
- You're on a clean main branch.
- `STAGING_REGISTRY_TOKEN` is in your environment.

## Steps

1. Run tests: `npm test`. Abort on failure.
2. Build the Docker image:
   ```bash
   docker build -t welzin/api:staging-$(git rev-parse --short HEAD) .
  1. Push to the registry:
    bash
    docker push welzin/api:staging-<sha>
    
  2. Trigger the staging rollout:
    bash
    fly deploy --app welzin-api-staging --image welzin/api:staging-<sha>
    
  3. Smoke test: curl -fs https://staging-api.welzin.ai/health
  4. Post in Slack #deploys: "Staging deployed at <sha>. Rolling back: fly releases list --app welzin-api-staging | head -2."

Rollback

If the smoke test fails OR an alert fires within 5 minutes, run:

bash
fly deploy --app welzin-api-staging --image <previous-sha>
text

#### When to write a skill

Write a skill the second time you do a task. The trigger: *"I've explained this twice already."*

Good skill candidates:

- Multi-step ops procedures (deploys, rollbacks, data migrations).
- Repo-specific conventions that aren't obvious from code (commit format, PR template, branch hygiene).
- Customer-handover playbooks (how to onboard customer X to module Y).
- Debugging patterns you'd repeat ("when a webhook fails, check these three things in this order").

#### Skill hygiene

- **`description` is everything.** It's how Claude decides whether to invoke the skill. Be specific about *when to use it*, not just *what it does*. Lead with the trigger phrase the user would type.
- **Be imperative.** "Run X. Verify Y. If Z, do W." Skills are runbooks, not essays.
- **Pin commands, not stories.** Tell Claude the *exact command*, not "use the appropriate Docker command."
- **Test it.** Open a fresh Claude Code session and trigger the skill. Watch what it does. Refine.
- **Version it.** Skills live in your repo (`.claude/skills/` or a shared plugin). They are code. Review them.

### Tool use / function calling (Claude API)

When you ship Claude inside your product, you usually give it *tools*. Claude decides which tool to call, with what arguments. You execute it and feed the result back.

```python
import anthropic

client = anthropic.Anthropic()

tools = [
    {
        "name": "search_customer",
        "description": "Look up a customer by email or company name. Use when "
                       "the user references a customer.",
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {"type": "string"},
                "limit": {"type": "integer", "default": 5},
            },
            "required": ["query"],
        },
    },
]

response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    tools=tools,
    messages=[{"role": "user", "content": "Find Acme Robotics in our CRM"}],
)
# response.stop_reason == "tool_use"
# response.content includes a tool_use block - execute it, append the result,
# call .messages.create again with the updated history. Loop until stop_reason
# becomes "end_turn".

The loop pattern (often called the agent loop):

text
while True:
    response = client.messages.create(model=..., tools=tools, messages=messages)
    if response.stop_reason == "end_turn":
        return response
    for block in response.content:
        if block.type == "tool_use":
            result = execute_tool(block.name, block.input)
            messages += [
                {"role": "assistant", "content": response.content},
                {"role": "user", "content": [{
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": result,
                }]},
            ]
    if iteration > MAX_ITERATIONS: break  # always bound the loop

Three rules of safe tool use:

  1. Bound the loop. A model can spiral. Set a max iteration count.
  2. Authorise destructive tools. A delete_customer tool needs a human-in-the-loop confirmation step - never a pure model decision.
  3. Validate tool inputs. Treat the model's tool-call arguments like untrusted input. Schema-check, type-check, range-check.

Claude Agent SDK - building beyond Claude Code

The Agent SDK is what you reach for when you want a long-running, headless agent that isn't sitting in a developer's terminal - e.g., a customer-facing assistant in your product, a scheduled internal worker, a Slack bot.

It gives you, for free:

  • The agent loop (no manual while True:).
  • File system + Bash tools, sandboxed.
  • Session memory and context compaction.
  • Streaming output to your UI.
  • Subagent dispatch.

A minimal Agent SDK script (Python, sketch):

python
from anthropic_agents import Agent, tools

agent = Agent(
    model="claude-sonnet-4-5",
    system="You triage incoming customer emails. Use the tools to look up "
           "the customer in our CRM, classify intent, and draft a reply. "
           "Always cite which CRM record you used.",
    tools=[tools.bash(), tools.fs(), search_customer, draft_reply],
    max_iterations=12,
)

result = agent.run(input=incoming_email)

Use the Agent SDK when:

  • The workflow needs > 1 tool call.
  • You want session memory / context management you don't want to write.
  • You're shipping an "agent" to a customer or as an internal worker.

Use the raw API when:

  • The call is single-shot or near-single-shot.
  • You want full control over the loop.

Prompt caching - the single biggest cost lever

Anthropic's prompt caching stores the prefix of your prompt server-side and reuses it across requests. Reads from cache are ~10% the cost and ~80% faster than fresh tokens.

The wins are real and instant. Anything that repeats - system prompt, tool definitions, common context, RAG sources - should be cacheable.

python
response = client.messages.create(
    model="claude-sonnet-4-5",
    system=[
        {
            "type": "text",
            "text": LARGE_STATIC_SYSTEM_PROMPT,
            "cache_control": {"type": "ephemeral"},  # ← this
        }
    ],
    tools=tools,  # tools are auto-cached
    messages=messages,
    max_tokens=1024,
)

Rules:

  • Cache the long static stuff. System prompts, tool schemas, retrieved docs that survive across messages, few-shot examples.
  • Cache lifetime is ~5 minutes (ephemeral). If your traffic has gaps, you'll miss the cache. Either keep traffic warm or accept the miss.
  • Order matters. The cache key is the prefix up to and including the cache_control marker. Reorder messages = cache miss.
  • Monitor the cache hit rate in response.usage.cache_read_input_tokens. If it's low, your prefix is changing more than you think.

A multi-turn chat with prompt caching on the system + tool prefix will routinely run at 30–60% cost reduction at zero quality cost. This is the single most impactful thing you'll learn this week.

Extended thinking

For genuinely hard reasoning (research-grade questions, multi-step planning, complex code generation), enable extended thinking to let Claude produce a private reasoning trace before its answer:

python
response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=4096,
    thinking={"type": "enabled", "budget_tokens": 8000},
    messages=[...],
)
# response.content includes a `thinking` block and a `text` block

Use it sparingly - it costs tokens and adds latency. Reach for it when:

  • The task is non-trivially compositional (planning a refactor, debugging across files).
  • You've seen Claude get the answer half-right on plain prompting.

For simple extraction / classification / routing: don't enable thinking. It's overkill.

Memory and the long-running session

Claude Code and the Agent SDK both support session memory - durable notes the model carries between turns and across sessions. Don't abuse it. Memory is for user-and-project-shaped facts the model should know next time:

  • "Customer prefers PRs split by surface (api/, web/, infra/)."
  • "Their staging URL is staging.acme.com, never *.dev-acme.com."
  • "Stack: Postgres 16 + Hono + Next.js."

Memory is not for: recent task state (use plans/tasks), code patterns (read the code), or anything that ages quickly.

When you save to memory, save why, not just what. A line saying "they want short PRs" without context will be misapplied. "They want short PRs because their reviewer is overloaded and bounces > 400-line diffs" can be judged on edge cases.

The Welzin Claude stack (current)

  • Claude Code is the default for in-repo work. Every repo has a CLAUDE.md.
  • Skills live in .claude/skills/ in each repo (project-scoped) or in ~/.claude/skills/ (personal). High-value skills get promoted to a shared welzin-skills plugin.
  • Product features ship on the API. No LangChain, no LlamaIndex by default - thin wrappers on the SDK. Reach for a framework only when you can name the specific thing it gives you.
  • Prompt caching is on by default on every multi-turn production call.
  • Tracing via Langfuse.
  • Eval harness in-repo per feature. Brittle? Yes. Necessary? Yes.
  • Memory in Claude Code: enabled. We treat the memory/ folder as source of context, not source of truth.

Hands-on Checkpoints

  • Install Claude Code (npm install -g @anthropic-ai/claude-code or via the docs). Run claude in this bootcamp repo. Browse the skills available to you with /skills.
  • Write a CLAUDE.md for one of your personal repos covering: stack, conventions, "never do X" rules, common commands.
  • Author a skill - pick a multi-step task you've done twice this week, write it as a markdown skill in .claude/skills/, test it in a fresh Claude Code session.
  • Build a tool-use loop with the Anthropic SDK in Python or TS. Two tools (one safe, one requiring confirmation), max 5 iterations, stop reason handling.
  • Enable prompt caching on a multi-turn call. Confirm the cache hit via usage.cache_read_input_tokens > 0.
  • Spin up an Agent SDK agent that triages a sample customer email - looks up the customer (mock tool), classifies, drafts a reply.
  • Read three skills under ~/.claude/skills/ or ~/.claude/plugins/. Note what makes a good description field. Steal patterns.

Further reading

Welzin opinion: A great skill written once saves the team a hundred prompts. Treat the skills folder like a shared brain: review it, evolve it, prune dead weight. Engineers who write skills compound the team. Engineers who only consume skills are using Claude in easy mode.

Knowledge check

Pass 80% to unlock
0/1 answered
What is the main benefit of prompt caching when calling the Claude API?