Cursor等AI IDE本质是一个AI Agent,他们背后主要是调用了LLM的能力,把LLM作为大脑,然后规划自己的行为。
一个主流的Agent大概会包含哪些内容:
其中以Cursor为例,短期记忆就是我们整个单次会话中的上下文内容,这个内容也决定我们单词任务执行是否足够智能。
哪个模型更合适编程开发
1. 模型建议排序:Claude >= Gemini > GPT-4o >= Deepseek-v3
2. Gemini 上下文会更长一些,另外Gemini 2.5 pro出来了,不知道是否会超越Claude
3. Deepseek-v3-0324 很接近 Claude 3.5 水平了
Claude-3.7 Sonnet 在很多场景中会容易有幻觉会导致胡乱发挥,错误修改代码,如果感觉Claude-3.7容易幻觉可以切换为 Claude-3.5 Sonnet,会更稳定发挥。
创意类或者是架构设计类场景,可以使用 Claude-3.7 Sonnet Think模型,或者是 GPT-4o模型,如果是纯需要稳定可靠输出,比如编程,或者是某些明确技术问题答案场景,可以考虑 Claude-3.5/Claude-3.7等模型。
上下文限制带来的问题
Cursor/Windsurf 本质就是一个Agent,LLM是它的大脑,每次我们编程交互过程的代码和沟通内容都会作为Context传递给大模型,方便模型有效的输出决策。
但是目前大部分场景下面,LLm都有上下文限制,主流大模型大部分都是在128K限制的上下文,在多轮LLM的沟通交互过程中,会导致之前的上下文被遗弃了,然后引发上下文切换的动作,会导致我们编写一个程序本来是需要反复修改的场景,可能之前需要大模型关注的信息被遗弃了,会导致会随意发挥,容易修改错误,或者大规模把功能或者代码改没了。
常见会出现的几种问题:
1. 缺乏“空间感”: 修改了一个文件,却忘记了另一个文件的逻辑。在大型项目中,AI可能会重复编写已经完成的功能;或者修改了A模块,却忘记B模块还依赖于A模块提供的接口,最终导致整个系统变得混乱不堪。
2. “时间感”混乱: 今天刚修复的问题,明天可能又会重新出现。比如,AI修复了bug A,但之后又无意中撤回了这个修复,导致问题再次出现。如此反复地“修复—回退—再修复”,陷入无休止的循环。
3. 代码“复用”困难: 尤其在需要与现有代码库集成时,AI往往无法清晰地把握整个项目的整体结构和设计理念。结果就是,它总倾向于从头开始重新编写代码,而不是复用已有的代码,导致同一个功能被重复开发多次,甚至相互冲突。
如何判断是否切换了上下文
一般如果需要判断上下文是否被切换了(遗弃了),可以约定一个“暗号”,这样如果每次输出都携带了“暗号”,说明上下文还没被切换,如果没有了,说明在这个整个对话超过了限制,让上下文进行了切换动作。
可以在对话开始,或者是.cursorrules 中增加对应的要求,类似于下面:
有哪些解决方法和思路
针对这种情况,有一些解决思路提供参考。
使用Cursor 0.48 新增功能
如果上下文满了会自动创建一个新会话,然后把上个会话的交互内容总结成为一个概要内容灌给新会话窗口。(new chat 后summary原来聊天窗口内容)
提升每次沟通技巧:给AI画重点,不要跑歪了
- 1. 上下文回顾提示方法:每次重要对话开始前,简单回顾一下项目背景和之前的决定。
请记住:这是一个电商项目,用Golang+Kratos开发。我们之前决定用redis存储登录session信息,
并用JWT处理认证。上次我们讨论过把用户服务改成微服务架构。
现在,我需要你帮我实现...
- 2. 文件索引提示方法:提供关键文件的路径和用途,帮 AI 建立项目文件认知地图。
项目主要文件:
src/services/UserService.go 用户核心业务逻辑(注册/登录/权限管理等)
src/models/User.go 用户数据模型(用户信息Schema定义)
src/controllers/UserController.go 用户API接口(处理HTTP请求)
src/utils/AuthHelper.go 鉴权工具(JWT生成/验证等)
现在我需要在UserService中添加退出登录功能...
- 3. 决策记忆提示:明确指出之前做过的技术决定,避免反复讨论已经解决的问题。
我们已经决定:
1.用RWMutex处理并发
2.状态变更通过事件系统广播
3.所有API返回统一用{code, data, message}格式
请基于这些决定,实现用户中心更新密码逻辑...
这些"提问技巧"有助于在 Cursor 中克服 AI 的"短期记忆"限制,实现更连贯的开发体验。
提示词模板:更高效地与 AI 沟通
提示词模板就像是一个现成的提问公式,预定义好的提示语,它能帮你把需求说得更清楚明白。用这种模板跟Cursor AI交流,AI更容易理解你想要什么,生成的代码也会更符合你的实际需要。
代码模版
先制作一批模版库,或者是你自己写好的第一层的代码,比如针对 DAO、Servier、Controller 等等生成对应的代码模版。
以下示例一个DAO层的代码模版:
package user_dao
import (
"context"
"errors"
"time"
"gorm.io/gorm"
)
// User 数据库模型
type User struct {
gorm.Model
Username string `gorm:"size:50;uniqueIndex;not null"`
Email string `gorm:"size:100;uniqueIndex;not null"`
Password string `gorm:"size:255;not null"`
IsActive bool `gorm:"default:true"`
Role string `gorm:"size:20;default:'user'"`
LastLogin *time.Time
}
// UserRepo 用户数据访问接口
type UserRepo interface {
Create(ctx context.Context, user *User) (*User, error)
Get(ctx context.Context, id uint) (*User, error)
GetByUsername(ctx context.Context, username string) (*User, error)
GetByEmail(ctx context.Context, email string) (*User, error)
List(ctx context.Context, page, size int) ([]*User, error)
Update(ctx context.Context, user *User) error
Delete(ctx context.Context, id uint) error
Count(ctx context.Context) (int64, error)
}
// userRepo 实现
type userRepo struct {
data *Data // 包含数据库连接
log *log.Helper
}
// NewUserRepo 创建用户仓库实例
func NewUserRepo(data *Data, logger log.Logger) UserRepo {
return &userRepo{
data: data,
log: log.NewHelper(logger),
}
}
// Create 创建用户
func (r *userRepo) Create(ctx context.Context, user *User) (*User, error) {
if err := r.data.db.WithContext(ctx).Create(user).Error; err != nil {
return nil, err
}
return user, nil
}
// Get 根据ID获取用户
func (r *userRepo) Get(ctx context.Context, id uint) (*User, error) {
var user User
if err := r.data.db.WithContext(ctx).First(&user, id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("user not found")
}
return nil, err
}
return &user, nil
}
// GetByUsername 根据用户名获取用户
func (r *userRepo) GetByUsername(ctx context.Context, username string) (*User, error) {
var user User
if err := r.data.db.WithContext(ctx).Where("username = ?", username).First(&user).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("user not found")
}
return nil, err
}
return &user, nil
}
// GetByEmail 根据邮箱获取用户
func (r *userRepo) GetByEmail(ctx context.Context, email string) (*User, error) {
var user User
if err := r.data.db.WithContext(ctx).Where("email = ?", email).First(&user).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("user not found")
}
return nil, err
}
return &user, nil
}
// List 分页获取用户列表
func (r *userRepo) List(ctx context.Context, page, size int) ([]*User, error) {
var users []*User
offset := (page - 1) * size
if err := r.data.db.WithContext(ctx).Offset(offset).Limit(size).Find(&users).Error; err != nil {
return nil, err
}
return users, nil
}
// Update 更新用户信息
func (r *userRepo) Update(ctx context.Context, user *User) error {
if err := r.data.db.WithContext(ctx).Save(user).Error; err != nil {
return err
}
return nil
}
// Delete 删除用户
func (r *userRepo) Delete(ctx context.Context, id uint) error {
if err := r.data.db.WithContext(ctx).Delete(&User{}, id).Error; err != nil {
return err
}
return nil
}
// Count 获取用户总数
func (r *userRepo) Count(ctx context.Context) (int64, error) {
var count int64
if err := r.data.db.WithContext(ctx).Model(&User{}).Count(&count).Error; err != nil {
return 0, err
}
return count, nil
}
配套相应的SQL语句:(PostgreSQL样式)
-- 用户表
CREATE TABLE users (
id SERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP WITH TIME ZONE,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(255) NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
role VARCHAR(20) NOT NULL DEFAULT 'user',
last_login TIMESTAMP WITH TIME ZONE,
-- 创建唯一索引
CONSTRAINT uk_users_username UNIQUE (username),
CONSTRAINT uk_users_email UNIQUE (email),
-- 为软删除字段创建部分索引
CONSTRAINT idx_users_deleted_at EXCLUDE WHERE (deleted_at IS NULL)
);
-- 为常用查询字段创建索引
CREATE INDEX idx_users_username ON users (username);
CREATE INDEX idx_users_email ON users (email);
CREATE INDEX idx_users_is_active ON users (is_active);
CREATE INDEX idx_users_role ON users (role);
-- 为软删除查询优化
CREATE INDEX idx_users_not_deleted ON users (id) WHERE (deleted_at IS NULL);
-- 注释
COMMENT ON TABLE users IS '系统用户表';
COMMENT ON COLUMN users.id IS '主键ID';
COMMENT ON COLUMN users.created_at IS '创建时间';
COMMENT ON COLUMN users.updated_at IS '更新时间';
COMMENT ON COLUMN users.deleted_at IS '删除时间(软删除)';
COMMENT ON COLUMN users.username IS '用户名';
COMMENT ON COLUMN users.email IS '电子邮箱';
COMMENT ON COLUMN users.password IS '密码哈希';
COMMENT ON COLUMN users.is_active IS '是否激活';
COMMENT ON COLUMN users.role IS '用户角色';
COMMENT ON COLUMN users.last_login IS '最后登录时间';
然后在与Cursor互动的时候,就可以直接 at 代码模版,让它照着写,并且最好还提供表结构或者是SQL语句,会有助于加速整个过程。
实战使用提示词参考:
请使用以下SQL定义,结合 @docs/backend/template/user-dao.md 描述和其对应的数据库表定义 @docs/backend/template/user-sql.md,它们是配套关系,按照这种配套逻辑,为我生成对应的 DAO层程序:
-- 用户操作日志表
CREATE TABLE user_operation_logs (
id BIGSERIAL PRIMARY KEY,
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
user_id INTEGER NOT NULL,
operation_type VARCHAR(50) NOT NULL,
operation_target VARCHAR(100) NOT NULL,
operation_detail TEXT,
ip_address VARCHAR(50),
user_agent TEXT,
status_code INTEGER,
request_method VARCHAR(10),
request_path VARCHAR(255),
parameters JSONB,
response_time INTEGER, -- 毫秒
error_message TEXT,
-- 外键约束(可选)
CONSTRAINT fk_user_operation_logs_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL,
-- 索引
CONSTRAINT idx_user_operation_logs_created_at_operation_type
EXCLUDE (operation_type WITH =, created_at WITH <)
);
-- 常用查询索引
CREATE INDEX idx_user_operation_logs_user_id ON user_operation_logs (user_id);
CREATE INDEX idx_user_operation_logs_operation_type ON user_operation_logs (operation_type);
CREATE INDEX idx_user_operation_logs_created_at ON user_operation_logs (created_at);
CREATE INDEX idx_user_operation_logs_status_code ON user_operation_logs (status_code);
CREATE INDEX idx_user_operation_logs_operation_target ON user_operation_logs (operation_target);
-- 复合索引
CREATE INDEX idx_user_operation_logs_user_operation ON user_operation_logs (user_id, operation_type);
CREATE INDEX idx_user_operation_logs_time_range ON user_operation_logs (created_at, operation_type, status_code);
-- 注释
COMMENT ON TABLE user_operation_logs IS '用户操作日志表';
COMMENT ON COLUMN user_operation_logs.id IS '主键ID';
COMMENT ON COLUMN user_operation_logs.created_at IS '操作时间';
COMMENT ON COLUMN user_operation_logs.user_id IS '操作用户ID';
COMMENT ON COLUMN user_operation_logs.operation_type IS '操作类型(login/create/update/delete等)';
COMMENT ON COLUMN user_operation_logs.operation_target IS '操作目标(用户/订单/产品等)';
COMMENT ON COLUMN user_operation_logs.operation_detail IS '操作详情';
COMMENT ON COLUMN user_operation_logs.ip_address IS '客户端IP地址';
COMMENT ON COLUMN user_operation_logs.user_agent IS '客户端User-Agent';
COMMENT ON COLUMN user_operation_logs.status_code IS 'HTTP状态码';
COMMENT ON COLUMN user_operation_logs.request_method IS 'HTTP请求方法';
COMMENT ON COLUMN user_operation_logs.request_path IS '请求路径';
COMMENT ON COLUMN user_operation_logs.parameters IS '请求参数(JSON格式)';
COMMENT ON COLUMN user_operation_logs.response_time IS '响应时间(毫秒)';
COMMENT ON COLUMN user_operation_logs.error_message IS '错误信息';
模块名:system
业务名:log
提示词模版
和代码模板一样,提示词模板也可以通过拖拽或 @ 引用的方式更便捷地使用:
这两种方法比手动复制粘贴更高效,并且能够保持模板的格式和结构完整性。你甚至可以同时引用提示词模板和代码模板,例如:
请使用 @templates/prompts/kratos-api-creation.md 提示词模板,
结合 @docs/backend/template/kratos-controller.md 代码模板,
为商品管理模块创建一个创建商品的API接口。
我已将占位符替换如下:
- 模块名称: 用户管理
- 功能描述: 创建新账户
- 接口路径: /api/users
- 请求方法: POST
...(其他替换内容)
这种组合使用方式可以让 AI 同时理解你的需求(通过提示词模板)和代码实现方式(通过代码模板),产出更符合预期的结果。
=== 提示词模板 - Golang API 接口创建 ===
**上下文信息:**
- 项目名称: [项目名称]
- 模块名称: [模块名称]
- 技术栈: Golang, Kratos, [数据库类型]
- 架构风格: RESTful API
**任务描述:**
请基于 Kratos 框架,为 [模块名称] 模块创建一个新的 API 接口,功能是 [功能描述]。
**接口路径:**
- [接口路径]
**请求方法:**
- [请求方法] (例如: GET, POST, PUT, DELETE)
**请求参数:**
- [请求参数描述] (包括参数名称、类型、是否必填、示例值等)
**响应数据:**
- [响应数据描述] (包括数据结构、字段名称、类型、示例值等)
**技术约束:**
- 数据库操作: 使用 [ORM 框架,例如 GORM] 进行数据库交互
- 数据验证: 使用 Kratos 内置验证器进行请求参数验证
- 错误处理: 统一返回 JSON 格式的错误响应
- 日志记录: 使用 Kratos 日志中间件
**期望输出:**
- 请生成完整的 Golang 代码,包括:
- Kratos 路由定义
- Protobuf 定义文件
- Service 层实现
- Repository 层实现 (如果需要)
- 请求参数结构体定义
- 响应数据结构体定义
- 接口功能的简要注释
**使用方法:**
请将方括号 `[]` 中的占位符替换为实际的项目信息和需求描述。
与Cursor的提问技巧
1. 把设计信息"揉"进提示里:把设计决策和架构要求都写进提示里。
根据我们的分层架构(Controller->Service->Dao),
实现用户注册功能,遵循以下规则:
- 所有验证在Service层进行
- 密码必须加密存储
- 返回统一错误格式
2. 上下文压缩技巧:用简短但信息量大的方式描述需求。
实现商品搜索API:
- 入参: 关键词、分类ID(可选)、价格区间(可选)、页码、每页数量
- 出参: 总条数、总页数、当前页商品列表
- 缓存: Redis, 5分钟
- 权限: 公开接口
3. 引导式提问:通过引导性问题帮 AI 理解项目上下文。
在开始写代码前,请思考:
1. 这个功能和现有的用户模块怎么交互?
2. 我们之前是怎么处理异步操作的?
3. 错误处理应该遵循什么模式?
【大模型介绍电子书】
要获取本书全文PDF内容,请在【黑夜路人技术】VX后台留言:“AI大模型基础” 或者 “大模型基础” 就会获得电子书的PDF。
默认主题
复制内容▼