Agent Skills 系列(5):一个管理后台查询页案例,怎么把“隐性规范”变成可执行 Skill

系列说明

前几篇讲了为什么要 Skill、怎么写、怎么分发、什么值得做成 Skill。这一篇只做一件事:给一个具体落地案例,演示如何把“需求文档没写、但团队一直默认遵守”的规则,固化成项目级 Skill。


为什么“看起来对”的代码会在测试里翻车

场景很典型:你让 AI 生成一个管理后台查询页,代码能跑,页面也能看。但一测就出问题:

  • 分页组件只写了 pageSize,却漏掉 showSizeChanger,导致用户无法切换每页条数
  • 需求文档说查询范围不超过一年,默认开发会按照惯例来写,但AI如何判断不超过一年?
  • 查询项只有一两行却默认折叠,用户得多点一次
  • 机构筛选忽略了权限差异,导致普通用户也能改机构条件
  • 导出接口返回异常 JSON 时没有提示,用户只看到“下载失败”

这些不是“复杂业务”,而是“隐性项目约定”。文档常只写本次需求,不会把这些历史惯例全部重复写一遍。结果就是:AI 每次都按通用范式写,你每次都在补同一批修正意见。


这个案例的核心结论

把“会重复纠正 AI 的内容”拆成项目 Skill,而不是继续靠口头补充。

判断标准很直接:

  • 重复出现:两周内被你纠正 3 次以上
  • 口径稳定:半年内不会频繁变化
  • 可检查:能写成 checklist,而不是抽象口号

符合这三条,就别再留在聊天里,直接沉淀成 Skill。


数据先行:先定义约束对象,再写规则

先把数据关系说清,这个案例里最关键的是 5 组数据:

  1. 查询参数QueryParams(表单字段 + 分页字段)
  2. 后端请求参数ApiParams(把 pageSize/current 映射成 count/page
  3. 时间范围dateRange -> startTime/endTime/durationDays
  4. 机构权限状态canSelectOrgfixedOrgCode
  5. 导出状态loadingbloberrorJson

不变约束(invariants)也要写死:

  • 分页映射永远做:pageSize -> countcurrent -> page
  • 未触发查询前不请求列表(可选策略)
  • 时间范围校验必须统一(31 天或 365 天按场景选其一)
  • 无权限用户不能修改机构,只能用自身归属机构
  • 导出响应先尝试识别异常 JSON,再按文件流处理

这一步做完,Skill 才有“可执行的骨架”,而不是一堆口号。


脱敏后的项目 Skill 示例(可直接用)

下面是脱敏版结构,项目名与路径都用通用写法,代码只保留伪代码。

先看目录结构:

admin-pc-query-guidelines/
├── SKILL.md
└── references/
    ├── query-page.md
    ├── query-form-fields.md
    └── export-download.md

1)SKILL.md(主文件)

---
name: admin-pc-query-guidelines
description: 在开发 admin-pc 管理后台查询页、详情页、导出功能时使用。覆盖分页参数映射、机构权限查询、时间范围约束、查询折叠策略与导出异常处理。
tags:
  - admin-pc
  - 管理后台
  - 查询页
---

# 管理后台开发指南

## 何时使用
- 新建或修改查询页(ProTable)
- 新建或修改详情页中的查询模块
- 新增报表导出功能
- 涉及机构筛选与时间范围筛选

## 参考文档

开发时必须参考以下规范文档:

### 查询页面开发

- [ProTable 查询页面开发规范](references/query-page.md) - 包含完整的模板代码、必要配置说明、列配置示例和检查清单

### 查询项配置

- [查询项配置规范](references/query-form-fields.md) - 包含项目、分公司/中支机构选择、时间范围约束(默认一个月、最多一年)等

### 报表下载

- [报表下载功能](references/export-download.md) - 包含下载接口定义、异常处理等

2)references/query-page.md(查询页模板与检查)

# 查询页面规范

## 必要配置
- 定义 actionRef / formRef
- 设置 rowKey
- 设置完整 pagination(包含 `showSizeChanger`
- request 中执行分页参数映射

## 示例代码
```tsx
const pagination = {
  defaultPageSize: 10,
  pageSizeOptions: ['10', '20', '50', '100'],
  showTotal: (total, range) =>
    `第${range[0]}-${range[1]}条/总共${total}条`,
  showSizeChanger: true,
};

function requestList(params) {
  if (!shouldRequest) return emptyResult();

  const apiParams = {
    ...params,
    count: params.pageSize ?? 10,
    page: params.current ?? 1,
  };

  const res = await queryList(apiParams);
  return normalizeTableResult(res);
}
```

## 折叠策略
- 若查询项渲染后不超过两行:`defaultCollapsed = false`
- 否则允许默认折叠

3)references/query-form-fields.md(机构与时间范围)

# 查询项配置规范

## 机构筛选
- 先查询当前用户权限
- 无权限切换机构时:隐藏机构选择框,使用固定机构值
- 有权限时:展示机构选择框

## 时间范围
- 默认值:当月(本月1号到昨天)
- 转换为 startTime / endTime(00:00:00 ~ 23:59:59)
- 校验 durationDays,不满足直接提示并阻断提交
- 默认 MAX_DAYS 为 30 天

## 伪代码
```ts
if (durationDays > MAX_DAYS) {
  showError(`请选择 ${MAX_DAYS} 天以内的数据`);
  return false;
}
```

4)references/export-download.md(导出逻辑)

# 导出规范

## 请求约束
- responseType = blob
- 导出按钮与查询条件同源

## 异常处理
- 先尝试把响应按文本解析为 JSON
- 若解析成功且 code != 0,提示业务错误
- 解析失败则按文件流继续下载

## 伪代码
```ts
async function handleExport(params) {
  const hide = showLoading("正在导出...");
  try {
    const blob = await exportApi(params);
    await tryParseBusinessError(blob);
    triggerFileDownload(blob);
    return true;
  } catch {
    showError("导出失败,请重试");
    return false;
  } finally {
    hide();
  }
}
```

为什么这套写法有效

关键不是“模板多完整”,而是把容易漏的点变成可检查项:

  • AI 首轮就拿到项目“真约束”,不再靠默认猜测
  • 代码 review 从“凭经验挑错”变成“对 checklist 勾选”
  • 需求文档即使只写增量,也不会把历史惯例丢掉
  • 新同学能按 Skill 对齐,不必每次口口相传

一句话:把隐性知识从人脑搬到版本化文件里。


落地顺序(不要一口吃成胖子)

建议按这个顺序推进,最稳:

  1. 先只收一类高频页面(比如查询页)
  2. 先固化 5~8 条“最常漏”的硬规则
  3. 连续两周只观察首轮通过率与返工轮次
  4. 再把导出、权限、时间校验扩展到同类页面

别一上来写“全项目万能 Skill”,那一定会失控。


给非技术场景的迁移提示

同一套路可以迁移到市场、内容、运营写作:

  • 市场:把品牌禁用词、合规口径、活动文案结构写成 Skill
  • 内容:把选题结构、标题约束、引用规范、发布检查写成 Skill
  • 运营:把 SOP、话术边界、异常升级路径写成 Skill

底层逻辑不变:重复、稳定、可检查。


系列导航(姊妹篇)

文章在讲什么
1痛点与动机为什么需要 Skill
2概念实战篇SKILL.md 结构与渐进式披露
3工具引入篇skill-base / skb 分发安装
4什么值得做成 Skill选题标准与反例
6运维手册触发、冲突与版本治理
延伸碎片化困局多工具并存下的触发与治理

相关阅读