Skip to main content

How we Claude Code

TL;DR

  • Arno from Anthropic's Applied AI team runs a workshop on "how we Claude Code at Anthropic," covering three levels: letting Claude interview you to extract requirements, using information-dense HTML files instead of Markdown specs, and building verification natively into the artifact.
  • As models get more capable, you should resist over-constraining them (echoing Richard Sutton's "bitter lesson") and let Claude prompt and interview you via the ask-user-question tool, since Claude is often better at extracting your latent requirements than you are at articulating them.
  • The workshop builds a bill-splitting app and a to-do React app, showing how to generate multiple HTML design directions for richer feedback, and how to embed agent-readable verification (DOM state contracts, Storybook fixtures, Playwright MCP) that runs as a human dashboard, an agent-driven flow, or headlessly in CI.

Takeaways

  • The session is based on Tariq's San Francisco talk and his blog post "The Unreasonable Effectiveness of HTML files," arguing for moving from Markdown to HTML for specs; a companion repo (under the "Claude with Code workshops" as "how we Claude Code") lets attendees code along through three phases.
  • As models improve, agents run longer on more complex tasks, which can burn many tokens if they go wrong — so you should front-load the verification a human would do into a richer, more human-ergonomic HTML format.
  • Resist constraining capable models (Richard Sutton's "bitter lesson"): Claude is likely better at extracting what you want from you than you are at specifying it, so let it interview you to remove ambiguity rather than over-specifying outcomes up front.
  • Good prompting gives Claude domains and areas of interest and uses the ask-user-question tool to trigger an iterative interview workflow; bad prompting is just typing "make it better."
  • Recommended Claude Code settings: use auto mode (shift-tab to cycle in), set the effort parameter (recommended extra-high, or max), and use fast mode for quick spec iteration — and take screenshots to give Claude visual feedback, especially for front-end work.
  • HTML files are more information-dense and ergonomic than Markdown for reviewing what an app will look like (Markdown files over ~200 lines rarely get read); Opus 4.7 generated four design directions (e.g. brutalist, Tokyo fintech) for the bill-splitting app to click through and give feedback on.
  • The verification approach makes state agent-readable by publishing component state to the DOM (data-verify attributes, schemas, fixtures, known states, invariants, probes) so an agent can run verification independently of React internals, rather than scraping the DOM.
  • Verification runs three ways — a human-readable dashboard, an agent-driven flow from the browser via Playwright MCP, and headlessly via bun verify in CI — and the Claude Code team records verification runs as clips stored on S3 to share as evidence; an HTML spec is not more token-inefficient long-term because a rich spec means fewer iterations.

Vocabulary

HTML spec — An information-dense, human-ergonomic specification format proposed as a replacement for long Markdown specs. Ask-user-question tool — A Claude Code tool that triggers an iterative interview so Claude extracts requirements from you turn by turn. The bitter lesson — Richard Sutton's idea that pouring more data and compute generally beats hand-coded human constraints. Auto mode — A Claude Code mode (cycled via shift-tab) the presenter strongly recommends for ease of use. Effort parameter — A Claude Code setting (recommended extra-high or max) controlling how much effort the model puts in. Fast mode — A Claude Code mode that costs more but is great for quickly iterating on specs. Playwright MCP — An MCP integration letting Claude drive a browser to take screenshots and run verification steps. DOM contract — Component state published to the DOM (via data attributes) so an agent can verify behavior independently of React internals. Invariants — Conditions that must always hold for a component, tested with probes that push off the happy path. Storybook fixtures — Known component states and test data used to make verification reproducible.

Transcript

Hello, hello, hello. Welcome all. Thank you for joining the workshop. We have a pretty full house here today. Quick show of hands — who here loves Claude Code? Okay, you're in the right place. My name is Arno. I'm a member of the Applied AI team. I'm an architect there. I'm here today to tell you how we Claude Code at Anthropic. We'll do a workshop and you can code along. You'll get some credits — there'll be a QR code in just a moment, so make sure to grab that. There'll be people floating around that might support you, so if you have technical difficulties, we can help you out. Anybody here who hasn't used Claude Code before? Okay, great — there's more to find out. Let's get started.

Please grab the QR code, set yourselves up. There'll be a repo here as well that you can clone. There are three phases we're going to work through. There's an interesting verification setup that you can work through alongside me, and it's quite detailed, so you probably will want to investigate it a bit later yourselves. What we're covering today is based on the version of the talk that Tariq gave in San Francisco just about a week and a half ago. He published that as a blog post called "The Unreasonable Effectiveness of HTML files." He's basically pitching that, moving on from Markdown files, we're going to be using HTML instead. And we're showing some of that today.

Where is this all going? I think everybody probably notices that agents are becoming more and more capable. Why is that happening? Because the models are becoming more and more capable. And so if the models become more capable, it means agents can run for longer and you can give them more and more complex tasks. But that also means that we have to change our way of working. You have to change your habits. How can you change the way that you're working with Claude Code to get more out of it? If you're going to let your agent run for a longer period of time, then you can burn through a lot of tokens if it does the wrong thing. And you want to avoid that, ideally at the beginning. That's where the idea came from to front-load more of the verification that the human would do in the spec into an HTML file, because it's a more rich and more human-ergonomic way of engaging with the content that your agent is going to be building for you.

There are a bunch of things around agents that are worth reading. We have a lot of engineering blogs on our web page. There's a lot of interesting information about harnesses, about long-running agents. Today we'll focus on three levels. The first thing is: the more capable the models get, the more you should try to resist constraining them. Who here has heard of the bitter lesson by Richard Sutton? Richard Sutton is basically the father of reinforcement learning. His idea was that you could spend all your time trying to, with your human capabilities, hard-code up front and constrain the system, but in the end, pouring more data and more compute at it ends up getting more capability than anything that you could have come up with. There's a similar analogy here: the models are becoming more and more capable. And so you should accept that the model is probably better at extracting requirements from you than you are at defining your requirements. The requirements are latent within you, just like when you talk to your users. Your users have an idea — they know it when they see it, but they're often not very good at articulating what they need. Likewise, you probably know what you want when you see it, but Claude is likely better at extracting what you want and what you need from you than you are at specifying it to Claude.

So we'll talk about that — removing ambiguity, letting Claude prompt you and interview you in prompting. Then, how to understand and plan. We used to do this all with Markdown files. We still do it with Markdown files. A colleague of mine once said, "The Markdown file is the lingua franca of the AI-native software development life cycle." That was pretty poetic. But it seems like that format is a bit constrained. It's getting too long with a lot of lines of Markdown file to read. We can condense more information into HTML files, and that's what we're going to do today. And then, how to verify. Not test, actually, but just to verify in this context. How to make verification native to the thing itself, so that the agent can drive it alongside a human, or eventually not — headlessly as well. That's where this is all going. And how can you set the artifacts up to natively be testable and verifiable in the way that you need.

Let's say we want to do a bill-splitting app. Very simple — you go out with friends, you want to find out who owes what. Let's let Claude interview us around doing this. First, an example of how you would do this and how you could do this better. What's good prompting? What's bad prompting? Bad prompting is when you say, "Just make it better." A lot of people that I watch using Claude Code just type, "make it better." Make no mistake — that's not good prompting. You want to encourage Claude to extract from you specific details. You give the domains. Don't over-specify the outcome, but specify the areas that you are interested in. That's what makes a good prompt different and better. Focusing on the audience, for example, or suggesting an open-ended way to answer the question as opposed to predefining it up front. And then that will prompt Claude to iteratively interview.

I've got Claude open here, two different Claudes. Who here has used fast mode? Okay, not that many people. And who here uses auto mode? Oh, I'm very happy that you all use auto mode. You need to be using auto mode. If you're not using auto mode, you need to be using auto mode. It makes it so much easier. Who here is setting their effort parameter? Good. Our recommendation is extra-high, but you can also set max effort. Just to touch on how those look: we've got forward-slash effort, which is the effort parameter; forward-slash fast, which is fast mode; and the auto mode, which we cycle into like this, shift-tab. Auto mode is the best. So I'll copy-paste my prompt on the bill-splitting app. Claude's going to ask me — you tap through these. In my case, I want it just for friends. Is there a secondary audience? No. The key thing here in the prompt is that you want to prompt Claude to use the ask-user-question tool that you saw me use earlier. That's what triggers this workflow, and depending on how well you specify that prompt, you'll get better outcomes. It'll generate a spec. We could then turn that into a bunch of different ways of building the app.

Let's say we have a plan. It generates a plan. We've answered some questions. It's getting better at extracting turn by turn from me what I actually want without me having to up front verbalize everything myself. Then I want to be able to check, is it what I want? Well, an HTML file is more dense, much more information-dense, much more ergonomic for you to understand what the thing is going to look like. You can even use a screenshot with it. You can use the Playwright MCP later on for that as well. You can interact with it much more richly than you could with a very long Markdown file. And especially if the Markdown files get more than about 200 lines long, it's unlikely you're going to read it, and certainly unlikely that your colleagues are going to read them. Before we started here, I had Claude with Opus 4.7 generate a few examples of what this could look like with my bill-splitting app. I asked Claude, "Give me a few different directions, four different design directions, explore them, generate them as HTML." And they came up with these different ones — one sort of brutalist, one Tokyo fintech. We'll click them all one by one. Completely different aesthetics. And this is much better for me to give feedback to Claude on than it would be to just try to infer from a Markdown file what the thing is going to look like. I could go in and take screenshots, feed them back into Claude. Who here regularly takes screenshots to give information to Claude? Very good. You should be doing that. Especially when you're doing front end, it's really hard to articulate that the thing is slightly off or there's a misalignment, and you'll find that you run into the limits of what you can express. It's actually easier for especially Opus 4.7, which has a much better vision model than before, to extract from you what the problem is.

So far we've covered letting Claude extract information from you interactively as an interviewer, because the longer you let an agent run, the more important it is that the spec is comprehensive, and the less likely it is that you'll be able to up front define everything. Then, what's a better and more efficient and ergonomic form factor? It would be the HTML file. And now, the more important part: how to verify what Claude has done and how to make it agent-native. What you want to do is make it part of the artifact. Part of what we're doing today is we're going to use Storybook fixtures, a testing library, data emissions, and attributes, and Playwright MCP for a React app, with components that you will have seen before but remixed in a way to make it easy for Claude as an agent to extract the data contracts in the DOM, and then run verification, and even record the verification. That's how the Claude Code team that Tariq is on runs this. It'll be a generation of verification steps that get run through, they get a recording, and that's then put on S3 or shared somewhere else with colleagues.

So I encourage you to go to that link. There'll be a repo. This is the repo under "CW workshops" — Claude with Code workshops — and there's the one for today's session, "how we Claude Code." Phase one is the simple prompt to say, "Hey, I'm writing a bill-splitting app. Interrogate me on the requirements so that I don't have to miss any in my up-front description to Claude." The second one is generating four different HTML design directions that we could explore for me to then give feedback on. And then thirdly, we have a verification framework. It's in a different context — it's not to do with the bill-splitting app, it's regarding a small to-do app written in React. We're going to show how we built verification entirely into that. That's described in detail in the readme for phase three and also in the verification detail.

We've written a small to-do list app here. I can add an item, tick it off, and drop it as well. And I could clear the finished items. Many things are happening here in terms of the state. We'd like to verify that it's all working alongside the tests that are already defined. But these verification steps, we'd like them to be driven by an agent. There are three ways we're going to do this: in a human-readable way; in an agent-first way (let Claude do that from Claude Code or elsewhere); and headlessly, like you might do it in CI. So human-readable, agent-driven, and headless.

We'll go into the app and look at the elements. We have here the actual emitting of different data aspects — the data-verify unit, the total done and active. The component itself here is publishing its state to the DOM. If I change my state, if I add "test," that updates. And then I drop it, it updates again. So this is what the agent can read later, as opposed to having to scrape the DOM. If you publish the state here separately from the React internals, you'd be able to run the verification independently of whatever the state of the app is. Every component gets one of these — there'll be schemas, there'll be fixtures, the known states, and then there are the invariants. There are particular ones here that always have to hold. You'll test them with probes. We've hardcoded an example that will fail the verification, and we'll let the human-verified dashboard catch up, and then we'll also let the agentic way of doing it catch up so Claude Code can find it and diagnose it for us.

I've got the dashboard defined here. We've got the different schemas, the invariants that we've defined. We can run these individually, or I could run all of them. One of them triggers artificially because we planted it before. We will also look at how we can replicate this for an agent. We could run the manifest of all the different verification steps that are defined here as state in the DOM. We can get them in the same way that we have them here. If we do that, then we can run them. In this case, we're running this not to perform the verification, but to provide the evidence of the verification. We can later record these as clips, which will just be videos we capture, and then we would store them, share them with colleagues, put them on S3.

Here's our summary. We have one that's deliberately failed. In each case you can also see the details of how this was done. The key thing here is that it's important to include the probes to push off the happy path. And a lot of this will be generated by Claude for Claude, so there's a way of scaling this further. We'll go to the one that didn't work — the one where we hardcoded that the sums do not match. The state doesn't match: 3 + 4 does not equal 10 in this case. We'll get the same result if we run verify-all from Claude here as well. We can change this. The idea is to let something agent-native be read as the DOM contract. The state is at least viewable to an agent that it can then run the verification end-to-end itself.

We can also make a change that will break more. Let me break the contract but not the app. Under the to-do app, total stats, I'll delete that. If we now run, then all of these ones at the bottom will fail. All of these are failing — not because we broke the app, but because we broke the contract that Claude can then natively verify. I want Claude to tell me what's going on with these. So let me correct the change I made before, rerun. We've done it manually and shown how we can match what the agent would see versus what we would do. But we can let Claude run this headlessly itself as well. In this case, what we're going to do is let Opus 4.7 help us find out why that particular verification failed. I've already connected the Playwright MCP for this. Schema got rejected — 4 + 3 does not equal 10. If you were to run bun verify, then you would actually pass the tests in this case, because we deliberately put the verification in wrong just to demonstrate, but the test metric itself will actually pass. The idea here is to separate out what you could do as a human versus what the agent could do directly from the browser, and what you could run headlessly directly from the CLI.

Then you could record the outcome that we talked about. The same delayed running we've shown, you could run and record as evidence to show that it would work, and then store that. This is very common right now. The Claude Code team records basically all the code changes that they do like this — all the front-end changes at least, especially at the pace of shipping that we have at the moment. You can just put them in S3 or share them with colleagues. In our case we do record them as part of a regular cadence. You have each clip, you could download all of them or download them individually, and that's basically the bundle that proves the verification worked.

So to bring it around to what we've covered: three different surfaces — the human surface, the agent-first from the browser mapping on the same way, and then you can also run it in CI with just bun verify. The objective here is to figure out how do you embed the verification into the artifact itself. I encourage you to check out the repo itself and actually run a few examples yourself and run a few tests. You can change the code, see what breaks, rerun it yourselves. It's quite detailed and it's what Tariq and team use in the Claude Code team for their work already. What's new really is the remixing and the new arrangement of primitives that you're already familiar with, just to make it available to the agent first.

That concludes what I wanted to cover. I encourage you to spend more time on the repo. There's great documentation there, and you can get a lot out of it with Opus 4.7. Opus 4.7 works really well because it has a better vision model. That's where this really excels. If you use Sonnet, I wouldn't recommend that — I'd say try using Opus 4.7 for it. Try using fast mode for it. Fast mode is great, costs more, but it's great for iterating quickly on specs. People will sometimes ask, "Well, isn't an HTML spec more token-inefficient?" And the answer tends to be no. The reason is that in the long term you iterate less if you have a good and rich HTML spec, even if in one-off instances you spend more tokens to generate it. So that would be my recommendation to you. I enjoyed speaking to you and thank you for your attention.

Feedback / ReportSpotted an issue or have an improvement idea?