znlgis 博客

GIS开发与技术分享 — GDAL · GeoServer · PostGIS · QGIS · OpenLayers · Cesium · FreeCAD · NPOI

第十章:典型工作流实战

本章将前面九章的所有知识点串联起来,通过真实的开发场景,展示如何在不同任务中高效使用 OpenCode × DeepSeek 多 Agent 协作框架。每种工作流都配有详细的模拟对话,让你可以直观地看到 Orchestrator 如何自动路由、各个 Agent 如何协作、以及命令别名如何加速日常操作。

读完本章后,你将能够在日常开发中自如地选择正确的工作流,最大化这套配置的效率。

本章所有对话示例均为模拟演示,展示了理想的交互流程。实际使用中,Orchestrator 的路由决策和 Agent 输出会根据具体上下文有所变化。


10.1 工作流设计理念

10.1.1 两种使用模式

本配置方案支持两种核心使用模式,各有适用场景:

模式 输入方式 路由机制 适用场景
Orchestrator 自动路由(默认) 自然语言直接描述需求 Orchestrator 分析意图 → 自动选择 Agent → 必要时调度子 Agent 日常开发、探索性任务、不确定该用什么 Agent
命令别名直达 / 开头的自定义命令 跳过 Orchestrator 分析,直接启动指定 Agent 明确知道任务类型、追求极致效率、重复性操作

10.1.2 模式选择建议

优先使用自动路由的场景:

  • 你是新手,还不熟悉 10 个 Agent 各自擅长的领域
  • 任务边界模糊,可能同时涉及探索、分析和实现
  • 想利用 Orchestrator 的多 Agent 并行调度能力

优先使用命令别名的场景:

  • 你清楚地知道当前任务需要哪个 Agent(如”做个代码审查”→ /review
  • 执行高频重复操作(如提交代码 → /commit
  • 任务非常明确,不需要 Orchestrator 额外分析(如”把这个文件里的 foo 改成 bar“→ /quick

实际操作中的典型节奏是:

  1. 复杂任务:先用自然语言让 Orchestrator 分析 → 发现需要实现 → Orchestrator 调度 deep-worker → 完成后 /review 审查 → /commit 提交
  2. 简单任务:直接 /quick "改个变量名" 一步到位

10.1.3 理解 Orchestrator 的调度决策

当你用自然语言描述任务时,Orchestrator 内部的分析过程大致如下:

用户输入:"我有一个登录超时的问题,帮我排查一下"

Orchestrator 内部分析:
├── 意图分类:诊断调试(Bug排查)
├── 复杂度评估:中等(涉及代码层面分析)
├── 路由决策:oracle(深度分析能力)
├── 技能自动加载:
│   ├── diagnose(6阶段结构化调试)
│   └── systematic-debugging(系统化调试方法)
├── 预估步骤:3-5步
└── 可能需要的后续 Agent:deep-worker(修复)、reviewer(审查)

这个分析过程对用户完全透明 —— 你只需要用自然语言描述需求,Orchestrator 自动处理剩下的。


10.2 开发新功能(规约驱动工作流)

这是本配置方案中最完整、最正式的工作流,适合中大型功能的开发。它遵循 规约驱动开发(Spec-Driven Development) 的理念 —— 先想清楚要做什么、怎么做,再动手写代码。

10.2.1 工作流全景图

/explore        → 探索现有代码结构
  ↓
/propose        → 起草变更提案(proposal.md + design.md + specs/ + tasks.md)
  ↓
/apply          → 按任务清单逐步实现
  ↓
/review         → 多维度代码审查
  ↓
/archive        → 归档 delta spec,合入主规范

每一步都可以单独执行,也可以连贯推进。如果某一步发现问题,可以随时回退到前一步修正。

10.2.2 各阶段详解

阶段一:探索(/explore)

目的:在动手之前,先全面理解现有代码的结构和相关模块。

路由过程

  1. Orchestrator 接收 /explore 命令
  2. 自动路由到 explore Agent(Flash 模型,快速搜索)
  3. Orchestrator 可能同时启动多个 explore 子 Agent 并行探索不同模块
  4. 加载 codemap 技能生成仓库结构图
  5. 产出代码库探索报告

最佳实践

  • /explore 后附带明确的探索范围(如”探索用户认证相关的所有模块”)
  • 让 explore 关注文件和符号级别的信息,不要让它做代码审查
  • 如果探索范围很广,Orchestrator 会自动分解为多个并行探索任务

模拟对话 —— 探索阶段

用户: /explore 我想加一个用户收藏文章的功能,帮我先看看现有的文章和用户模块

(Orchestrator 内部分析)
意图:代码库探索
复杂度:中等 —— 需要探索多个模块
策略:并行启动 3 个 explore 子 Agent

(explore #1:探索文章模块)
正在搜索 articles/ 相关的模型、路由和控制器...
发现:
  - models/article.model.ts (234行):文章数据模型,包含 title/content/authorId/tags 字段
  - routes/article.routes.ts (56行):文章路由,GET /api/articles, POST /api/articles 等
  - controllers/article.controller.ts (189行):文章控制器,含 create/getById/list/update/delete
  - services/article.service.ts (312行):业务逻辑层,含全文搜索、分页等

(explore #2:探索用户模块)
正在搜索 users/ 相关的模型和关系...
发现:
  - models/user.model.ts (145行):用户模型,包含 username/email/role 字段
  - models/user.model.ts:87 存在与 Article 的关联:User.hasMany(Article, { foreignKey: 'authorId' })
  - 当前没有收藏(favorite/bookmark)相关的表和关联

(explore #3:探索数据库迁移历史)
正在查找迁移文件...
发现:
  - migrations/ 目录下有 12 个迁移文件
  - 最近一次迁移是 2025-06-15-003-add-tags-to-articles.ts
  - 数据库使用 PostgreSQL,通过 Sequelize ORM 操作


Orchestrator(综合报告):

【探索报告 —— 用户收藏文章功能】

现有结构:
1. Article 模型位于 models/article.model.ts,包含字段:id/title/content/authorId/tags/createdAt/updatedAt
2. User 模型位于 models/user.model.ts,与 Article 通过 authorId 做了一对多关联
3. 当前数据库中没有收藏相关的表,需要新建

关键发现:
- User 与 Article 的关联在 user.model.ts:87 行
- 文章列表接口支持分页(article.service.ts:142)
- 认证中间件在 middlewares/auth.middleware.ts

建议下一步:/propose 起草变更提案

阶段二:提案(/propose)

目的:基于探索报告,草拟完整的变更方案,包括需求、设计、任务拆分。

路由过程

  1. Orchestrator 接收 /propose 命令
  2. 自动路由到 planner Agent(Pro 模型,深度推理)
  3. 加载 spec-workflow 技能,按规范流程产出
  4. 产出文件:proposal.mddesign.mdspecs/ 目录、tasks.md

产出物说明

文件 内容 作用
proposal.md WHY —— 为什么要做,业务价值,影响范围 确保每个人理解变更的动机
design.md HOW —— 技术方案、架构决策、数据模型 确保技术方案被评审过
specs/<feature>/ WHAT —— 功能的行为规范、接口定义 确保实现有据可依
tasks.md 有序的任务清单,每个任务小而可验证 确保实现步骤清晰可跟踪

模拟对话 —— 提案阶段

用户: /propose

(Orchestrator 路由到 planner Agent)
planner:正在基于探索报告起草变更提案...

✅ 已创建 proposal.md
内容概要:
  为什么做:用户需要一个收藏功能,能把感兴趣的文章保存起来随时查看。
  这个功能直接影响用户留存率,也是社区功能的必要前置。
  影响范围:新增 Favorite 模型 + 收藏路由 + 前端收藏按钮组件

✅ 已创建 design.md
技术方案:
  数据模型:新建 favorites 表(userId + articleId 复合唯一索引)
  API 接口:
    - POST   /api/articles/:id/favorite     → 收藏文章
    - DELETE /api/articles/:id/favorite     → 取消收藏
    - GET    /api/users/me/favorites        → 获取我的收藏列表
  缓存策略:收藏状态缓存于 Redis,TTL 30分钟
  前端组件:FavoriteButton 组件(可复用)

✅ 已创建 specs/favorites/ 目录
  - api-spec.md:接口规范定义
  - data-model-spec.md:数据库模型规范
  - ui-behavior-spec.md:UI 交互行为规范

✅ 已创建 tasks.md(共 7 个任务):
  1. [ ] 创建 favorites 数据库迁移文件
  2. [ ] 实现 Favorite 模型与关联
  3. [ ] 实现收藏/取消收藏 API
  4. [ ] 实现获取收藏列表 API(含分页)
  5. [ ] 实现 FavoriteButton 前端组件
  6. [ ] 在文章详情页集成 FavoriteButton
  7. [ ] 创建「我的收藏」页面

提案已就绪,请审阅 proposal.md 和 design.md。
确认无误后执行 /apply 开始实现。

阶段三:实现(/apply)

目的:按照 tasks.md 清单,由 deep-worker 逐项实现。

路由过程

  1. Orchestrator 接收 /apply 命令
  2. 自动路由到 deep-worker Agent(Pro 模型,重型实现能力)
  3. deep-worker 读取 tasks.md,按顺序执行
  4. 每完成一个 task 立即标记 completed
  5. 严格遵循”一次只做一件事”的原则

deep-worker 的工作方式

  • 读取当前 in_progress 的任务
  • 执行所有必要的文件操作(读、写、改)
  • 完成后自我验证(重读修改的文件、检查调用方、运行测试)
  • 将任务标记为 completed
  • 自动进入下一个任务

模拟对话 —— 实现阶段

用户: /apply

(Orchestrator 路由到 deep-worker Agent)
deep-worker:已读取 tasks.md,共 7 个任务,开始执行。

deep-worker:
  📋 Task 1/7 in_progress:创建 favorites 数据库迁移文件

  正在读取 migrations/ 目录结构...
  正在读取 models/article.model.ts 了解字段类型...
  创建迁移文件:migrations/2025-07-30-add-favorites-table.ts
  验证:文件已创建,包含 userId/articleId 字段和复合唯一索引
  ✅ Task 1 completed

deep-worker:
  📋 Task 2/7 in_progress:实现 Favorite 模型与关联

  正在读取 models/user.model.ts 和 models/article.model.ts...
  创建 models/favorite.model.ts
  在 models/user.model.ts 添加关联:User.belongsToMany(Article, { through: Favorite })
  在 models/article.model.ts 添加关联:Article.belongsToMany(User, { through: Favorite })
  验证:重读所有相关文件,关联定义正确
  ✅ Task 2 completed

deep-worker:
  📋 Task 3/7 in_progress:实现收藏/取消收藏 API

  正在读取 controllers/article.controller.ts 了解代码风格...
  正在读取 middlewares/auth.middleware.ts 确认认证中间件...
  创建 controllers/favorite.controller.ts(toggleFavorite 方法)
  创建 services/favorite.service.ts(业务逻辑)
  在 routes/article.routes.ts 添加路由:
    POST   /api/articles/:id/favorite
    DELETE /api/articles/:id/favorite
  验证:路由已注册,中间件链正确,错误处理完整
  运行测试:PASS  tests/favorite.test.ts (4 tests)
  ✅ Task 3 completed

  ... (继续 Task 4-7) ...

deep-worker:
  ✅ 全部 7 个任务已完成。所有测试通过。
  建议下一步:/review 进行代码审查。

注意:deep-worker 在实现过程中会严格遵循 AGENTS.md 中的全局规则,包括代码风格约束、注释原则、自我验证要求等。每一步完成后都会进行自我验证,确保不会引入低级错误。

阶段四:审查(/review)

目的:对变更进行多维度代码审查,发现问题并修复。

路由过程

  1. Orchestrator 接收 /review 命令
  2. 自动路由到 reviewer Agent(Pro 模型)
  3. 加载 code-review 技能
  4. 根据 diff 大小自适应审查深度
  5. 产出多维度审查报告

审查维度

维度 关注点 严重程度
正确性 逻辑是否满足 spec 要求 P0-P1
安全性 SQL注入、XSS、权限校验、敏感数据泄露 P0-P1
性能 N+1查询、缺失索引、不必要的循环 P1-P2
可维护性 命名、重复代码、函数长度、耦合度 P2-P3
一致性 是否遵循项目现有模式和约定 P2-P3

模拟对话 —— 审查阶段

用户: /review

(Orchestrator 路由到 reviewer Agent)
reviewer:正在分析 diff(7 个文件,+312 行,-4 行)。审查深度:中等。

reviewer:
📊 审查报告

✅ 正确性(通过)
  - 收藏/取消收藏逻辑正确,使用了 upsert 防止重复
  - 分页参数验证完整

🔴 安全性(发现 1 个问题)
  [P0] controllers/favorite.controller.ts:34
  getFavorites 接口未校验 articleId 参数类型,存在 SQL 注入风险
  修复方案:使用 parseInt 或 Joi 校验入库参数

🟡 性能(发现 1 个问题)
  [P1] services/favorite.service.ts:67
  获取收藏列表时,对每篇文章单独查询作者信息(N+1 问题)
  修复方案:使用 Sequelize 的 include 预加载关联数据

🟢 可维护性(通过)
  - 命名清晰,函数长度合理
  - 错误处理完整

🟢 一致性(通过)
  - 遵循项目现有代码风格
  - 路由命名与现有 API 一致

总结:2 个问题需要修复(1个P0,1个P1),建议修复后再次审查或使用 /review-loop 自动修复循环。

阶段五:归档(/archive)

目的:将 delta spec 合并到主规范目录,保持 specs 目录的可维护性。

用户: /archive

(Orchestrator 路由到 planner/worker)
planner:
  正在归档 specs/favorites/ → specs/
  合并 api-spec.md 到主 API 规范
  合并 data-model-spec.md 到主数据模型规范
  归档完成,specs/favorites/ 已清理。

10.2.3 完整端到端对话示例

下面是一个从零开始到完成归档的完整对话(压缩版):

用户: 我想给文章加个收藏功能

Orchestrator:好的,收藏功能涉及多个模块。让我先 /explore 了解现有结构,
  然后再 /propose 起草方案。确认吗?还是你想直接开始?

用户: 确认,按流程来

(自动执行 /explore → 产出探索报告)
(自动执行 /propose → 产出 proposal.md + design.md + tasks.md)

Orchestrator:提案已就绪。tasks.md 包含 7 个任务:
  1. 数据库迁移  2. 模型关联  3. 收藏API  4. 列表API
  5. 前端组件  6. 页面集成  7. 收藏页面

用户: /apply

(deep-worker 执行全部 7 个任务,每完成一个标记 completed)

deep-worker:✅ 全部任务完成。建议 /review。

用户: /review

(reviewer 审查,发现 2 个问题)

用户: 修复这两个问题

(deep-worker 自动修复)

用户: /review

reviewer:✅ 第二次审查通过,没有新问题。

用户: /commit

(生成规范提交信息,提交代码)

用户: /archive

planner:✅ 归档完成。本次开发流程结束。

10.3 排查 Bug(诊断修复工作流)

Bug 修复是最常见的开发任务之一。本配置方案提供了从诊断到修复到清理的完整闭环。

10.3.1 工作流全景图

自然语言描述 Bug → Orchestrator 自动路由 oracle
  ↓
/oracle(diagnose技能加载 → 6阶段调试 → 根因分析报告)
  ↓
/deep(根据根因报告修复代码)
  ↓
/rmslop(清理修复过程中可能留下的死代码)
  ↓
/commit(生成规范提交信息)

10.3.2 各阶段详解

阶段一:诊断(Orchestrator 自动路由 oracle)

目的:不急于修复,先用系统化方法找到根因。

路由过程

  1. 用户用自然语言描述 Bug
  2. Orchestrator 识别为调试类意图
  3. 自动路由到 oracle Agent(Pro 模型,深度分析和推理)
  4. oracle 自动加载 diagnose 技能(6 阶段结构化调试)和 systematic-debugging 技能
  5. 产出根因分析报告

diagnose 技能的 6 个阶段

阶段 名称 做什么 产出
1 问题复述 确认理解正确,描述观察到的行为和期望行为 问题确认文档
2 信息收集 收集日志、错误信息、相关代码上下文 信息清单
3 假设生成 基于证据生成可能的根因假设(2-5个) 按概率排序的假设列表
4 假设验证 逐个验证假设,排除不成立的 验证结果
5 根因确认 锁定真正的根因 根因确认声明
6 修复建议 提出修复方案和预防措施 修复建议文档

模拟对话 —— 诊断阶段

用户: 登录接口返回 500 错误,之前是好的,今天突然不行了

(Orchestrator 分析意图 → 路由到 oracle)
oracle:让我用结构化方法来排查。先进入诊断第1阶段。

oracle:
📋 阶段 1/6 —— 问题复述
  观察到:POST /api/auth/login 返回 HTTP 500
  期望:正常返回 JWT token
  影响范围:所有用户的登录功能
  最近变更:请确认 —— 今天有没有部署代码或改配置?

用户: 今天上午部署了一个依赖版本升级

oracle:
📋 阶段 2/6 —— 信息收集
  让我查看相关代码文件和最近的变更...

  正在读取 routes/auth.routes.ts...
  正在读取 controllers/auth.controller.ts...
  正在读取 services/auth.service.ts...
  正在查看 git 日志(最近 24 小时变更)...
  发现:
    - services/auth.service.ts:45 调用了 bcrypt.compare()
    - package.json 今天变更:bcrypt 从 5.0.1 升级到 6.0.0
    - bcrypt 6.0.0 的 CHANGELOG 显示 API 有 breaking change

oracle:
📋 阶段 3/6 —— 假设生成(按概率排序)
  假设 A(90%):bcrypt 6.x 的 compare() 返回值类型变更,导致判断逻辑错误
  假设 B(7%):登录接口依赖的 Redis session 服务连接失败
  假设 C(3%):JWT 签名密钥配置被误改

oracle:
📋 阶段 4/6 —— 假设验证

  验证假设 A:
    正在读取 services/auth.service.ts 第 45 行上下文...
    ```
    const isValid = await bcrypt.compare(password, user.password);
    if (!isValid) { ... }
    ```
    bcrypt 5.x:compare() 返回 boolean
    bcrypt 6.x:compare() 返回 Promise<string | false>(变更!)
    → 文本比较 !isValid 在 string 上永远为 false
    → 即使密码错误也会继续执行后续逻辑
    → 后续代码试图访问 null 对象导致 500
    ✅ 假设 A 成立

  验证假设 B:
    正在检查 Redis 连接状态...
    检查日志:Redis 连接正常
    ❌ 假设 B 不成立 —— Redis 运行正常

  跳过假设 C(概率极低,且假设 A 已确认)

oracle:
📋 阶段 5/6 —— 根因确认
  根因:bcrypt 6.0.0 的 compare() 返回值类型从 boolean 改为 string|false,
  导致 auth.service.ts:45 的条件判断失效。当密码正确时,compare() 返回
  hash 字符串,`!isValid` 为 false,继续执行但 user 对象可能已过期导致 500。

oracle:
📋 阶段 6/6 —— 修复建议
  方案 A(推荐):将 !isValid 改为 isValid !== true(兼容两种类型)
  方案 B:回退 bcrypt 到 5.0.1
  方案 C:查阅 bcrypt 6.x migration guide 全面适配

  建议方案 A 快速修复 + 后续调研方案 C 全面适配。

  诊断完成。建议 /deep 执行修复。

注意:整个诊断过程 oracle 没有修改任何文件 —— 它只做分析。这符合 Agent 职责边界:oracle 是只读分析师,不实施修改。

阶段二:修复(/deep)

用户: /deep 按方案A修复

(Orchestrator 路由到 deep-worker)
deep-worker:
  正在读取 oracle 的诊断报告...
  正在读取 services/auth.service.ts:45 上下文...
  执行修复:
    - 将 `if (!isValid)` 改为 `if (isValid !== true)`
  自我验证:重读文件,逻辑正确
  运行测试:
    PASS  tests/auth.test.ts (12 tests)
  ✅ 修复完成。
  注意:这只是一个临时兼容修复,bcrypt 6.x 全面适配请后续用 /propose 规划。

阶段三:清理(/rmslop)

修复过程中可能留下未使用的变量或导入,用 /rmslop 一次性清理。

用户: /rmslop

(Orchestrator 路由到合适 Agent,加载 remove-deadcode 技能)
Agent:
  正在扫描最近变更的文件...
  检查 auth.service.ts:
    - 无未使用的导入
    - 无未使用的变量
    ✅ 没有发现死代码。

阶段四:提交(/commit)

用户: /commit

(加载 conventional-commits 技能)
Agent:
  分析 diff:1 个文件变更,+1 行,-1 行
  建议提交信息:

    fix(auth): 兼容 bcrypt 6.x compare() 返回值类型变更

    bcrypt 6.0.0 的 compare() 返回值从 boolean 改为 string|false,
    导致登录校验逻辑失效。修改条件判断以兼容新旧类型。

  确认提交?(y/n)

用户: y
Agent:✅ 已提交:e3f7a2d fix(auth): 兼容 bcrypt 6.x compare() 返回值类型变更

10.3.3 完整诊断修复对话示例

── 对话开始 ──────────────────────────

用户: 用户反馈说收藏文章功能在移动端点了没反应,桌面端正常

Orchestrator:听起来像是移动端事件处理的问题。让我调度 oracle 来排查。

(oracle 加载 diagnose + systematic-debugging)

oracle:
📋 阶段 1/6 问题复述:
  移动端点击收藏按钮无响应,桌面端正常。
  请补充:所有移动端浏览器都这样,还是特定型号?

用户: iOS Safari 和 Chrome 都不行

oracle:
📋 阶段 2/6 信息收集:
  正在读取 components/FavoriteButton.tsx...
  发现 onClick 事件绑定在 <div> 上,没有 role="button" 或 tabIndex。
  
📋 阶段 3/6 假设生成:
  假设 A(85%):移动端 Safari 不会对普通 <div> 触发 click 事件
  (需要添加 onClick + role="button" + tabIndex={0} 或改用 <button>)

📋 阶段 4/6 验证:
  经查 WebKit 文档,iOS Safari 确实对非交互元素不触发 click。
  ✅ 假设 A 成立。

📋 阶段 5/6 根因确认:
  根因:FavoriteButton 组件使用 <div> 作为点击容器,
  移动端 Safari/Chrome 不将其视为可交互元素。

📋 阶段 6/6 修复建议:
  将 <div> 改为 <button>,或给 <div> 添加 role="button" tabIndex={0}。

用户: /deep 改成 button

deep-worker:
  正在修复 components/FavoriteButton.tsx...
  将外层 <div onClick={...}> 改为 <button onClick={...}>
  调整对应 CSS 以兼容 button 的默认样式
  验证:组件渲染正常,移动端模拟测试通过
  ✅ 修复完成。

用户: /commit
Agent:✅ 提交:a1b2c3d fix(favorite): 修复移动端收藏按钮无响应问题

── 对话结束 ──────────────────────────

10.4 代码审查工作流

代码审查是本配置方案的核心能力之一。提供两种审查模式以满足不同场景。

10.4.1 /review-pr(审查 PR 并回帖)

适用场景:GitHub 上已经有一个 PR,需要全面审查并自动将审查意见发到 PR 评论区。

路由过程

  1. Orchestrator 路由到 reviewer Agent
  2. reviewer 加载 code-review 技能 + gh-cli 技能
  3. 通过 gh 拉取 PR diff
  4. 多维度审查
  5. 通过 gh 将审查报告自动回帖到 GitHub PR 页面

模拟对话

用户: /review-pr https://github.com/my-team/my-repo/pull/152

(reviewer 加载 code-review + gh-cli)
reviewer:
  正在通过 gh 拉取 PR #152 的 diff...
  PR 标题:Add user favorites feature
  Diff 统计:7 个文件,+312 行,-4 行
  审查深度:中等

  审查中...

📊 审查报告 —— PR #152

✅ 正确性(通过)
  收藏/取消收藏逻辑正确

🔴 安全性(1个问题)
  [P0] controllers/favorite.controller.ts:34
  未校验 articleId 参数类型

🟡 性能(1个问题)
  [P1] services/favorite.service.ts:67
  N+1 查询问题

🟢 可维护性(通过)
🟢 一致性(通过)

  正在将审查报告回帖到 GitHub PR #152...
  ✅ 审查报告已发布到 PR 评论区。
  PR 链接:https://github.com/my-team/my-repo/pull/152#issuecomment-xxx

自动回帖的评论格式(GitHub 上的实际呈现):

## 🤖 Code Review by OpenCode Reviewer

审查范围:7 files, +312/-4

### 🔴 安全性

**P0 - controllers/favorite.controller.ts:34**
未对 `articleId` 参数做类型校验,存在注入风险。
```suggestion
const articleId = parseInt(req.params.id, 10);
if (isNaN(articleId)) return res.status(400).json({ error: 'Invalid articleId' });

🟡 性能

P1 - services/favorite.service.ts:67 对每篇文章单独查询作者信息(N+1 问题)。 建议使用 include 预加载。


✅ 带修复建议的评论可直接在 GitHub 上 commit suggestion。


### 10.4.2 /review-loop(审查修复循环)

**适用场景**:开发过程中持续质量保证,审查 → 修复 → 再审查,直至干净或达到上限。

**工作流程**:

第 1 轮:reviewer 审查 → 发现问题 → deep-worker 修复 第 2 轮:reviewer 重审 → 发现残留问题 → deep-worker 修复 第 3 轮:reviewer 重审 → 无问题 → 循环结束 … 最多 5 轮(防止死循环)


**模拟对话**:

用户: /review-loop 检查我刚提交的所有改动

(reviewer + deep-worker 协作循环)

🔄 Round 1/5 —— 审查

reviewer: 扫描 diff:5 个文件,+89 行 发现: [P1] utils/format.ts:23 —— 使用了已废弃的 String.prototype.substr() 应改用 substring() 或 slice() [P2] components/Dashboard.tsx:145 —— 未使用的 useState 导入

🔄 Round 1/5 —— 修复

deep-worker: 正在修复… ✅ utils/format.ts:substr() → slice() ✅ components/Dashboard.tsx: 移除未使用的 useState 导入 修复完成,进入第 2 轮审查。

🔄 Round 2/5 —— 审查

reviewer: 重新扫描修复后的 diff… 已修复:✅ utils/format.ts —— 确认改用 slice() 已修复:✅ components/Dashboard.tsx —— confirm 无多余导入 本轮无新问题。

✅ 审查修复循环结束(2 轮)。 最终状态:0 P0,0 P1,0 P2 代码已就绪,建议 /commit。


**循环终止条件**:

| 条件 | 结果 |
|------|------|
| 审查无新问题 | ✅ 干净,循环结束 |
| 第 5 轮后仍有问题 | ⚠️ 输出剩余问题,建议人工介入 |
| 连续 2 轮发现相同问题(未修复) | ⚠️ 停止循环,提示修复可能未生效 |

### 10.4.3 审查模式选择建议

需要审查已有 PR ──→ /review-pr(自动回帖到 GitHub) │ 开发中,持续质量保证 ──→ /review-loop(自动修复循环) │ 想先看看有什么问题 ──→ /review(仅审查,不自动修复)


---

## 10.5 技术方案调研

当你不确定"该怎么做"时,这个工作流帮你从搜索到决策到规划,步步为营。

### 10.5.1 工作流全景图

/search → 外部信息收集(API文档、最佳实践、社区讨论) ↓ /consult → 多方案对比评估,给出推荐 ↓ /plan → 将选定方案落地为可执行的实施计划


### 10.5.2 各阶段详解

#### 阶段一:外部调研(/search)

**路由**:Orchestrator → `librarian` Agent(Flash 模型,快速检索)  
**技能**:`verify-with-docs`(核对官方文档)

用户: /search Next.js 14 的 Server Actions 怎么处理文件上传

(Orchestrator 路由到 librarian) librarian: 正在搜索 Next.js 官方文档… 正在搜索社区最佳实践… 正在搜索相关 GitHub issues…

📚 调研结果:

  1. 官方文档(nextjs.org/docs/app/api-reference/functions/server-actions) Server Actions 支持通过 FormData 传递文件:
    async function uploadFile(formData: FormData) {
      'use server'
      const file = formData.get('file') as File
      // 处理文件
    }
    

    注意:文件大小受 bodySizeLimit 配置限制(默认 1MB)

  2. 社区实践(next.js GitHub Discussions #45678) 推荐组合:Server Actions + UploadThing 或直接写文件系统 大文件场景建议直接上传到 S3/R2 获取预签名 URL

  3. 已知陷阱
    • Server Actions 中的 File 对象不能直接传给 ORM(需要转 Buffer)
    • 进度条需要在客户端用 fetch 方式调用(不能用 action={} 属性)

建议下一步:/consult 讨论哪种方案适合你的场景。


#### 阶段二:方案讨论(/consult)

**路由**:Orchestrator → `consultant` Agent(Pro 模型,方案评估与建议)

用户: /consult 我们有这些限制:文件不超过10MB,需要显示上传进度

consultant: 根据你的限制条件(文件 ≤ 10MB、需要进度条),分析三种方案:

┌──────────┬──────────────────┬──────────────────┬──────────────────┐ │ 方案 │ Server Actions │ API Route │ 预签名 URL │ │ │ 直接处理 │ + fetch │ + S3 │ ├──────────┼──────────────────┼──────────────────┼──────────────────┤ │ 复杂度 │ ⭐ 低 │ ⭐⭐ 中 │ ⭐⭐⭐ 高 │ │ 进度条 │ ❌ 不支持 │ ✅ 支持 │ ✅ 支持 │ │ 10MB支持 │ ✅(配置即可) │ ✅ │ ✅ │ │ 扩展性 │ ⭐⭐ │ ⭐⭐⭐ │ ⭐⭐⭐⭐⭐ │ │ 适合场景 │ 简单上传、 │ 需要进度的 │ 大文件、高并发 │ │ │ 无进度需求 │ 中小文件上传 │ 生产级项目 │ └──────────┴──────────────────┴──────────────────┴──────────────────┘

推荐:方案 B(API Route + fetch) 理由:你的核心需求是上传进度条,Server Actions 不支持。 API Route 方案复杂度适中,完全满足 10MB 限制。 S3 预签名方案对你的场景来说过度设计了。

你倾向于哪个方案?

用户: 方案B,详细说说

consultant: 方案 B 实现要点:

  1. 前端:用 fetch + FormData + XMLHttpRequest.upload.onprogress 实现进度条
  2. API Route:app/api/upload/route.ts 接收文件,写文件系统或用 multer 解析
  3. bodySizeLimit 设置为 10MB(next.config.js)
  4. 返回上传结果(文件路径/URL)

建议下一步:/plan 制定实施计划。


#### 阶段三:规划落地(/plan)

**路由**:Orchestrator → `planner` Agent

用户: /plan

planner: 基于方案 B(API Route + fetch),制定实施计划:

📋 实施计划 —— 文件上传功能

tasks.md(共 4 个任务):

  1. 配置 next.config.js:bodySizeLimit 设为 10MB
  2. 实现 API Route:app/api/upload/route.ts(文件接收与校验)
  3. 实现前端上传组件:UploadButton.tsx(含进度条)
  4. 集成测试:验证 10MB 文件上传和进度条显示

建议执行 /apply 开始实现。


---

## 10.6 日常轻量任务

并非所有任务都需要走完整的工作流。日常开发中的大量小任务,用自然语言直接描述即可。

### 10.6.1 轻量任务的路由逻辑

当你用自然语言描述一个简单任务时,Orchestrator 的评估过程:

复杂度低 + 操作明确 → light-orchestrator(Flash 模型,快速响应) 复杂度中 + 需要实现 → deep-worker(Pro 模型) 需要探索/查询 → explore / librarian(Flash 模型)


### 10.6.2 日常任务示例

以下是一些典型的日常直接对话:

**示例 1:变量重命名**

用户: 把 user.controller.ts 里的 userCount 改成 activeUserCount

(Orchestrator 评估:简单重构 → light-orchestrator) light-orchestrator: 正在使用 LSP 查找 user.controller.ts 中所有 userCount 的引用… 发现 3 处引用(定义 + 2 处使用),全部替换。 ✅ 已完成重命名:userCount → activeUserCount(3 处)


**示例 2:查找定义**

用户: getUserPermissions 这个函数在哪定义的

(Orchestrator 评估:探索类 → explore) explore: 正在使用 LSP workspaceSymbol 搜索 getUserPermissions… 定义位置:services/permission.service.ts:142 声明:export async function getUserPermissions(userId: string): Promise<Permission[]> 调用方:3 个文件(middleware/auth.ts, controllers/user.ts, utils/checkAccess.ts)


**示例 3:API 查询**

用户: React 19 的 useOptimistic 怎么用

(Orchestrator 评估:文档检索 → librarian) librarian: 正在查询 React 19 官方文档…

useOptimistic 是 React 19 新增的 Hook,用于乐观更新。

基本用法: const [optimisticState, addOptimistic] = useOptimistic( state, (currentState, optimisticValue) => { // 返回乐观更新的状态 } );

典型场景:点赞功能

  1. 用户点击点赞 → 立即更新 UI(乐观)
  2. 发送请求到服务器
  3. 如果失败 → 回滚 UI

详见:react.dev/reference/react/useOptimistic


**示例 4:代码生成**

用户: 给我写一个 formatDate 的工具函数,格式是 YYYY-MM-DD

(Orchestrator 评估:简单实现 → light-orchestrator) light-orchestrator: 正在读取 utils/ 目录了解现有工具函数风格…

建议工具函数(匹配项目代码风格):

  export const formatDate = (date: Date | string): string => {
    const d = typeof date === 'string' ? new Date(date) : date;
    const yyyy = d.getFullYear();
    const mm = String(d.getMonth() + 1).padStart(2, '0');
    const dd = String(d.getDate()).padStart(2, '0');
    return `${yyyy}-${mm}-${dd}`;
  };

是否需要我创建 utils/format-date.ts 并写入此函数?

用户: 是的

light-orchestrator: ✅ 已创建 utils/format-date.ts


### 10.6.3 命令别名 vs 自然语言的效率对比

| 场景 | 自然语言(自动路由) | 命令别名(直达) | 效率差 |
|------|-------------------|-----------------|--------|
| 变量重命名 | 15 字描述 | `/quick "userCount改activeUserCount"` | 快 30% |
| 代码审查 | 3 字 "审查一下" | `/review` | 快 50% |
| 提交代码 | 10 字 "帮我写个提交信息" | `/commit` | 快 70% |
| Bug 排查 | 20 字描述(需分析意图) | `/oracle 描述bug` | 相当 |
| 新建功能 | 50 字描述(需分析+规划) | 无直接别名,需用自然语言 | 自然语言更好 |

**经验法则:重复操作用别名,一次性任务用自然语言。**

---

## 10.7 代码简化与清理

项目维护过程中,代码会累积各种"不忍直视但不敢动"的地方。这个工作流帮你安全地简化代码。

### 10.7.1 工作流全景图

/simplify → oracle 分析并提出行为保持的简化方案 ↓(确认方案后) /deep → 实施简化重构 ↓ /rmslop → 清理重构中留下的死代码 ↓ /commit → 规范提交


### 10.7.2 各阶段详解

#### 阶段一:分析简化(/simplify)

**路由**:Orchestrator → `oracle` Agent(深度分析)+ 加载 `simplify` 技能

**simplify 的核心原则**:

- 行为保持 —— 简化后代码的输出和副作用必须与原来完全相同
- 可读性优先 —— 降低认知负担比减少行数更重要
- 消除偶然复杂性 —— 保留本质复杂性,只消除不必要的复杂

用户: /simplify services/order.service.ts 里的 calculateDiscount 函数太复杂了

oracle: 正在分析 services/order.service.ts:calculateDiscount… 函数长度:87 行 圈复杂度:18(偏高,建议 ≤ 10)

📊 分析报告

问题点:

  1. 第 15-32 行:嵌套 4 层的 if-else,难以追踪逻辑流向 → 建议:使用策略模式或 early return 扁平化

  2. 第 42-56 行:重复的折扣计算逻辑出现 3 次(VIP/新用户/活动折扣) → 建议:提取公共计算函数

  3. 第 63-78 行:一个循环同时做了过滤、映射和求和 → 建议:拆分为独立的 filter → map → reduce 链

  4. 第 12 行:magic number 0.85、0.7、0.5 散落在各处 → 建议:提取为命名的 DISCOUNT_RATES 常量

简化方案(行为保持,零风险): 重构后预计 42 行,圈复杂度降至 8

确认执行简化?(这次只做分析,不改代码)

用户: 确认

planner(oracle 已将方案传递给 planner): ✅ 简化方案已记录。执行 /deep 开始重构。


#### 阶段二:执行重构

用户: /deep

deep-worker: 正在按照 oracle 的分析方案重构 services/order.service.ts…

变更 1:扁平化嵌套 if-else → early return 模式 变更 2:提取 calculateDiscountRate 公共函数 变更 3:拆分循环为 filter → map → reduce 链 变更 4:提取 DISCOUNT_RATES 常量

自我验证: 重读文件,确认逻辑等价… 运行测试:PASS tests/order.test.ts(24 tests,全部通过)

✅ 重构完成。函数从 87 行减至 41 行,圈复杂度从 18 降至 7。


#### 阶段三:清理与提交

用户: /rmslop

Agent:扫描 order.service.ts… 发现重构后不再使用的私有函数 _applySeasonalDiscount ✅ 已移除。

用户: /commit

Agent:✅ 已提交:d4e5f6g refactor(order): 简化 calculateDiscount 函数,降低圈复杂度


---

## 10.8 持续改进工作流

项目不是一次写完就完了。这个工作流帮你定期审视和优化开发体验本身。

### 10.8.1 工作流全景图

/reflect → oracle 分析最近的会话,发现配置摩擦点 ↓ /learn → 沉淀项目特有的知识和规范 ↓ 手动更新配置 → 根据反思结果调整 agents/skills/commands


### 10.8.2 /reflect(反思配置)

**目的**:发现 Orcherstrator 路由不准、Agent 响应质量差、技能不适合当前项目等问题。

用户: /reflect

(Orchestrator 路由到 oracle,加载 reflect 技能) oracle: 正在分析最近 10 次会话的交互模式…

📊 配置效能报告

发现 3 个摩擦点:

  1. 路由偏差(3/10 次会话) 现象:用户描述 “修复一个小bug” 时,Orchestrator 有时路由到 deep-worker 而不是先路由到 oracle 诊断。 建议:调高 AGENTS.md 中 oracle 的权重,或在 bug 关键词上增加匹配。

  2. 技能利用率低(利用率为 4/18) 18 个技能中只有 4 个被实际使用过。常规开发中 code-review、diagnose、 spec-workflow、codemap 高频使用;其余 14 个从未触发。 建议:如果某些技能确实不需要(如 git-release),可以考虑移除以减少 Orchestrator 的决策空间。

  3. 模型浪费(2/10 次会话) 简单的文件读取任务被路由到了 Pro 模型(deep-worker),多花了一倍费用。 建议:在 AGENTS.md 中明确 “简单文件编辑” → light-orchestrator 的路由规则。

是否需要我根据这些发现提出具体的配置修改方案?


### 10.8.3 /learn(沉淀项目知识)

**目的**:将项目特有的规范、架构决策、命名约定等编码到配置中,让 Agent 在后续会话中自动遵循。

用户: /learn 我们的项目有一个约定:所有 API 返回值都要包裹在 { data, message } 里

(Orchestrator 路由到 oracle 或 planner) Agent: 理解了。这个约定需要在以下位置体现:

  1. AGENTS.md 中追加一条规则: “本项目所有 API 返回值必须使用 { data, message } 格式。 错误响应使用 { error, message } 格式。”

  2. 在 opencode.jsonc 的 context 字段中追加项目约定链接。

建议加到 AGENTS.md 的 Constraints 区块。要我现在执行吗?

用户: 加到 AGENTS.md

Agent: ✅ 已追加到 AGENTS.md。 后续所有 Agent 会话(包括 deep-worker、planner 等)都会遵循此约定。


---

## 10.9 多 Agent 并行协作示例

Orchestrator 的一个核心能力是同时调度多个 Agent 并行工作,大幅缩短复杂任务的总耗时。

### 10.9.1 并行调度的触发条件

Orchestrator 在以下情况会启动并行 Agent:

1. **独立探索**:多个模块之间没有依赖关系
2. **多源搜索**:需要同时查官方文档、社区讨论、代码库
3. **读写分离**:一个 Agent 分析,另一个 Agent 同时准备工具

### 10.9.2 并行协作实战示例

**场景:需要实现一个新功能,但同时需要调研前端组件库和后端 API 设计**

用户: 我想加一个用户通知功能。需要调研:1)前端用什么通知组件合适 2)后端数据库怎么设计通知表 3)参考现有项目的消息推送是怎么做的

(Orchestrator 分析:3 个独立的调研任务,无依赖关系 → 并行调度)

Orchestrator: 将同时启动 3 个 Agent 并行工作:

┌─ librarian #1:调研前端通知组件 │ 正在搜索:react-hot-toast vs sonner vs shadcn toast… │ … │ 结果:推荐 sonner(轻量、支持 promise toast、TypeScript 友好) │ ├─ librarian #2:调研后端通知表设计 │ 正在搜索:PostgreSQL notification table schema best practices… │ … │ 结果:推荐以下表结构 │ notifications(id, userId, type, title, body, isRead, createdAt) │ … │ └─ explore:搜索现有项目的消息推送代码 正在搜索:websocket/socket.io/eventemitter… … 结果:项目已使用 Socket.IO,在 services/socket.service.ts:201 现有 emit 方式:io.to(userId).emit(‘event’, data) 可以直接复用

── 3 个 Agent 同时完成 ──

Orchestrator(综合结果):

【并行调研综合报告 —— 用户通知功能】

前端方案:sonner(npm install sonner)

  • 支持多种通知类型(success/error/promise/action)
  • 项目已有 toast 通知基础,替换成本低

后端数据模型:

  CREATE TABLE notifications (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id),
    type VARCHAR(50) NOT NULL,
    title VARCHAR(200) NOT NULL,
    body TEXT,
    is_read BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT NOW()
  );

现有基础设施:Socket.IO 已接入(services/socket.service.ts)

  • 可直接用 io.to(userId).emit('notification', data) 推送实时通知
  • 无需额外引入消息队列

建议下一步:/propose 起草完整方案。


### 10.9.3 并行 vs 串行效率对比

以这个用户通知功能调研为例:

| 执行方式 | 耗时 | 说明 |
|---------|------|------|
| 串行(一个 Agent 逐个调研) | ~45 秒 | 15s + 15s + 15s |
| 并行(三个 Agent 同时调研) | ~18 秒 | 最慢的那个决定总耗时 |
| **效率提升** | **2.5x** | 任务越独立,并行优势越大 |

---

## 10.10 工作流选择决策树

面对一个开发任务,该选哪个工作流?下面的决策树帮你快速判断:

你的任务是什么? │ ├─ 「我想加一个新功能」 │ ├─ 简单功能(≤3 文件,逻辑清晰) │ │ └─ 直接用自然语言描述 → Orchestrator 路由 → deep-worker 实现 │ │ │ └─ 复杂功能(多模块、需要设计) │ └─ /explore → /propose → /apply → /review → /archive │ ├─ 「有个 Bug 需要修复」 │ ├─ 知道原因(如拼写错误) │ │ └─ /quick “修复 xxx” 或直接自然语言描述 │ │ │ └─ 不知道原因 │ └─ 自然语言描述 → /oracle(自动) → /deep → /rmslop → /commit │ ├─ 「帮我审查代码」 │ ├─ 审查已有的 PR │ │ └─ /review-pr https://github.com/xxx/pull/N │ │ │ └─ 审查当前改动(本地未提交或刚提交) │ └─ /review(一次性) 或 /review-loop(自动修复循环) │ ├─ 「我不确定怎么实现」 │ └─ /search → /consult → /plan → /apply │ ├─ 「代码太复杂,想简化」 │ └─ /simplify → /deep → /rmslop → /commit │ ├─ 「想优化我的开发配置」 │ └─ /reflect → /learn → 手动更新配置 │ ├─ 「提交代码」 │ └─ /commit │ └─ 「只是个小改动(改名、删一行、查定义)」 └─ 直接用自然语言描述(Orchestrator 会自动选择 light-orchestrator) ```

10.10.1 快速决策口诀

  • 新功能:大则 spec-flow(/explore → /propose → /apply),小则直达 deep-worker
  • 修 Bug:先 /oracle 诊断,再 /deep 修复,最后 /commit
  • 查代码:自然语言直接问
  • 审代码:PR 用 /review-pr,本地用 /review-loop
  • 不确定:/search → /consult → /plan
  • 改配置:/reflect → /learn
  • 提代码:/commit

10.11 工作流效率对比

10.11.1 纯自然语言 vs 命令别名直达

为了量化两种模式的效率差异,我们以一个典型的”登录 Bug 修复”场景为例:

步骤 纯自然语言模式 耗时 命令别名模式 耗时
1. 描述 Bug “登录接口报 500,帮我看看” 3 秒 /oracle 登录报500 3 秒
2. 等待路由 Orchestrator 分析意图 → 路由 oracle +2 秒 直达 oracle +0 秒
3. 诊断完成 oracle 输出根因报告 30 秒 oracle 输出根因报告 30 秒
4. 开始修复 “帮我修复” → 分析 → 路由 deep-worker +3 秒 /deep +0.5 秒
5. 修复完成 deep-worker 执行修复 15 秒 deep-worker 执行修复 15 秒
6. 提交代码 “提交一下” → 分析 → 路由 commit +2 秒 /commit +0.5 秒
总耗时   55 秒   49 秒
效率差     快 11%  

结论:对于步骤清晰的任务,命令别名可节省约 10-15% 的”分析等待”时间。但对于探索性的、边界模糊的任务,自然语言的灵活性带来的收益远超这点延迟。

10.11.2 自动路由准确率分析

基于本配置方案的设计,不同任务类型的路由准确率大致如下:

任务类型 准确率 说明
代码搜索/定位 95%+ explore 和 librarian 分工明确
Bug 排查 90%+ oracle agent 描述精确匹配调试场景
代码实现 85%+ 需区分 light-orchestrator 和 deep-worker
代码审查 95%+ reviewer agent 有明确的触发关键词
方案讨论 80% consultant 和 planner 的边界有时模糊

减少路由偏差的技巧

  1. 在描述中带上 Agent 名称的关键词:”帮我分析一下”(oracle)、”实现这个”(deep-worker)、”搜一下”(explore/librarian)
  2. 如果不确定路由是否正确,直接用命令别名
  3. 定期执行 /reflect 检查路由质量

10.11.3 何时手动指定 Agent

以下情况建议直接使用命令别名跳过自动路由:

  1. 你已经知道该用哪个 Agent —— 没必要让 Orchestrator 再分析一遍
  2. 前一次路由不准 —— 直接指定正确的 Agent
  3. 高频重复操作 —— /commit/review 等,命令别名已成肌肉记忆
  4. 性能敏感场景 —— 不想浪费 2 秒等待意图分析
  5. 多 Agent 协作场景 —— 用自然语言让 Orchestrator 并行调度比自己逐个调用更高效

10.12 小结

本章覆盖了这套配置方案中最核心的 8 种工作流,涵盖了日常开发的绝大部分场景:

工作流 入口 核心链路 产出
规约驱动开发 /explore explore → propose → apply → review → archive 可归档的规范文件 + 代码
Bug 诊断修复 自然语言 oracle → deep → rmslop → commit 根因报告 + 修复 + 提交
代码审查 /review-pr/review-loop reviewer → (deep) → reviewer 审查报告或干净代码
方案调研 /search search → consult → plan → apply 可执行的实施计划
日常轻量 自然语言 light-orchestrator / explore / librarian 即时响应
代码简化 /simplify simplify → deep → rmslop → commit 简化后的干净代码
持续改进 /reflect reflect → learn → 手动更新 优化的配置
并行调研 自然语言 多个 Agent 并行 → 综合报告 全局调研报告

核心心法

  1. 先想清楚再动手 —— 复杂任务用 /propose,不要边写边想
  2. 诊断先于修复 —— 先用 oracle 找到根因,再用 deep 执行修复
  3. 审查是最后的防线 —— 每次改动后用 /review 兜底
  4. 善用并行 —— 多个独立任务一起做,效率翻倍
  5. 定期反思 —— /reflect 帮你不断优化自己的开发配置

掌握了这些工作流,你就真正掌握了这套 OpenCode × DeepSeek 多 Agent 配置方案的精髓。在第十二章(最佳实践与定制指南)中,我们将进一步探讨如何根据团队和项目的实际情况,定制属于自己的工作流。


下一章第十一章:设计决策与迭代历程 —— 了解这套配置方案的设计思路、关键取舍和版本演进历程。