2026年AI Agent实战:用Claude Code + Cursor,我从外包搬砖到日入500美元

2 阅读9分钟

坦白讲,这篇文章不是教你一夜暴富。但如果你是一个有基础的全栈开发者,读完之后你确实可以在30天内把接单效率提升3-5倍,月收入翻个倍不是梦。

写在前面:我是怎么走到这一步的

我叫老张(化名),做了6年全栈开发,Node.js/Python为主,React/Next.js做前端。2024年底之前,我的收入来源很传统:上班拿工资,偶尔接点外包赚零花钱。一个中等复杂度的CRUD后台管理系统,我大概需要2-3周交付,收费3000-8000块。

转折发生在2025年初。当时公司裁员,我被迫开始全职freelancer生涯。一开始很焦虑——不是接不到单,而是接了单做不完。直到我系统性地把Claude Code + Cursor接入工作流,事情开始发生了质变。

到2026年4月,我的接单模式已经完全变了:

  • 以前:2-3周做一个项目,收费3000-8000元
  • 现在:3-5天做一个同级别项目,收费300300-500(折合人民币2000-3600元),但同时并行2-3个项目

算下来,好的月份日入500美元(约合3600元)是常态。不是每个月都稳定,但平均下来确实达到了这个水平。

这篇文章我会把整个工作流拆开讲,包括具体的代码和配置,你可以直接拿去用。


一、认知升级:AI时代的接单逻辑变了

1.1 不要再"按代码量"计价了

传统接单的思路是:客户提需求 -> 你评估工作量 -> 报价 -> 开发 -> 交付。

问题在于,这个模式里你卖的是时间。而时间是有上限的——一天最多写8小时代码,一年最多干250天。

AI Agent时代,你需要转变思维:你卖的不是代码,而是解决方案的交付能力

举个例子:

客户说:"我要一个带用户管理、权限控制、数据看板的SaaS后台。"

传统模式下你评估:这得写2万行代码,至少3周。

AI Agent模式下你评估:我有一个模板库 + Claude Code能生成70%的代码 + Cursor帮我快速调试,3天能搞定。但客户觉得值500,那我就收500,那我就收500。

你的利润率从"时薪100元"变成了"时薪1000元",因为你交付速度提升了10倍,但市场价格没有等比例下降。

1.2 三个核心工具的定位

在我的工作流里,三个工具各有明确的分工:

工具定位核心价值
Claude Code后端/基础设施生成API设计、数据库schema、中间件、自动化脚本
Cursor前端/全栈编码组件开发、样式调整、实时调试、代码审查
ChatGPT/Claude Web需求分析+Prompt设计和客户沟通、拆解需求、设计system prompt

记住:工具只是杠杆,真正赚钱的是你拆解问题和整合方案的能力


二、Claude Code实战:30分钟搭建完整后端

Claude Code是Anthropic推出的CLI编程工具,简单说就是一个能在终端里直接读写你项目文件的AI。它的最大优势是上下文理解能力强——它能读懂你的整个项目结构,而不是像网页版那样需要你反复粘贴代码。

2.1 项目初始化

假设接到一个新单:做一个API服务,包含用户认证、文章CRUD、评论系统。

传统做法是打开终端,npm init,然后一个个文件创建。用Claude Code的话,一个prompt搞定:

# 启动Claude Code
claude

# 输入以下prompt
请帮我初始化一个Node.js + Express + TypeScript后端项目,要求:
1. 使用Prisma作为ORM,数据库用PostgreSQL
2. 项目结构如下:
   - src/routes/    路由层
   - src/controllers/ 控制器层
   - src/middleware/   中间件(JWT认证、错误处理)
   - src/services/    业务逻辑层
   - src/utils/       工具函数
3. 包含完整的tsconfig.json、.env配置
4. 预设用户(User)、文章(Post)、评论(Comment)三个数据模型
5. User和Post是一对多关系,Post和Comment是一对多关系

Claude Code会在几分钟内生成完整的项目骨架。但关键是,你不能完全依赖它一次生成。正确的工作方式是分步骤推进:

Step 1: 初始化项目结构 + package.json
Step 2: 配置Prisma schema
Step 3: 生成数据库迁移
Step 4: 实现JWT中间件
Step 5: 实现各个路由和控制器
Step 6: 添加错误处理和日志

每一步完成后,你检查一遍,确认没问题再进行下一步。这样出错的概率大大降低。

2.2 Prisma Schema示例

Claude Code生成的Prisma schema通常质量不错,但我会手动优化一些细节:

// prisma/schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id        String   @id @default(uuid())
  email     String   @unique
  username  String   @unique
  password  String   // bcrypt hash
  avatar    String?
  role      Role     @default(USER)
  posts     Post[]
  comments  Comment[]
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@map("users")
}

model Post {
  id        String   @id @default(uuid())
  title     String
  slug      String   @unique
  content   String   @db.Text
  published Boolean  @default(false)
  authorId  String
  author    User     @relation(fields: [authorId], references: [id])
  comments  Comment[]
  tags      String[] // 简单用数组存储
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@index([authorId])
  @@index([slug])
  @@map("posts")
}

model Comment {
  id        String   @id @default(uuid())
  content   String   @db.Text
  authorId  String
  author    User     @relation(fields: [authorId], references: [id])
  postId    String
  post      Post     @relation(fields: [postId], references: [id], onDelete: Cascade)
  createdAt DateTime @default(now())

  @@index([postId])
  @@map("comments")
}

enum Role {
  USER
  ADMIN
}

注意几个实战细节:

  • @@map把表名改成复数小写,这是PostgreSQL的惯例
  • 加了@@index在常用查询字段上,避免后期性能问题
  • CommentonDelete: Cascade确保删文章时评论也删掉

2.3 JWT认证中间件

让Claude Code生成中间件时,我用的prompt是这样的:

基于上面的Prisma schema,帮我实现JWT认证中间件,要求:
1. 使用jsonwebtoken库
2. token有效期为7天
3. 支持refresh token机制
4. 中间件要区分认证用户和可选认证(某些接口不强制登录)
5. 包含完整的错误码定义(401, 403)

生成的代码大概是这样(我做了微调):

// src/middleware/auth.ts
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();
const ACCESS_SECRET = process.env.JWT_ACCESS_SECRET!;
const REFRESH_SECRET = process.env.JWT_REFRESH_SECRET!;

export interface AuthRequest extends Request {
  user?: {
    id: string;
    email: string;
    role: string;
  };
}

// 必须登录
export function requireAuth(req: AuthRequest, res: Response, next: NextFunction) {
  const token = extractToken(req);
  if (!token) {
    return res.status(401).json({ error: '未提供认证令牌', code: 'MISSING_TOKEN' });
  }

  try {
    const payload = jwt.verify(token, ACCESS_SECRET) as { userId: string };
    req.user = { id: payload.userId, email: '', role: '' };
    next();
  } catch (err) {
    if (err instanceof jwt.TokenExpiredError) {
      return res.status(401).json({ error: '令牌已过期', code: 'TOKEN_EXPIRED' });
    }
    return res.status(401).json({ error: '令牌无效', code: 'INVALID_TOKEN' });
  }
}

// 可选登录(匿名用户也能访问,登录后有额外信息)
export function optionalAuth(req: AuthRequest, res: Response, next: NextFunction) {
  const token = extractToken(req);
  if (!token) {
    return next();
  }

  try {
    const payload = jwt.verify(token, ACCESS_SECRET) as { userId: string };
    req.user = { id: payload.userId, email: '', role: '' };
  } catch {
    // token无效时忽略,不阻塞请求
  }
  next();
}

// 管理员权限
export function requireAdmin(req: AuthRequest, res: Response, next: NextFunction) {
  requireAuth(req, res, () => {
    // 实际项目中应该查数据库获取最新role
    if (req.user?.role !== 'ADMIN') {
      return res.status(403).json({ error: '权限不足', code: 'FORBIDDEN' });
    }
    next();
  });
}

function extractToken(req: Request): string | null {
  const header = req.headers.authorization;
  if (header?.startsWith('Bearer ')) {
    return header.slice(7);
  }
  return null;
}

实战技巧:我通常会让Claude Code先生成一个基础版本,然后用Cursor打开项目,在IDE里进一步优化。这两个工具配合使用效率最高。


三、Cursor深度使用:前端开发效率翻倍的秘诀

Cursor是基于VS Code的AI IDE,它的杀手级功能是整个项目上下文理解 + 内联编辑。简单说,它不只是补全代码,而是真正"理解"你在做什么。

3.1 我的Cursor配置

以下是我实际使用的配置,在.cursorrules文件中(放在项目根目录):

# Cursor Rules - 全栈项目

## 技术栈
- 前端:Next.js 15 (App Router) + TypeScript + Tailwind CSS + shadcn/ui
- 后端:Node.js + Express + Prisma
- 状态管理:Zustand
- API调用:TanStack Query (React Query)

## 编码规范
- 组件使用函数式组件 + hooks
- TypeScript严格模式,禁止any(除非绝对必要)
- 使用path alias: @/components, @/lib, @/hooks
- 所有API响应遵循格式: { data: T, error?: string, code?: string }
- 组件文件使用PascalCase,工具函数使用camelCase

## AI辅助规则
- 生成组件时必须包含对应的TypeScript类型定义
- 优先使用shadcn/ui组件,不要重复造轮子
- 表单验证使用zod + react-hook-form
- 不要生成不必要的注释,代码要自解释
- 响应式设计优先考虑移动端

这个文件是关键。它告诉Cursor你的项目规范,这样它生成的代码风格统一,不需要大量手动调整。

3.2 用Cursor快速搭建前端组件

假设客户要求做一个数据看板页面,包含统计卡片、折线图、最近活动列表。

在Cursor里,我会在新建文件后使用 Cmd+K(内联编辑),输入:

创建一个Dashboard页面,包含:
1. 顶部4个统计卡片(总用户、今日活跃、总收入、订单数),使用shadcn/ui的Card组件
2. 中间一个折线图展示最近7天的活跃用户趋势,使用recharts
3. 底部一个最近活动列表,显示用户名、操作类型、时间
4. 所有数据从API获取,使用TanStack Query
5. 响应式布局:移动端单列,桌面端网格
6. 配色使用深色主题风格

Cursor会直接生成完整的页面组件。这里是一个简化版(实际生成的会更完整):

// app/dashboard/page.tsx
'use client';

import { useQuery } from '@tanstack/react-query';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
  LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer
} from 'recharts';

// TypeScript类型
interface Stats {
  totalUsers: number;
  activeToday: number;
  totalRevenue: number;
  totalOrders: number;
}

interface Activity {
  id: string;
  username: string;
  action: string;
  timestamp: string;
}

interface DailyActive {
  date: string;
  count: number;
}

// 统计卡片配置
const statCards = [
  { key: 'totalUsers' as const, label: '总用户', format: (v: number) => v.toLocaleString() },
  { key: 'activeToday' as const, label: '今日活跃', format: (v: number) => v.toLocaleString() },
  { key: 'totalRevenue' as const, label: '总收入', format: (v: number) => ${v.toLocaleString()}` },
  { key: 'totalOrders' as const, label: '订单数', format: (v: number) => v.toLocaleString() },
];

async function fetchDashboard() {
  const res = await fetch('/api/dashboard');
  if (!res.ok) throw new Error('获取数据失败');
  return res.json();
}

export default function DashboardPage() {
  const { data, isLoading, error } = useQuery({
    queryKey: ['dashboard'],
    queryFn: fetchDashboard,
    refetchInterval: 30000, // 每30秒刷新
  });

  if (isLoading) return <DashboardSkeleton />;
  if (error) return <div className="p-8 text-center text-red-400">加载失败</div>;

  const stats: Stats = data?.data?.stats ?? {};
  const activities: Activity[] = data?.data?.activities ?? [];
  const dailyActive: DailyActive[] = data?.data?.dailyActive ?? [];

  return (
    <div className="space-y-6 p-6">
      {/* 统计卡片 */}
      <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
        {statCards.map((card) => (
          <Card key={card.key}>
            <CardHeader className="pb-2">
              <CardTitle className="text-sm font-medium text-muted-foreground">
                {card.label}
              </CardTitle>
            </CardHeader>
            <CardContent>
              <div className="text-2xl font-bold">
                {card.format(stats[card.key] ?? 0)}
              </div>
            </CardContent>
          </Card>
        ))}
      </div>

      {/* 折线图 */}
      <Card>
        <CardHeader>
          <CardTitle>用户活跃趋势(近7天)</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="h-[300px]">
            <ResponsiveContainer width="100%" height="100%">
              <LineChart data={dailyActive}>
                <CartesianGrid strokeDasharray="3 3" stroke="#333" />
                <XAxis dataKey="date" stroke="#888" fontSize={12} />
                <YAxis stroke="#888" fontSize={12} />
                <Tooltip
                  contentStyle={{
                    backgroundColor: '#1a1a2e',
                    border: '1px solid #333',
                    borderRadius: '8px',
                  }}
                />
                <Line
                  type="monotone"
                  dataKey="count"
                  stroke="#6366f1"
                  strokeWidth={2}
                  dot={{ fill: '#6366f1', r: 4 }}
                />
              </LineChart>
            </ResponsiveContainer>
          </div>
        </CardContent>
      </Card>

      {/* 最近活动 */}
      <Card>
        <CardHeader>
          <CardTitle>最近活动</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="space-y-3">
            {activities.map((activity) => (
              <div key={activity.id} className="flex items-center justify-between rounded-lg bg-muted/50 p-3">
                <div className="flex items-center gap-3">
                  <div className="h-8 w-8 rounded-full bg-primary/20 flex items-center justify-center text-xs font-bold">
                    {activity.username[0].toUpperCase()}
                  </div>
                  <div>
                    <p className="text-sm font-medium">{activity.username}</p>
                    <p className="text-xs text-muted-foreground">{activity.action}</p>
                  </div>
                </div>
                <span className="text-xs text-muted-foreground">
                  {new Date(activity.timestamp).toLocaleString('zh-CN')}
                </span>
              </div>
            ))}
          </div>
        </CardContent>
      </Card>
    </div>
  );
}

// 骨架屏组件
function DashboardSkeleton() {
  return (
    <div className="space-y-6 p-6 animate-pulse">
      <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
        {Array.from({ length: 4 }).map((_, i) => (
          <div key={i} className="h-24 rounded-lg bg-muted" />
        ))}
      </div>
      <div className="h-[300px] rounded-lg bg-muted" />
      <div className="h-[200px] rounded-lg bg-muted" />
    </div>
  );
}

这个页面如果纯手写,至少要2-3小时。用Cursor的话,加上调整时间,30-45分钟搞定。

3.3 Cursor的三个高阶用法

用法一:Chat面板做代码审查

把一段代码粘贴到Cursor的Chat面板,然后输入:

审查这段代码,关注以下方面:
1. 是否有潜在的安全问题(SQL注入、XSS等)
2. 性能是否有优化空间
3. TypeScript类型是否严格
4. 错误处理是否完善
直接给出修改建议,不要解释太多

用法二:@Codebase 全局搜索理解

在Chat里用 @Codebase 引用整个项目,然后问:

这个项目的认证流程是怎样的?从登录到API调用,完整链路是什么?

这对快速理解一个新项目非常有用,尤其是接手别人的代码时。

用法三:Ctrl+I 多文件编辑

Cursor的Composer功能(Ctrl+I / Cmd+I)可以同时修改多个文件。比如:

给所有API路由添加rate limiting中间件:
1. 创建src/middleware/rateLimit.ts,使用express-rate-limit
2. 在所有/src/routes/*.ts文件中应用该中间件
3. 管理员路由设置更高的限制
4. 在.env中添加RATE_LIMIT_WINDOW和RATE_LIMIT_MAX配置

Cursor会一次性修改所有相关文件,而不是你手动一个个改。


四、Prompt Engineering:让AI输出质量提升一个档次

很多人用AI编程工具效率不高,根本原因是prompt写得不好。这里分享几个实战中总结出来的prompt模式。

4.1 结构化需求Prompt模板

每次开始一个新功能前,我会用这个模板整理需求:

## 功能需求:[功能名称]

### 背景
[为什么需要这个功能,一两句话]

### 数据模型
- 涉及的表/模型:[列出]
- 字段和关系:[描述]

### API设计
- POST /api/xxx - [描述]
  - 请求体:{ ... }
  - 响应:{ ... }
- GET /api/xxx - [描述]
  - 查询参数:?xxx=yyy
  - 响应:{ ... }

### 业务规则
1. [规则1]
2. [规则2]

### 边界情况
- [异常情况1]:应该返回xxx错误
- [异常情况2]:应该做xxx处理

### 非功能要求
- 需要分页(每页20条)
- 需要排序(按创建时间倒序)
- 需要缓存(Redis,TTL 5分钟)

把这个模板填好之后丢给Claude Code,生成的代码质量会显著提高。因为AI最怕的不是复杂,而是模糊

4.2 迭代式Prompt:不要一次给太多

新手最常见的错误是把所有需求一次性丢给AI,然后得到一堆半成品代码。

正确的方式是小步迭代

第1轮:先让AI设计数据模型和API接口(不写实现)
第2轮:确认设计没问题,让AI实现数据层(Prisma queries)
第3轮:让AI实现路由和控制器
第4轮:让AI写单元测试
第5轮:让AI检查错误处理和边界情况

每轮之间你检查一遍,发现问题就修正prompt再继续。这看起来慢,实际上比"一次生成一大堆然后花几个小时修bug"快得多。

4.3 System Prompt的最佳实践

如果你在开发自己的AI Agent产品,system prompt的设计至关重要。这是我常用的一个通用开发Agent的system prompt:

你是一个全栈开发工程师,擅长Node.js、TypeScript、React、Next.js。

## 工作原则
1. 代码优先于解释。用户要代码,你就给代码,不要废话。
2. 生成的代码必须是生产级质量:类型安全、错误处理完善、有必要的注释。
3. 如果需求不明确,主动提问而不是猜测。
4. 遵循项目现有的代码风格和架构模式。
5. 每次修改只做一件事,不要一次性改太多文件。

## 技术决策偏好
- 优先使用成熟的库,不追求最新最炫的
- 简单优于复杂,能用一个文件解决就不要拆成三个
- 安全第一:所有用户输入都要验证,所有数据库查询都要防注入

## 输出格式
- 代码块标注语言类型
- 修改已有代码时,明确标注哪些文件被修改了
- 涉及数据库变更时,提供migration步骤

五、我的接单流水线(可复制的SOP)

最后分享一下我现在的完整工作流程,这也是日入500美元的关键。

第一步:需求沟通(1-2小时)

  • 用Zoom/腾讯会议和客户聊30分钟
  • 期间用ChatGPT帮我整理需求文档
  • 产出:一份结构化的需求文档(上面那个模板)

第二步:技术方案设计(2-3小时)

  • 用Claude Code初始化项目骨架
  • 生成数据库设计、API接口定义
  • 给客户确认方案(展示API文档,不展示代码)

第三步:核心功能开发(1-2天)

  • 后端用Claude Code生成70%,手动调30%
  • 前端用Cursor生成60%,手动调40%
  • 关键业务逻辑(支付、权限等)自己写

第四步:联调测试(半天)

  • 写E2E测试用例(也可以让Claude Code辅助生成)
  • 修bug,优化性能

第五步:部署交付(半天)

  • Docker部署到客户的服务器
  • 写一份简单的使用文档
  • 交付,收款

整个流程3-5天,收费300300-500。一个月做8-10个这样的项目,收入就很可观了。


总结与行动建议

回顾一下这篇文章的核心观点:

  1. AI不是替代你写代码,而是放大你的交付能力。  你的核心竞争力不是"会写代码",而是"能把需求变成可用的产品"。
  2. 工具的组合比单个工具更重要。  Claude Code负责生成和搭建,Cursor负责编辑和调试,两者配合效率最高。
  3. Prompt质量决定了AI输出的质量。  投入时间学习prompt engineering,回报率是所有技能中最高的。
  4. 建立自己的模板库和SOP。  每做完一个项目,把可复用的部分沉淀下来。项目做得越多,效率越高。

给你的行动建议(按优先级)

第一周:

  • 安装Claude Code,用一个真实小项目(比如Todo API)练手
  • 安装Cursor,把一个已有项目导入试试Composer功能
  • 在项目中创建.cursorrules文件

第二周:

  • 用迭代式prompt完成一个完整功能
  • 尝试用AI辅助生成单元测试
  • 在Fiverr/Upwork上接一个100100-200的小单练手

第三周:

  • 建立自己的项目模板(后端模板 + 前端模板)
  • 优化你的接单SOP,记录每个环节的时间
  • 开始在社交媒体(掘金/知乎/Twitter)分享你的AI开发经验

第四周及以后:

  • 提高客单价,瞄准300300-500的项目
  • 考虑开发自己的AI Agent产品(模板+SaaS)
  • 建立个人品牌,让客户主动找你

最后说一句实话:  日入500美元不是终点,它只是一个"用AI工具提升生产力"的自然结果。真正有长期价值的是你在过程中积累的:拆解问题的能力、快速学习的能力、以及把AI当做"超级助手"的思维方式。

2026年,AI编程工具只会越来越强。早一天系统性地用好它们,你就早一天建立起别人难以追赶的效率优势。

如果你觉得这篇文章有帮助,欢迎点赞收藏,也欢迎在评论区交流你的AI开发经验。我会在评论区回复大家的问题。


本文写于2026年4月,基于作者过去一年的真实freelancing经验。所有代码示例均经过实际项目验证。