SAAS 平台接口对接(hk-saas-api)
⚠️ 本 skill 的唯一产出:客户端调用海科 SAAS 平台的对接代码。全部 162 个接口统一流程:组参 → 签名 → HTTP POST → 处理响应。绝不生成服务端代码。
⛔ 关键误判警告(必读,最高优先级)
正确推理链:所有接口文档都是服务商对接 SAAS 的参考材料 → 文档中的 notify_url 只是请求参数之一(值为服务商自己的通知地址),或文档描述的是 SAAS 将发给服务商的通知格式 → 生成的是服务商侧的客户端代码(组参→签名→调 SAAS API,或解析通知数据→调 SAAS 查询接口),不是服务端接收端点。
最常见的误判场景:
| 文档特征 | ❌ 常见错误判断 | ✅ 正确理解 |
|---------|-------------|---------|
| 参数含 notify_url,值为 http://www.baidu.com 等示例 | 需要生成接收通知的服务端代码 | notify_url 只是请求参数,与其他参数无区别。服务商调用 SAAS 时传自己的通知地址,仍是 client→SAAS |
| 文档写"通知地址为...notify_url",无固定 URL | 这个接口缺 URL,无法生成 HTTP 调用 | 该文档描述的是 SAAS 发给服务商的通知格式。代码应为客户端处理逻辑:解析通知数据 → 调 SAAS 查询接口确认 |
| 文档名含"通知"(如支付成功异步通知) | 需要生成 HTTP 端点接收 SAAS 通知 | 文档是通知格式参考,生成的处理代码是客户端代码:入参为通知数据 → 签名校验(用 accesskey 计算 sign 比对,不是 verifySign)→ 调 SAAS 查询接口确认状态 |
一句话铁律:本 skill 不生成任何HTTP 端点注册代码。 如果你生成的代码中出现了这些,说明你犯了方向错误。所有 162 个文档,产出物永远是客户端代码——能被 main 函数或业务方法直接调用的代码,不需要启动服务器就能运行。
通知类接口的正确产出示例(Java)——这是你应该生成的代码形态:
// ✅ 正确:客户端代码。入参为通知数据,内部做签名校验 + 调 SAAS 查询接口
// 注意:没有 @RestController / @PostMapping / @Service 等任何 Spring 注解
// 复制 doc/SignUtils.java 到项目 utils 包,不要自己写 SignUtil
public class MerchantNotifyDemo {
/**
* 处理 SAAS 发来的商户状态变更通知数据。
* 此方法由你现有的 HTTP 框架调用(如何接收通知由你的框架决定,不在生成范围)。
*
* @param notifyData SAAS POST 过来的 JSON 解析为 Map
* @param accesskey 签名密钥(来自环境变量/配置)
* @param saasBaseUrl SAAS 平台地址,用于调查询接口二次确认
*/
public static void handleMerchantStatusNotify(
Map<String, Object> notifyData,
String accesskey,
String saasBaseUrl) {
// 1. 客户端签名校验:自己算 sign
Map<String, Object> params = new HashMap<>(notifyData);
params.remove("sign");
String computedSign = SignUtils.signParams(accesskey, params);
// 2. 调接口
params.put("sign", computedSign);
String response = httpClient.post(saasBaseUrl + "/api/merchant/notify", params);
// 3. 处理返回请求
}
}
⛔ 强制生成流程(按序号执行,禁止跳步、禁止重排)
以下 6 步是硬性要求。任一步的条件不满足 → 停止,询问用户 → 确认后继续。跳过任一步直接生成代码 = 未按 SKILL 执行。
第 1 步:确认接口
- 从
doc/api-catalog.yaml匹配接口,读取文档 - 多个匹配 → 列出所有候选项,让用户选择;禁止自行挑一个
- catalog 无匹配 → 告知用户,请用户提供接口名称或文档 URL
- ⛔ 未确认具体接口前,禁止进入下一步
第 2 步:确认请求 URL ⛔(最高频遗漏项)
- 从接口文档中提取请求 URL
- 以下情况视为缺 URL,必须询问用户提供完整地址:
- 仅有 path(如
/api/v1/xxx)无完整域名 - 写"运营配置""需运营配置后提供"
- 完全无地址信息
- 仅有 path(如
- 特殊:文档写"通知地址为 notify_url":这不是缺 URL。该文档描述的是 SAAS 将发给服务商的通知数据格式。处理方式:生成客户端代码,入参为通知数据(Map/JSON),计算 sign 与通知中的 sign 比对(用 accesskey,不是 verifySign),然后调 SAAS 查询接口确认状态。不是生成 HTTP 端点去接收通知。注意:调 SAAS 查询接口需要 SAAS 的 base URL,若提示词/配置文件未提供 → 仍需询问用户。
- ⛔ URL 不完整 → 停止,询问用户 → 用户给出后才继续。禁止编造域名、禁止跳过 HTTP 调用
第 3 步:组装请求参数
- 优先使用文档请求示例中的字段和值(
sign除外 — 见第 4 步) - 无请求示例 → 用参数表样例列;仍无 → 询问用户
- 必填参数缺值 → 告知用户,列出缺失项
- ⛔ 禁止使用
"test"、"xxx"、"abc"等自编占位值。参数值只能来自:文档示例 > 参数表样例 > 用户提供
第 4 步:获取 accesskey 并计算 sign
- accesskey 来源:环境变量 > 项目配置 > 询问用户
- ⛔ sign 必须实时计算,禁止抄文档示例中的 sign 值
- 签名算法以
reference/signing.md为准:[过滤空值+sign/mac] → [按 key 字典序排序] → [拼成k1=v1&k2=v2] → [末尾追加 accesskey] → [MD5 大写] - ⛔ 禁止生成
verifySign、checkSign等验签方法
第 5 步:发送 HTTP POST 请求
- 向第 2 步确认的 URL 发 POST,
Content-Type: application/json; charset=utf-8 - sign 必须在第 4 步计算完成后才放入请求体
- ⛔ 最终代码必须包含 HTTP 客户端调用。只生成签名计算而无 HTTP 调用 = 方向错误
第 6 步:处理响应
- 解析 HTTP 状态码 + 响应 body
- 处理成功/失败分支,输出日志
⛔ 生成前强制自检(以下任一项为"否" → 禁止生成代码)
| # | 检查项 | 否 → 处理 | |---|--------|----------| | 1 | 接口已唯一确认? | 列出候选项让用户选 | | 2 | 完整请求 URL 已确认?(含协议+域名+路径) | 询问用户,禁止编造 | | 3 | accesskey 获取方式已确认? | 询问用户 | | 4 | 所有必填参数有值来源? | 列出缺失项,询问用户 | | 5 | 目标语言已明确? | 询问用户 | | 6 | 代码方向是客户端→SAAS(非服务端接收)?含"通知"关键词的接口也是客户端 API | 重新检查,参考顶部「关键误判警告」和「方向规则」 |
⛔ 生成后强制自检(以下任一项为"否" → 代码不合格,必须重写)
| # | 检查项 |
|---|--------|
| 1 | 代码中有 URL 变量或常量(HTTP 请求的目标地址)? |
| 2 | 代码中有 HTTP 客户端 POST 调用? |
| 3 | sign 来自签名方法返回值(非字符串常量)? |
| 4 | 没有 verifySign / checkSign / handleNotify / receiveNotify? |
| 5 | 参数值来自文档示例或用户提供(非 "test" / "xxx")? |
方向规则(客户端 → SAAS,非服务端)
| # | 规则 | 禁止 | |---|------|------| | 1 | 代码方向:客户端 → HTTP POST → SAAS 平台 | 禁止生成服务端接收端(Controller/handler) | | 2 | 签名:用 accesskey 计算 sign | 禁止验签(verifySign/checkSign) | | 3 | 必须包含 HTTP 客户端调用 | 禁止只生成签名计算而无 HTTP 请求 | | 4 | sign 实时计算 | 禁止抄文档示例 sign 值 |
反模式速查:类名含 Receiver/Handler/Listener → 错误;方法名含 handleNotify/receiveNotify → 错误;import 不存在的类(如 SaasConfig)→ 错误;看到"通知""回调"关键词就认为需要生成服务端接收代码 → 错误;说"这超出 skill 范围但我可以为你生成" → 错误(本 skill 无例外)
何时启用
用户在消息中使用 /hk-saas-api,或表达要对接 海科SAAS接口、实现 sign签名、按接口文档生成对接代码时,须按本 skill 流程执行。产出均为客户端代码(组参 → 签名 → HTTP 调平台);绝不生成任何服务端验签、接收通知 Controller 或平台下行处理逻辑。
用户在消息中使用 /hk-saas-update,或表达要更新接口文档时,须按 §7 流程执行。
自包含约束(必读)
本 skill 可单独复制到任意工程或工具目录使用。执行时只读本目录内资源:
| 路径 | 用途 |
|------|------|
| doc/api-catalog.yaml | 接口场景与在线文档 URL(唯一结构化目录,勿再找历史 txt);每个 API 含 local_doc 指向本地缓存 |
| doc/docs/ | 本地接口文档缓存(Markdown 格式,从在线文档门户预下载并转换),manifest.json 记录下载时间与映射 |
| doc/SignUtils.java | Java 可直接复制到目标工程工具包;其它语言勿直接拷贝,见 §5 |
| reference/signing.md | Sign 算法、速查表、golden examples(规范与跨语言对照) |
| reference/api-index.md | 场景 id与人类可读索引 |
| reference/languages.md | 多语言检测与 HTTP 栈建议 |
| doc/README.md(可选) | doc/ 目录说明 |
仅导入本文件夹即可:无论从何处复制(例如本仓库的 api-server/skills/hk-saas-api),目标环境只需要这一层目录内的全部文件与子目录;不必带上 hkrt_ai、api-server 或任何上级路径。Markdown/YAML 中的相对路径均以 hk-saas-api/根目录 为基准解析。
禁止引用本 skill 目录外的「原始 txt / 未整理附件」;禁止假设运行时代码仓库里一定存在名为 api-server/ 的目录(文中若出现仅作反面说明)。
签名 sign 与请求示例(必读,防误判)
接口文档「请求示例」里的 sign 仅为排版演示,与当前时刻、当前 accesskey、当前参数字典不保证一致,也不能代表你联调时的正确签名。
| 必须做 | 禁止做 |
|--------|--------|
| 用 accesskey + 待发送的完整业务参数字典(不含 sign),按 reference/signing.md 现算 sign,再 POST | 把请求示例里的 sign 原样写进代码或配置 |
| 单元测试里用 signing.md 的 golden examples 校验签名实现 | 用文档请求示例里的 sign 作为期望值,做 assertEquals / == / 或把「与文档 sign 一致」当作联调成功依据 |
| 联调失败时对照「待签串、key 序、空值过滤」排查 | 认为「算出来的 sign 必须和文档示例一样」才算对 |
结论:文档示例中的 sign 不是合法联调凭据;唯一合法来源是:对本请求实际参数 + 本环境 accesskey 调用签名方法得到的值。
工作流(必须按序)
flowchart TD
trigger[Trigger_slash_saas_or_intent]
scene[Resolve_or_list_business_scenes]
api[Resolve_or_list_APIs_under_scene]
miss{Catalog_hit?}
clarify[Confirm_API_name_or_user_doc_URL_or_paste]
lang[Detect_or_ask_target_language]
learn[Learn_project_conventions]
fetch_online[Try_fetch_doc_url_online]
online_ok{Online_fetch_ok?}
fetch_local[Read_local_doc_cache]
local_ok{Local_doc_exists?}
ask_user[Ask_user_to_provide_doc]
confirm[Confirm_uncertain_info_URL_params_values]
confirm_ok{All_confirmed?}
gen[Generate_client_sign_and_HTTP]
check[Syntax_and_convention_check]
trigger --> scene --> api --> miss
miss -->|no| clarify --> lang --> learn --> fetch_online
miss -->|yes| lang --> learn --> fetch_online
fetch_online --> online_ok
online_ok -->|yes| confirm
online_ok -->|no| fetch_local --> local_ok
local_ok -->|yes| confirm
local_ok -->|no| ask_user --> confirm
confirm --> confirm_ok
confirm_ok -->|yes| gen --> check
confirm_ok -->|no| ask_user --> confirm
进度清单:
- [ ] 业务场景已明确(或已从 api-catalog 的 scenario 列出并确认)
- [ ] 具体接口已明确(catalog 唯一命中,或多匹配时已列出候选并由用户选定具体接口,或用户已提供文档/URL)
- [ ] 若在 catalog 中未命中:已向用户说明无匹配项,并确认名称准确性或已取得文档/URL
- [ ] 目标语言已明确
- [ ] 已学习当前项目的开发规范(目录结构、命名风格、代码分层、依赖管理等)
- [ ] 已取得接口文档内容(在线抓取成功 / 本地缓存读取 / 用户提供)
- [ ] **完整请求 URL 已确认**:文档有完整 URL → 直接使用;文档缺 URL(仅 path / 运营配置 / 完全缺失等)→ 已询问用户并获得完整地址;文档为通知格式描述(url_status=notify_url)→ 按通知处理模式生成客户端代码(见第 2 步);**禁止**编造域名或因缺 URL 而跳过 HTTP 调用
- [ ] **accesskey 获取方式已确认**:环境变量 / 密钥管理 / 项目配置;若无法获取 → 已询问用户
- [ ] **参数值已确认**(请求示例存在且完整,或无示例时已告知用户并获取测试值;**`sign` 除外**——从不采用示例值,一律现算)
- [ ] **所有不确定信息已确认**(无未确认的地址、参数值、语言、落点等)
- [ ] **方向自检已通过**(对照顶部「方向规则」和「生成后强制自检」):代码方向为客户端→SAAS,包含 HTTP 调用,sign 为实时计算,无服务端验签/接收端逻辑
- [ ] 已在用户指定路径生成对接代码:包含 **完整客户端对接流程**(获取参数 → 现算 sign → HTTP 调用 → 处理响应);签名实现符合 `reference/signing.md`;**禁止**仅签名计算而无 HTTP 调用;**不含**任何服务端代码(验签/接收通知/Controller)
- [ ] 已对生成代码做语法检查与项目规范一致性校验
1. 业务场景检测
- 读取
reference/api-index.md中的场景表(与api-catalog.yaml的scenarios[].id对应)。 - 无法确定时:列出全部
title,用 AskQuestion 或对话映射到某个id。
2. 接口检测
- 解析
doc/api-catalog.yaml:在用户已选或已推断的scenarios[].id下匹配apis[].name;若用户未选场景,可在全部 scenarios 中按名称做模糊检索。 - 唯一命中:展示该条的
name+doc_url,进入 §4。 - 多个命中(必须确认,严禁全量生成):
- 停止生成,将匹配到的接口列表展示给用户(每项含
name+ 所属场景),并询问用户具体需要对接哪个(或哪些)。 - 用户指定后才继续:在用户明确选出具体接口之前,不得生成任何对接代码。
- 例外:仅当用户明确说明「全部都要对接」或「上面列出的都生成」时,方可按列表逐接口生成。
- 停止生成,将匹配到的接口列表展示给用户(每项含
未命中 catalog 时(必读,禁止硬编)
- 明确告知:当前
api-catalog.yaml中没有与用户描述一致的接口条目(或无法唯一确定),不要猜测或捏造doc_url、路径与参数字段。 - 询问用户:提供的接口名称是否准确(是否别名、简称、口误、是否属于别的产品线)。
- 名称不准确:请用户给出准确接口名称或从门户里复制的完整标题后,重新检索 catalog;在用户提供准确名称之前,不生成对接代码。
- 名称准确仍无条目(或用户直接选择自建流程):请用户任选其一提供材料,再进入 §4 / §5:
- 接口文档正文(可粘贴):须至少包含测试/生产 请求 URL、参数表或请求示例、返回说明(能支撑签名与 HTTP 即可);
- 接口文档地址:用户给出的 URL 与 catalog 里的
doc_url同等对待——按 §4「快速提取法」抓取页面得到正文后再生成代码。
- 用户仅提供模糊需求且无法补齐名称或文档时:停止生成,保持对话直到材料足够;可建议用户到 SAAS 文档门户按关键词搜索后把页面链接或截图文字发回。
3. 目标语言检测(多语言)
见 reference/languages.md:优先用户明示 → 仓库文件信号 → 询问。
3.5 项目规范学习(必读,生成代码前必须执行)
本 skill 可能被导入不同的开发工具、不同的项目、使用不同的编程语言,因此生成代码前必须先了解当前项目的开发规范,确保生成的代码与项目风格一致。
学习步骤:
-
扫描项目结构:查看项目根目录及子目录的文件组织方式,识别:
- 源码目录结构(如
src/main/java、app/、lib/等) - 配置文件位置(如
resources/、config/、.env等) - 工具类/公共方法存放目录(如
utils/、common/、helpers/等) - 业务逻辑存放目录(如
service/、controllers/、api/等)
- 源码目录结构(如
-
识别开发规范:检查项目中是否包含规范文件:
.editorconfig— 编辑器配置eslint/ruff/checkstyle等代码检查配置README.md中的开发规范章节- 项目已有的代码风格(命名约定、注释风格、异常处理模式等)
-
总结规范要点:将扫描到的规范整理为以下维度,作为代码生成的约束:
- 目录规范:代码文件应放在哪个目录下(如公用方法放
common、工具类放utils、业务逻辑放service、配置放config/resources) - 命名规范:类名、方法名、变量名的命名风格(camelCase、snake_case、PascalCase)
- 代码分层:controller 层避免过多业务逻辑、SQL 通过配置文件管理不嵌入代码
- 依赖管理:新增依赖需同步更新打包部署文件
- 代码复用:重复逻辑提取为公共方法
- 方法长度:方法代码行数控制(如 50 行以内),复杂逻辑需拆分
- 目录规范:代码文件应放在哪个目录下(如公用方法放
-
规范冲突处理:
- 若项目规范与本 skill 默认建议冲突,以项目规范为准
- 若项目无明确规范,则按
reference/languages.md中该语言的通用最佳实践执行
4. 获取接口文档(三级回退,必读)
获取接口文档时必须按以下优先级逐级回退,确保在网络不稳定时仍能正常工作:
优先级 1:在线抓取 doc_url → 成功则使用
优先级 2:读取本地缓存 local_doc → 文件存在则使用
优先级 3:请用户提供文档 → 用户粘贴正文或提供新 URL
4.1 第一级:在线抓取(优先)
- 文档来源可以是:catalog 中的
doc_url,或 用户在 §2 中提供的官方/自建文档 URL。对 URL:统一先做一次"快速抓取",目标是直接拿到接口页主体内容(避免工具长时间探索整个站点)。 - 该文档站点页面通常包含
editormd/markdown-article-inner等标记;主体内容一般在 HTML 的:<article class="markdown-article-inner"> ... </article>(优先)- 或
id="page-content"所在区域
推荐的快速提取法(适用于 Mindoc/EditorMD 风格页面)
- 使用 Agent 的 WebFetch 能力抓取
doc_url页面,获取 HTML 内容 - 从 HTML 中只提取
<article ...markdown-article-inner...>的内部 HTML(剔除目录 TOC,如markdown-tocdiv),再做 HTML→Markdown 的轻量转换 - 只要先拿到"接口名称、请求方法、路径、参数表、示例、返回字段",就可以开始生成代码;无需完整还原页面样式
- 在线抓取成功 → 直接使用抓取内容,跳过第二级和第三级
备选命令行方式(仅当 Agent 无 WebFetch 能力时使用):
- 用命令行先确认可访问(返回 200):
curl -I <doc_url> - 获取 HTML:
curl -L <doc_url> - 再按上述步骤 2-3 提取主体内容
4.2 第二级:本地缓存回退
若在线抓取失败(网络超时、连接拒绝、登录/动态渲染/反爬等),立即回退到本地缓存:
- 从
api-catalog.yaml中该 API 条目读取local_doc字段(如docs/files_saas-1ebob0j33h3ed.md)。 - 以
doc/目录为基准,拼接local_doc路径,读取本地 Markdown 文件。 - 本地 Markdown 已是从 HTML 转换后的格式,包含完整的接口参数表、请求示例、返回示例等,可直接读取使用。
- 本地文件存在且可读 → 使用本地缓存内容,跳过第三级。
- 本地文件不存在 → 进入第三级。
本地缓存说明:
doc/docs/目录包含从文档门户预下载并转换为 Markdown 的全部接口文档(161 个文件)。doc/docs/manifest.json记录了下载时间、每个 API 的doc_url与本地文件的映射关系。- 可通过
doc/download_docs.py脚本重新下载或更新本地缓存(自动将 HTML 转换为 Markdown)。 - 本地缓存可能不是最新版本;若用户反馈文档内容过时,应优先尝试在线抓取。
4.3 第三级:请用户提供
若在线抓取失败且本地无缓存,必须请用户提供文档材料:
- 明确告知:在线文档抓取失败,本地也无该接口的缓存文档。
- 请用户任选其一提供材料:
- 接口文档正文(可粘贴):须至少包含测试/生产 请求 URL、参数表或请求示例、返回说明(能支撑签名与 HTTP 即可);
- 接口文档地址:用户给出的 URL → 按 §4.1「快速提取法」重新尝试抓取(用户提供的 URL 可能指向不同的文档站点)。
- 用户仅提供模糊需求且无法补齐文档时:停止生成,保持对话直到材料足够。
页面内出现的关联链接(如公共参数)按需再抓取;优先抓取与当前接口直接相关的链接,避免全站爬取。
实测提示(减少探索时间)
- 该站点
doc_url页面往往未显式标注 HTTP 方法,但请求示例为 JSON;默认按POST+Content-Type: application/json; charset=utf-8实现,若接口页另有说明则覆盖。 - 请求示例中的
sign通常是示例值;生成代码时应当忽略示例 sign并按reference/signing.md实时计算;禁止用示例sign做单元测试或「签名校验」的期望值(详见上文 「签名 sign 与请求示例」)。 - 若接口参数说明包含"至少送一个"这类约束(例如:
agent_apply_no、merch_no 至少送一个),生成代码时必须做显式校验并给出清晰错误提示,避免请求发出后才失败。- 若同一业务存在微信/支付宝等多渠道的"业务申请"接口,其必填字段通常不同(例如:微信
settle_id,支付宝mcc/business_id)。生成代码时应:- 为不同渠道生成独立的 payload builder / 配置键(例如
wx_*、ali_*),避免字段混用; - 依据文档参数表的
M/O(必传/非必传)做必填校验,并在报错中明确缺失的字段名。
- 为不同渠道生成独立的 payload builder / 配置键(例如
- Windows 终端可能不是 UTF-8,导致中文报错乱码;生成代码时建议在 README 加提示(如
chcp 65001或PYTHONUTF8=1),且异常信息至少包含field_name等可读的 ASCII 关键字,便于定位。 - 文档标题可能出现多余空格(例如
请求 URL:),仅用grep 请求URL可能漏检;提取测试地址时可搜测试环境、<a href="http://47.** 或页面内 第一个业务路径型 URL。 - 参数表 可空列均为 O,但说明里写 「二选一」(如
apply_no与business_code)时,应按说明做 OR 校验,不能误以为都可省略。 - 部分接口请求 JSON 使用 camelCase 或与
agent_no并存的agentNo等字段名;必须与文档示例完全一致后再参与签名(签名按 key 字典序拼接,大小写敏感)。 - 页面 概要描述 偶发与真实接口不符(复制错误);以 请求 URL + 参数表 + 请求示例 为准;若 YAML 目录缺项,可抓取门户首页 HTML 搜索中文接口名得到
doc_url,并将条目补回doc/api-catalog.yaml(保持 skill 自洽)。 api-catalog.yaml未收录时:下载文档门户首页 HTML(如doc_portal_base),用标题关键词检索<a ... title="...">定位doc_url;勿凭接口中文名猜路径。- 整页 HTML 常为一超长行:
rg/grep在部分环境可能对「超长行」匹配不稳定;可搜 URL 路径片段(如trade/limit、query-merchant-product),或对已保存的 HTML 用脚本/read_file局部查看。 accessid并非所有接口必传:accessid主要用于在平台侧获取accesskey,而非所有接口的必传参数。若接口文档参数表中包含accessid,则按文档要求传入并参与签名;若文档中无此字段,则无需配置和传入。生成代码时以接口文档的参数表 M/O 标注为准,但请求示例中包含的字段即使参数表未列出也应传入(参数表偶有遗漏,请求示例是实际可用的参考)。签名只需accesskey,accessid仅当接口文档要求时才作为请求参数参与签名。但生成 Demo/测试代码时,若请求示例中出现accessid,则 Demo 参数中也必须包含该字段(使用示例中的值),不得因"非必传"而自行省略。- 签名计算顺序至关重要:必须先组装业务参数(按文档参数表)→ 计算签名 → 放入
sign。若sign提前放入参数字典,签名必然失败。 - 嵌套对象中的空值字段必须递归过滤:如
merchant_data.ledger_receive_flag=""、product_data.wx.mcc=""等字段,签名时必须跳过。Java 的SignUtils.getToBeSign()已实现递归过滤;其他语言实现时也必须对嵌套 dict/object 做同样的空值过滤。 - 部分页面无 JSON 请求示例:仅有参数表时,按 M/C/O 与说明组装字典,样例列有值必须采用(勿编造或使用通用占位值如 "test"、"xxx");在代码注释中标明「无示例,来自参数表」。
- 测试参数严禁编造:请求示例是测试参数的唯一合法来源,不得使用自编占位值。完整规则见 §5.0。
- 请求示例中包含但参数表未列出的字段也必须保留:部分接口文档的参数表可能不完整(如未列出
accessid,但请求示例明确包含且 API 实际要求),生成代码时请求示例中出现过的字段一律视为应传入字段,不得因"参数表未列"而省略。请求示例与参数表冲突时,以请求示例为准。 - 接口调用地址可能未在文档中明确展示:部分接口的请求 URL(如
https://xxx.xxx.com/xxx/xxx)需要由运营在后台配置后才能获取,文档中可能仅给出请求路径(如/api/trade/pay)而无完整域名。禁止猜测或编造调用地址。若文档中未包含完整的测试/生产请求 URL,必须询问用户获取实际的接口调用地址后再生成代码;在代码中用占位符(如{BASE_URL}/api/trade/pay)并加注释说明「请替换为运营提供的实际调用地址」。
- 若同一业务存在微信/支付宝等多渠道的"业务申请"接口,其必填字段通常不同(例如:微信
4.5 不确定信息确认
在生成任何对接代码之前,必须逐一确认以下不确定信息。任何一项未确认时,禁止生成代码。
4.5.1 请求地址确认
凡无法在接口文档中确定「客户端本次 HTTP 请求应发往的完整地址(含协议与域名,如 https://api.example.com/path)」时,必须询问用户,禁止猜测或编造域名。
首先判断文档类型:
| 文档特征 | 类型 | 处理方式 |
|---------|------|---------|
| 有明确的请求 URL(含 http:// 或 https://) | 标准客户端 API | 直接使用该 URL |
| 有 path 但缺域名 / 写"运营配置" / 完全无地址 | 标准客户端 API,URL 待确认 | 询问用户提供完整地址 |
| 写"通知地址为...notify_url" / url_status=notify_url / 文档名含"通知"且无请求 URL | 通知格式参考文档(描述 SAAS→服务商的通知数据格式) | 不询问 URL。按通知处理模式生成客户端代码(见下) |
通知格式参考文档的处理模式(url_status=notify_url 的接口):
这类文档描述的是 SAAS 将发送给服务商的通知数据格式(如支付成功通知、退款结果通知等),通知发往服务商此前在业务请求中上送的 notify_url。由于每个服务商的 notify_url 不同,文档不写固定地址。
生成的代码是服务商侧的客户端代码,不是服务端接收端点:
- 生成一个方法/函数,入参为通知数据(
Map<String, Object>/dict/ JSON 字符串) - 方法内:用 accesskey 计算通知数据的 sign,与通知中的 sign 比对(这是客户端签名校验,不是 verifySign 服务端验签)
- 根据需要调 SAAS 查询接口(如交易查询)确认状态
- 返回处理结果
- 不生成
@PostMapping/@app.route等 HTTP 端点注册代码——通知如何到达这个方法由服务商自己的框架决定
缺 URL 的识别(标准客户端 API,从文档正文判断):
文档中出现以下任一特征时,视为缺 URL:
- 仅有 path(如
/api/v1/xxx)而无https://或http://开头的完整地址 - 写「运营配置」「运营配置地址」「需运营配置后提供」
- 完全无任何地址信息
- 协议、域名、端口任一缺失
也可从 api-catalog.yaml 预判:该 API 条目含 url_status 字段且值非 complete 时,按以下规则处理。url_status 值含义:
path_only:仅提供 path,缺 Base URL → 询问用户operator_config:运营配置,无具体 URL → 询问用户notify_url:通知格式参考文档,不是可调用的 SAAS API → 不询问 URL,按上述通知处理模式生成客户端代码missing:完全无地址信息 → 询问用户
4.5.2 参数值确认
生成测试/Demo 代码时,参数值必须来自文档请求示例(见 §5.0 强制规则)。遇到以下情况时,必须明确告知用户并确认:
-
无请求示例:接口文档中完全没有请求示例 JSON 或表单。
- 告知用户:"该接口文档中未提供请求示例。参数值将仅按参数表中的样例列生成(如有),或需要您手动提供测试值。请确认是否继续,或提供您期望的测试参数值。"
-
请求示例中缺少某些必填参数:请求示例 JSON 中未包含参数表中标注为必填(M)的字段。
- 告知用户:"请求示例中缺少以下必填参数:
xxx、yyy。请提供这些参数的测试值,或确认这些参数在您的场景中是否确实需要。"
- 告知用户:"请求示例中缺少以下必填参数:
-
参数值具有业务特定性:如商户编号、订单号、金额等与具体业务场景强相关的参数。
- 告知用户:"以下参数值与您的具体业务场景相关,请确认或提供实际值:
merch_no(商户编号)、out_trade_no(订单号)等。"
- 告知用户:"以下参数值与您的具体业务场景相关,请确认或提供实际值:
4.5.3 其他不确定信息
-
目标语言未明确:用户未说明要生成哪种语言的代码,且无法从项目结构中推断。
- 必须询问用户:"请指定要生成的目标语言(Java / Python / Go / TypeScript / C# 等)。"
-
代码落点未明确:用户未说明代码应该放在项目的哪个位置。
- 可按 §5.1 的默认规则生成 Demo,但必须告知用户:"您未指定代码落点,已按默认规则生成 Demo 代码。如需集成到具体业务模块,请告知目标文件路径。"
-
多接口歧义:用户描述的接口名称在 catalog 中有多个匹配项。
- 必须列出所有匹配项,让用户选择具体要对接哪个接口。禁止自行选择一个生成代码。
4.5.4 确认流程与交互规范
必须明确列出不确定项,询问用户确认处理方式,生成代码后标注需补充的内容。
第一步:列出不确定信息清单
发现不确定信息时,必须先明确列出,让用户清楚知道哪些需要确认:
示例输出格式:
「检测到以下信息不确定,需要您确认:
1. **请求地址**:文档中未提供完整可请求的 URL(或仅有 path),需您提供实际调用的完整地址(含 `https://`)。
2. **参数 `merch_no`**:请求示例中未包含此必填参数,需要商户编号。
3. **参数 `out_trade_no`**:订单号需根据您的业务场景生成。
📌 请确认:您能否提供以上信息的实际值?若暂时无法提供,我先用示例值生成代码,并标注需要您后续替换的位置。」
第二步:等待用户确认
- 用户提供了实际值 → 使用用户提供的值
- 用户无法提供,但确认可以用示例值/空值 → 执行第三步
- 用户未回复或回复不明确 → 再次询问:「是否可以用示例值/空值先完成代码生成?确认后我将标注哪些需要您后续修改。」
第三步:生成示例值/空值并标注
用户确认后,按以下规则生成:
| 不确定类型 | 示例值/空值规则 | 标注方式 |
|-----------|----------------|---------|
| 请求地址未定时 | {BASE_URL} 或用户提供的占位 URL | 代码注释「须替换为完整请求地址,已由用户/运营确认」 |
| 商户编号 | "83300000001"(格式化示例) | 代码注释「示例值,需替换为实际商户编号」 |
| 订单号 | "ORD20240101XXXXXX"(时间戳格式) | 代码注释「示例值,需替换为实际订单号」 |
| 其他标识类参数 | "EXAMPLE_XXX" | 代码注释「示例值,需替换」 |
| 无法推断的参数 | 空值 "" 或 "待填写" | 代码注释「需填写实际值」 |
第四步:生成代码并输出补充清单
代码生成后,必须输出一份清单告知用户哪些需要后续补充修改:
示例输出格式:
「代码已生成。以下内容使用示例值/空值,需要您后续补充修改:
【需替换的请求地址】
- `{REQUEST_URL}` → 文档未写全或需运营配置时,由您提供的完整请求地址(如 `https://api.example.com/saas/xxx`)
【需替换的参数值】
- `merch_no: "83300000001"` → 实际商户编号
- `out_trade_no: "ORD20240101XXXXXX"` → 实际订单号
请在上传到生产环境前完成以上替换。」
注意:所有接口在本 skill 下的客户端对接交付物一致:组参 → 按 reference/signing.md 现算 sign → HTTP 客户端向已确认 URL 发起请求 → 解析响应。文档未写全 URL 时,须已完成 §4.5.1 询问并在代码中占位。本 skill 绝不生成任何服务端验签逻辑或接收通知 Controller。
禁止事项:
- 禁止编造真实商户名、真实手机号、真实身份证号
- 禁止使用
"test"、"xxx"、"abc"等无意义占位符(应使用格式化示例值) - 禁止在用户未确认的情况下直接生成代码(必须先询问确认)
核心原则:明确列出不确定项 → 询问用户能否提供 → 用户确认后生成示例值 → 输出补充清单。不猜测,不隐瞒,让用户清楚知道哪些需要修改。
5. 生成对接代码
5.0 测试请求参数来源(强制规则 — 违反即未按 SKILL 执行)
本规则是 SKILL 内最高优先级规则,覆盖一切相悖的其他指引。
生成任何 Demo / 测试类 / build_xxx_params 的请求参数时:
- 先找请求示例:在接口文档中搜索
请求示例标题,定位 JSON 或表单代码块。 - 逐字段原样复制:将请求示例中的每一个字段名和字段值(
sign除外,见下条)原样复制到代码中。 sign唯一例外(与「复制示例」相反):从请求示例复制参数时,不得复制示例中的sign值;不得用该值做变量初值、常量、配置,也不得在客户端联调代码里把「与文档示例sign一致」当作成功条件。sign必须且只能由:当前 Map 中的业务参数(仍不含sign)+accesskey,按reference/signing.md计算后写入。agent_no、accessid等鉴权字段可用环境变量或配置项包装,但常量值必须来自请求示例(sign不在此列)。- 严禁编造:绝对禁止使用
"test"、"xxx"、"abc123"、"your_value_here"、"value1"、AI 自行推测的姓名/手机号/金额等一切非文档来源的值。一个字都不准编。(例外:sign不来自文档,而来自签名算法输出,见上条。) - 仅无请求示例时可例外:当且仅当接口文档完全不存在请求示例时,才允许按参数表样例列构造参数值,且必须在代码注释中标注「无请求示例,数据来自参数表样例列」。
- 所有接口类型的 sign 规则一致:无论接口是否为异步通知、仅提供 path、运营配置地址等,请求示例中的
sign均仅为排版演示,一律禁止抄用,必须用 accesskey + 当前参数字典按reference/signing.md现算。
执行流程:读取接口文档 → 定位请求示例 → 复制到代码 → 删除或未设置 sign → 用 accesskey 与参数字典按 signing.md 计算 sign 后写入 → 添加注释标注数据来源(可写「sign 由签名方法生成,非文档示例值」)。禁止在测试或业务代码中把计算结果与文档示例 sign 做相等断言。跳过「定位请求示例」这一步骤直接生成代码的,视为未按规范执行。
- 输出路径仅按用户指定或询问后写入。
- HTTP 客户端与风格见
languages.md。 - 用户指令优先(必读)
- 若用户已说明 传参方式 / 数据来源 / 代码应落在哪个文件、类或函数,须 严格按用户要求 实现与落点。
- 不要在用户已指定业务落点的情况下,再强行追加一套「仅含文档示例」的独立 Demo 或并行的
build_xxx_params,除非用户明确要求示例并存。 - 仅当用户未说明 传参逻辑与代码位置时,才提供可运行的 Demo(参数来源见 §5.0 强制规则;并注明「生产请改为真实数据来源」)。
5.1 配置与代码分层(必读)
真实接入流程是:先在业务代码里准备好请求参数字典,再调用 SAAS;本 skill 会在不同项目、不同工具里执行,默认没有统一的「参数从哪张表来」的实现,因此生成代码时必须遵守:
| 层级 | 放什么 | 禁止 |
|------|--------|------|
| 配置文件(如 YAML) | 仅各环境的 请求 URL(可按接口分键,如 query_merchant_info_url)。注意:部分接口的调用地址需由运营配置,文档中可能无完整 URL;此时配置文件中放占位符(如 https://{BASE_URL}/api/xxx),并加注释说明「请替换为运营提供的实际调用地址」 | 不要把 merch_no、门店信息、费率等业务字段写进「接口配置文件」;禁止猜测或编造调用地址 |
| 鉴权 | accesskey(签名必需)、agent_no 等:按目标工程使用 环境变量 / 密钥管理 / 独立凭据文件(勿提交真实密钥);accessid 仅当接口文档要求时才配置,主要用于在平台侧获取 accesskey;跨工具可复制示例名如 SAAS_ACCESSKEY、SAAS_AGENT_NO、SAAS_ACCESSID(可选) | 与大量业务键混在同一份「万能 YAML」里 |
| 公用封装 | 一个「给定 URL + accesskey + 业务参数字典(不含 sign)→ 按 reference/signing.md 计算 sign → POST application/json; charset=utf-8(以文档为准)→ 返回响应 body」的方法/类,全项目复用 | 每个接口各写一套散落的签名 + HTTP 拼接(除非用户项目已有统一客户端,则接入该客户端);禁止只有签名计算而无 HTTP 调用(强制规则,无论何种接口类型) |
| 业务层 | 用户在提示词中指定的模块/函数内组装参数;未指定时再由 Agent 在合理位置实现或落 Demo | 与用户指定的文件路径、命名或调用链冲突 |
| Demo(可选) | 仅当用户未说明传参逻辑与落点:可提供 build_xxx_params(参数来源见 §5.0)+ main/脚本入口,便于工具内快速验证签名与 HTTP | 用户已指定落点时仍默认再生成一套「仅示例」的并行入口(除非用户要) |
交付形态建议
- 用户已指定传参与代码位置:只改/只增用户要求处,并接上既有或新建的 公用签名 + HTTP 调用;若用户说复用项目里已有 HTTP 客户端,则不要再新建一套并行封装。
- 用户未指定:公用封装 +(可选)文档示例
build_xxx_params(参数来源见 §5.0)+ 简短可运行入口(入口内须包含一次发往配置 URL 的 HTTP 调用,URL 可占位)。
5.2 accesskey 与联调
accesskey是签名计算的必需凭据,一般在服务商入网成功后下发,也可通过agent_no在平台侧查询/获取。accessid主要用于在平台侧获取accesskey,并非所有接口的必传参数。仅当接口文档参数表中包含accessid时,才需将其作为请求参数传入并参与签名。- 生成代码时:优先用环境变量或项目既有密钥模块存放
accesskey,不要把它和业务参数堆在同一配置文件中。accessid仅在接口文档要求时才配置。 - 若用户仅有
agent_no:提示向平台补全accesskey后再联调,避免在文档站无意义翻找。 - 签名工具类落盘规则(必守)
- Java:将本 skill 内
doc/SignUtils.java原样复制到用户项目工具类所在包路径下(仅修改package与必要时类名以符合项目规范);补全pom.xml/build.gradle中 net.sf.json(json-lib,注意需指定jdk15classifier)、commons-codec 等与该类 import 一致的依赖。 - 非 Java:不得直接复制
SignUtils.java。须阅读doc/SignUtils.java与reference/signing.md,将同等逻辑用目标语言实现后,写入用户项目约定的 utils / helpers / common 等目录(与项目现有工具类组织方式一致);并用signing.md§5 golden examples 做自测。
- Java:将本 skill 内
- 签名语义始终以
reference/signing.md为准;与平台单接口文档冲突时以接口文档为准。 - 生成物须可编译、可测,勿留未解析依赖。
Java 签名调用模板(必读,防止签名错误)
生成 Java 对接代码时,签名与 HTTP 调用必须遵循以下模板(与 languages.md 中 HTTP 栈结合):
// 1. 组装业务参数(不要包含 sign 字段,按文档参数表组装)
Map<String, Object> params = new HashMap<>();
params.put("agent_no", agentNo);
params.put("agent_apply_no", applyNo);
// ... 其他业务参数(按文档参数表 M/O 标注添加)
// 若文档参数表包含 accessid,则添加(accessid 主要用于获取 accesskey,非所有接口必传):
// params.put("accessid", accessId);
// 2. 计算签名(只需 accesskey,SignUtils 会自动过滤 sign/mac 和空值)
String sign = SignUtils.signParams(accessKey, params);
// 3. 将 sign 放入请求体
params.put("sign", sign);
// 4. 发送请求
String response = httpClient.post(url, JSONObject.fromObject(params).toString());
关键注意事项:
- 签名只需
accesskey:accesskey是签名计算的必需凭据;accessid主要用于获取accesskey,仅当接口文档要求时才作为请求参数参与签名 - 步骤 3 必须在步骤 2 之后:
sign字段不能参与签名计算 - 嵌套对象中的空值字段会自动被过滤:如
product_data.wx.mcc=""不会出现在签名串中 - 不要使用
JSONObject直接遍历拼接:JSONObject键序不确定,必须通过SignUtils.getToBeSign()转为TreeMap后拼接
5.3 Java 参数类规范(必读)
生成 Java 请求参数类/DTO 时,必须使用 Lombok 注解,禁止手写 getter/setter/constructor 等样板代码。
强制规则:
| 场景 | 必须使用 | 禁止 |
|------|---------|------|
| 请求参数类(DTO/Request/VO) | @Data | 手写 getXxx()/setXxx() |
| 不可变参数类 | @Value | 手写 final 字段 + 全参构造器 + getter |
| 链式构造参数类 | @Data + @Builder | 手写 Builder 模式 |
| 嵌套参数对象 | @Data | 手写 getter/setter |
示例:
// ✅ 正确:使用 @Data
@Data
public class CreateMerchantRequest {
private String agentNo;
private String merchName;
private String contactPhone;
}
// ❌ 错误:手写 getter/setter(冗余,不符合规范)
public class CreateMerchantRequest {
private String agentNo;
public String getAgentNo() { return agentNo; }
public void setAgentNo(String agentNo) { this.agentNo = agentNo; }
// ...
}
Lombok 依赖(如项目未引入,生成代码时需提醒用户在 pom.xml 中添加):
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<scope>provided</scope>
</dependency>
注意:
lombok的scope为provided,运行时由 IDE/编译器处理,不打包进最终 jar。
5.5 语法检查与规范校验(生成代码后必须执行)
代码生成完成后,必须进行以下检查,确保代码可正常运行且符合项目规范:
-
方向与流程检查(对照顶部「⛔ 强制生成流程」和「方向规则」,最高优先级):
- 代码中是否有 URL 变量/常量(请求地址)?无 → 方向错误,必须添加
- 代码中是否有 HTTP 客户端 POST 调用?无 → 方向错误,必须添加
- 代码中是否有
verifySign、checkSign、validateSign等验签操作?有 → 必须删除 - 代码中是否有
handleNotify、receiveNotify、onNotify等服务端接收方法?有 → 必须删除 - 代码中是否有解析请求 body → 业务处理 → 构建响应(如
SUCCESS/return_code)的服务端逻辑?有 → 必须删除 - 代码中的
sign是否来自签名方法返回值(而非字符串常量)?否 → 必须重构 - 是否生成了
import saas.notify.*、SaasConfig.getInstance()等目标项目不存在的依赖?有 → 使用标准库实现
-
语法检查:
- Java:检查 import 是否完整、类型是否匹配、方法签名是否正确、异常处理是否完善;参数类/DTO 是否使用 Lombok
@Data(禁止手写 getter/setter) - Python:检查缩进是否一致、import 是否完整、类型注解是否正确
- Java:检查 import 是否完整、类型是否匹配、方法签名是否正确、异常处理是否完善;参数类/DTO 是否使用 Lombok
-
项目规范一致性校验(基于 §3.5 学习到的规范):
- 代码文件是否放在正确的目录下(公用方法 →
common,工具类 →utils,业务逻辑 →service,配置 →config/resources) - 命名风格是否与项目一致(类名、方法名、变量名)
- 方法长度是否在限制内(如 50 行以内),超长方法需拆分
- controller 层是否避免了过多业务逻辑
- SQL 语句是否通过配置文件管理,而非直接嵌入代码
- 新增依赖是否已同步更新到打包部署文件
- 是否存在重复逻辑应提取为公共方法
- 代码文件是否放在正确的目录下(公用方法 →
-
签名逻辑校验:
- 签名实现是否与
reference/signing.md一致 - 是否正确过滤了
sign/mac字段和空值 - 嵌套参数展开规则是否正确(对照 golden examples)
- 密钥拼接方式是否与接口文档要求一致(直接拼接 vs
&key=前缀) - Java 特有检查:
- 是否使用了
SignUtils.signParams()而非自行拼接签名串 accessid仅在接口文档要求时才传入和参与签名,非文档要求时不应强行添加;accesskey是签名必需凭据sign字段是否在签名计算之后才放入参数 Map- 嵌套对象中的空值字段(如
mcc="")是否被递归过滤 pom.xml中 json-lib 是否指定了jdk15classifier- 是否编写了 golden examples 单元测试(见
signing.md§8.2) - Demo/测试参数是否符合 §5.0 强制规则(来自请求示例,非编造)
- 是否使用了
- 签名实现是否与
-
客户端对接流程完整性(对照顶部「⛔ 强制生成流程」):
- 是否存在「获取参数 → 现算 sign → HTTP 客户端 POST → 处理响应」的完整调用链
- 缺 URL 接口是否已按第 2 步询问用户,代码中用占位符 + 注释
- 是否存在仅签名计算而无 HTTP 调用的生成代码(禁止,与顶部强制规则对齐)
- 是否误生成了服务端验签 / 接收通知 Controller(本 SKILL 绝不生成任何服务端代码)
- 是否误用文档请求示例中的 sign:不得硬编码、不得作为断言期望值
-
sign 生成逻辑(与 §5.0 对齐):
- sign 是否通过 accesskey + 参数字典现算(而非抄用文档示例值)
- sign 是否在签名计算后才放入参数字典
- 嵌套参数展开规则是否正确(对照 golden examples)
- 密钥拼接方式是否与接口文档要求一致(直接拼接 vs
&key=前缀)
-
依赖完整性检查:
- 新增的第三方库是否已在项目依赖文件中声明(
pom.xml、requirements.txt、go.mod、package.json等) - 是否存在未解析的 import 或引用
- 新增的第三方库是否已在项目依赖文件中声明(
-
问题处理:
- 发现语法错误 → 立即修复后重新检查
- 发现规范不一致 → 调整代码以符合项目规范
- 发现签名逻辑问题 → 对照
reference/signing.md修正
6. 清理临时文件(生成后必须执行)
- 若为"抓文档→生成代码"过程创建了临时文件(如
*.html、*_doc.html、抓取缓存、解析中间产物),在代码生成完成后应自动删除,避免污染用户工程与提交历史。 - 仅保留:最终对接代码、配置模板、必要的单元测试(如签名 golden tests)与简短 README。
详细参考
安装到各工具
复制整个 hk-saas-api 文件夹(含 doc/、doc/docs/、reference/、SKILL.md)到对应 skills 目录。缺少 doc/api-catalog.yaml、doc/docs/(本地文档缓存)、doc/SignUtils.java(Java 直拷用)或 reference/signing.md 则本 skill 不完整。
可通过 doc/download_docs.py 脚本重新下载或更新本地接口文档缓存(需网络连接到文档门户,仅当环境中安装了 Python 时可用)。
7. 更新接口文档(/hk-saas-update 命令)
用户使用 /hk-saas-update 命令时,按以下流程更新本地接口文档缓存。
重要:本 skill 支持 Java/Python 等多语言环境,不能假设运行环境已安装 Python。更新操作必须通过 Agent 自身能力(WebFetch 抓取页面 + 文件写入)完成,而非调用 Python 脚本。
命令格式:
/hk-saas-update # 更新全部接口文档
/hk-saas-update {接口名称} # 按接口名称模糊匹配,仅更新匹配的接口
示例:
/hk-saas-update # 更新全部 161 个接口文档
/hk-saas-update 预下单 # 更新"预下单"接口文档
/hk-saas-update 商户入网 # 更新所有包含"商户入网"的接口文档
/hk-saas-update pre-pay # 按英文标识(local_doc 文件名)匹配
执行步骤(由 Agent 直接执行,不依赖 Python):
- 解析过滤条件:从命令参数中提取接口名称关键词(支持中文名称和英文标识模糊匹配)
- 匹配接口:读取
doc/api-catalog.yaml,遍历所有scenarios[].apis[],对name(中文名称)和local_doc(英文标识文件名)做模糊匹配 - 在线抓取:对匹配到的每个接口,使用 Agent 的 WebFetch 能力从
doc_url抓取文档页面 HTML - 提取主体内容:从 HTML 中提取
<article class="markdown-article-inner">区域的内容,剔除 TOC 目录(markdown-tocdiv),转换为 Markdown 格式 - 保存到本地:将 Markdown 内容写入
doc/{local_doc}指定的文件路径(如doc/docs/pre-pay.md),已有文件直接覆盖 - 更新清单:更新
doc/docs/manifest.json中对应条目的下载时间和状态 - 输出结果:报告成功/失败数量,失败的接口输出名称和 URL
HTML 提取规则(与 doc/download_docs.py 一致):
- 定位
<article class="markdown-article-inner">标签,提取其内部 HTML - 若无此标签,尝试
<article id="page-content"> - 剔除
<div class="markdown-toc">目录导航区域 - 剔除
<script>和<style>标签 - 将清理后的 HTML 转换为 Markdown 格式(保留表格、代码块、链接等结构)
- 合并多余空行(3 个以上连续空行合并为 2 个)
备选方案:若环境中安装了 Python 及 yaml、markdownify 依赖,也可直接运行脚本:
python doc/download_docs.py 预下单 订单查询 # 按名称过滤
python doc/download_docs.py # 更新全部
但不得将此脚本作为唯一更新方式,Agent 必须能独立完成更新操作。
Scan to join WeChat group