George Song

My AI-Assisted Development Workflow (With Claude Code)

If you’re reading this, you’ve probably already tried AI coding tools. Maybe you’ve had some wins, maybe some frustrations. This isn’t a guide to “the right way” to work with AI—it’s a snapshot of what I’ve landed on after lots of experimentation with Claude Code.

The most important thing I can tell you? Your workflow should emerge from your needs, not from copying mine. Take what resonates, ignore the rest, and adapt everything to your context.

The Foundation: Two Key Directories

Before diving into workflows and tooling, let’s talk about the directories that anchor my AI collaboration.

ai-swap/: The Collaboration Space

This is a gitignored directory where Claude Code and I brainstorm, plan, and explore ideas without cluttering the repository. Think of it as a scratch space—it lives alongside my codebase but stays local.

I might start drafting an implementation plan here, iterate on architecture decisions, or just work through complex problems without worrying about commit history. It’s messy, it’s temporary, and that’s exactly the point.

docs-ai/: Project Memory

While ai-swap/ is ephemeral, docs-ai/ is permanent. This directory contains documentation specifically written for Claude Code to consume:

The key insight: docs-ai/ gets updated as part of the development cycle, not as an afterthought. When I merge a PR that introduces a new pattern or makes an architectural decision worth documenting, updating docs-ai/ is part of the process.

This version-controlled documentation evolves with the project, giving Claude Code the context it needs to make better suggestions and maintain consistency.

A Complete Development Cycle

Let me walk you through how I typically approach a feature from start to finish.

1. Think

Before touching Claude Code, I spend time thinking through what I actually want. Mostly the desired outcome, though sometimes I’ll have implementation ideas worth suggesting.

2. Explore

I start Claude Code in chat mode and talk through the feature. What are we trying to achieve? What constraints exist? What are the possible approaches?

This is conversation, not instruction. I’m exploring the solution space, not prescribing solutions.

3. Design

Once we’ve explored options, I switch to plan mode and ask for an implementation plan. If there’s a UI component, I’ll request ASCII diagrams to visualize the layout.

For non-trivial plans, we break everything down into steps so we can implement them one at a time and change direction if needed. This incremental approach keeps options open.

The plan might stay in ai-swap/ for my reference, or it might become GitHub or Linear issues if I’m working with a team.

4. Review and edit

I read the plan carefully and edit as needed. This often involves a few rounds of iteration with Claude Code alongside manual edits—I’m the one who knows the project’s hidden constraints and long-term direction.

5. Branch or worktree

Usually a branch is enough. But when I’m exploring multiple options simultaneously or juggling multiple features, I’ll create git worktrees. This gives me clean, isolated environments and makes it easy to switch contexts without stashing changes.

6. Iterate

Now we implement in auto mode. When the requirements are clear and I know the inputs and outputs, I’ll use red-green-refactor (TDD). But often I’m exploring, and that’s okay—we’ll implement, adjust, refactor, and commit frequently.

7. Commit frequently

Lots of small commits create rewind points. If we take a wrong turn, we can easily back up without losing much work. (Claude Code has a /rewind command for this too, but I prefer using git.)

8. Create PR

Once the implementation feels right, I create a pull request.

9. Critical review

This is an area where I’m constantly experimenting. Right now I’m testing a team of specialized agents—each focused on different facets of the review (security, accessibility, performance, test coverage)—rather than a single agent reviewing everything. But here’s what doesn’t change: I review the code myself. The AI-assisted review surfaces issues and perspectives I might miss, but ultimately I’m responsible for what gets merged, regardless of how the code was generated.

10. Address feedback

I work through the review feedback, making changes where they make sense and pushing back where they don’t.

11. Update docs-ai/

If this PR introduced new patterns or made architectural decisions worth documenting, I update docs-ai/ before merging.

12. Merge to main

Ship it!

The Philosophy: Delegation vs Collaboration

Did you notice something about that development cycle? I’m intentionally vague about how to implement things.

There are two modes of working with Claude Code: delegation and collaboration. I prefer collaboration, but delegation has its place.

Delegation mode:

Create a pie chart that breaks down the line items of capex and opex, and add radio buttons to toggle between the two charts. When I hover over each pie piece, I want to see the actual dollar amount as a tooltip. Also, there should be callouts showing the percentage of each pie piece.

Collaboration mode:

I want to create visualizations for capex and opex that I can toggle between

The first approach is delegation—I’ve already decided on the solution and I’m asking Claude Code to implement my specific design. This is perfectly valid when I know exactly what I want and how it should work.

But I usually prefer collaboration. The second approach states the goal and invites Claude Code to explore the solution space with me. Maybe a pie chart isn’t the best visualization. Maybe radio buttons aren’t the most intuitive toggle. By focusing on the outcome rather than the implementation, we can discover options I might not have considered.

Choose delegation when you know the solution. Choose collaboration when you want to explore possibilities.

Development Approaches: When to Use What

I mentioned red-green-refactor earlier, but that’s not always the right approach. Let me explain when I use which strategy.

Red-Green-Refactor (TDD)

This works well when:

With Claude Code, TDD becomes incredibly efficient. Write a failing test, let Claude Code implement it, verify it passes, refactor if needed. Repeat.

Exploratory Implementation

But sometimes I don’t want TDD. I use exploratory implementation when:

This isn’t sloppiness—it’s intentionality about the development approach. Sometimes the best way forward is to try something, see how it feels, and adjust.

The Tooling Philosophy

Now let’s talk about the tools I’ve built around Claude Code. These fall into three categories, each serving a distinct purpose.

Slash Commands: Complex Workflows

I use slash commands for workflows that need LLM decision-making—tasks that would be hard to script because they require judgment calls at each step.

My most-used commands:

Notice what these have in common: they’re all workflows that require making decisions based on context. A bash script could approximate these, but it would need complex branching logic to handle all the cases. With a slash command, Claude Code makes those judgment calls.

You could also use slash commands as a prompt library (shortcuts to frequently-used prompts), though I don’t primarily use them that way.

MCP Servers: Extended Capabilities

MCP servers give Claude Code access to tools it can’t reach via bash commands alone.

Examples of what I use:

My strategy: only enable MCP servers when I need them. I might keep them configured in my session but disabled. This prevents context bloat (wasting Claude Code’s token budget on unused tool descriptions) while maintaining quick access when I do need them.

(Shameless plug: I built ccmcp to make managing MCP server configurations easier. Check it out if you find yourself juggling multiple MCP setups.)

Agents: Context Management

Here’s where my thinking shifted: I initially thought of agents as task delegation tools. But the real value represents a fundamental shift in how I think about AI collaboration—agents aren’t just about saving time, they’re about saving context.

Example: docs-lookup agent

Instead of the main Claude Code instance reading through all my docs-ai/ files (consuming valuable context tokens), I have an agent that specializes in that task. The orchestrator asks the agent a question, the agent searches the docs and returns an answer, and the orchestrator continues with its work.

The agent has its own context window, which means the orchestrator’s context stays focused on the implementation task at hand.

Skills: Still Exploring

Skills are a brand new primitive in Claude Code, and I’m still figuring out how they fit into my workflow. I’m experimenting with them, but haven’t yet found their natural place in my development process the way I have with slash commands, MCP servers, and agents.

Context Management: Being Intentional

Claude Code’s token budget is generous, but it’s not infinite. My strategy is minimal but ready:

Why does this matter? Because a cleaner context means better responses. When Claude Code isn’t wading through dozens of tool descriptions it won’t use, it can focus on the task at hand.

Git Workflow Integration

Since we’re talking about practical workflows, let me touch on how this all integrates with git:

This isn’t revolutionary—it’s just being intentional about how AI assistance fits into a solid development workflow.

Make It Your Own

Here’s the thing: this workflow evolved through lots of trial and error. I tried things, kept what worked, and discarded what didn’t. Your context is different than mine. Your projects have different constraints. Your thinking style might prefer different approaches.

Start with one or two ideas from this article that resonate with you. Try them out. Adapt them. Break them if they don’t work. Add your own innovations.

The tools are flexible. Claude Code supports slash commands, MCP servers, agents, different modes—but there’s no single “right” way to use them. The best workflow is the one you’ll actually use consistently.

Some questions to guide your experimentation:

Your answers will lead you to different solutions than mine. And that’s exactly how it should be.

The goal isn’t to copy my workflow. The goal is to find the workflow that makes you more effective, more creative, and maybe even more excited about the work you’re doing.

Now go experiment.