coderio 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- coderio/__init__.py +14 -0
- coderio/agent/__init__.py +5 -0
- coderio/agent/_deepagents_compat.py +139 -0
- coderio/agent/command_review.py +140 -0
- coderio/agent/deep_loop.py +758 -0
- coderio/agent/harness.py +768 -0
- coderio/agent/harness_middleware.py +293 -0
- coderio/agent/permission_middleware.py +52 -0
- coderio/agent/prompts.py +304 -0
- coderio/agent/skill_tool.py +70 -0
- coderio/agent/state.py +144 -0
- coderio/agent/stream.py +93 -0
- coderio/cli/__init__.py +0 -0
- coderio/cli/app.py +257 -0
- coderio/cli/commands.py +339 -0
- coderio/cli/credentials.py +70 -0
- coderio/cli/mcp_cmd.py +227 -0
- coderio/cli/multimodal.py +94 -0
- coderio/cli/onboarding.py +270 -0
- coderio/cli/providers.py +113 -0
- coderio/cli/render.py +28 -0
- coderio/cli/repl.py +189 -0
- coderio/cli/run_cmd.py +171 -0
- coderio/cli/skills_cmd.py +77 -0
- coderio/cli/stream.py +224 -0
- coderio/cli/tui.py +1584 -0
- coderio/cli/tui_onboarding.py +465 -0
- coderio/cli/tui_screens.py +334 -0
- coderio/cli/tui_widgets.py +453 -0
- coderio/config/__init__.py +21 -0
- coderio/config/bootstrap.py +38 -0
- coderio/config/loader.py +273 -0
- coderio/config/models.py +193 -0
- coderio/config/trust.py +136 -0
- coderio/llm/__init__.py +3 -0
- coderio/llm/factory.py +164 -0
- coderio/llm/probe.py +153 -0
- coderio/mcp_loader.py +274 -0
- coderio/session/__init__.py +3 -0
- coderio/session/message.py +79 -0
- coderio/session/store.py +244 -0
- coderio/skills/__init__.py +4 -0
- coderio/skills/bundled/executing-plans/SKILL.md +15 -0
- coderio/skills/lion-skills/LICENSE +21 -0
- coderio/skills/lion-skills/README.md +114 -0
- coderio/skills/lion-skills/skills/clarifying-questions/SKILL.md +119 -0
- coderio/skills/lion-skills/skills/clarifying-questions/evals/evals.json +40 -0
- coderio/skills/lion-skills/skills/code-review/SKILL.md +102 -0
- coderio/skills/lion-skills/skills/code-review/evals/evals.json +40 -0
- coderio/skills/lion-skills/skills/commit-message/SKILL.md +97 -0
- coderio/skills/lion-skills/skills/commit-message/evals/evals.json +20 -0
- coderio/skills/lion-skills/skills/debugging/SKILL.md +116 -0
- coderio/skills/lion-skills/skills/debugging/evals/evals.json +40 -0
- coderio/skills/lion-skills/skills/error-handling/SKILL.md +74 -0
- coderio/skills/lion-skills/skills/error-handling/evals/evals.json +20 -0
- coderio/skills/lion-skills/skills/lion-writing-skills/SKILL.md +85 -0
- coderio/skills/lion-skills/skills/lion-writing-skills/evals/evals.json +20 -0
- coderio/skills/lion-skills/skills/naming/SKILL.md +85 -0
- coderio/skills/lion-skills/skills/naming/evals/evals.json +20 -0
- coderio/skills/lion-skills/skills/onboarding-unknown-codebase/SKILL.md +95 -0
- coderio/skills/lion-skills/skills/onboarding-unknown-codebase/evals/evals.json +20 -0
- coderio/skills/lion-skills/skills/spec-writing/SKILL.md +154 -0
- coderio/skills/lion-skills/skills/spec-writing/evals/evals.json +40 -0
- coderio/skills/lion-skills/skills/task-breakdown/SKILL.md +134 -0
- coderio/skills/lion-skills/skills/task-breakdown/evals/evals.json +46 -0
- coderio/skills/lion-skills/skills/testing/SKILL.md +134 -0
- coderio/skills/lion-skills/skills/testing/evals/evals.json +40 -0
- coderio/skills/lion-skills/skills/verify-and-fix/SKILL.md +132 -0
- coderio/skills/lion-skills/skills/verify-and-fix/evals/evals.json +40 -0
- coderio/skills/models.py +66 -0
- coderio/skills/parser.py +50 -0
- coderio/skills/store.py +102 -0
- coderio/tools/__init__.py +94 -0
- coderio/tools/base.py +55 -0
- coderio/tools/bash.py +168 -0
- coderio/tools/command_policy.py +364 -0
- coderio/tools/edit_file.py +55 -0
- coderio/tools/glob_tool.py +21 -0
- coderio/tools/grep_tool.py +90 -0
- coderio/tools/linux_sandbox.py +196 -0
- coderio/tools/list_dir.py +58 -0
- coderio/tools/multi_edit.py +62 -0
- coderio/tools/note.py +72 -0
- coderio/tools/permission.py +214 -0
- coderio/tools/read_file.py +51 -0
- coderio/tools/sandbox_runner.py +113 -0
- coderio/tools/todo.py +71 -0
- coderio/tools/web_fetch.py +188 -0
- coderio/tools/web_search.py +49 -0
- coderio/tools/win_job.py +214 -0
- coderio/tools/win_sandbox.py +639 -0
- coderio/tools/write_file.py +25 -0
- coderio-0.4.0.dist-info/METADATA +490 -0
- coderio-0.4.0.dist-info/RECORD +97 -0
- coderio-0.4.0.dist-info/WHEEL +4 -0
- coderio-0.4.0.dist-info/entry_points.txt +2 -0
- coderio-0.4.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: naming
|
|
3
|
+
description: 为代码标识符(变量/函数/类/文件/API/数据库字段)决定名字时。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Naming
|
|
7
|
+
|
|
8
|
+
## 概述
|
|
9
|
+
|
|
10
|
+
名字要回答"它是什么/它做什么",而不是"它在哪/什么类型"。好名字让代码自解释,坏名字逼读者来回跳转确认含义。
|
|
11
|
+
|
|
12
|
+
## 何时使用
|
|
13
|
+
|
|
14
|
+
- 写代码时卡在取某个名字上
|
|
15
|
+
- 觉得现有名字不准、误导,想改
|
|
16
|
+
- 设计 API/接口,定资源和字段名
|
|
17
|
+
- 想统一一个模块的命名风格
|
|
18
|
+
|
|
19
|
+
**不该用**:已在用团队既定规范(遵循即可);纯格式问题(用 linter)。
|
|
20
|
+
|
|
21
|
+
## 核心内容
|
|
22
|
+
|
|
23
|
+
### 取名前先搞清四件事
|
|
24
|
+
|
|
25
|
+
套快速规则前先回答这四个问题,否则会在错的对象上取名。前两个是**定性**(决定名字的形态),后两个是**收口**(决定用哪个词):
|
|
26
|
+
|
|
27
|
+
1. **它是对象还是动作?** 数据/状态/实体 → 名词;行为/操作 → 动词。(这是最根本的一刀,定错了后面全错。)
|
|
28
|
+
2. **一个职责还是两个?** 像"转换 + 校验"这种复合,先问该不该拆成两个名字——能独立复用/测试就拆,再各自取名。别把两件事塞进一个名字(如 `parseAndValidateCsv` 不如 `parseCsv` + `validateRecords`)。
|
|
29
|
+
3. **信息够不够?** 用户只甩"flag 叫啥"不给语义时,先反问"它具体表示什么状态",别凭猜取名。
|
|
30
|
+
4. **有歧义吗?** 同名异义/异名同义(项目里既有 `login` 又有 `auth`),先定以谁为基准——通常以领域模型/核心资源名为准,全项目统一。
|
|
31
|
+
|
|
32
|
+
问题 1 的答案同时决定了下面「快速规则」第一条该走名词还是动词那一支。
|
|
33
|
+
|
|
34
|
+
### 快速规则
|
|
35
|
+
|
|
36
|
+
- **函数/方法用动词**:`fetchUser`、`validateEmail`
|
|
37
|
+
- **变量/属性用名词**:`user`、`emailAddress`
|
|
38
|
+
- **布尔用 is/has/can/should**:`isLoggedIn`、`hasPermission`
|
|
39
|
+
- **避免否定**:`isEmpty` 优于 `isNotEmpty`
|
|
40
|
+
- **避免无意义词**:名词 `data`/`info`/`helper`/`manager`/`util`,动词 `process`/`handle`/`do`——都说不清做啥
|
|
41
|
+
- **少缩写**:除非领域通用(`id`、`url`、`http`,以及 `csv`、`json`、`xml` 这类格式名);`usr`、`cfg`、`tmp` 别用
|
|
42
|
+
- **范围越窄越具体**:模块内可简短,全局/API 要自解释
|
|
43
|
+
- **一致**:同一概念全项目用同一个词(别 `user`/`account`/`member` 混用)
|
|
44
|
+
|
|
45
|
+
### before / after
|
|
46
|
+
|
|
47
|
+
| 不好 | 好 | 原因 |
|
|
48
|
+
|------|-----|------|
|
|
49
|
+
| `processData(d)` | `parseCsvToRecords(text)` | 说清做什么、入参是啥 |
|
|
50
|
+
| `flag` | `isLoggedIn` | 布尔用 is,表意明确 |
|
|
51
|
+
| `userList` | `users` | 复数即集合,去冗余类型后缀 |
|
|
52
|
+
| `strName` | `name` | 去掉匈牙利记法前缀 |
|
|
53
|
+
| `handleStuff()` | `sendInvoice()` | 动词具体,不抽象 |
|
|
54
|
+
| `UserInfoManager` | `UserProfile` | 去掉无意义 Manager |
|
|
55
|
+
|
|
56
|
+
### 转换类动词按数据流向选
|
|
57
|
+
|
|
58
|
+
"把 A 变成 B"这类操作最容易被塞进万能的 `process`/`handle`,丢掉数据流向信息。按**输入→输出的形态变化**选最贴切的动词:
|
|
59
|
+
|
|
60
|
+
| 动词 | 数据流向 | 例子 |
|
|
61
|
+
|------|---------|------|
|
|
62
|
+
| `parse` | 文本 → 结构化对象 | `parseCsv(text)` → `Record[]` |
|
|
63
|
+
| `serialize` | 结构 → 文本/字节 | `serializeOrder(order)` → JSON 字符串 |
|
|
64
|
+
| `convert` / `transform` | 结构 → 结构(同层级换形态) | `convertMsToSeconds`、`transformUserToDto` |
|
|
65
|
+
| `format` | 结构 → 展示用文本 | `formatDate(date)` → `"2026-06-22"` |
|
|
66
|
+
| `map` / `reduce` | 集合 → 集合/标量 | `mapToIds(users)`、`reduceToTotal(items)` |
|
|
67
|
+
|
|
68
|
+
选名时问自己:**读者看到动词,能不能猜出输入和输出分别是什么形态?**猜不出(如 `processData`)就换。
|
|
69
|
+
|
|
70
|
+
### API 命名
|
|
71
|
+
|
|
72
|
+
- 资源用复数名词:`/users`、`/orders`
|
|
73
|
+
- 嵌套表达从属:`/users/{id}/orders/{oid}/items`
|
|
74
|
+
- 代码内字段 case 跟语言:JS camelCase、Python/DB snake_case。但 API 响应字段是跨语言契约——case 由 API 规范定(通常跟主力前端或团队约定),**不跟服务端语言**(例:后端 Python 用 snake_case,对外 JSON 仍可 camelCase)
|
|
75
|
+
- 动作用 HTTP 方法表达,别塞进 URL:`DELETE /users/123` 而非 `/users/123/delete`
|
|
76
|
+
|
|
77
|
+
## 常见错误
|
|
78
|
+
|
|
79
|
+
| 问题 | 修法 |
|
|
80
|
+
|------|------|
|
|
81
|
+
| 缩写成谜(`usrCfg`) | 写全,除非领域通用缩写 |
|
|
82
|
+
| 同概念多名(user/account/member) | 全项目统一一个 |
|
|
83
|
+
| 匈牙利记法(`strName`、`intAge`) | 去掉类型前缀 |
|
|
84
|
+
| 过度抽象(Manager/Handler/Util) | 用具体名词 |
|
|
85
|
+
| 否定布尔(isNotValid) | 改肯定(isValid) |
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "naming",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "我有个函数叫 processData,它其实是把 CSV 文本转成 JSON 并校验数据合法性。起个更好的名字。",
|
|
7
|
+
"expected": "给出具体动词前缀的名字如 parseCsvToRecords / validateAndConvertCsv,解释为何 processData 不好(无意义动词)"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": 2,
|
|
11
|
+
"prompt": "这个变量叫 flag,根据上下文它表示用户是否已登录。叫啥好?",
|
|
12
|
+
"expected": "建议 isLoggedIn,说明布尔用 is 前缀、flag 是无意义词"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": 3,
|
|
16
|
+
"prompt": "我在设计一个 REST API,资源是'用户订单里的商品'。URL 路径和返回字段怎么命名?",
|
|
17
|
+
"expected": "URL 用复数名词嵌套如 /users/{id}/orders/{oid}/items,字段遵循语言 case 约定,避免动词进 URL"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: onboarding-unknown-codebase
|
|
3
|
+
description: 需快速上手陌生代码库、理解项目结构时。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Onboarding Unknown Codebase
|
|
7
|
+
|
|
8
|
+
## 概述
|
|
9
|
+
|
|
10
|
+
用一套分层流程把陌生代码库变成一张"项目地图",而不是一头扎进某个文件读细节。核心:先建立全局心智模型,再按需深入。
|
|
11
|
+
|
|
12
|
+
## 何时使用
|
|
13
|
+
|
|
14
|
+
- clone 了新项目,不知从哪读起
|
|
15
|
+
- 接手别人的代码(同事离职、新入职)
|
|
16
|
+
- 要给别人讲清楚一个项目
|
|
17
|
+
- 想搞清某个项目的整体架构/数据流
|
|
18
|
+
|
|
19
|
+
**不该用**:只想找某个具体函数/bug(直接搜);项目你已经熟了。
|
|
20
|
+
|
|
21
|
+
## 核心内容
|
|
22
|
+
|
|
23
|
+
### 先确认对象(前置)
|
|
24
|
+
|
|
25
|
+
三遍法假设你已经拿到目标代码库。但用户常只说"帮我梳理这个项目""讲讲这个代码库"却没给路径——这是高频形态。开跑前先确认对象:
|
|
26
|
+
|
|
27
|
+
- 有明确本地路径或 git 地址 → 直接进入三遍法
|
|
28
|
+
- 没给 → 先向用户要:本地路径、git 地址、或至少 `README.md` + 包管理清单(`package.json`/`go.mod` 等)+ 顶层目录树(`tree -L 2`)。拿到这三样就能完成第一遍宏观 + 第二遍结构骨架
|
|
29
|
+
- **不要默认当前工作目录就是目标**,更不要凭空臆造一个项目来梳理——那会跑题
|
|
30
|
+
|
|
31
|
+
### 三遍法
|
|
32
|
+
|
|
33
|
+
**第一遍·宏观(5-10 分钟,别读代码)**
|
|
34
|
+
读"元信息"文件,搞清"这是什么、技术栈、怎么跑"(按项目实际有的读,没有的就跳过):
|
|
35
|
+
- `README.md` —— 项目用途、怎么跑起来
|
|
36
|
+
- 包管理清单:`package.json` / `go.mod` / `Cargo.toml` / `requirements.txt` —— 技术栈、依赖
|
|
37
|
+
- `Dockerfile` / `docker-compose.yml` —— 怎么部署(库/CLI 项目通常没有)
|
|
38
|
+
- CI 配置:`.github/workflows/` —— 怎么构建测试
|
|
39
|
+
- 配置:`.env.example`、`config/` —— 运行时配置
|
|
40
|
+
|
|
41
|
+
**第二遍·结构(10-15 分钟)**
|
|
42
|
+
看目录布局和分层,建立"地图骨架":
|
|
43
|
+
- 顶层目录各自负责什么?(`src/` 源码、`tests/` 测试、`docs/` 文档)
|
|
44
|
+
- 分层模式:前后端分离?MVC?分层架构?
|
|
45
|
+
- 入口在哪?(`main`、`index`、`app`、`server`;库/CLI 项目最快的方式是看 `package.json` 的 `bin` 和 `exports` 字段)
|
|
46
|
+
- 模块之间怎么依赖(谁调用谁)
|
|
47
|
+
|
|
48
|
+
**第三遍·主线(15-30 分钟)**
|
|
49
|
+
从入口顺一条**核心调用链**读到底,不求全:
|
|
50
|
+
- 入口启动后,处理一个典型请求/操作,经过哪些模块?
|
|
51
|
+
- 只读主干,遇到分支先标记跳过
|
|
52
|
+
- 这条链路走通,就理解了项目的"骨架动力"
|
|
53
|
+
|
|
54
|
+
**不同项目类型的主线形态不同**——别用同一把尺子:
|
|
55
|
+
|
|
56
|
+
| 类型 | 入口找法 | 主线追踪什么 |
|
|
57
|
+
|------|---------|-------------|
|
|
58
|
+
| 服务型(web/api) | `server.listen` / `app.run` / 路由表 | **一次请求的链路**:HTTP 进来 → 中间件 → controller/handler → service → 数据层 → 响应 |
|
|
59
|
+
| 库 / SDK | `package.json` 的 `exports`、`go.mod` 主包、`__init__.py` 暴露的符号 | **一次典型函数调用**:公开 API 入口 → 内部参数校验 → 核心算法/数据变换 → 返回值组装 |
|
|
60
|
+
| CLI | `bin` 字段、`main` 函数、命令注册表 | **一次典型命令的执行**:参数解析 → 子命令分发 → 业务逻辑 → 输出/副作用 |
|
|
61
|
+
|
|
62
|
+
库项目的常见坑是"没有明显的请求入口"——这时从**公开 API(exports/导出符号)**切入,挑一个最常用的函数,顺它的调用栈读到底,等价于服务型项目的"一次请求"。
|
|
63
|
+
|
|
64
|
+
### 产出:项目地图
|
|
65
|
+
|
|
66
|
+
给用户一份结构化地图(不是流水账):
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
## 这是什么 <一两句:项目用途>
|
|
70
|
+
## 技术栈 <语言、框架、关键依赖>
|
|
71
|
+
## 目录结构 <顶层目录职责 + 入口位置>
|
|
72
|
+
## 核心流程 <从入口出发的主调用链,逐步>
|
|
73
|
+
## 关键文件 <最重要的 3-5 个文件及职责>
|
|
74
|
+
## 怎么跑起来 <安装、配置、启动命令>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**重要:标注信息来源。** 项目地图里的每一条信息,标明它是来自文档(README/架构文档/git log)
|
|
78
|
+
还是来自源码(实际 read_file 读到的)。如果某条信息只来自文档、还没读源码确认,标注"(待源码
|
|
79
|
+
确认)"。这样你不会把文档描述当成源码事实,也不会因为发现"文档说的和源码不一样"而推翻整个
|
|
80
|
+
分析重来——直接标注差异即可。
|
|
81
|
+
|
|
82
|
+
### 边界
|
|
83
|
+
|
|
84
|
+
- **先地图后细节**:别一上来读某个函数实现
|
|
85
|
+
- **不求全**:80/20,先懂主干
|
|
86
|
+
- **产出要结构化**:口头散讲不如一份地图
|
|
87
|
+
|
|
88
|
+
## 常见错误
|
|
89
|
+
|
|
90
|
+
| 问题 | 修法 |
|
|
91
|
+
|------|------|
|
|
92
|
+
| 一上来深挖某文件 | 先宏观再结构,最后才深入 |
|
|
93
|
+
| 不看配置就猜架构 | 第一遍先读 README 和包清单 |
|
|
94
|
+
| 只口头讲不产出 | 给用户一份结构化地图 |
|
|
95
|
+
| 试图读完所有文件 | 只读主干,标记跳过分支 |
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "onboarding-unknown-codebase",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "我刚 clone 了 vite 这个项目到本地,帮我看懂它是干啥的、结构怎样、入口在哪。把它当成陌生代码库来梳理。",
|
|
7
|
+
"expected": "走三遍法,产出一个结构化项目地图(是什么/技术栈/目录结构/核心流程/关键文件/怎么跑),而不是一头扎进某个文件"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": 2,
|
|
11
|
+
"prompt": "同事离职留下一个项目,我接手了,不知道怎么跑起来也看不懂整体逻辑。帮我梳理。",
|
|
12
|
+
"expected": "对象未给出时,先向用户要项目路径/README,不默认当前目录或臆造;拿到后先读 README/配置搞清怎么跑,再理结构产出地图"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": 3,
|
|
16
|
+
"prompt": "我刚 clone 了 expressjs/express,讲讲它从收到 HTTP 请求到返回响应经过哪些层。",
|
|
17
|
+
"expected": "走第三遍主线追踪,从 express 入口(createApplication/handle)顺请求经过中间件链到响应"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-writing
|
|
3
|
+
description: 需为非平凡功能/重构写设计文档(spec/design doc/RFC)时。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Spec Writing
|
|
7
|
+
|
|
8
|
+
## 概述
|
|
9
|
+
|
|
10
|
+
把一个还没动手的方案写成**可评审、可追溯、可验收**的设计文档。核心:spec 是**决策的固化**——它记录"为什么这么定、定了什么、没定什么、怎么算实现成功",而不是知识的搬运(堆背景介绍)或愿望的罗列(只说要做什么不说怎么做)。
|
|
11
|
+
|
|
12
|
+
## 何时使用
|
|
13
|
+
|
|
14
|
+
- 要做一个非平凡功能/重构/迁移,想先写设计再动手
|
|
15
|
+
- 要把脑里模糊的方案固化成可给同事评审的文档
|
|
16
|
+
- 已有设计草稿,想审查写得好不好
|
|
17
|
+
|
|
18
|
+
**不该用**:小到一目了然的改动(直接做,写 spec 是负担);纯研究性命题还没结论时(先做 spike 调研,有了结论再写 spec——spec 记录决策,调研产出结论)。
|
|
19
|
+
|
|
20
|
+
**与相邻 skill 的衔接**:spec-writing 在"需求澄清 → **写 spec** → 拆任务"流水线的中间。spec 定稿后,把方案交给 `task-breakdown` 拆成可执行任务;需求还太模糊连方案都形不成时,先澄清(见 `clarifying-questions`,未实现)再写 spec。
|
|
21
|
+
|
|
22
|
+
## 核心内容
|
|
23
|
+
|
|
24
|
+
### 先判断时机:spec 之前还有没有重大未知
|
|
25
|
+
|
|
26
|
+
不是所有"写个 spec"的需求都该直接开写。如果方案的核心决策还依赖未澄清的未知,硬写出来的 spec 就是空架子或一堆猜测。先问自己:**写 spec 需要的决策,我都有依据了吗?**
|
|
27
|
+
|
|
28
|
+
判断标准——把"影响方案结构的关键决策"列出来,看每条是哪种状态:
|
|
29
|
+
|
|
30
|
+
- **已明**:有依据、能定。直接写进 spec 的决策部分。
|
|
31
|
+
- **需要澄清**:用户一句话能定(范围、约束、目标)。**写 spec 前先问**,不要替用户猜。
|
|
32
|
+
- **需要调研**:一句话定不了,得查/试/比(技术选型、性能可行性)。**先做 spike(专门的调研任务,产出结论而非代码),有结论再写 spec**——否则 spec 里只能写"待定",决策部分就空了。
|
|
33
|
+
|
|
34
|
+
如果大量关键决策都是"需要调研"状态,说明现在不是写 spec 的时机——先做调研。澄清和调研占 spec 前置工作的大头,跳过它们直接写,是最常见的失败模式。
|
|
35
|
+
|
|
36
|
+
**判断后的产出顺序**(很重要,别把几步混在一起让用户困惑):
|
|
37
|
+
|
|
38
|
+
- **关键决策大多"已明"** → 直接写 spec。
|
|
39
|
+
- **有"需要澄清"项** → 先把澄清问题列给用户(阻塞项优先),**等回答**。这一步的产出就是"澄清问题清单",不要同时甩一份假设性 spec——用户分不清该先回答问题还是改 spec。
|
|
40
|
+
- **有"需要调研"项** → 标出该做哪些 spike,说明"结论出来才能填 spec 的哪几节"。产出是"spike 清单 + 这些 spike 解锁的 spec 章节",同样不提前硬写。
|
|
41
|
+
- **混合** → 澄清问题 + spike 清单一起给,标注各自解锁什么。把"前置工作"和"spec 本体"分开交付。
|
|
42
|
+
|
|
43
|
+
**澄清问题怎么问**(这一步的产出质量直接决定 spec 质量):
|
|
44
|
+
|
|
45
|
+
- **每条带"为什么问"**:让用户理解这个未知为什么影响方案,而非凭空盘问。差:"QPS 多少?";好:"读 QPS 大概多少?(决定能否用单机 Redis 还是必须集群)"。
|
|
46
|
+
- **给默认假设让用户确认,而非开放式追问**:"我假设日读 < 1k QPS、单机够用,不对请纠正"——用户一句话能校正;纯开放式问题用户得从头想,消耗耐心。
|
|
47
|
+
- **问影响方案结构的,不问实现细节**:问"实时还是离线计算"(改变架构),不问"用 Flink 还是 Spark"(实现细节,spec 阶段还太早)。
|
|
48
|
+
- **一次别超过 6-8 条**:多了用户接不住。真有更多未知,先问阻塞第一刀的,其余用默认假设推进。把未知按"阻塞/非阻塞"分类(阻塞项先问、非阻塞用假设推进)很关键——`task-breakdown` 的"澄清未知"对此有更细的分类法,可参考。
|
|
49
|
+
|
|
50
|
+
> 反例:用户说"写个限流 spec",你直接套模板写"背景/方案/步骤"——但"限流维度(接口/用户/IP)、算法(令牌桶/漏桶)、单机/分布式"都没定,写出来的方案部分全是占位符。
|
|
51
|
+
|
|
52
|
+
### spec 写什么:决策,不是知识
|
|
53
|
+
|
|
54
|
+
spec 的价值密度集中在**决策**上。每写一段问自己:**这是决策,还是背景知识?**两者的篇幅分配严重失衡是 spec 写差的信号:
|
|
55
|
+
|
|
56
|
+
- **决策**(spec 的核心):选了什么方案、为什么选它、放弃了什么、怎么算成功。这是别人来评审、未来回溯时要看的东西,值得详细写。
|
|
57
|
+
- **背景**(spec 的脚手架):问题是什么、为什么做、相关技术是什么。**点到决策够用为止**,不要写成技术科普。读者不需要在限流 spec 里学"什么是令牌桶算法"——他们需要知道"我们为什么在令牌桶和漏桶之间选了令牌桶"。
|
|
58
|
+
|
|
59
|
+
> 反例:搜索功能 spec 一半篇幅在介绍 Elasticsearch 基于 Lucene、支持全文检索、生态丰富——这是知识搬运,不是决策。读者看完不知道你们为什么选它、什么场景选它、不选它会怎样。
|
|
60
|
+
|
|
61
|
+
**研究基础怎么写**:调研/spike 的结论要进 spec,但**只写"对决策有用的结论",不写调研过程**。差的做法是堆"我查了 A、B、C,A 是……B 是……"的流水账;好的做法是直接给"对比结论 + 选定理由",如"对比 Redis 滑动窗口与 Sentinel 网关限流:Redis 方案在多实例下计数精确(误差<1%)、Sentinel 依赖单网关成瓶颈,选 Redis"。读者要的是结论支撑决策,不是重新跟你调研一遍。
|
|
62
|
+
|
|
63
|
+
### 显式标注未决项,别藏不确定性
|
|
64
|
+
|
|
65
|
+
spec 里一定有没定死的东西(技术选型还在权衡、依赖外部团队、待 spike 结论)。**显式标出来**,不要把它们包装成"已定方案"蒙混过关。藏起来的不确定性会在实现期爆炸——下游按"已定"去做,结果方案根本没敲定,返工。
|
|
66
|
+
|
|
67
|
+
标注方式:
|
|
68
|
+
|
|
69
|
+
- **待定项**:明确写 `TBD:xxx,待 yyy 后定`。例:`分布式事务方案 TBD,待 Saga 与最终一致性的压测对比后定`。
|
|
70
|
+
- **选项 + 权衡**:一时定不了的,列候选方案 + 各自的代价,标"待选"。例:`消息队列:Kafka(吞吐高、运维重)vs RabbitMQ(够用、轻量),倾向 RabbitMQ,待容量评估确认`。
|
|
71
|
+
|
|
72
|
+
显式 TBD 让评审者一眼看到"哪里还没定",也能让 spec 在未决状态下流转(不必等所有事都想清才能写)。
|
|
73
|
+
|
|
74
|
+
### 范围:做什么,同样重要的是不做什么
|
|
75
|
+
|
|
76
|
+
明确"本轮做什么"的同时,**显式列出"不做什么"**。范围不清是 spec 失败的高频原因——什么都往里塞,最后要么无限膨胀做不完,要么做出来的和初衷不符。
|
|
77
|
+
|
|
78
|
+
"不做什么"包含两类:
|
|
79
|
+
|
|
80
|
+
- **本轮排除**:相关但本轮不做的(如"做搜索本轮不做向量搜索,留后续")。写出来防止范围蔓延。
|
|
81
|
+
- **明确不属于**:容易混淆但不是 spec 范围的(如"限流 spec 不管鉴权,那是另一个 spec")。写出来防止边界模糊。
|
|
82
|
+
|
|
83
|
+
### 验收标准:spec 要定义"实现怎样算成功"
|
|
84
|
+
|
|
85
|
+
spec 不止写"做什么",还要写"做完怎么算成功"——可验证的验收标准。否则实现完了没法判断达标与否,"是否完成"变成主观感受。
|
|
86
|
+
|
|
87
|
+
好的验收标准是**可观测、可量化**的:
|
|
88
|
+
|
|
89
|
+
- **差的验收**:"搜索功能上线"(上线了但慢、不准、缺功能都算吗?)
|
|
90
|
+
- **好的验收**:"核心商品搜索 P95 < 200ms、Top-10 召回率 > 90%、支持前缀匹配与高亮;订单/用户搜索本轮不做"
|
|
91
|
+
|
|
92
|
+
验收标准同时是 spec 范围的**反向校验**——如果你写不出验收标准,说明"做什么"本身还没定义清楚,回去补范围。
|
|
93
|
+
|
|
94
|
+
### 风险与回滚(高风险方案的必备维度)
|
|
95
|
+
|
|
96
|
+
对**高风险**方案(迁移、架构重构、数据变更、破坏性改动),spec 必须有"风险与回滚"维度。这类方案最怕的不是"怎么做",而是"做错了怎么办":
|
|
97
|
+
|
|
98
|
+
- **风险**:可能出什么事?(数据不一致、服务中断、性能退化、兼容性破坏)
|
|
99
|
+
- **发现机制**:怎么尽早发现做错了?(监控、灰度、对比校验、回滚触发条件)
|
|
100
|
+
- **回滚方案**:错了怎么退回?(特性开关、双写、分阶段切换、可回滚的部署)
|
|
101
|
+
|
|
102
|
+
低风险的小改动不必硬塞这个维度,过度防御也是 spec 的负担。
|
|
103
|
+
|
|
104
|
+
### 审查已有草稿:先分类,再对症
|
|
105
|
+
|
|
106
|
+
用户拿一份已有草稿让你"看看",先判断它属于哪种问题,处理方式完全不同:
|
|
107
|
+
|
|
108
|
+
- **信息不足型**:草稿只写了背景/愿望,核心决策全空(如"要加搜索功能,用 ES"——为什么用 ES、搜什么、怎么算成功都没写)。这种其实是"现在还不是写 spec 的时机"——**退回前置流程**:列澄清问题 + 必要的 spike,别在残缺草稿上打补丁。
|
|
109
|
+
- **写法缺陷型**:草稿信息基本齐,但写法差(堆背景、藏不确定性、没验收、范围蔓延)。这种才是"改草稿"——逐条指出具体问题 + 改法。
|
|
110
|
+
|
|
111
|
+
**审查意见要排优先级,别一次甩十几条**。按"致命 → 重要 → 锦上添花"分:致命的是会导致返工或方向错的(藏了不确定性、范围不清、没验收);重要的是影响可读性的(堆背景);锦上添花的是措辞结构。先改致命的——一份 spec 修好最致命的 1-2 条,价值远大于把 10 条小毛病都列出来。一次列太多,用户接不住、反而无从下手。
|
|
112
|
+
|
|
113
|
+
审查用**具体定位**而非泛泛批评:指出"第 X 段是背景科普,应压成一句决策依据",而不是"写得不够详细"。
|
|
114
|
+
|
|
115
|
+
### 产出形态
|
|
116
|
+
|
|
117
|
+
最终交给用户的是**精简、结构化**的内容,不是论证长文:
|
|
118
|
+
|
|
119
|
+
- **写 spec 时**:用骨架的章节结构,决策部分每条带"为什么",背景一两句点到。别把决策推理过程、候选方案的逐个展开(除非是 TBD 权衡需要)全倒进去——读者要结论,不是陪你想一遍。
|
|
120
|
+
- **判断时机 / 审查草稿时**:产出是"澄清问题清单"或"审查意见(按优先级)",编号列表为主。别在意见里掺大段 skill 原文引用或方法论解释——那是你的工作依据,不是交付物。
|
|
121
|
+
- **TBD 与选项权衡**:用紧凑格式(`TBD:xxx,候选 A(代价)/B(代价),倾向 X,待 Y`),别展开成多段。
|
|
122
|
+
|
|
123
|
+
记住:spec 的读者是**评审者和未来的实现者**,他们要快速判断"这方案对不对、怎么做",不是欣赏你分析得多彻底。
|
|
124
|
+
|
|
125
|
+
## spec 的结构骨架
|
|
126
|
+
|
|
127
|
+
按需取用,不必每节都有——以"能讲清决策"为准:
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
# <标题>
|
|
131
|
+
|
|
132
|
+
## 元信息 <日期、状态(草稿/评审中/已定)、范围>
|
|
133
|
+
## 背景与目标 <问题是什么、为什么做、目标是什么;背景点到够用>
|
|
134
|
+
## 研究基础 <决策依据:调研结论、对标、数据;不是科普>
|
|
135
|
+
## 范围 <做什么 + 明确不做什么>
|
|
136
|
+
## 设计 <核心决策:选了什么、为什么、放弃什么;未决项标 TBD>
|
|
137
|
+
## 风险与回滚 <高风险方案必备;低风险可省>
|
|
138
|
+
## 验收标准 <怎样算实现成功:可观测、可量化>
|
|
139
|
+
## 后续 <下一步动作、依赖、待定项的解决计划>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## 常见错误
|
|
143
|
+
|
|
144
|
+
| 问题 | 修法 |
|
|
145
|
+
|------|------|
|
|
146
|
+
| 核心决策未知未澄清就硬写 spec | 先判断决策状态,需澄清先问、需调研先做 spike |
|
|
147
|
+
| 堆背景知识,决策却一带而过 | 压缩背景到"决策够用",篇幅让给"为什么这么定" |
|
|
148
|
+
| 把未决项写成已定方案 | 显式标 `TBD` + 列选项权衡,别藏不确定性 |
|
|
149
|
+
| 范围只有"做什么"没有"不做什么" | 显式列排除项,防范围蔓延 |
|
|
150
|
+
| 没有"做完算成功"的标准 | 写可观测、可量化的验收标准 |
|
|
151
|
+
| 高风险方案没写风险与回滚 | 迁移/重构/破坏性改动必加风险与回滚维度 |
|
|
152
|
+
| 小改动也套完整模板硬撑篇幅 | 按需取节,能讲清决策即可,不为全而全 |
|
|
153
|
+
| 信息不足型草稿直接打补丁 | 退回前置流程:列澄清问题 + spike,别在残缺上修 |
|
|
154
|
+
| 审查意见一次列十几条不排优先级 | 按"致命/重要/锦上添花"分,先改最致命的 1-2 条 |
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "spec-writing",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "我们后端服务想加个限流功能,帮我写个设计文档。",
|
|
7
|
+
"expected": "不直接开写 spec。先判断时机——核心决策(限流维度/算法/单机分布式/是否配合熔断)未明就硬写会成空架子。先盘点决策状态,产出'澄清问题清单+必要 spike'(各自解锁什么 spec 章节),前置工作与 spec 本体分开交付;澄清问题每条带'为什么问'且用默认假设让用户确认;澄清后 spec 范围明确、决策有依据、带可观测验收标准、不堆背景科普"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": 2,
|
|
11
|
+
"prompt": "我写了份搜索功能的设计文档草稿,你帮我看看。草稿内容:'搜索是核心功能。业界常用 Elasticsearch 和 Solr,Elasticsearch 基于 Lucene,支持全文检索、聚合分析,生态丰富。Solr 也不错。我们也可以考虑用 Postgres 全文搜索。另外向量搜索最近很火,像 pgvector、Milvus 都可以做语义搜索。方案:用 Elasticsearch。开发步骤:1.搭集群 2.同步数据 3.写查询接口 4.加高亮。'",
|
|
12
|
+
"expected": "识别草稿通病:堆背景(技术科普占大半)、藏不确定性(向量搜索未决被一笔带过)、缺验收标准、范围蔓延(ES和向量边界不清);审查意见排优先级(致命的先说,如'决策无依据'排最前)而非平铺列一堆;改进方向具体(压背景成决策依据、标TBD、补验收、砍范围外)而非泛泛'写得不够好'"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": 3,
|
|
16
|
+
"prompt": "我们打算把单体应用拆成微服务,先拆订单服务出来。帮我写个迁移设计文档。",
|
|
17
|
+
"expected": "识别高风险迁移,spec 必须有'风险与回滚'维度;写回滚方案(特性开关/双写/分阶段切换/可回滚部署)不只写'怎么拆'的正向计划;可观测验收标准(行为不变/性能不退化/监控就位);未决项(分布式事务 Saga/2PC/最终一致)显式标 TBD + 列选项权衡,不藏不确定性"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": 4,
|
|
21
|
+
"prompt": "我们想做用户画像标签系统,帮我写个技术方案文档。",
|
|
22
|
+
"expected": "信息严重不足场景:先盘点关键决策(标签来源/计算方式/存储选型/查询模式/规模)大多需澄清或调研;清晰区分前置工作(澄清+spike,各自解锁章节)与 spec 本体,不混在一起甩假设性 spec;澄清问题排优先级(P0阻塞项在前)控量不淹没用户;不堆'什么是用户画像'科普"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": 5,
|
|
26
|
+
"prompt": "我写了份缓存层的设计文档草稿,你帮我看看。草稿:'为了提升性能我们决定加 Redis 缓存。Redis 是内存数据库,速度很快,支持多种数据结构。我们会用 Redis 缓存热点查询结果。开发步骤:1.装 Redis 2.接入代码 3.设置过期时间。'",
|
|
27
|
+
"expected": "判断为'信息不足型'草稿(核心决策全空:缓存什么/一致性策略/击穿雪崩防护/序列化都没定),退回前置流程(澄清+spike)而非在残缺草稿上打补丁补全步骤;指出堆背景科普('Redis 是内存数据库…')+藏不确定性(策略写成已定步骤)+缺验收标准;审查意见排优先级(致命的'应退回前置'排最前)"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": 6,
|
|
31
|
+
"prompt": "我们已经决定用 webhook 方式对接第三方支付回调(而不是主动查询),支付方文档也看过了。帮我写个支付回调的设计文档。",
|
|
32
|
+
"expected": "识别决策已明(已决策已调研),可直接写 spec 而非退回澄清——若无视用户已决策强行要澄清则 FAIL;spec 范围明确(本轮只做回调接收与订单状态更新,排除主动查询对账);识别高风险(涉及钱,回调可能重复/伪造)写风险与回滚(幂等/验签防伪/重复处理/重试补偿);可观测验收(伪造100%拒绝/重复不重复扣款/延迟P95<X/成功率可见);精简不堆 webhook 原理科普"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"_validation_history": {
|
|
36
|
+
"round_1": "v1 跑 case 1/2/3:3×4=12 项全过。但发现 v1 缺'产出时序结构''审查草稿分类''研究基础写法''产出形态'四块",
|
|
37
|
+
"round_2": "v2 跑变体 case 4/5/6:3×4-5=14 项全过,压测五处新增能力(产出时序/草稿分类/意见排优先级/研究基础/产出形态)全部生效",
|
|
38
|
+
"round_3": "v3 补'澄清问题怎么问'(发现 v2 该项分散指引、靠 subagent 自行推断);回归 case 1/2/3:3×4-5=14 项全过,确认 v3 生效且未破坏 v2 能力。迭代收敛"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: task-breakdown
|
|
3
|
+
description: 需把需求拆成可执行任务并排依赖时。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Task Breakdown
|
|
7
|
+
|
|
8
|
+
## 概述
|
|
9
|
+
|
|
10
|
+
把一个需求拆成"今天就能动手、做完就能验证"的小任务。核心:**每个任务是一次端到端的价值交付,而不是一层架构的横切**——前者让你随时有可验证的进展,后者让你做到最后才看见东西跑起来。
|
|
11
|
+
|
|
12
|
+
## 何时使用
|
|
13
|
+
|
|
14
|
+
- 拿到一个需求/用户故事,要转成开发任务
|
|
15
|
+
- 面对一个大需求,不知从何下手
|
|
16
|
+
- 已有任务清单,想审查拆得对不对
|
|
17
|
+
- 要排开发顺序和依赖关系
|
|
18
|
+
|
|
19
|
+
**不该用**:需求本身已经是一个明确的小改动(直接做);纯调研性命题(用 spike 流程,见下文)。
|
|
20
|
+
|
|
21
|
+
**与相邻 skill 的衔接**:task-breakdown 在"写 spec → **拆任务** → 执行"流水线的中间。理想入口是拿到一份定稿的 spec(用 `spec-writing` 产出)——方案决策已定,拆出的任务才有稳固依据;只有模糊需求时,先澄清/写 spec 再拆,否则任务建立在假设沙地上。
|
|
22
|
+
|
|
23
|
+
## 核心内容
|
|
24
|
+
|
|
25
|
+
### 先判断任务大小
|
|
26
|
+
|
|
27
|
+
不是所有需求都该拆,也不是越细越好。拿到需求先问两个方向:
|
|
28
|
+
|
|
29
|
+
- **拆不够**:它能不能在一次提交里端到端做完、且做完就能验证?能 → 别拆,直接做;不能 → 用下面的流程拆。
|
|
30
|
+
- **拆过细**:清单里有没有一堆"半小时以内的微步骤"(如"建表"和"加字段"分开、"写接口"和"加路由"分开)?有 → 合并回可独立验证的粒度。每个任务都有管理开销(上下文切换、状态追踪),碎任务的成本会淹没价值。
|
|
31
|
+
|
|
32
|
+
过度拆分比不拆还糟。粒度的尺子:**一个任务做完后,能独立验证、独立合并、独立回滚**——到这个粒度就停,再大不好做、再小是浪费。
|
|
33
|
+
|
|
34
|
+
### 澄清未知
|
|
35
|
+
|
|
36
|
+
模糊需求直接拆,会拆出一堆基于错误假设的任务。拆之前先把"会影响切片方式的未知"问清楚,不要凭猜往下走。典型该问的:
|
|
37
|
+
|
|
38
|
+
- **范围边界**:哪些在 scope 内、哪些不在?("支持邮件通知"——只发交易邮件还是也发营销?)
|
|
39
|
+
- **规模/量级**:影响技术选型和切片顺序(日活 100 vs 100 万,缓存策略天差地别)
|
|
40
|
+
- **完成标准**:怎样算"做完了"?(性能要求、合规要求、可观测性要求)
|
|
41
|
+
- **已知约束**:必须用的技术、不能动的部分、截止时间
|
|
42
|
+
|
|
43
|
+
**分优先级问,别一次性甩给用户**。未知通常很多,一次列十几条会淹没用户。按"是否阻塞第一刀"分两类:
|
|
44
|
+
|
|
45
|
+
- **阻塞项**(不答就没法切第一片)——先问。例:通知系统"发什么类型、给谁发"不答,第一刀都没法落。
|
|
46
|
+
- **非阻塞项**(先用合理默认假设推进,遇到再问)——后问或直接用假设。例:通知系统"是否多语言"——先用"只做中文"的假设推进,等做到模板那片再确认。
|
|
47
|
+
|
|
48
|
+
问的方式:把你的假设**显式写出来**让用户确认("我假设 X,不对就纠正我"),而不是连环追问——前者用户一句话就能校正方向,后者消耗耐心。每条最好带一句"为什么问"(这个未知如何影响切片),并在意控量(一次别超 6-8 条);`spec-writing` 的"澄清问题怎么问"对此有更细的展开,可参考。
|
|
49
|
+
|
|
50
|
+
> 反例:用户说"做个通知系统",你直接拆成"建表/写 API/写 UI"——所有切片都建立在"通知是什么、发给谁、怎么算成功"都未定义的沙地上。
|
|
51
|
+
|
|
52
|
+
### 选切片方向:垂直切片,别横切
|
|
53
|
+
|
|
54
|
+
这是拆任务最关键的决策。有两种切法:
|
|
55
|
+
|
|
56
|
+
- **横切层(糟糕的默认)**:按架构层切——"先建数据库表 → 再写后端 API → 再写前端 → 最后联调"。直觉上像"循序渐进",实则把价值验证堆到最后:你做完前 3 个任务,**什么可运行的东西都没有**,直到联调那一刻才暴露所有集成错误。
|
|
57
|
+
- **垂直切片(推荐)**:按端到端的价值切——"邮件通知:从 DB 读用户 → 调邮件服务发送 → 用户能在收件箱看到"。**每个切片自己走完所有层**,做完就有一个可验证的、跑通的功能增量。
|
|
58
|
+
|
|
59
|
+
**为什么垂直切片更优**:
|
|
60
|
+
1. **早验证**:第一个切片做完就能演示,错也错得早、错得便宜。
|
|
61
|
+
2. **早集成**:集成风险被摊到每个切片,而不是堆到最后爆炸。
|
|
62
|
+
3. **进度可见**:完成 N 个切片 = N 个可演示功能,而不是"后端 80% 完成"这种无法验证的进度。
|
|
63
|
+
|
|
64
|
+
**一个完整的垂直切片长这样**:选一个最小但真实的数据 → 走通它的 DB schema + API + 业务逻辑 + UI + 测试。第一片可以很糙(hardcode 数据、丑 UI),但要端到端跑通。
|
|
65
|
+
|
|
66
|
+
**重构/迁移场景:价值换成"风险消化",切片换成"渐进可回滚"**。上面定义的切片是"新功能语言"(DB+API+UI+测试、用户可演示的价值)。但重构、迁移、框架升级、性能改造这类任务**没有用户可感知的新价值**——用户看不到"项目变成了 TS"或"换了状态管理库"。这时机械套用"垂直切片"会卡壳,但**别因此退化成横切**。
|
|
67
|
+
|
|
68
|
+
理解垂直切片的本质——它不是"用户价值",而是 **"做完一片就能验证、就能回滚、就把这部分风险消化掉了"**。把这点迁移到重构场景:
|
|
69
|
+
|
|
70
|
+
- **切片单位 = 一个可独立验证、独立回滚的子范围**(通常按模块/目录/路由切),而非"一个用户故事"。
|
|
71
|
+
- **每片做完,整个项目仍能构建、测试全绿、可运行**——这是重构可验证的等价物(新功能的"能演示"= 重构的"仍能构建且测试绿")。
|
|
72
|
+
- **顺序按依赖图从叶子往根部**(叶子 = 被依赖多、本身不依赖别人的基础模块),让每一片的影响范围可控。
|
|
73
|
+
- **典型反模式(必踩的坑)**:"先全局改后缀/先全局换语法/先一次性升级大依赖"——改完整个项目编译不过、无法验证、无法回滚,等同于新功能里"先建完所有表再联调"的横切。
|
|
74
|
+
|
|
75
|
+
例:JS→TS 迁移,按 utils → constants → services → components → pages 渐进迁移,每迁一个目录全项目 `tsc --noEmit` 仍通过、测试仍绿、可独立合并回滚。第一片可以很糙(只迁 utils,且暂时 `any` 不卡),但要保持项目始终可构建。
|
|
76
|
+
|
|
77
|
+
**用户已有清单时的渐进改法**:真实场景里,用户的清单很少是纯横切,往往是**横切和合理项的混合**。别要求用户推倒重来。先挑出**最该改的那一刀**——通常是"第一个本该端到端、却被横切的任务"——改给它看,让用户感受到差别,再决定要不要把其余的也改了。一次改太多,用户接不住、也容易引发抵触。
|
|
78
|
+
|
|
79
|
+
**横切任务在垂直切片下会自然消失**:用户清单里常见的"联调""写单元测试""部署"单独成项,往往是横切思维的产物——垂直切片每片都端到端跑通,"联调"在每片里就发生了;测试是每片的完成定义的一部分;部署是每片合并时自动发生。改写时把它们并入各切片的完成定义,而不是留作后置任务。
|
|
80
|
+
|
|
81
|
+
**什么时候允许横切**:仅当某一层是"所有切片都依赖的公共地基"(如先把 CI 跑起来、先建空项目骨架),且它本身规模小、做完即不再返工。这种横切的"基础设施片"应该很少,且排在最前。
|
|
82
|
+
|
|
83
|
+
### 每个任务带完成定义
|
|
84
|
+
|
|
85
|
+
每个任务必须能回答"怎样算做完了"——不是"写完代码",而是**可验证的标准**:
|
|
86
|
+
|
|
87
|
+
- **差的完成定义**:"实现邮件发送接口"(写完?跑通?测过?)
|
|
88
|
+
- **好的完成定义**:"在测试环境调用 POST /notify/email,能在 Mailtrap 收件箱看到测试邮件,且失败时有日志"
|
|
89
|
+
|
|
90
|
+
完成定义让任务"可验收",也防止"看起来做完了实际没做完"。一个简单的检查:**任务清单里的每一条,你能不能说出它做完后怎么验证?**说不出来 → 任务定义不清,补完成定义。
|
|
91
|
+
|
|
92
|
+
### 研究和执行分开
|
|
93
|
+
|
|
94
|
+
有些任务不是"写代码"而是"搞清楚能不能做、怎么做"——这种叫 **spike**(调研打桩)。比如"缓存方案选 Redis 还是 Memcached"在没调研前,你拆不出执行任务,只能拆出研究任务。
|
|
95
|
+
|
|
96
|
+
把研究和执行分开标记:
|
|
97
|
+
- **研究任务(spike)**:产出是结论/决策/技术选型,不是代码。例:"调研三家短信服务商的送达率和价格,给出选型建议"。完成后可能改变后续执行任务的结构。
|
|
98
|
+
- **执行任务**:产出是可验证的代码/配置变更。
|
|
99
|
+
|
|
100
|
+
研究任务通常排在执行任务之前,且完成后要**回头修订执行计划**(因为研究结论可能让原计划失效)。
|
|
101
|
+
|
|
102
|
+
### 依赖排序
|
|
103
|
+
|
|
104
|
+
拆完后检查依赖关系、排出可执行的顺序:
|
|
105
|
+
|
|
106
|
+
- **研究 → 执行**:执行依赖研究的结论,研究先行
|
|
107
|
+
- **地基 → 上层**:基础设施片排在垂直切片之前
|
|
108
|
+
- **解耦的任务可并行**:**主动标出来**——哪些切片之间无依赖、可以并行推进(如多个独立通道、多个独立查询接口)。并行机会不标出来,团队就会串行做完、白白浪费并发空间
|
|
109
|
+
|
|
110
|
+
排完序的理想形态:**从头到尾做下去,每个任务做完都能验证、都能合并**,而不是攒一堆到某个点才能集成。
|
|
111
|
+
|
|
112
|
+
### 产出形态
|
|
113
|
+
|
|
114
|
+
最终交给用户的是一份**精简的任务清单**,不是论证长文。规则:
|
|
115
|
+
|
|
116
|
+
- **清单优先**:用户要的是"做什么、什么顺序",给编号任务清单 + 每条的完成定义。别把推理过程、skill 原文引用、为什么这样切的论证全倒给用户——那是你的工作记录,不是交付物。
|
|
117
|
+
- **澄清要精炼**:澄清问题用编号列表,阻塞项在前、非阻塞假设在后("以下我用默认假设推进,不对请纠正")。一次别超过 6–8 条,多了用户接不住。
|
|
118
|
+
- **改写要有对照**:审查已有清单时,给"原条目 → 改写"的对照,让用户看到具体差异,而非抽象批评。
|
|
119
|
+
|
|
120
|
+
记住:skill 的产出是**帮用户决策和执行**,不是**展示你分析得多彻底**。
|
|
121
|
+
|
|
122
|
+
## 常见错误
|
|
123
|
+
|
|
124
|
+
| 问题 | 修法 |
|
|
125
|
+
|------|------|
|
|
126
|
+
| 模糊需求直接拆 | 先澄清会影响切片方式的未知,显式写假设让用户确认 |
|
|
127
|
+
| 横切层切片(按架构分层) | 改成垂直切片,每个切片端到端走通 |
|
|
128
|
+
| 重构/迁移任务一次性横切("先全局改后缀/换语法/升大依赖") | 按模块渐进,每片做完项目仍能构建测试全绿、可回滚 |
|
|
129
|
+
| 任务无完成定义 | 每个任务写明"做完后怎么验证" |
|
|
130
|
+
| 把所有任务都当执行任务 | 区分研究(spike)和执行,研究先行且回头修订计划 |
|
|
131
|
+
| 过度拆分(一堆半小时任务) | 合并同一切片内的微步骤,保留可独立验证的粒度 |
|
|
132
|
+
| 任务顺序靠直觉排 | 按研究→地基→垂直切片的依赖关系排 |
|
|
133
|
+
| 一次甩十几条澄清问题淹没用户 | 分优先级:阻塞项先问,非阻塞项用默认假设推进 |
|
|
134
|
+
| 把推理过程当产出倒给用户 | 交付精简任务清单,论证留在工作记录里 |
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "task-breakdown",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "帮我做一个用户通知系统,要支持邮件、短信、站内信,还能让用户在设置页配置偏好。",
|
|
7
|
+
"expected": "不直接开干,先识别模糊需求并反问阻塞未知(发送量级/送达率/触发方式等);澄清分优先级(阻塞项先问、非阻塞用默认假设推进),控制数量不淹没用户;澄清后按端到端垂直切片拆解,每片走通 DB+API+UI+测试并带完成定义;产出是精简清单而非论证长文"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": 2,
|
|
11
|
+
"prompt": "我准备做这个功能,已经想好任务了:1. 设计数据库表 2. 写后端API 3. 写前端页面 4. 联调 5. 写测试 6. 部署。帮我安排下顺序和依赖。",
|
|
12
|
+
"expected": "识别这是横切层切片(按层而非价值切)的陷阱;指出联调/测试/部署单独成项是横切思维产物、在垂直切片下会自然消失并入完成定义;建议改成端到端垂直切片;用原条目→改写对照形式而非推倒重来"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": 3,
|
|
16
|
+
"prompt": "我要给项目加 Redis 缓存。任务:1. 装 Redis 2. 接入代码 3. 配置失效时间 4. 写缓存读写逻辑。帮我看看这个拆分有没有问题。",
|
|
17
|
+
"expected": "识别跳过了研究阶段(spike:缓存什么/一致性策略/击穿雪崩防护/序列化),补研究子任务排最前且回头修订计划;执行任务补完成定义(装Redis=ping通);识别'配置失效时间'与'写缓存读写逻辑'边界模糊需合并;排序时主动标出可并行项"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": 4,
|
|
21
|
+
"prompt": "我想给 app 加个搜索功能。",
|
|
22
|
+
"expected": "面对极模糊单句需求,不直接列技术任务;澄清分优先级(阻塞项如'搜什么内容/数据源/搜完去哪'先问,非阻塞如多语言/排序用假设推进);总数控制在 6-8 条以内;产出精简清单带完成定义"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": 5,
|
|
26
|
+
"prompt": "我要做一个文件上传功能,任务我列了一下:1. 设计 files 表 2. 写上传接口 3. 写前端上传组件 4. 接入对象存储(S3) 5. 加文件大小限制 6. 联调 7. 写单元测试 8. 上线。帮我看看怎么排顺序。",
|
|
27
|
+
"expected": "识别混合清单(1/2/3/4 横切、6 集成后置、7 测试独立是横切、5/8 相对合理);用渐进改法只挑最该改的一刀(整合1-4成端到端切片)给用户看,不推倒重来;保留合理项(5大小限制可独立);用原条目→改写对照形式"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"id": 6,
|
|
31
|
+
"prompt": "我给'用户登录'拆了这些任务:1. 建 users 表 2. 加 email 字段 3. 加 password_hash 字段 4. 写 /login 路由 5. 写 login controller 6. 写密码哈希校验逻辑 7. 写登录表单组件 8. 加表单 state 9. 写 fetch 调用 10. 加错误提示 11. 写测试 12. 部署。帮我看看怎么样。",
|
|
32
|
+
"expected": "识别这是'拆过细'(把单切片的内部步骤摊成了任务清单),用判断任务大小的双向判断(看到拆过细这一面);合并到可独立验证/合并/回滚的粒度(1-2个垂直切片)并说明尺子;识别测试(11)部署(12)独立成项是横切、应并入每片的完成定义;产出精简"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": 7,
|
|
36
|
+
"prompt": "帮我把一个 5 万行的 JS 前端项目迁移到 TypeScript。",
|
|
37
|
+
"expected": "重构/迁移场景(无新功能价值):不直接列技术步骤,先澄清迁移策略(strict/allowJs、strictNullChecks、tsc vs babel、是否允许中间态);补 spike(策略选型/现状摸底/错误盘点)排执行前并说明回头修订;明确拒绝一次性横切(先全局改后缀=编译不过无法回滚),改用按模块渐进、每片做完项目仍能构建测试全绿可回滚、按依赖图叶子→根部;每任务带完成定义;产出精简"
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"_validation_history": {
|
|
41
|
+
"round_1": "v1 跑 case 1/2/3:3×4=12 项全过。但发现 v1 缺'澄清分优先级''混合清单渐进改法''判断拆过细''产出形态'四块",
|
|
42
|
+
"round_2": "v2 跑变体 case 4/5/6:3×5=15 项全过,压测五处新增能力全部生效",
|
|
43
|
+
"round_3": "v3 回归 case 1/2/3:3×5=15 项全过,确认两处小修(横切任务自然消失/主动标并行)生效且未破坏 v2 能力",
|
|
44
|
+
"round_4": "v4 补'重构/迁移场景的切片'(发现 v3 该场景是空白,靠 subagent 自行合理化才过);新 case 7(TS迁移) + 回归两个核心 case 验证"
|
|
45
|
+
}
|
|
46
|
+
}
|