---
title: Vibe Coding 时代：我是怎么把 AI 从「聊天搭子」养成「全能员工」的
slug: vibe-coding-my-ai-workflow
description: 从写浏览器抓包插件到把内部系统封装成 AI Skill，再到搭建完整的数据查询流水线——记录我在 Vibe Coding 时代的工具进化史。
date: 2026-07-29
published_at: 2026-07-29 21:00
category: Notes
tags:
  - Vibe Coding
  - Agent
  - 工作流
  - 浏览器扩展
draft: false
featured: true
hidden: false
archived: false
---

> **Vibe Coding** 是最近很火的一个词。大意是：你不需要精通编程语言，只需要用自然语言描述你想要什么，AI 帮你把代码写出来、跑起来、调试好。

这篇文章不是在科普 Vibe Coding 概念，而是想记录一下：**在过去几个月里，我到底用这个模式做了哪些事，以及这些事是怎么一步步从「小玩具」变成「生产力工具」的。**

整个过程大概分三个阶段：

```d2
direction: right

stage1: {
  label: "阶段一\n用 AI 写工具"
  style.fill: "#282840"
  style.stroke: "#89B4FA"
  style.stroke-width: 2
  style.border-radius: 8
}

stage2: {
  label: "阶段二\n把网站变成 Skill"
  style.fill: "#282840"
  style.stroke: "#A6E3A1"
  style.stroke-width: 2
  style.border-radius: 8
}

stage3: {
  label: "阶段三\n串成工作流"
  style.fill: "#282840"
  style.stroke: "#F9E2AF"
  style.stroke-width: 2
  style.border-radius: 8
}

stage1 -> stage2 -> stage3
```

## 阶段一：我让 AI 写了一个浏览器抓包插件

### 起因：我想「看见」数据

我在工作中经常需要对接一些内部系统的 API——查企业信息、跑数据查询、看业务状态。这些 API 都是网页端操作的，没有公开文档。

以前的做法是：打开浏览器 DevTools → Network 面板 → 手动找请求 → 一条一条看参数和返回值。**效率低不说，关键是没法批量保存和分析。**

我想：能不能有个插件，自动把我关心的请求和响应都抓下来，导出成结构化数据？

### 过程：从「我不会写 Chrome 插件」到「能用」

说实话，我对 Chrome Extension 开发的了解基本为零。我知道有 `manifest.json` 这种东西，但 `debugger` API、DevTools Protocol、Service Worker 这些概念对我来说都是黑盒。

但在 Vibe Coding 模式下，这个过程变成了这样：

**第一步：描述需求**

> 「我要一个 Chrome 插件，能按域名过滤网络请求，抓到请求头、请求体、响应头、响应体，然后导出为 JSONL 格式。」

AI 给了我一个 Manifest V3 的骨架，包括 `manifest.json`、`background.js`（Service Worker）、`popup.html/js/css`（点击图标的弹窗面板）。

**第二步：解决核心难题**

做到一半遇到一个问题：**Chrome 扩展 API 拿不到响应体**。普通的 `webRequest` / `fetch` 拦截只能拿到请求元数据和响应头，响应体拿不到。

AI 告诉我可以用 `chrome.debugger` + DevTools Protocol 的 `Network` 事件来绕过这个限制。这招我肯定自己想不到——它需要知道 Chrome 底层的调试协议存在，并且知道 `Network.responseReceived` 和 `Network.getResponseBody` 这两个事件可以组合使用。

**第三步：迭代打磨**

接下来的过程就是不断地「试 → 报错 → 给 AI 看 → 改」：

| 问题 | AI 的解法 |
| ----- | ---------- |
| Service Worker 没有 DOM API | 用 `chrome.offscreen` 创建离屏文档 |
| 响应体太大撑爆存储 | 加了 `maxBodyChars` 截断阈值 |
| 敏感信息泄露风险 | 自动对 `Authorization`、`Cookie` 等头做脱敏 |
| 用户不知道怎么填过滤规则 | 在 UI 里加了示例文案和默认值 |

最终产物是一个 **~200 行 background.js + ~100 行 popup.js** 的完整插件，功能包括：

- 按域名/API 路径/通配符过滤监听
- 本地存储抓包记录
- 导出 JSON / JSONL / CSV 三种格式
- 自动脱敏敏感字段

### 我的体感

这件事给我的冲击不是「我会写 Chrome 插件了」，而是：

> **我不需要学会写 Chrome 插件。我只需要能把需求说清楚，并且有能力判断 AI 给的方案靠不靠谱。**

这两件事的门槛，比「学会 JavaScript + Chrome Extension API + DevTools Protocol」低了不止一个数量级。

而且这个插件后来成了后续所有工作的基础设施——**我用它抓到了各种内部 API 的请求格式，才有了后面把网站变成 Skill 的可能。**

```d2
direction: right

想法: {
  label: "想要个抓包插件"
  shape: circle
  style.fill: "#282840"
  style.stroke: "#89B4FA"
}

AI: {
  label: "AI 写代码"
  style.fill: "#282840"
  style.stroke: "#A6E3A1"
}

调试: {
  label: "试错迭代"
  style.fill: "#282840"
  style.stroke: "#F9E2AF"
}

工具: {
  label: "可用工具 ✓"
  shape: circle
  style.fill: "#282840"
  style.stroke: "#A6E3A1"
  style.stroke-width: 3
}

想法 --> AI --> 调试 --> 工具
```

## 阶段二：把工作的网站变成 AI Skill

### 从「手动操作网页」到「AI 帮我操作」

有了抓包插件之后，我开始观察自己的工作模式，发现一个很大的时间黑洞：

**每天要在好几个内部系统之间来回切换，手动操作网页界面来完成重复性的查询任务。**

比如：

- 在 A 系统里搜一家企业的基本信息
- 在 B 系统里跑一条 SQL 查询数据分布
- 在 C 系统里看某个业务的配置开关

每个操作本身不复杂，但一天下来几十次，加上切换上下文的时间，非常碎片化。

### 核心思路：网页 → API → Skill

我的做法是：

```
手动操作网页
  → 用抓包插件抓到背后的 API 请求
  → 分析请求格式（URL、参数、鉴权方式）
  → 用 Python 脚本复现这个 API 调用
  → 封装成 AI 可以调用的 Skill
```

每一步都不复杂，但串起来之后效果很惊人。

### 为什么选 API 而不是操控浏览器

这里有一个关键的技术选择值得展开说说。

现在市面上很多 AI 工具和 RPA 方案，跟网站交互的方式都是**操控浏览器**——用 Playwright / Puppeteer / Selenium 打开页面、截图、点击按钮、抓取 HTML、提取文字。这种方式的好处是**通用性强**，不需要了解目标网站的实现细节。

但我没有走这条路，而是选择了**直接调用 API**。原因很简单：**我比较了解前后端分离架构。**

我知道现代 Web 应用的大致结构是：

```d2
direction: right

browser: {
  label: "浏览器"
  style.fill: "#282840"
  style.stroke: "#6C7086"
}

frontend: {
  label: "前端 (JS/Vue/React)"
  style.fill: "#282840"
  style.stroke: "#89B4FA"
}

api: {
  label: "API 服务端"
  style.fill: "#282840"
  style.stroke: "#A6E3A1"
}

db: {
  label: "数据库 / 数仓"
  style.fill: "#282840"
  style.stroke: "#F38BA8"
}

browser --> frontend: "渲染页面\n用户交互"
frontend --> api: "HTTP 请求\nJSON"
api --> db: "查询数据"

browser -.-> api: {
  label: "浏览器自动化方案\n(截图/点击/抓HTML)"
  style.stroke: "#6C7086"
  style.stroke-dash: 4
}

frontend -.-> api: {
  label: "API 直连方案\n(跳过渲染层)"
  style.stroke: "#CBA6F7"
  style.stroke-width: 3
}
```

当你在浏览器里点一个按钮时，真正发生的事情是：**前端 JavaScript 发了一个 HTTP 请求到后端 API，API 去数据库查了数据，返回 JSON 给前端，前端再渲染成你看到的页面。**

浏览器自动化方案是在最外层（浏览器）模拟操作，要经过完整的页面加载、JS 执行、DOM 渲染过程。而 API 直连方案是直接跟服务端对话——**跳过了整个渲染层**。

这两种方案的差异在实际使用中非常明显：

| 维度 | 浏览器自动化 | API 直连 |
| ---- | ----------- | ------- |
| **速度** | 慢（需要等页面加载、JS 渲染） | 快（一次 HTTP 请求，毫秒级） |
| **稳定性** | 脆弱（前端改了 DOM 结构就挂了） | 稳定（API 接口契约变化频率远低于 UI） |
| **Token 消耗** | 高（截图 + HTML 占大量上下文窗口） | 低（结构化 JSON，信息密度高） |
| **依赖** | 需要浏览器环境（headless chrome 等） | 只要网络能通就行 |
| **门槛** | 低（不需要了解实现细节） | 中（需要分析 API 格式和鉴权方式） |
| **适用场景** | 没有 API 的老系统 / 验证码场景 | 前后端分离的现代 Web 应用 |

**对于内部系统这种前后端分离架构，API 直连几乎是全面优于浏览器自动化的。** 唯一的「门槛」是你得先知道 API 长什么样——而这正是我在阶段一做的抓包插件解决的事情。

有了抓包插件之后，「分析 API」这个门槛也变得很低了：打开目标网页操作一遍，导出 JSONL，所有请求和响应都清清楚楚地摆在那里。

#### 案例 1：登录鉴权 Skill

第一个要解决的问题是**鉴权**。这些内部系统用的是统一的 SSO 登录（类似公司通行证），流程大概是：

1. 访问登录页 → 拿到 CSRF Token
2. 调预登录接口 → 初始化会话
3. 提交账号密码（密码做 MD5）→ 拿到 Token
4. 用 Token 换取各子系统的 Cookie

我把整个流程写成了一个 Python 脚本，大约 150 行代码。AI 帮我处理了：

- HTTP 会话管理（CookieJar 自动维护）
- MD5 密码加密（与前端行为一致）
- XSRF-TOKEN 的提取和回传
- 错误码映射和异常处理

**这个登录脚本成了所有后续 Skill 的地基**——其他 Skill 都复用它拿到的 Cookie 来调用各自系统的 API。

#### 案例 2：数仓查询 Skill

这是我最常用的一个 Skill。我们团队有一个内部的数仓查询平台（底层是 Trino 引擎），网页端可以搜索表、看表结构、写 SQL、提交任务、查看结果。

我把它的全部操作封装成了 CLI：

| 网页操作 | CLI 命令 | 说明 |
| --------- | --------- | ------ |
| 搜索表名 | `search 关键词` | 模糊搜索表名/中文名 |
| 查看表结构 | `table 表名` | 字段、类型、枚举、样例数据 |
| 校验 SQL | `explain --hql "SELECT ..."` | 语法检查，不消耗配额 |
| 提交任务 | `submit --name 任务名 --hql "..."` | 自动 explain 通过后才提交 |
| 查看结果 | `status <taskId>` | 进度、前20行结果、执行日志 |
| 一键跑完 | `run --hql-file query.sql` | explain → submit → 轮询 → 输出 |

整个脚本大概 400 行 Python，纯标准库 + requests。**从抓包到能用，大概花了两个晚上。**

#### 案例 3：企业信息查询 Skill

还有一个常用的内部系统是企业数据库（类似企查查/天眼查的内网版），可以搜企业名称、看工商信息、融资历程、对外投资等。

同样的流程：抓包 → 分析 API → 写脚本 → 封装 Skill。这个更简单，因为它的 API 设计比较 RESTful，基本上就是不同的路径对应不同的查询维度。

### Skill 的真正价值：不是自动化，是「可被 AI 调度的能力」

把这些东西做成 Skill 之后，最爽的不是我自己用 CLI 跑命令——而是**我的 AI 编程助手可以直接调用它们**。

当我和 AI 对话时：
> 我：「帮我查一下近 30 天某业务的订单量按天分布」
>
> AI：（自动调用 business-consult 定位相关代码 → 下钻 DAO 层找到物理表名 → 调用 oct search 找到数仓表 → 对齐口径 → 写 SQL → 提交任务 → 验数 → 输出结论）

**整个过程我不需要打开任何网页、不需要手写 SQL、不需要知道表名叫什么。** 我只需要用业务语言描述我的问题。

这就是 Skill 和普通脚本的区别：**Skill 是给 AI 看的操作手册，而不只是给人用的工具。**

## 阶段三：串成完整的数据查询工作流

### 单个 Skill 不够用，需要「流水线」

随着 Skill 越来越多，我发现一个新问题：**很多实际任务不是单个 Skill 能搞定的，需要多个 Skill 协同。**

最典型的场景就是**数据查询**。当一个产品经理或运营同事问我：

> 「某功能上线后，B 端用户的活跃度怎么样？」

这个问题拆开来看，至少需要：

1. **理解业务定义** —— 「B 端用户」在代码里的精确含义是什么？哪些算活跃？
2. **定位数据来源** —— 这个业务的数据落在哪张表？字段叫什么？枚举值是什么？
3. **编写查询语句** —— 把业务语言翻译成 SQL，注意口径、去重、时间窗口
4. **执行并验数** —— 跑出来结果之后，抽样核对、总数校验、枚举验证
5. **输出可读结论** —— 把数字翻译回业务语言，附上口径说明

这五个步骤分别对应不同的能力：读代码能力、数仓操作能力、SQL 能力、数据验证能力、业务翻译能力。

### 我的解决方案：business-data-query

我把上面这套流程封装成了一个**元 Skill**（meta-skill），叫做 `business-data-query`。它本身不直接实现任何 API 调用，而是**编排其他 Skill 的执行顺序**：

```d2
direction: down

class stepDef {
  style.fill: "#1e1e2e"
  style.border-radius: 8
  style.stroke-width: 2
  width: 280
}

s0: {
  label: "Step 0: 鉴权准备"
  class: stepDef
  style.stroke: "#6C7086"
}
s1: {
  label: "Step 1: 查代码定表\n读工程代码 → DAO层 → 物理表名"
  class: stepDef
  style.stroke: "#89B4FA"
}
s2: {
  label: "Step 2: 应用表→数仓映射\noct search/table 核对口径"
  class: stepDef
  style.stroke: "#A6E3A1"
}
s3: {
  label: "Step 3: 口径确认 ⭐\n输出卡片 + 主动建议 + 等拍板"
  class: stepDef
  style.stroke: "#F9E2AF"
}
s4: {
  label: "Step 4: 写SQL+跑结果\nexplain→submit→wait\n❌失败则自动查错→改SQL→重跑"
  class: stepDef
  style.stroke: "#FAB387"
}
s5: {
  label: "Step 5: 验数 ⭐⭐\n抽查明细 / 对总数 / 对枚举\n(数据分析师思维)"
  class: stepDef
  style.stroke: "#F38BA8"
  style.stroke-width: 3
}
s6: {
  label: "Step 6: 输出\n业务结论 + 口径卡片 + SQL + 验证记录"
  class: stepDef
  style.stroke: "#CBA6F7"
}

s0 -> s1 -> s2 -> s3 -> s4 -> s5 -> s6
```

### 几个体现「数据思维」的设计细节

在这个过程中，有几个决策我觉得值得单独拿出来说说。它们不是技术难点，而是**思维方式**的差异：

#### 1. 强制下钻到 DAO 层

很多数据查询出错的原因是**表名猜错了**。服务端的业务逻辑和数据库的物理表名之间往往不是一一对应的——可能有中间层、可能有聚合表、可能命名规范不统一。

所以我的规则是：**不从 service 层猜测表名，必须追踪到 DAO/Entity/Mapper 层，从 `@EntityInfo` 注解或 MyBatis XML 里读到真实的库名和表名。**

多花 5 分钟追踪，少返工半小时。

#### 2. 写 SQL 前先输出口径卡片

这是我踩过最多坑的地方。产品经理说「查一下活跃用户」，这句话至少有十个歧义：

| 歧义点 | 可能的含义 |
| ------- | ----------- |
| 「活跃」是什么？ | 登录？产生业务操作？页面浏览？ |
| 「用户」是谁？ | 企业账号？个人账号？是否包含测试账号？ |
| 时间范围？ | 自然日？工作日？过去多少天？ |
| 去重粒度？ | 按用户 ID？按设备？按会话？ |
| 是否包含已注销/封禁？ | 正常状态？含历史？ |

所以我设计了一个强制步骤：**写 SQL 之前，必须先以「口径卡片」的形式把所有假设列出来，主动向提问者确认。** 这一步看起来拖慢了速度，实际上大幅减少了返工。

#### 3. 聚合结果必须验数 —— 这是整个 Skill 的灵魂

跑出来的数字很好看，但**不对怎么办？**

说实话，写 SQL 让 AI 来做已经不难了——现在的模型写个查询语句基本没问题。**真正体现「数据思维」的不是写 SQL，而是验数。**

我用的是数据分析师的思路来设计这个环节。一个合格的数据分析师拿到查询结果后的第一反应不是「贴上去」，而是**怀疑**：这个数对不对？为什么是这个量级？有没有遗漏？有没有重复？

我把这种怀疑精神固化成了三步验数法：

1. **抽查明细**：取某一分组的明细行，肉眼核对字段值和过滤条件——**这条记录真的属于这个分组吗？字段值符合预期吗？**
2. **对总数**：各分组计数之和应该等于全局 count(*)——**数学上必须闭合，不闭合就一定有 bug**
3. **对枚举**：CASE 映射后的取值落在预期范围内——**有没有异常码值被错误地归类了？**

这三步的本质是**用数据自身的逻辑来验证数据的正确性**，而不是信任「SQL 没报错所以结果是对的」。SQL 不报错只说明语法没问题，不代表业务逻辑对了。

这也是为什么我说**验数才是整个 Skill 最有价值的部分**。写 SQL 是「生产能力」，验数是「质量控制能力」。一个只有生产没有质检的流水线，产出是不可信的。

#### 4. SQL 自我迭代：失败了不要停，自己修

还有一个经常被忽视的点：**SQL 第一次就能跑通是小概率事件。**

尤其是面对不熟悉的数仓表，你可能遇到的问题包括：

- 字段名记错了（`order_status` 还是 `status`？）
- Trino 和 Hive 方言差异（`||` 不支持拼接、`split` 返回 array 类型…）
- 分区字段格式不对（`p_date` 是 `yyyyMMdd` 还是 `yyyy-MM-dd`？）
- 枚举值对不上（代码里是 `0/1`，数仓存的是 `有效/无效`）

传统做法是：报错了 → 复制错误信息 → 给人看 → 人去改 → 再提交。每次循环都要人工参与。

在我的工作流里，这一步是**自动化的**：

```d2
direction: right

write_sql: {
  label: "写 SQL"
  style.fill: "#282840"
  style.stroke: "#FAB387"
}

submit: {
  label: "提交执行"
  style.fill: "#282840"
  style.stroke: "#A6E3A1"
}

success: {
  label: "✅ 成功 → 进入验数"
  style.fill: "#282840"
  style.stroke: "#A6E3A1"
  style.border-radius: 8
}

fail: {
  label: "❌ 失败"
  style.fill: "#282840"
  style.stroke: "#F38BA8"
}

read_error: {
  label: "读取错误日志\n(line N:M 定位)"
  style.fill: "#282840"
  style.stroke: "#89B4FA"
}

fix_sql: {
  label: "AI 自动修改 SQL"
  style.fill: "#282840"
  style.stroke: "#F9E2AF"
}

retry: {
  label: "重新提交"
  style.fill: "#282840"
  style.stroke: "#CBA6F7"
}

write_sql --> submit
submit --> success
submit --> fail
fail --> read_error
read_error --> fix_sql
fix_sql --> retry
retry -.-> submit: {
  style.stroke-dash: 4
}
```

具体来说：提交任务后如果返回 FAILED，Skill 会自动读取执行日志里的异常信息（通常精确到 `line N:M`），把错误上下文连同原始 SQL 一起交给 AI，AI 根据错误信息修改 SQL 后重新提交。这个循环最多跑几轮，大部分语法问题在 1-2 轮内就能解决。

**这其实就是一种最小规模的「自我进化」**：根据上一次执行的反馈来调整下一次的行为。只不过这里的「进化」粒度很小——仅限于修复一条 SQL。但思路和大规模的 Agent 自我进化是一致的。

#### 5. 默认排除脏数据

业务数据库里永远有一些不该被统计进去的数据：测试账号、灰度标记的异常企业、软删除的记录、未来时间的预约数据……

与其每次都让使用者想起来排除，不如**在 Skill 层面默认加过滤**，并在口径卡片里明确声明。不想排除的人可以显式要求包含。

### 会写 SQL，才有了这个思维

说到这里，有一个前提我不能不提：**我其实会写 SQL。**

不是那种「能跑通 `SELECT *`」的水平，是真的在数仓里摸爬滚打过——知道 `JOIN` 和 `LEFT JOIN` 的区别、知道窗口函数什么时候用、知道 Trino 的方言坑在哪里、知道同一个业务逻辑可以有三种写法但性能差十倍。

正因为我自己会写，我才可能设计出前面那套验数流程。**验数三步法不是凭空想出来的，是我在无数次手写 SQL 踩坑之后沉淀下来的肌肉记忆。** 如果我自己都不懂 SQL，我根本不知道哪里容易出错，更不知道该怎么验。

但有意思的是——用了这个 Skill 之后，我发现自己**再也不愿意手动写 SQL 了**。

不是不会写，而是「不愿意」。因为对比太明显了：

| 手动写 SQL | 用 Skill |
| ---------- | -------- |
| 自己想表名、查表结构 | AI 从代码追踪到物理表 |
| 自己斟酌口径，容易漏 | 强制输出口径卡片 |
| 报错了自己看日志、自己改 | AI 自动查错、改完重跑 |
| 跑完自己验数，容易偷懒 | 三步验数法强制执行 |

一旦体验过「说一句话就出结果 + 自带质检」的流程，你就回不去了。就像用过导航之后，你不会再愿意靠记忆找路。

**所以我现在的状态是：我靠会写 SQL 的经验来设计系统，但日常查询我一句 SQL 都不想自己敲。** 这两件事不矛盾——恰恰是因为我懂，我才知道怎么让 AI 替我把这件事做好。

### 这套工作流带来的变化

| 以前 | 现在 |
| ----- | ------ |
| 打开网页 → 手动翻页找数据 | 说一句话，AI 自动完成全链路 |
| 表名靠猜 / 问同事 | 从代码里精确追踪到物理表 |
| SQL 写完直接贴结果 | 先口径确认 → 再跑数 → 再验数 |
| 口径只有我自己清楚 | 每次输出附带完整的口径卡片，任何人可追溯 |
| 一个查询 30-60 分钟 | 3-5 分钟（大部分时间是等 SQL 跑完） |

**省下来的不只是时间，更是认知负担。** 我不需要同时记住「这张表的 status 字段 0 表示有效还是无效」「那个枚举 H07 到底是汽车还是化工」「灰企名单要不要排除」……这些都写在 Skill 的执行逻辑里了。

## 回顾：三个阶段的跃迁

回头看这三个阶段，每一阶段的产出都成了下一阶段的基础：

| 阶段 | 产出 | 为下一阶段提供了什么 |
| ----- | ------ | ------------------- |
| 一、写抓包插件 | network-capture | **看见 API** 的能力——没有它就没办法分析内部接口 |
| 二、封装 Skill | login / oct / fengniao 等 | **操作 API** 的能力——把手工操作变成可被调用的接口 |
| 三、串联工作流 | business-data-query | **编排能力** 的能力——把单点技能串成自动化流水线 |

```d2
direction: right

plugin: {
  label: "抓包插件\n看见 API"
  style.fill: "#282840"
  style.stroke: "#89B4FA"
  style.stroke-width: 2
}

skills: {
  label: "Skills\n操作 API"
  style.fill: "#282840"
  style.stroke: "#A6E3A1"
  style.stroke-width: 2
}

workflow: {
  label: "工作流\n编排能力"
  style.fill: "#282840"
  style.stroke: "#F9E2AF"
  style.stroke-width: 2
}

agent: {
  label: "Agent\n自主完成"
  style.fill: "#282840"
  style.stroke: "#CBA6F7"
  style.stroke-width: 3
  style.border-radius: 12
}

plugin -.-> skills: "抓包分析\nAPI 格式"
skills -.-> workflow: "Skill 编排\n协同工作"
workflow -.-> agent: "越用越聪明\n自我进化"
```

## 一些不成经验的「经验」

最后整理几个这段时间下来的感受，不算方法论，更像个人观察：

### 1. Vibe Coding 的核心竞争力不是「写代码」，是「判断力」

AI 已经能写出 80 分的代码了。剩下 20 分决定生死的是：**你知不知道它写的对不对？**

- 这个 API 的鉴权方式安全吗？
- 这个 SQL 的过滤条件有没有遗漏边界情况？
- 这个错误处理够不够健壮？

这些都需要领域知识来判断，而领域知识恰恰是 AI 最缺的。

### 2. 先做「最小可用」，再迭代

我的抓包插件第一版只有 50 行代码，只能抓一种域名。但那 50 行已经足够用了——它让我拿到了第一个 API 的请求格式，然后才有了后面的 Skill。

**不要一上来就想做完美的工具。先用最简陋的方式验证「这件事可行」，再逐步打磨。**

### 3. Skill 是投资，不是消费

每封装一个 Skill，花费的时间可能是几小时到几天。但它之后每次被调用都在**回收这笔投资**。

我的数仓查询 Skill 写了一周，但现在平均每天被调用 5-10 次。如果每次都手动去网页上操作，累积节省的时间早就超过了最初投入的开发时间。

### 4. 脱敏和安全意识要从第一天就有

因为我做的这些工具都涉及内部系统的 API 和数据，**脱敏和权限控制从第一天就考虑在内**：

- 抓包插件默认脱敏 Authorization/Cookie 等敏感头
- 登录凭据走环境变量，绝不硬编码
- 所有 Skill 的输出都有合规提示

这不只是「应该做」，而是**不做的话这些工具根本没法在公司环境里推广使用**。

---
> **总结一下：Vibe Coding 不是让你不学编程，而是改变了学习的方式——从「记忆语法和 API」变成「描述需求和判断质量」。**
>
> 当你能把工作中的重复性操作一步步抽象成 Skill，再把 Skill 串成工作流，AI 就不再是一个聊天机器人，而是你的**数字员工**。
>
> 而这个员工的特点是：**它不会累，不会忘，而且越用越强。**
