SKILL实战——手写接口文档对接SKILL

47 阅读8分钟

一、业务背景

  • 需要把数据发送给指定平台,对方平台会提供接口文档,根据接口文档做数据对接
  • 下游平台有多个,因此把这个过程提炼成skill,提升对接代码生成的准确性

二、Skill基本概念

1. Claude官方定义

  • Skill 是一组打包好的指令,教给 AI 一次,永久受用。与其在每次对话中重复解释偏好和流程,不如通过 Skill 只教一次

2. 文件结构

  • 这是skill的常规定义,一些简单的skill只需要SKILL.md即可
  • 本次我手写的skill就只用到了SKILL.md
skill-name/ 
├── SKILL.md # 必需 - markdown指令
├── scripts/ # 可选 - 可执行脚本 
│ └── validate.py 
├── references/ # 可选 - 按需加载的文档
│ └── api-guide.md 
└── assets/ # 可选 - 输出中使用的模版等资源
└── template.md

3.渐进式披露(核心设计原则)

  • 第一级(YAML frontmatter):提供足够的信息让AI知道应该何时使用Skill
  • 第二级(SKILL.md正文):包含完整的指令和指导
  • 第三级(链接文件):Skill目录中捆绑的附加文件

三、Skill实战——基础信息文件

1.概念

  • 这个基础信息文件并非必须,是接口对接需要一些基础信息
  • 名为generate.md,里面会填充一些定制化数据
  • skill中定义通用能力,基础信息文件中定义定制化属性

2.generate.md

## 1.基础信息
- 接口文档:xxx对外开放接口文档V1.1.pdf
- ReceiverId:1xxxx(业务中每个对接平台唯一)
- 类名:xxxService
- 车辆类型:单车(业务相关)
- config命名:xxx_config(配置中心配置项命名)

## 2.鉴权相关(接口文档中鉴权相关定义)
- 签名算法:接口文档中第二部分
- 鉴权接口:

## 3.接口对接(来源Kafka实时数据消息)
- 3.3 推送订单数据 —— handleOrder

## 4.接口对接(来源定时任务)
- 3.4 定时推送定位数据 —— uploadLocation

## 6.参考Service(参考类很重要,如果有相似的对接平台,可以大大提升AI生成代码的准确性)
- xxxService

四、Skill实战——SKILL.md

1.front matter

  • 这个一定要定义! 否则AI不知道什么时候触发skill
---
name: interface-documentation
description: 当用户要求在新增、生成、修改平台对接Service类,或根据接口文档和 generate.md 落地平台对接,使用此 skill
---

2.名称

  • 定义skill的名称
# 接口文档对接 Skill

3.适用场景

  • 定义skill的触发场景,以及不应触发的场景
当用户的需求符合以下任一情况时,应使用本 skill:

- 提到“平台对接”“接口文档对接”“生成对接类”
- 提到“根据接口文档生成接入代码”
- 提到 `generate.md`
- 提到 `xxx(工程项目名)` 仓库中的平台对接实现

如果只是普通 Java 代码修改、测试修复、文档整理,而不是接口文档对接流程,不要强行使用本 skill

4.核心目标

  • 定义skill要完成的事情,即需要生成哪些代码
根据模版文件和接口文档,在仓库中生成或修改一套符合现有工程规范的平台对接实现。重点是:
- 找到正确的接入入口和参考实现
- 按仓库现有模式新增 Service、Task、Plugin、Constant 等代码
- 严格按接口文档中的必填字段组织上报报文
- 尽量沿用仓库现有的上传、鉴权、日志、坐标转换方式

5.输入

  • 这里我的输入就是基础信息文件,接口文档,以及基础信息文件中定义的一些信息
执行本 skill 前,优先确认以下输入:

1. 模版文件
- 默认使用 `generate.md`
- 如果仓库中存在更具体的路径,以实际文件为准

2. 接口文档
- 根据 `generate.md` 中“1.基础信息”里的接口文档名称获取
- 若是 PDF、Word 或图片形式,先提取出必要字段和接口说明
- 如果pdf skill不可用,用mac自带的PDFKit,必须解析接口文档才能开始生成代码

3. 接入基础信息
- ReceiverId
- Service 类名
- 车辆类型:单车或电单
- Apollo 配置命名
- 是否有签名算法
- 是否有独立鉴权接口
- 需要对接的接口列表
- 参考 Service

6.输出

  • 这里我们想要的输出结果就是一个Service类,可以把上游数据转化为发送给下游平台的数据
完成后,通常应产出以下内容中的一部分或全部:
- `ReceiverEnum` 中新增接收方枚举
- 新的 Service 类
- 新的 `constant` 常量类
- 新的 `task` 定时任务类
- 新的 `plugin` 鉴权类(如需要)
- 新的 `enum` / `param` / `model` 类(如接口确实需要)
- 必要的 Spring / Dubbo / 任务注册代码
- 必要的日志、车辆类型校验和坐标转换逻辑

7.行为

  • 定义skill具体行为,防止AI读过多上下文,或者参考错误的Service类
### 1. 先读模版,再读接口文档

优先从 `generate.md` 中读取:

- Service 类名
- ReceiverId
- 车辆类型
- Apollo 配置名
- 需要实现的接口清单
- 参考 Gov

如果模版和接口文档冲突,以接口文档的字段和协议为准,但要在结果里明确说明冲突点。

### 2. 先找参考实现,再开始写代码

优先在仓库中搜索同类型、同风格、同地区的已有实现,尤其是:

- 同为单车或同为电单的 Service
- 同类平台协议的 Service
- 模版中指定的参考 Service

默认参考规则:

- 单车优先参考:`xxxService`
- 电单优先参考:`xxxService`

如果模版中已经指定了参考 Service,则优先使用模版指定项。

### 3. 先补基础注册项

通常应先完成这些基础项:

1.`ReceiverEnum` 中新增 receiver
2. 创建 Service 类
3. 创建 Apollo 配置变量
4. 创建常量类

这样可以先搭起完整结构,再补协议细节。

### 4. 再做鉴权

#### 签名算法鉴权

如果模版“2.鉴权相关”说明了签名算法:

- 按接口文档实现签名
- 不要自行发明协议字段
- 复用仓库现有的加签工具优先,确实没有再新增

#### 鉴权接口鉴权

如果模版“2.鉴权相关”说明需要通过接口换取 token:

- 实现 `ServiceTokenPlugin`
- token 获取、刷新、缓存方式尽量复用现有模式
- redis key、过期时间、日志命名沿用仓库风格

如果模版未说明,则跳过,不要擅自补一个 token 机制。

### 5. 实现实时数据对接

根据模版“3.接口对接(来源Kafka实时数据消息)”逐项实现。

要求:

- 实时数据对接方法通常为 `handle...` 开头
- 所有实时上报可以复用一个统一上传方法
- 方法体必须严格按以下顺序组织

固定顺序:

1. 先判断车辆类型是否匹配
- 单车使用 `isHtw`
- 电单使用 `isBh`

2. 进行数据转换和接口调用
- 把内部对象转换成接口文档要求的字段
- 调用政府接口上传

不要打乱这个顺序。

### 6. 实现定时任务对接

根据模版“4.接口对接(来源定时任务)”实现。

推荐方式:

1. 先创建一个 Task 类
2. 从数据表按城市查询数据
3. 批量调用 Gov 中定义的上传方法

8.评测标准

  • 一些必须要实现的准则,比如坐标系转换,是否做了鉴权
实现完成后,至少检查以下内容:

1. Receiver 是否已注册
2. Service 是否能被 Spring 扫描到
3. 定时任务是否已注册到对应 XML 或调度配置
4. 单车 / 电单判断是否正确
5. 上传字段是否只包含文档要求的必填项
6. 坐标是否按要求转换
7. 鉴权逻辑是否匹配文档
8. 日志、缓存 key、常量是否符合仓库风格

9.失败处理

  • 信息不足时的处理方式,防止AI幻觉
如果信息不足,不要硬猜。

优先按以下方式处理:

1. 先完成结构骨架
2. 明确标注缺失信息
3. 仅实现仓库和模版中可以确认的部分

尤其不要在以下情况强行实现完整协议:

- 接口文档读不到
- 签名规则缺失
- 字段定义不完整
- 参考 Service 与目标协议差异很大

10.一句话原则

  • 给AI一个最核心的原则
先按 `generate.md` 定边界,再按接口文档定字段,最后严格沿用 `project` 现有 Service 风格落地实现。

五、总结

  • 这个skill可以提升对接效率,让代码生成准确度达到80%以上
    • 如果直接丢接口文档给AI,只有50-60%代码可用,剩下需要多次对话或者自己手动修改代码
    • 后续也会继续做优化,比如skill拆分,把接口文档解析和Service生成拆开
  • 还有一个最佳实践,就是把自己的想法写出来,然后让AI生成一个skill,会更符合AI自身的规范