AI编程工具核心功能测评:agents与commands对比
盯着项目里那个熟悉的.cursor目录,里面躺着一堆文件夹:agents、commands、memory、modes、rules、skills……这些名词见过无数次,但说实话,过去很长一段时间里,我对它们各自的职责边界只有一个模糊的印象。每次AI助手说要“切换模式”或者“激活技能”,我都点头附和,心里却在犯嘀咕:这玩意儿到底是干嘛的?
直到上周,一个React项目里的操作让我彻底翻车了。当时把一项“一次性任务”当成了“持久化记忆”存进了memory里,结果AI助手每次对话都去读取那些已经过期的任务状态,导致代码越改越乱。那一刻才真正意识到,过去的使用方式可能完全是错的。
作为业务开发,日常工作就是在代码、需求、Bug之间反复横跳。工作特点决定了:重复性高、上下文切换频繁、需要快速响应但又必须保证质量。这篇文章就来梳理一下,这几个模块到底该在什么场景下派上用场。读完你会明白,为什么有些团队用AI越用越顺手,而有些却越用越迷茫。
起因:一次失败的“记忆”实践
事情要从两周前说起。
那天正打算为一个模块添加重试逻辑,心血来潮想测试一下项目的memory功能。打开.cursor/memory目录,里面空空如也,灵机一动:不如把需求描述和设计方案都记进去,这样AI助手每次对话都能“记住”当前在做什么。
于是手写了这么一条memory:
---
name: retry-logic-task
type: project
---当前正在为支付模块添加重试逻辑,需要在 `PaymentService.ts` 中增加指数退避算法。
**Why:** 支付接口偶尔超时,用户投诉多。
**How to apply:** 每次修改支付相关代码时,都要考虑重试逻辑。
写完之后还挺得意,觉得这相当于给AI助手装了“长期记忆”。
结果呢?
三天后需求变了,重试逻辑先不做了,改成加个超时提示就行。但完全忘了更新memory。接下来的每次对话,AI助手都会热心地建议:“要不要考虑在PaymentService里加指数退避?” 甚至已经把超时提示写完之后,它还在提那个已经废弃的重试方案。
越改越火大,最后只能把整个memory目录清空了事。
这件事让人彻底清醒:memory不是用来存“当前任务”的,它存的是“持久的上下文和偏好”。
逐个厘清:每个模块的真正用途
带着失败的经验,决定重新梳理每个模块的定位。从项目根目录的.cursor开始,一个一个打开看。
首先是 agents:AI助手的“人格设定”
打开.cursor/agent.json,看到一个JSON配置文件,里面定义了一个叫joyspec的agent:
{
"agentId": "joyspec",
"source": "project",
"contentPath": "agents/JoySpec.md",
"isActive": true
}
再打开agents/JoySpec.md,好家伙,300多行的详细定义。核心部分是这样的:
---
name: "JoySpec"
whenToUse: "当需要基于规约文档进行结构化编程时使用此模式"
---你是 **JoySpec 规约工程师**。
你的主要职责是使用 JoySpec 方法论管理项目规约的生命周期。**角色:**
- 技术规约的架构师和管理者
- 项目范围和质量的守护者
- 结构化开发工作流的促进者
这意味着,agents定义的是AI助手的“角色人格”。它告诉AI助手:你现在是谁、你应该做什么、你的行为准则是什么。比如这个JoySpec agent,它的核心职责是“管理规约生命周期”,而不是“随手写代码”。
什么时候需要自定义agent?
- 有特定的开发流程(比如项目里的JoySpec规约驱动开发)
- 希望AI助手在某些场景下自动遵循特定规范
- 接入了特定的MCP服务(比如接了Figma、Excel、热点获取等一堆MCP)
什么时候不需要?
- 临时性的小任务
- 标准的代码编写、调试
- 自己都没想清楚要AI遵循什么规范
还有一个坑是 modes:场景化的“工作模式”
刚搞清楚agents,又被modes搞混了:这俩不是一回事吗?
打开.cursor/mode.json,看到:
{
"customModes": [
{
"agentId": "joyspec",
"name": "JoySpec",
"whenToUse": "当需要基于规约文档进行结构化编程时使用此模式"
}
]
}
看起来和agents差不多?但仔细看agentId字段——modes是agents的“场景化封装”。
打个比方:
- agents是“职业身份”:我是规约工程师
- modes是“工作模式”:现在我进入了“规约实施”模式
一个agent可以有多个modes。比如JoySpec agent下有这些modes:
- Propose:创建变更提案(规划阶段)
- Explore:思考伙伴模式(探索阶段)
- Apply:实施变更(执行阶段)
- Archive:归档变更(完成阶段)
一个踩过的坑:在Apply模式下搞探索。
有一次在Apply模式下(正在实施一个变更),突然想“顺便看看这个模块是怎么设计的”。AI助手立刻警告:“当前是Apply模式,不应该做探索性工作。”当时还不服气,觉得“看两眼又不会怎样”。结果AI助手读了一堆无关文件,Token消耗飙升,还差点把正在实施的任务搞混了。
从那以后学到的经验:不同阶段,切不同模式。
接着是 commands:预定义的“操作流程”
commands目录下有一堆joyspec-xxx.md文件:
joyspec-propose.md
joyspec-apply.md
joyspec-archive.md
joyspec-explore.md
...
打开joyspec-propose.md,看到一段详细的“操作手册”:
# joyspec-propose — 一键变更提案你是一个**变更架构师**。在一次调用中,你将创建一个新的 JoySpec 变更,
并生成 schema 要求的所有产物(proposal.md、design.md、tasks.md,以及 spec deltas)。## 工作流
1. **询问**用户想要构建或变更什么。
2. **创建变更脚手架**:`joyspec new change ""`
3. **检查变更 schema**:`joyspec status --change "" --json`
4. **循环 — 创建每个产物**
5. **最终状态**:`joyspec status --change ""`
commands是“可复用的操作流程”。像是给AI助手的“宏命令”——触发一次,它就按预定义的步骤一步步执行。比如joyspec-propose这个command,它会:询问用户要做什么、创建变更目录、生成所有必需的规划文档,最后显示状态供审查。
什么时候用commands?
- 有固定的、多步骤的工作流
- 希望减少每次对话的重复说明
- 需要确保每次操作都遵循相同规范
什么时候不用?
- 一次性的、简单的操作
- 流程还在摸索中,没固定下来
- 不想让AI助手“自动走流程”,想一步步交互
然后是 skills:场景化的“技能包”
skills目录下有这些文件:
code-review.md
doc-writer.md
test-gen.md
joyspec-apply-change/
joyspec-archive-change/
...
打开code-review.md:
---
name: Code Review
description: Provide comprehensive code review feedback
---You are an expert code reviewer. Your goal is to analyze the provided code diffs
and files to identify potential issues, suggest improvements, and ensure adherence
to best practices.Focus on:
1. Correctness
2. Security
3. Performance
4. Readability & Maintainability
5. Style
skills是“临时性的能力增强包”。和modes不同,skills不会改变AI助手的整体人格,只是给它加一个“临时技能”。比如:要写测试就激活test-gen skill,要写文档就激活doc-writer skill,要做代码审查就激活code-review skill。
一个真实案例:
上周要给一个复杂的计算模块写单元测试,直接让AI助手写,它给的测试用例很泛泛。后来激活了test-gen skill,它立刻变了样:先分析项目的测试框架(从package.json推断出用的是Jest),列出关键测试点(边界值、异常处理、性能),甚至给出了mock策略。
从那以后学到的经验:特定任务,先激活对应的skill。
还有 memory:持久的“上下文记忆”
这就是开头踩坑的地方。
重新理解后,memory的真正用途是这样的:
---
name: user_role
type: user
---我是前端工程师,熟悉 React 和 TypeScript,对后端不太熟。
**Why:** 帮助 AI 助手在解释后端概念时用前端类比。
**How to apply:** 涉及后端代码时,用"类似 React 的 useEffect"这种类比。
memory存的是“跨对话的持久信息”,不是“当前任务”。
适合存的内容:
- user 类型:角色、偏好、熟悉的技术栈
- feedback 类型:给过AI助手的反馈(“不要生成测试代码”、“少总结,多干活”)
- project 类型:项目的长期约束(“这周在冻结发布”、“法律要求token不能那样存”)
- reference 类型:外部资源的指针(“Bug在Linear的INGEST项目”、“性能看这个Grafana面板”)
不适合存的内容:
- 当前正在做的任务
- 临时性的状态
- 代码本身
后来的一条feedback memory示例:
---
name: a void-summarizing
type: feedback
---AI 助手不要在每次回复末尾总结"我做了什么",用户自己会看 diff。
**Why:** 用户反馈总结太冗余,浪费时间。
**How to apply:** 完成任务后直接结束,不要加"我刚才帮你修改了..."这段。
从那以后,AI助手真的不再总结了——这才是memory的正确用法。
最后是 rules
rules是“全局约束规则”,类似于.editorconfig或.eslintrc,用来定义一些全局行为规范。比如常量定义规范、开发基础规范、路由配置规范、目录配置规范等等。
方案演进:一张图搞清楚所有模块
这些模块的关系可以这样理解:
┌─────────────────────────────────────────────────────┐
│ .cursor/ 目录 │
├─────────────────────────────────────────────────────┤
│ │
│ agents/ 定义"角色人格" │
│ └─ JoySpec.md ← 我是规约工程师 │
│ │
│ modes/ 定义"场景化模式" │
│ └─ JoySpec ← 当前处于 Apply 模式 │
│ │
│ commands/ 定义"操作流程" │
│ ├─ joyspec-propose.md ← 创建提案的步骤 │
│ └─ joyspec-apply.md ← 实施变更的步骤 │
│ │
│ skills/ 定义"临时技能" │
│ ├─ code-review.md ← 代码审查技能 │
│ └─ test-gen.md ← 测试生成技能 │
│ │
│ memory/ 定义"持久记忆" │
│ ├─ user_role.md ← 用户是谁 │
│ └─ feedback_xxx.md ← 用户反馈 │
│ │
│ rules/ 定义"全局约束" │
│ └─ system_rules.md ← 系统级规则 │
│ │
└─────────────────────────────────────────────────────┘
调用链路是这样的:
- 发起请求:“帮我创建一个变更提案”
- AI助手识别关键词,匹配到
joyspec-proposecommand - 激活
JoySpecagent,进入对应的mode - 如果需要,激活特定的skill(比如
doc-writer) - 执行过程中,读取memory里的上下文
- 受rules里的全局约束限制
关键设计点:为什么这样划分
理解每个模块的用途后,开始思考:为什么要划分这么多模块?直接塞一起不行吗?
设计点 1:职责分离,避免混乱
如果所有东西都塞在一个文件里,结果就是:AI助手不知道当前是“谁”(agents),不知道应该按什么流程走(commands),不知道有没有临时技能加成(skills),还要读取大量无关的memory内容。职责分离后,AI助手可以精准加载需要的东西。
设计点 2:可插拔、可组合
比如code-review skill,可以在任何agent、任何mode下激活。在普通模式下能用,在JoySpec模式下也能用。这就像是“技能卡”,随用随插。
设计点 3:持久性分层
- agents / modes / commands / skills / rules:随项目代码提交,全团队共享
- memory:个人本地存储,不提交到Git
这样设计的好处是:团队协作和个人偏好两不误。
优化与踩坑:从失败案例反推规则
经过两周的实践,总结了这些规则:
规则 1:不要把临时任务存进 memory
- 错误:把“今天要加重试逻辑”存成 memory
- 正确:用
task_create_todolist管理临时任务
Why: memory是持久的,任务完成后不会自动清理。
规则 2:切换模式要明确告诉 AI 助手
- 错误:在Apply模式下突然开始探索代码
- 正确:先说“切换到Explore模式”,再开始探索
Why: 不同模式有不同的行为约束,混用会混乱。
规则 3:不要为了一致性强行用所有模块
- 错误:rules是空的,非要写几条没意义的规则
- 正确:够用就好,没用到就空着
Why: 过度设计会增加认知负担,违背“简化”初衷。
规则 4:feedback memory 要具体,不要抽象
- 错误:“要写得简洁”
- 正确:“回复末尾不要加总结段落”
Why: 抽象指令AI助手很难理解,具体指令才能执行。
规则 5:定期清理 memory
- 错误:memory文件越来越多,从不清理
- 正确:每周检查一次,删除过期的memory
Why: memory太多会降低检索效率,甚至引入噪音。
适用边界:谁适合用这些模块
特别适合的场景
- 团队协作项目:agents / commands / skills 可以统一团队的开发流程
- 长期维护的大型项目:memory 可以积累项目上下文,减少重复说明
- 有固定工作流的场景:比如 JoySpec 流程(Propose → Apply → Archive)
- 个人偏好明显:比如就是不喜欢 AI 助手总结,可以存进 feedback memory
不太适合的场景
- 一次性脚本:用不上这么复杂的机制
- 快速原型开发:流程还在变,不适合固化
- 简单的小项目:直接对话就够了,用不上这些模块
- 刚接触 AI 辅助编程:先熟悉基本对话,再上高级功能
真实案例:Before & After
Before:混乱的对话
场景:给支付模块加重试逻辑
我:帮我给支付模块加重试逻辑
AI:好的,我先看看你的支付模块……(读文件)
AI:我建议加个指数退避算法……
我:等等,上次我已经加了超时提示了,重试逻辑不做了
AI:哦,我没看到……让我重新读一下……
我:...
问题:AI助手不知道需求已变更,没有明确的记忆机制,每次对话都要重新说明上下文。
After:使用 memory + mode
Step 1:更新 memory
---
name: payment-module-context
type: project
---支付模块当前需求:只加超时提示,不加重试逻辑。
**Why:** 产品变更,重试逻辑暂时不做。
**How to apply:** 涉及支付模块时,不要建议重试相关代码。
Step 2:激活正确的 skill
我:用 doc-writer skill,帮我给支付模块的超时提示写个文档
AI:好的,我只针对超时提示功能写文档……
结果:AI助手自动避开重试逻辑,不用每次都重复说明,对话更高效。
入门指南:三步上手
如果看完觉得“有点意思”,想在自己的项目里试试,建议这样开始:
第一步:先观察,不要急着配置
打开项目的.cursor目录,看看:有哪些agents?(在agent.json里)、有哪些modes?(在mode.json里)、有哪些commands / skills?(在对应目录下)。不要一上来就改配置,先理解现有结构。
第二步:从一个 feedback memory 开始
想想最近给AI助手的反馈,比如:“不要每次都总结”、“生成代码前先问我”、“不要生成测试文件”。把这些写成feedback memory。
第三步:尝试激活一个 skill
下次要做特定任务时,试试先激活skill:
我:激活 code-review skill,帮我审查这段代码
AI:(读取 skill 定义,进入代码审查模式)
AI:我发现了三个安全问题……
不用一步到位,先从最常用的场景开始。
认知升级
之前以为AI辅助编程就是“写代码时有个智能助手”。
现在明白,真正高效的使用方式,是把AI助手当成一个可以定制、可以调教的协作伙伴。
- agents 定义了它的工作身份
- modes 定义了它的工作模式
- commands 定义了它的工作流程
- skills 定义了它的临时能力
- memory 定义了它的持久记忆
- rules 定义了它的全局约束
这些模块不是为了让AI更“聪明”,而是为了让它更“懂你”。
从那以后,在开始一个任务前,会先问自己三个问题:
- 这个任务需要什么角色?(选 agent / mode)
- 我有什么偏好要让它记住?(检查 memory)
- 需要什么特殊技能?(激活 skill)
回答完这三个问题,AI助手就不再是“通用助手”,而是“专属搭档”。
这就是AI辅助编程的真正用法:不是让它代替你思考,而是让它按你的方式思考。
附录 A:memory 文件模板
user 类型(用户画像)
---
name: user_role
type: user
---我是前端工程师,熟悉 React 和 TypeScript,对后端不太熟悉。
**Why:** 帮助 AI 助手用我熟悉的方式解释概念。
**How to apply:** 涉及后端时,用前端类比(如"类似 React 的 useEffect")。
feedback 类型(用户反馈)
---
name: no-summary
type: feedback
---AI 助手不要在回复末尾总结做了什么。
**Why:** 用户会自己看 diff,总结浪费时间。
**How to apply:** 完成任务后直接结束,不要加"我刚才修改了..."这段。
附录 B:常用 skills 快速参考
| Skill 名称 | 用途 | 何时激活 |
|---|---|---|
code-review | 代码审查 | 完成代码后,请求审查时 |
doc-writer | 文档编写 | 需要写 JSDoc、README 时 |
test-gen | 测试生成 | 需要写单元测试时 |
joyspec-propose | 创建变更提案 | 规划新功能时 |
joyspec-apply | 实施变更 | 开始编码时 |
joyspec-explore | 探索代码 | 想理解架构时 |
附录 C:常见问题
Q:memory 和对话上下文有什么区别?
A:对话上下文只在当前对话有效,关闭就没了。memory 跨对话持久化,下次打开还在。
Q:modes 和 skills 有什么区别?
A:modes 改变 AI 助手的整体行为模式,skills 只是临时加个能力。比如从“实施模式”切换到“探索模式”是 mode 切换,而“激活代码审查技能”是 skill。
Q:rules 和 feedback memory 有什么区别?
A:rules 是全局约束,提交到 Git,全团队共享。feedback memory 是个人偏好,存本地,不影响他人。
Q:我的项目没有这些模块,需要自己建吗?
A:先从 feedback memory 开始,其他模块等有明确需求再建。不要为了用而用。
写在最后:
AI 辅助编程的效率提升,不取决于 AI 有多聪明,而取决于你有多会“调教”它。
这些模块,就是调教的工具。用好它们,AI 助手才能从“通用助手”变成“专属搭档”。