如何使用 AI 全流程驱动的前端开发,看这一篇就够了
这篇文章记录的是我在一个已有的 Vue3 OA 系统上,逐步把一个“传统前端项目”改造成 AI 全流程协作项目的过程。项目本身不是为 AI 时代准备的,没有现成的规范、没有结构化的上下文、也没有什么“开箱即用的智能研发体系”。说白了,它一开始就是一个正常能跑、但 AI 一接手就容易乱改的老项目。
我做的事情其实不复杂:不重构业务、不换技术栈,主要是把项目里的隐性知识整理成 Rules、Skills 和 OpenSpec,让 AI 后续参与需求开发时不再靠猜。
一、问题不是 AI 不会写代码,而是它根本不认识这个项目
这个项目是一个基于 Vue3 + Vite + Pinia + Element Plus 的 OA 前端,功能不算少:考勤管理、通知管理、员工管理、AI 对话、大文件上传,都是实打实的业务模块。
代码本身没什么问题,真正让我头疼的是另一件事:每次把 AI 拉进来帮忙干活,都像在给一个新入职、但是记忆只有一轮对话的同事做 onboarding。
今天要解释:
- 目录结构怎么分
src/api/里接口按什么逻辑拆OA前缀组件是什么意思- JWT 刷新逻辑在哪
- commit message 为什么必须是中文动宾结构
明天开一个新会话,这些东西还得再说一遍。
更离谱的是,AI 有时候会表现出一种非常自信的状态,看起来像是“懂了”,实际上属于“懂了一点,但决定全部自由发挥”。这种情况放在聊天里还算可爱,放在老项目里就容易出事故。
所以我想做的不是“让 AI 更聪明”,而是“让 AI 更守规矩”。
我最后沉淀出来的思路,基本就是这三步:
第一步:把老项目里散落的经验和约定,整理成 Rules 和 Skills
第二步:把新需求接入 OpenSpec,让需求从一开始就有结构
第三步:在真实需求里跑通 propose -> explore -> apply -> archive 闭环
流程概览:
二、先别急着让 AI 改代码,先让它知道什么叫“别乱改”
2.1 Rules 是什么
Cursor 的 Rules 本质上就是项目级的长期提示词,但比临时 prompt 更稳定,也更像制度。
它通常放在 .cursor/rules/ 目录下,用 .mdc 文件维护。作用很直接:把那些原本只能靠口口相传的开发约定,变成 AI 每次都能读到的上下文。
比如一条很典型的规则可以写成这样:
---
description: Vue 组件开发规范
globs: src/**/*.vue
alwaysApply: false
---
# Vue Rules
- 使用 Composition API(script setup)
- 组件命名使用 OA 前缀,如 OAPageHeader、OADialog
- 事件命名使用 kebab-case
第一次看到这个东西的时候,我的感受很直接:这不就是给 AI 写员工手册吗。
区别在于,员工手册写了不一定有人看,Cursor Rule 写了,AI 大概率真会看。
2.2 老项目里的 Rules 从哪来
很多人一说“给项目建规则”,第一反应是“我们项目没有规范”。
实际上大多数老项目不是没有规范,而是规范都藏起来了。
它们通常藏在三个地方:
- 团队默认约定里
- 某位老同事的脑子里
- 历史代码里反复出现的模式里
我当时提取 Rules,主要也是按这三个方向去抠。
第一类:编码约定
比如这个 OA 项目里,有些模式重复得非常明显:
- 通用组件统一用
OA前缀 - API 接口按业务放在
src/api/下 - JWT 认证和刷新逻辑统一走
http.js - 路由权限依赖
meta.permissions+opt
这些内容,如果不写成 Rule,AI 靠猜基本猜不准。
它可能能写出“能跑的代码”,但很难写出“像这个项目里本来就会有的代码”。
而我真正想要的是后者。
第二类:文档约定
这个项目不只是拿来做功能,还承担了一个很现实的任务:面试复习。
所以我专门加了一条文档规则,要求 AI 产出的总结、复盘、博客类文档:
- 统一写到
docs/下面 - 用主人公口吻来写
- 不要写成和我对话的语气
- 风格尽量贴近掘金技术博客
这个规则后来我改成了只对 docs/**/*.md 生效。
原因很简单,我不希望 AI 在排查定时任务失败的时候,突然写出一股“今天来聊聊 cron 表达式为什么总在凌晨背刺我”的博客味。气氛是活跃了,问题没解决。
第三类:提交约定
提交规范也很适合变成 Rule。
比如这个项目里,commit message 不是随便写的,而是明确要求:
<type>(<scope>): <subject>
而且 subject 还是中文、动宾结构、不能乱写。
这种约束如果不提前告诉 AI,它很容易给出一种看起来很工整、但实际上完全不符合团队习惯的提交信息。
比如 update code 这种提交信息,放在个人练习仓库里也许还能自我安慰一下,放在团队项目里就属于“谁看谁沉默”。
2.3 Rules 有四种生效方式,别一上来就全局生效
Cursor 里的 Rule 可以有四种触发方式:
| 方式 | 含义 | 适合场景 |
|---|---|---|
Always Apply | 每次对话都生效 | 全局约束,比如语言、提交规范 |
Apply Intelligently | AI 自己判断是否相关 | 低频但有价值的规则 |
Apply to Specific Files | 命中文件时才生效 | 文档、Vue、测试文件的专项规范 |
Apply Manually | 手动引用时才生效 | 迁移指南、发布流程、专项排查手册 |
我一开始犯过一个很典型的错误,就是把文档规则设成了全局。
结果就是:AI 改代码的时候,也带着一股“掘金创作中心正在加载”的气质。
后来我立刻把它收窄到 docs/**/*.md,世界清净了很多。
这件事给我的经验是:Rule 写得越具体,副作用越小;Rule 生效范围越精确,AI 越像一个专业协作者,而不是一个热情过度的实习生。
三、Skill 才是真正让 AI“会干活”的那一层
如果说 Rule 解决的是“别乱来”,那 Skill 解决的就是“到底该怎么来”。
3.1 Skill 是什么
Skill 可以理解成一套工作流说明书。
它不是单纯告诉 AI 一条规范,而是把某类任务的完整执行步骤写清楚。
Skill 通常放在 .cursor/skills/ 下,每个 Skill 对应一个目录,核心文件是 SKILL.md。
在这个项目里,我主要配了四个和 OpenSpec 相关的 Skill:
.cursor/skills/
├── openspec-propose/SKILL.md
├── openspec-explore/SKILL.md
├── openspec-apply-change/SKILL.md
└── openspec-archive-change/SKILL.md
它们分别对应四个动作:
- 新需求先建 proposal
- 方案不确定时先 explore
- 确认后按 tasks 实施
- 完成后 archive 归档
也就是说,Skill 不是在教 AI“写什么”,而是在教 AI“按什么顺序做、做到哪一步停、什么情况要先问人”。
3.2 怎么创建自己的 Skill:/create-skill
Cursor 内置了一个 /create-skill 命令,专门用来创建新的 Skill。
用法很直接:在对话里输入 /create-skill,AI 会引导完成以下几步:
- 确认用途:这个 Skill 要教 AI 做什么
- 确认存储位置:
- 个人级:
~/.cursor/skills/<skill-name>/SKILL.md(所有项目通用) - 项目级:
.cursor/skills/<skill-name>/SKILL.md(跟着仓库走,团队共享)
- 个人级:
- 确认触发方式:什么场景下 AI 应该使用这个 Skill
- 生成
SKILL.md:包含 frontmatter 和具体执行步骤
生成出来的 SKILL.md 大概是这个结构:
---
name: my-custom-skill
description: 描述这个 Skill 做什么、什么时候该用它
---
# Skill 标题
## 执行步骤
1. 第一步做什么
2. 第二步做什么
3. ...
这里有个细节值得注意:description 字段非常关键。Cursor 决定是否自动调用某个 Skill 时,主要就是靠这个字段做语义匹配。所以写 description 的时候,最好同时写清楚两件事:
- WHAT:这个 Skill 能做什么
- WHEN:什么场景下应该触发
比如写成 "生成标准化的 Git commit message。在用户要求提交代码或 review 暂存区变更时使用" 就比单纯写 "帮助提交代码" 好得多。
我在这个项目里用 /create-skill 没有创建太多自定义 Skill,因为 OpenSpec 相关的四个 Skill 已经覆盖了主要流程。但如果团队有一些高频操作(比如固定的发布流程、特定的 code review checklist、数据库迁移步骤),完全值得用这个命令封装成 Skill。
3.3 用 skills.sh 发现社区现成的 Skill
除了自己写,还有一个更省事的路径:直接用社区里别人已经写好的 Skill。
skills.sh 是目前最活跃的 Agent Skill 开放市场,上面有大量现成的 Skill 可以一键安装,相当于 AI 能力的 npm。
安装方式非常简单,一行命令:
npx skills find 寻找命令名
安装:
npx skills add <skill-owner>/<skill-repo>/<skill-name>
比如要装 Vercel 官方出的 React 最佳实践:
npx skills add vercel-labs/agent-skills/vercel-react-best-practices
或者装 Anthropic 官方的前端设计指南:
npx skills add anthropics/skills/frontend-design
| Skill | 来源 | 用途 |
|---|---|---|
find-skills | vercel-labs | 让 AI 自己去 skills.sh 搜索并安装 Skill(套娃属性拉满) |
vercel-react-best-practices | vercel-labs | React 组件设计和性能优化最佳实践 |
frontend-design | anthropics | 前端 UI/UX 设计指南 |
systematic-debugging | obra | 系统化调试流程,不让 AI 瞎猜 |
vue-best-practices | hyf0 | Vue 组件开发最佳实践 |
vue | antfu | Vue 生态工具链(antfu 出品,懂的都懂) |
vite | antfu | Vite 构建配置最佳实践 |
test-driven-development | obra | TDD 工作流 |
其中 find-skills 这个 Skill 比较有意思:装上之后,AI 自己就能去 skills.sh 搜索和安装新的 Skill。等于给 AI 装了一个"自己找工具"的能力。有一种"我给 AI 装了一个让它自己装插件的插件"的递归感。
我的建议是:先去 skills.sh 上看看有没有现成的,没有再自己写。 社区 Skill 经过了大量用户验证,质量通常比自己从零写更稳定。自己写的 Skill 更适合处理那些和项目业务强绑定的流程——比如"我们团队的发版流程"这种东西,外面肯定找不到现成的。
3.4 为什么老项目值得拆出自己的 Skills
老项目最痛苦的一点,是流程往往存在,但没人把流程写下来。
比如很多团队其实都默认遵守下面这套步骤:
- 先看产品文档和接口文档
- 再确认影响范围
- 不确定的地方先讨论方案
- 确认后再拆任务实施
- 做完补文档,最后归档
问题在于,这些东西平时靠“默契”运行,一旦换成 AI,就会发现默契这种东西没有 API。
所以我后来非常认同一件事:想让 AI 真正接入老项目,不只是把规则抽出来,还要把流程抽出来。
Rules 抽的是“项目约束”,Skills 抽的是“团队动作”。
3.5 Rules 和 Skills 怎么分工
我后来给自己定了一个很粗暴但很好用的判断标准:
- 如果这句话是在说“不要怎么做”,那大概率是 Rule
- 如果这句话是在说“遇到这种事你按什么步骤做”,那大概率是 Skill
比如:
- “文档统一写在
docs/” 是 Rule - “先创建 change,再生成 proposal/design/tasks/spec” 是 Skill
- “commit message 必须符合规范” 是 Rule
- “所有任务完成后再 archive” 是 Skill
这样分清之后,整个 AI 协作体系就清晰很多。
四、OpenSpec 才是把新需求接进来时最关键的一环
光有 Rules 和 Skills,还不足以让 AI 在真实需求里稳定工作。
因为一个需求从“我有个想法”到“代码上线”,中间天然会经历很多信息变化:
需求会补充,设计会调整,任务会拆分,验收标准也会逐渐清晰。
如果这些过程都只停留在聊天记录里,那 AI 再聪明也会丢上下文。
这时候就轮到 OpenSpec 上场了。 初始化 OpenSpec 的命令是:
openspec init
它会在项目根目录下创建 openspec/ 目录,包含 project.md、config.yaml 等基础文件。
4.1 OpenSpec 到底是什么
我更愿意把 OpenSpec 理解成一种“把需求过程文件化”的方式。
它不是业务框架,也不是组件库,而是一组目录和文件约定,用来把一个需求从想法、方案、任务到验收标准全部落成文档。
这个项目里的结构大概是这样(没有的需要使用命令):
openspec/
├── project.md
├── config.yaml
├── specs/
│ └── chat-markdown-render/
│ └── spec.md
└── changes/
├── add-voice-input-aichat/
│ ├── .openspec.yaml
│ ├── proposal.md
│ ├── design.md
│ ├── tasks.md
│ └── specs/voice-input/spec.md
└── archive/
└── 2026-03-04-render-chat-markdown/
第一次把它跑起来的时候,我最大的感受不是“这个东西好高级”,而是“终于不用靠聊天记录找需求上下文了”。
4.2 OpenSpec 里最重要的四类文件
proposal.md:先说清楚要做什么
这个文件回答的是两个问题:
- 为什么要做
- 这次准备改什么
比如项目里那个“AI 对话加语音输入”的 change,proposal 里写的不是实现细节,而是业务背景:
- 用户输入成本高,尤其移动端
- 目标是增加语音输入能力
- 语音按钮放在发送按钮右侧
- 不支持的浏览器要显示禁用状态
这一步很重要,因为很多需求一上来就开始讨论技术方案,最后做着做着发现,连问题本身都没定义清楚。
design.md:把关键决策说人话
这个文件回答的是“打算怎么做,以及为什么这么做”。
还是语音输入这个例子,design 里会明确写:
- 为什么选 composable,而不是普通工具函数
- 为什么识别结果直接写入
inputText - 为什么只支持
zh-CN - 浏览器不支持时怎么降级
- 录音按钮在 UI 上放哪里
我很喜欢 design 这一步,因为它会逼着整个方案把“我觉得这样做比较好”翻译成“为什么这里必须这样做”。
这两句话看起来差不多,含金量完全不是一个级别。
tasks.md:把大需求拆成能真正落地的小块
tasks 的价值在于防止 AI 一上来就做“整体优化”。
只要没有任务拆分,AI 就很容易陷入一种熟悉的节奏:
“我已经理解需求了,接下来我将对多个模块做综合调整。”
这句话一出现,基本就要提高警惕了。
而 tasks.md 的好处是,所有工作都被拆成 checkbox:
- 安装依赖
- 创建组件
- 配样式
- 集成页面
- 做测试
- 检查提交
这样 AI 的行为会被限制在一个个明确的小目标里,不容易一脚油门直接冲到不可描述的地方。
spec.md:最后用行为来定义“做完”
spec.md 更像验收标准,而不是设计方案。
它关心的是结果行为,比如:
- WHEN 用户在 Chrome 打开页面,THEN 按钮可见且可点击
- WHEN 用户正在录音再次点击按钮,THEN 录音停止
- WHEN AI 正在流式输出,THEN 语音按钮禁用
我很喜欢这种写法,因为它能把“感觉差不多做完了”这种危险的主观判断,替换成“哪些场景必须成立”的客观标准。
对前端来说,这一点尤其重要。
毕竟“我本地看着没问题”和“真的没问题”之间,历史上一直隔着不少事故。
4.3 为什么不直接让 AI 开干
这个问题我一开始也想过。
既然 AI 已经很会写代码了,为什么还要 proposal、design、tasks、spec 这一套,看起来好像流程变长了?
后来我在项目里踩了几次坑,就彻底想明白了。
直接让 AI 写代码,最容易遇到三类问题:
- 需求边界不清,AI 很容易顺手多做一点
- 设计没有记录,做完后自己都讲不清楚为什么这么实现
- 下次要复盘时,只能去翻聊天记录,体验堪比考古
而 OpenSpec 的价值恰恰在于:它不是让开发变慢,而是把原来混在聊天里的过程,变成可复用、可追溯、可复盘的资产。
五、真实落地时,我是怎么让一个新需求走完整个 AI 流程的
说完概念,下面直接讲我在项目里实际怎么跑。
这一套流程并不是“理想状态下应该如此”,而是我在老项目里试出来以后,觉得最稳的一条路径。
5.1 先从共享仓库拿文档,而不是直接开写
我这里前后端不是一个仓库,但有一个共享的 Git subtree,用来存产品文档、后端接口说明和一些公共 Markdown 资料。
所以每次接到新需求,我第一步不是让 AI 写代码,而是先把共享文档同步下来。
git subtree pull --prefix=docs/shared shared-docs main --squash
这样做的好处很直接:
- AI 在 propose 阶段就能读到后端接口约束
- explore 的时候能看到产品文档,而不是靠我口述
- 后续写 design 时,方案更容易贴近真实上下文
这一步非常像正式开发里的“先对齐需求资料”。
只不过以前是人看文档,现在是把文档也喂给 AI 看。
5.2 后端没好之前,先把 mock 顶上
如果一个需求要依赖后端接口,但后端那边还没开发完成,我会先准备 mock 数据。
这件事在 AI 流程里也很关键,因为没有 mock,很多前端需求就只能停在 proposal 或 design,落不到 apply 阶段。
我通常会这么处理:
const useMock = import.meta.env.VITE_USE_MOCK === 'true'
export async function fetchMessages(sessionId) {
if (useMock) {
return mockMessages[sessionId] || []
}
return http.get(`/chat/sessions/${sessionId}/messages/`)
}
有了 mock 以后,整个开发流程就顺了很多。
前端继续推进,后端慢慢补,谁也别耽误谁。大家各自体面。
5.3 用 /openspec-propose 把“想法”变成正式 change
文档和 mock 准备差不多之后,我会用 /openspec-propose 创建新需求。
这一步最舒服的地方在于,不需要先写一大坨正式文档。
只要把需求说清楚,哪怕是一段自然语言,AI 也能基于现有项目上下文帮忙起草第一版 change。
比如我会直接这样描述:
给 AI 对话页面添加 Markdown 渲染功能,支持代码高亮、表格、列表。流式输出时先显示纯文本,完成后切换为渲染结果。
然后 AI 会开始做这些事:
- 创建
openspec/changes/<change-name>/ - 生成
proposal.md - 生成
design.md - 生成
tasks.md - 生成对应 capability 的
spec.md
这一步的体验很像:我不再是让 AI 直接“写功能”,而是先让它和我一起把需求立项。
5.4 用 /openspec-explore 先把不确定的地方聊透
提案出来之后,如果方案里有不确定的点,我不会立刻进入 apply,而是先跑一轮 /openspec-explore。
这个模式特别适合处理那种“不是不会做,而是不知道哪种做法更值”的问题。
比如我在 Markdown 渲染这个需求里,就认真问过一个问题:
流式输出过程中,到底要不要实时渲染 Markdown?
乍一看,实时渲染好像更“高级”。
但一细想就会发现问题很多:
- Markdown 可能还没输完整
- 代码块可能只有开头没有结尾
- 页面容易闪烁、跳动
- 半截表格渲染出来像事故现场
最后 explore 的结论是:
- 流式过程中先按纯文本显示
- 流结束后再统一渲染 Markdown
这个决策后面被写进了 design.md,实施的时候就不需要再来回讨论。
这也是我现在很喜欢 explore 阶段的原因。
它能把很多本来会在开发中途爆炸的问题,提前拆掉。
5.5 用 /opsx-apply 或 /openspec-apply-change 正式实施
方案确认后,才轮到实施。
我现在一般直接用 /opsx-apply这一步非常适合在agent聊天框挂载一些相关业务与组件的skill,代码错误能够大大降低),本质上就是让 AI 按 tasks.md 一项一项往下做。
它会先读取:
proposal.mddesign.mdtasks.mdspec.md
然后按顺序执行任务,并且每完成一项,就把 checkbox 从 - [ ] 改成 - [x]。
这一步的好处特别明显:AI 的行为会变得非常收敛。
它不再是“我理解了整个系统,我准备优化一下相关模块”,而是:
- 现在做 2.1
- 做完勾掉
- 再做 2.2
- 如果遇到阻塞,就停下来说明情况
说得直白一点,就是终于从“自由发挥”切回了“按单施工”。
而对老项目来说,这种克制其实比聪明更重要。
5.6 全部完成后,用 /openspec-archive-change 收尾
最后一步是归档。
这个动作看起来只是把目录移动到 archive/,但我后来越来越觉得,它其实是整个流程里很关键的一步。
归档时会做几件事:
- 检查 artifacts 是否完整
- 检查
tasks.md里的任务是否都完成 - 把变更后的 spec 同步到
openspec/specs/ - 把整个 change 目录迁移到
openspec/changes/archive/<date>-<name>/
归档之后,这次需求的来龙去脉就都留住了:
- 为什么做
- 怎么设计
- 如何拆任务
- 验收标准是什么
以后再遇到类似需求,或者面试时想讲这个项目,根本不用回忆,直接翻归档文档就行。
这时候才会真正体会到一句话:文档不是为了写给别人看,有时候是为了防止未来的自己失忆。
六、几个我确实踩过的坑
6.1 Rule 不是越大越好,越“全能”越危险
早期我总想一条 Rule 管很多事,结果很快就发现,AI 会把不同场景下的要求混在一起执行。
最典型的一次,就是文档规则设成了全局生效。
结果 AI 连排查问题时都能写出博客腔,像是在一边 debug 一边准备参加内容创作激励计划。
后来我的做法很简单:
- 全局规则只放全局约束
- 文件级规则就老老实实绑
globs - 一条 Rule 只讲一个主题
Rule 这东西,宁可多几条,也别写成万能大礼包。
6.2 openspec/project.md 必须持续维护
openspec/project.md 相当于项目总说明。
如果它过时了,后面的 proposal、design、tasks 都会建立在错误上下文上。
这就像把一个地图版本是去年的导航拿来开新路,方向感再强也容易带沟里。
所以我后来把它当成一个要持续维护的文件,而不是“初始化完就再也不看”的摆设。
6.3 简单需求可以直上,复杂需求千万别跳过 explore
我一开始对 explore 是有点怀疑的,总觉得这一步像在“多聊一轮天”。
后来发现,不是它多余,而是我低估了“提前讨论设计边界”这件事的价值。
尤其是这种情况:
- 涉及选型
- 涉及多模块联动
- 涉及 UI 和状态交互
- 涉及兼容性和降级
这种需求要是直接 apply,返工概率会明显上升。
所以我现在的判断标准很简单:
- 小需求、局部改动,可以少走一步
- 复杂需求、边界不清,一定先 explore
6.4 归档真的不是形式主义
以前我会觉得 archive 有点像“开发仪式感”,可做可不做。
现在完全不会这么想了。
因为归档之后,项目会留下真正可复用的东西:
- 稳定的 spec
- 已经验证过的设计思路
- 一次完整需求的上下文链路
这些东西在后续需求里都会继续发挥作用。
而且对准备面试的人来说,它几乎就是现成的复盘材料库。
七、最后总结一下:这套流程改造的到底是什么
表面上看,我做的是三件事:
- 用 Rules 把老项目的隐性知识显性化
- 用 Skills 把老项目的团队流程结构化
- 用 OpenSpec 把新需求的生命周期文档化
但更底层一点看,这套改造真正改变的其实不是代码,而是协作方式。
以前的模式是:
- AI 进来
- 我临时补背景
- 它开始写
- 写偏了再拉回来
现在的模式是:
- 项目先把规则和上下文准备好
- 新需求先进入结构化流程
- AI 按流程读文档、提方案、拆任务、做实现
- 做完以后还能留下完整的可复用资产
整个改造成本其实不高,不需要推翻现有业务,也不需要大改工程体系。
真正需要投入的,是把那些原本只存在于脑子里的经验,认真写下来。
这也是我们团队过去两个月一直在做的实践,并且已经取得了不错的效果。具体统计下来:代码的实现效率提升了 50%,原先计划两周的迭代开发时间缩短到了一周,并且是在不加班、不占用额外资源的情况下实现的。最关键的是,这种模式下,AI 的参与感很强,它不再是简单的工具,而是真正理解项目、遵守规则、按流程做事的协作者。而前端与后端花的最多的时间也不再是编码,而是需求分析、方案讨论、文档整理。顺带提一下:使用这种流程最好不要使用国产模型,因为国产模型目前在这方面还不够成熟,这也是我们多次总结出来的,推荐使用 GPT 系与 Claude 系模型。
最后说一下,我们团队也正在准备将这套流程推广到其他项目,并且已经取得了不错的效果。现在我最近的工作也由闷头开发代码,变成了总结老项目的业务并把这些业务抽离到 skills 与共享仓库中。
这件事一开始看起来有点“麻烦”,但做完之后会发现非常值。
因为 AI 最怕的,从来不是需求复杂,而是上下文混乱。
而我这套实践最后想解决的,正是这个问题:
怎么让 AI 不只是一个会生成代码的工具,而是一个真正理解项目、遵守规则、按流程做事的协作者。