前四篇我们讲了Trae的基础使用、SOLO模式、Builder模式和Prompt工程。今天聊一个决定长期使用体验的功能——上下文管理:让Trae记住你的项目规范、代码风格和历史决策,不用每次都重新交代背景。
很多人用AI编程助手的最大痛点是:"每次对话都像第一次见面"——你不得不反复告诉它你的技术栈、代码规范、项目结构。Trae的上下文管理机制就是为了解决这个问题。
类比一下:
具体痛点:
| 场景 | 没有上下文 | 有上下文 |
|---|---|---|
| 新会话开始 | 重新介绍项目 | AI自动加载项目背景 |
| 代码风格 | 每次提醒用2空格缩进 | AI自动按规范写 |
| 技术栈 | 每次说明用React+TypeScript | AI默认用你的技术栈 |
| 历史决策 | "为什么上次选了方案A?" | AI记得决策原因 |
Trae会在项目根目录创建.trae/文件夹,里面存放:
project.md:项目背景、技术栈、核心功能说明conventions.md:代码规范、命名规则、注释风格decisions.md:重要技术决策的记录和理由手动创建这些文件后,Trae会自动读取,并在每次对话开始时加载为上下文。
Trae会自动维护一个对话摘要,记录:
当对话变长时,Trae会自动压缩早期对话为摘要,保留关键信息,避免超出上下文窗口。
在Trae的设置中,你可以配置全局用户画像:
这个画像会应用到所有项目,让Trae的输出更符合你的习惯。
在你的项目根目录创建.trae/project.md:
# 项目规范
## 项目背景
这是一个电商管理后台,基于React + TypeScript + Ant Design。
## 技术栈
- 前端框架:React 18 + TypeScript
- UI组件库:Ant Design 5.x
- 状态管理:Zustand
- 路由:React Router v6
- 样式:Tailwind CSS + CSS Modules
- 构建工具:Vite
- API通信:Axios + SWR(用于数据获取和缓存)
## 代码规范
- 缩进:2空格
- 引号:单引号
- 分号:必须
- 组件命名:PascalCase
- 文件命名:kebab-case(如 user-profile.tsx)
- 接口命名:前缀I(如 IUser)
- 环境变量:VITE_ 前缀
## 禁止事项
- 不要用 any 类型
- 不要直接操作DOM(用ref)
- 不要使用console.log(用logger)
- 不要硬编码API地址(用环境变量)
## 项目结构
src/
components/ # 通用组件
pages/ # 页面组件
hooks/ # 自定义Hooks
store/ # Zustand store
utils/ # 工具函数
types/ # TypeScript类型定义
api/ # API请求封装
效果:创建这个文件后,Trae在生成任何代码时都会:
更细粒度的代码规范:
# 代码规范细则
## 命名规范
- 变量:camelCase(如 userName)
- 常量:UPPER_SNAKE_CASE(如 MAX_RETRY_COUNT)
- 函数:camelCase,动词开头(如 getUserInfo)
- 组件:PascalCase(如 UserProfile)
- 文件名:kebab-case(如 user-profile.tsx)
- CSS类:kebab-case(如 .user-profile-card)
## 注释规范
- 函数必须写JSDoc注释(参数、返回值、功能说明)
- 复杂逻辑必须写行内注释
- 不要用中文注释(项目统一用英文)
## 错误处理
- 所有API调用必须用try-catch
- 用户界面必须显示错误信息(用message.error)
- 不要在catch块里静默失败
## 性能规范
- 列表必须虚拟化(超过50条数据)
- 图片必须懒加载
- 组件必须用React.memo避免不必要的重渲染
- 事件处理函数用useCallback包裹
在Prompt里贴一段你们项目的典型代码,让Trae学习风格:
请参考以下代码的风格和模式,实现订单管理模块:
【参考代码】
// 这是 src/hooks/useUser.ts 的代码
// 注意它的:错误处理方式、返回值结构、loading状态管理
import { useState, useEffect } from 'react';
import { getUser } from '@/api/user';
import { User } from '@/types/user';
export function useUser(userId: string) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchUser() {
try {
setLoading(true);
const data = await getUser(userId);
setUser(data);
} catch (err) {
setError(err instanceof Error ? err : new Error('Failed to fetch user'));
} finally {
setLoading(false);
}
}
fetchUser();
}, [userId]);
return { user, loading, error };
}
【你的任务】
用相同的风格和模式,写 useOrder hook。
直接让Trae分析你的项目,自动生成风格指南:
分析我的项目代码,生成一份代码风格指南,包括:
1. 命名规范(变量、函数、组件、文件)
2. 缩进和格式规范
3. 注释风格
4. 错误处理模式
5. 导入顺序规范
把结果保存到 .trae/conventions.md
Trae会扫描你的项目,自动生成符合你项目实际情况的规范文件。
常见问题:
解决方案:在.trae/decisions.md里记录每个重要决策。
# 技术决策记录
## 决策1:选择Zustand而非Redux
- 日期:2026-06-15
- 背景:需要轻量级状态管理,Redux太重
- 决策:用Zustand
- 理由:
1. 包体积小(只有几KB)
2. 学习成本低(API简单)
3. TypeScript支持好
- 替代方案:Redux Toolkit(太复杂)、MobX(学习曲线陡)
## 决策2:用SWR而非React Query
- 日期:2026-06-16
- 背景:需要数据获取和缓存
- 决策:用SWR
- 理由:
1. 包体积更小
2. API更简单
3. 够用(我们不需要React Query的高级功能)
- 注意:如果未来需要mutation功能,考虑迁移到React Query
## 决策3:不用any类型
- 日期:2026-06-10(代码规范)
- 背景:TypeScript项目,但有人用any绕过类型检查
- 决策:禁止any类型
- 理由:
1. any失去了TypeScript的类型保护
2. 用unknown + 类型守卫更安全
3. 实在不行用 @ts-ignore 并写清理由
- 例外:第三方库返回类型不明确时,可以临时用any,但必须加注释说明
效果:当你问Trae"为什么用Zustand?"时,它会先查decisions.md,然后给你准确的答案。
不要等到项目进行了一半才想起来。在项目一开始就把:
.trae/project.md.trae/conventions.md.trae/decisions.md创建好,后面会省很多事。
每次做了重要技术决策(选框架、定规范、改架构),立即更新decisions.md。不要等"有空的时候",因为那时你已经忘了决策理由。
每隔一段时间(比如每完成一个大功能),让Trae审查一下.trae/里的文件是否还准确:
审查 .trae/ 文件夹里的所有文件,检查:
1. 是否和当前代码实际风格一致?
2. 是否有过时的信息?
3. 是否需要补充新的规范?
如果有问题,直接帮我更新文件。
有了完整的上下文,你可以让Trae做更符合项目实际情况的代码审查:
根据 .trae/ 里的项目规范,审查 src/components/UserProfile.tsx 这个文件:
1. 是否符合命名规范?
2. 是否有any类型?
3. 错误处理是否到位?
4. 性能有没有问题?
给出具体的修改建议。
下一篇(最后一篇),我们将通过一个完整实战案例,把前六篇的知识串起来:用Trae从0到1开发一个完整的SaaS后台管理系统。
评论区