1. 引言

Trae 作为一款新兴的 AI 辅助编程工具,正在改变我们编写代码的方式。它不仅仅是代码补全工具,更是一个能够理解上下文、生成完整功能模块的智能编程伙伴。然而,很多开发者在使用 Trae 时,要么过度依赖导致代码质量下降,要么使用方式不当导致效率低下。本文将带你掌握使用 Trae 编程的正确方式,帮助你从新手成长为高效开发者。

2. 理解 Trae 的核心能力

在深入使用之前,我们需要先了解 Trae 能做什么、不能做什么。

2.1 Trae 擅长什么

  • 代码生成与补全:根据注释或函数签名生成实现代码
  • 代码解释与重构:理解现有代码逻辑并提出优化建议
  • Bug 修复:定位错误并提供修复方案
  • 单元测试生成:为现有函数自动生成测试用例
  • 文档编写:生成函数注释、README 等文档内容

2.2 Trae 的局限性

  • 缺乏业务理解:无法理解你项目的业务上下文
  • 可能产生幻觉:会生成看似合理但实际错误的代码
  • 安全风险:可能引入不安全的依赖或实现
  • 架构决策:无法替代开发者的架构设计能力

3. 准备工作:搭建高效的开发环境

3.1 安装与配置

首先,确保你已正确安装 Trae 插件或客户端。以 VS Code 为例:

# 在 VS Code 扩展市场搜索并安装 Trae
# 或通过命令行安装
code --install-extension trae.trae-vscode

3.2 项目初始化

创建一个新项目并初始化版本控制:

mkdir my-trae-project
cd my-trae-project
git init
npm init -y  # 或 pip init、cargo init 等

3.3 配置 Trae 规则

在项目根目录创建 .trae/rules.md 文件,定义项目规范:

# Trae 项目规则

## 技术栈
- 语言:Python 3.11+
- 框架:FastAPI
- 数据库:PostgreSQL + SQLAlchemy

## 代码风格
- 遵循 PEP 8
- 使用类型注解
- 函数长度不超过 50 行

## 命名规范
- 类名:PascalCase
- 函数/变量:snake_case
- 常量:UPPER_CASE

4. 正确使用 Trae 的五个核心原则

4.1 原则一:先思考,再提问

不要直接让 Trae 生成整个功能。先理清思路,再逐步实现。

错误示范

帮我写一个用户管理系统

正确示范

我需要一个用户注册接口,接收用户名和密码,密码需要 bcrypt 加密后存入数据库。请生成 FastAPI 的注册路由和对应的 SQLAlchemy 模型。

4.2 原则二:提供充分的上下文

Trae 的上下文窗口有限,但你可以通过以下方式提供关键信息:

  • 在提问前先打开相关文件
  • 使用 @ 引用项目中的文件或符号
  • 描述当前文件的结构和依赖关系

示例

@models/user.py 中定义了 User 模型,@schemas/auth.py 中有注册请求的 Pydantic 模型。请基于这两个文件,在 @routers/auth.py 中实现注册接口。

4.3 原则三:分步验证,逐步构建

将大任务拆解为小步骤,每步完成后验证结果。

推荐流程

  1. 定义接口:先让 Trae 生成函数签名和类型注解
  2. 实现核心逻辑:逐步填充函数体
  3. 添加错误处理:补充异常处理和边界情况
  4. 编写测试:为每个函数生成单元测试
  5. 代码审查:手动检查生成的代码

4.4 原则四:审查每一行生成的代码

永远不要盲目信任 AI 生成的代码。每次生成后,你需要检查:

  • 逻辑正确性:代码是否实现了预期功能?
  • 安全性:是否存在 SQL 注入、XSS 等安全漏洞?
  • 性能:是否有不必要的循环或冗余操作?
  • 可读性:变量命名是否清晰?是否需要添加注释?

4.5 原则五:善用 Trae 的对话历史

Trae 会记住当前会话的上下文。你可以:

  • 在同一个对话中逐步完善功能
  • 使用“继续”或“基于以上代码”来延续上下文
  • 当上下文混乱时,开启新对话

5. 实战案例:用 Trae 构建一个 RESTful API

让我们通过一个实际案例,演示正确的使用流程。

5.1 步骤一:定义项目结构

首先,让 Trae 生成项目骨架:

请生成一个 FastAPI 项目的目录结构,包含以下模块:
- models/:数据库模型
- schemas/:Pydantic 模型
- routers/:API 路由
- services/:业务逻辑
- config.py:配置文件
- main.py:应用入口

Trae 生成的目录结构

my-fastapi-app/
├── app/
│   ├── __init__.py
│   ├── main.py              # 应用入口
│   ├── config.py            # 配置文件
│   ├── models/
│   │   ├── __init__.py
│   │   └── user.py          # 用户数据模型
│   ├── schemas/
│   │   ├── __init__.py
│   │   └── auth.py          # 认证相关 Pydantic 模型
│   ├── routers/
│   │   ├── __init__.py
│   │   └── auth.py          # 认证 API 路由
│   └── services/
│       ├── __init__.py
│       └── auth.py          # 认证业务逻辑
├── tests/
│   ├── __init__.py
│   └── test_auth.py         # 认证模块测试
├── requirements.txt
└── .trae/rules.md           # Trae 项目规则

说明:Trae 会生成一个标准化的 FastAPI 项目骨架,按功能模块分层组织代码,便于后续逐步填充实现。

5.2 步骤二:实现数据模型

在 models/user.py 中定义 User 模型,包含 id、username、email、hashed_password、created_at 字段。使用 SQLAlchemy 2.0 风格。

Trae 生成的 User 模型代码

# app/models/user.py
from datetime import datetime
from sqlalchemy import String, DateTime, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column


class Base(DeclarativeBase):
    pass


class User(Base):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    username: Mapped[str] = mapped_column(String(50), unique=True, nullable=False, index=True)
    email: Mapped[str] = mapped_column(String(120), unique=True, nullable=False, index=True)
    hashed_password: Mapped[str] = mapped_column(String(255), nullable=False)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), nullable=False
    )

    def __repr__(self) -> str:
        return f"<User(id={self.id}, username='{self.username}')>"

说明:Trae 使用 SQLAlchemy 2.0 的声明式映射风格(Mapped + mapped_column),自动添加了唯一约束、索引和默认时间戳,代码简洁且类型安全。

5.3 步骤三:实现业务逻辑

在 services/auth.py 中实现用户注册和登录逻辑:
- register:接收用户名、邮箱、密码,密码用 bcrypt 加密后存入数据库
- login:验证用户名密码,返回 JWT token

Trae 生成的业务逻辑代码

# app/services/auth.py
from datetime import datetime, timedelta
from typing import Optional

import bcrypt
import jwt
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.models.user import User
from app.schemas.auth import RegisterRequest, LoginRequest, TokenResponse

# JWT 配置(实际应从 config.py 读取)
SECRET_KEY = "your-secret-key-here"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30


def hash_password(password: str) -> str:
    """使用 bcrypt 加密密码"""
    salt = bcrypt.gensalt()
    return bcrypt.hashpw(password.encode("utf-8"), salt).decode("utf-8")


def verify_password(plain_password: str, hashed_password: str) -> bool:
    """验证密码"""
    return bcrypt.checkpw(
        plain_password.encode("utf-8"), hashed_password.encode("utf-8")
    )


def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -> str:
    """生成 JWT token"""
    to_encode = data.copy()
    expire = datetime.utcnow() + (expires_delta or timedelta(minutes=15))
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)


async def register(db: AsyncSession, request: RegisterRequest) -> User:
    """用户注册"""
    # 检查用户名是否已存在
    result = await db.execute(select(User).where(User.username == request.username))
    if result.scalar_one_or_none():
        raise ValueError("用户名已存在")

    # 检查邮箱是否已存在
    result = await db.execute(select(User).where(User.email == request.email))
    if result.scalar_one_or_none():
        raise ValueError("邮箱已被注册")

    # 创建新用户
    user = User(
        username=request.username,
        email=request.email,
        hashed_password=hash_password(request.password),
    )
    db.add(user)
    await db.commit()
    await db.refresh(user)
    return user


async def login(db: AsyncSession, request: LoginRequest) -> TokenResponse:
    """用户登录,返回 JWT token"""
    # 根据用户名查找用户
    result = await db.execute(select(User).where(User.username == request.username))
    user = result.scalar_one_or_none()

    if not user or not verify_password(request.password, user.hashed_password):
        raise ValueError("用户名或密码错误")

    # 生成 token
    access_token = create_access_token(
        data={"sub": user.username, "user_id": user.id},
        expires_delta=timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES),
    )
    return TokenResponse(access_token=access_token, token_type="bearer")

说明:Trae 生成了完整的注册和登录业务逻辑,包括密码加密(bcrypt)、JWT 生成、重复检查、错误处理,并使用了异步数据库会话(AsyncSession),符合现代 FastAPI 最佳实践。

5.4 步骤四:实现 API 路由

在 routers/auth.py 中实现注册和登录接口:
- POST /auth/register
- POST /auth/login
使用 services/auth.py 中的函数

Trae 生成的 API 路由代码

# app/routers/auth.py
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession

from app.database import get_db  # 假设已实现数据库会话依赖
from app.schemas.auth import RegisterRequest, LoginRequest, TokenResponse, UserResponse
from app.services import auth as auth_service

router = APIRouter(prefix="/auth", tags=["认证"])


@router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def register(request: RegisterRequest, db: AsyncSession = Depends(get_db)):
    """用户注册接口"""
    try:
        user = await auth_service.register(db, request)
        return UserResponse(
            id=user.id,
            username=user.username,
            email=user.email,
            created_at=user.created_at,
        )
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=str(e),
        )


@router.post("/login", response_model=TokenResponse)
async def login(request: LoginRequest, db: AsyncSession = Depends(get_db)):
    """用户登录接口,返回 JWT token"""
    try:
        return await auth_service.login(db, request)
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=str(e),
            headers={"WWW-Authenticate": "Bearer"},
        )

说明:Trae 生成了符合 RESTful 规范的 API 路由,使用 FastAPI 的依赖注入获取数据库会话,将业务异常转换为合适的 HTTP 状态码(409 冲突、401 未授权),并正确设置了响应模型和状态码。

5.5 步骤五:编写测试

为 services/auth.py 中的 register 和 login 函数编写 pytest 单元测试,使用 mock 模拟数据库操作。

Trae 生成的测试代码

# tests/test_auth.py
import pytest
from unittest.mock import AsyncMock, MagicMock, patch
from sqlalchemy.ext.asyncio import AsyncSession

from app.models.user import User
from app.schemas.auth import RegisterRequest, LoginRequest
from app.services.auth import register, login, hash_password


@pytest.fixture
def mock_db():
    """创建模拟的异步数据库会话"""
    db = AsyncMock(spec=AsyncSession)
    db.add = MagicMock()
    db.commit = AsyncMock()
    db.refresh = AsyncMock()
    return db


@pytest.fixture
def register_request():
    return RegisterRequest(
        username="testuser",
        email="test@example.com",
        password="SecurePass123!",
    )


@pytest.fixture
def login_request():
    return LoginRequest(
        username="testuser",
        password="SecurePass123!",
    )


@pytest.mark.asyncio
async def test_register_success(mock_db, register_request):
    """测试注册成功"""
    # mock 查询返回 None(用户不存在)
    mock_db.execute.return_value.scalar_one_or_none.return_value = None

    user = await register(mock_db, register_request)

    assert user.username == "testuser"
    assert user.email == "test@example.com"
    assert user.hashed_password != "SecurePass123!"  # 密码已加密
    mock_db.add.assert_called_once()
    mock_db.commit.assert_awaited_once()


@pytest.mark.asyncio
async def test_register_duplicate_username(mock_db, register_request):
    """测试注册时用户名已存在"""
    existing_user = User(username="testuser", email="other@example.com")
    mock_db.execute.return_value.scalar_one_or_none.return_value = existing_user

    with pytest.raises(ValueError, match="用户名已存在"):
        await register(mock_db, register_request)


@pytest.mark.asyncio
async def test_login_success(mock_db, login_request):
    """测试登录成功"""
    hashed_pw = hash_password("SecurePass123!")
    existing_user = User(
        id=1,
        username="testuser",
        email="test@example.com",
        hashed_password=hashed_pw,
    )
    mock_db.execute.return_value.scalar_one_or_none.return_value = existing_user

    token_response = await login(mock_db, login_request)

    assert token_response.access_token is not None
    assert token_response.token_type == "bearer"


@pytest.mark.asyncio
async def test_login_wrong_password(mock_db, login_request):
    """测试登录时密码错误"""
    hashed_pw = hash_password("WrongPassword")
    existing_user = User(
        username="testuser",
        email="test@example.com",
        hashed_password=hashed_pw,
    )
    mock_db.execute.return_value.scalar_one_or_none.return_value = existing_user

    with pytest.raises(ValueError, match="用户名或密码错误"):
        await login(mock_db, login_request)

说明:Trae 生成了完整的 pytest 单元测试,覆盖了注册成功、重复用户名、登录成功、密码错误等核心场景。使用 AsyncMock 模拟异步数据库操作,测试代码结构清晰,可直接运行验证业务逻辑的正确性。

6. 进阶技巧:让 Trae 成为你的团队伙伴

6.1 使用 Trae 进行代码审查

将你的代码粘贴给 Trae,要求它进行审查:

请审查以下代码,指出潜在问题:
1. 性能瓶颈
2. 安全漏洞
3. 代码风格问题
4. 可维护性建议

[粘贴代码]

6.2 使用 Trae 生成文档

请为以下函数生成 Google 风格的 docstring,包含参数说明、返回值说明和示例:

[粘贴函数]

6.3 使用 Trae 进行技术选型

我需要为一个小型电商系统选择数据库,请对比 PostgreSQL 和 MongoDB 的优缺点,并给出推荐。

7. 常见误区与避坑指南

7.1 误区一:让 Trae 生成整个项目

问题:一次性让 Trae 生成整个项目,导致代码耦合度高、难以维护。

解决方案:按模块逐步生成,每完成一个模块就进行测试和重构。

7.2 误区二:不提供任何上下文

问题:只给一句话需求,期望 Trae 理解你的全部意图。

解决方案:提供充分的上下文,包括技术栈、现有代码结构、具体需求。

7.3 误区三:完全依赖 Trae 调试

问题:遇到 Bug 直接丢给 Trae,不自己分析问题。

解决方案:先自己定位问题范围,再让 Trae 辅助分析具体原因。

8. 总结

使用 Trae 编程的正确方式,核心在于人机协作——Trae 是你的智能助手,而不是替代品。记住以下要点:

  1. 先思考,再提问:明确需求后再让 Trae 生成代码
  2. 提供上下文:让 Trae 理解你的项目背景
  3. 分步验证:小步快跑,每步都验证结果
  4. 审查代码:永远不要盲目信任 AI 生成的代码
  5. 持续学习:在使用 Trae 的过程中提升自己的编程能力

掌握这些原则,你就能充分发挥 Trae 的潜力,让编程效率提升数倍,同时保持代码质量和可维护性。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐