刚开始我也以为Claude Code就是给代码补注释的工具,结果用了一周后,我的开发流程彻底变了。今天聊聊我怎么用它做快速原型开发的,里面有几个坑,你大概率也会踩到。
(开篇:一张Claude Code界面截图,展示快速生成的原型代码片段,代码高亮显示)
先看第一个坑:别让Claude Code自己猜需求
我踩的第一个坑就是“给个模糊需求就让它写代码”。比如我说“帮我写个用户登录界面”,它确实生成了代码,但那界面丑得跟我上世纪的QQ空间有一拼。更离谱的是,它默认用了Flask框架,而我本来想用FastAPI。
正确姿势:
先给Claude Code喂一个“需求清单”,就像点菜一样:
“
你是一个资深全栈工程师。我需要一个轻量级的用户登录系统,用FastAPI+SQLite+JWT实现。具体需求:
,接受username和password,密码用bcrypt加密,返回JWT token,有效期24小时,需携带token`
然后让它生成。它就会像打了鸡血一样,一次性给你完整的项目结构。我试过,从输入到拿到可运行的代码,只用了4分32秒——比我自己写快了至少5倍。
`python
为什么这么写:让Claude Code理解技术栈和边界条件,避免它瞎猜
app/routers/auth.py
from fastapi import APIRouter, HTTPException, Depends
from app.models.user import User
from app.schemas.auth import LoginRequest, RegisterRequest, TokenResponse
from app.database import get_db
from jose import jwt
from passlib.context import CryptContext
from datetime import datetime, timedelta
router = APIRouter(prefix="/auth", tags=["auth"])
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
SECRET_KEY = "your-secret-key-here" # 生产环境用环境变量
@router.post("/register", status_code=201)
async def register(req: RegisterRequest, db=Depends(get_db)):
# 检查用户名是否已存在
if db.query(User).filter(User.username == req.username).first():
raise HTTPException(status_code=422, detail="Username already exists")
# 密码加密存储
hashed_password
<
p>= pwd_context.hash(req.password)
user = User(username=req.username, password_hash=hashed_password)
db.add(user)
db.commit()
return {"message": "User created successfully"}
`
这段代码看起来简单,但第一次跑的时候我踩了个坑:passlib在新版Python里会报crypt模块缺失的错误。官方文档文档不够清晰,最后还是靠Claude Code自己给我修好了——我直接扔错误日志给它,它秒回解决方案。
另一个坑:原型代码能用,但全是“面条式”
Claude Code默认喜欢把所有逻辑塞进一个文件里。当你只是验证一个想法时,这没问题。但一旦要扩展功能,那代码就像意大利面条一样缠在一起。
我的套路:
先让它生成“原型版”的代码,跑通核心流程。然后在同一个对话里,加一句指令:
`
现在,把这个原型代码重构为模块化结构。要求:
- 拆分成 routers/, services/, models/, schemas/ 四个模块
- 每个模块一个文件,依赖注入清晰
- 配置文件单独放 config.py
- 数据库连接放 database.py
- 不改变任何业务逻辑
`
这个设计真的反人类,但Claude Code处理得很好。它会分析代码的依赖关系,自动拆分。我举个例子:
(核心:一张代码重构前后对比图,左侧是单文件原型代码,右侧是模块化后的目录结构)
`python
重构后的 services/user_service.py
为什么这么写:把业务逻辑从路由中抽离,方便单元测试和复用
from app.models.user import User
from app.database import get_db
from passlib.context import CryptContext
from jose import jwt
from datetime import datetime, timedelta
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
class UserService:
def __init__(self, db_session):
self.db = db_session
def create_user(self, username: str, password: str) -> User:
if self.db.query(User).filter(User.username == username).first():
raise ValueError("Username already exists")
hashed_password = pwd_context.hash(password)
user = User(username=username, password_hash=hashed_password)
self.db.add(user)
self.db.commit()
return user
def authenticate_user(self, username: str, password: str) -> str:
user = self.db.query(User).filter(User.username == username).first()
if not user or not pwd_context.verify(password, user.password_hash):
raise ValueError("Invalid credentials")
# 生成JWT token
payload = {
"sub": user.username,
"exp": datetime.utcnow() + timedelta(hours=24)
}
return jwt.encode(payload, "your-secret-key", algorithm="HS256")r />`
重构后,路由文件变成这样:
`python
app/routers/auth.py
from fastapi import APIRouter, HTTPException
from app.services.user_service import UserService
from app.database import get_db
router = APIRouter(prefix="/auth", tags=["auth"])
@router.post("/register", status_code=201)
async def register(username: str, password: str, db=Depends(get_db)):
service = UserService(db)
try:
user = service.create_user(username, password)
return {"message": "User created", "user_id": user.id}
except ValueError as e:
raise HTTPException(status_code=422, detail=str(e))
`
这比原型版本清爽多了吧?而且Claude Code在重构时还会自动添加类型注解和文档字符串,省了我不少事。
还有个技巧:用“测试驱动”反推原型
这个技巧是我偶然发现的。有时候你连原型都懒得写,只想验证某个逻辑是否正确。这时候,你可以:
比如我想验证一个“用户积分排行榜”的算法,但我懒得先写完整代码:
`
写一个pytest测试用例,测试用户积分排行榜的top_n功能:
- 有5个用户,积分分别是100, 200, 300, 400, 500
- top_n(3) 应该返回 [500, 400, 300] 这三个用户
- 积分相同的情况按用户ID排序
- 边界情况:当n=0时返回空列表,当n>用户总数时返回所有用户
`
Claude Code会先写出测试用例,然后我就会说:“现在根据这个测试用例,写一个完整的实现。”它生成的代码通常一次通过,因为测试用例已经把边界条件定义清楚了。
`python
测试用例:test_leaderboard.py
为什么这么写:测试先行,确保原型代码覆盖所有边界情况
import pytest
from app.services.leaderboard import LeaderboardService
from app.models.user import User
def test_top_n_returns_correct_order():
# 准备数据
users = [
User(id=1, username="Alice", points=100),
User(id=2, username="Bob", points=200),
User(id=3, username="Charlie", points=300),
User(id=4, username="David", points=400),
User(id=5, username="Eve", points=500),
]
service = LeaderboardService(users)
# 执行
result = service.top_n(3)
# 断言
assert len(result) == 3
assert result[0].username == "Eve" # 积分500
assert result[1].username == "David" # 积分400
assert result[2].username == "Charlie" # 积分300
def test_top_n_with_ties():
users = [
User(id=1, username="Alice", points=100),
User(id=2, username="Bob", points=100), # 同分
]
service = LeaderboardService(users)
result = service.top_n(2)
assert result[0].id == 1 # 同分时按ID排序
assert result[1].id == 2
def test_top_n_boundary():
users = [User(id=1, username="Alice", points=100)]
service = LeaderboardService(users)
assert service.top_n(0) == [] # n=0
assert len(service.top_n(10)) == 1 # n>用户数
“
这个技巧特别适合做算法原型或者数据处理的原型,因为测试用例天然就是需求文档。
(总结前:一张流程图,展示从需求→测试用例→原型代码→重构的完整工作流)
总结一下,你可以立刻用的三个点
最后说一句:Claude Code不是取代你的,而是放大你的能力。它帮我把从需求到可运行原型的时间从半天压缩到半小时,而且代码质量还比我自己写的稳定——至少它不会犯低级拼写错误。
踩坑归踩坑,但这个工具确实值得一试。下次聊聊怎么用Claude Code做自动化测试,那个坑更多。