mcpField
G
generate-connectivity-knowledge

generate-connectivity-knowledge

github.com/mulesoft开发14226 次安装今天更新
代码仓库

关于 generate-connectivity-knowledge

此技能为缺少专用 Mule 连接器的 SaaS API 生成集成所需的连接知识,供 Mule HTTP-Connector 工作流使用。它研究 API、生成 OpenAPI 3.0 规范,并逐项对照在线服务验证操作。

主要功能

  1. 01研究 API 文档与端点
  2. 02生成 OpenAPI 3.0 规范
  3. 03针对在线服务验证操作
  4. 04整理认证、分页与实体信息
  5. 05输出 API 参考和配置占位文件

适用场景

  1. 01为缺少专用 Mule 连接器的 SaaS 生成 HTTP 集成资料
  2. 02验证生成的 API 操作及其请求响应
  3. 03将 OpenAPI 规范提供给 Exchange 或其他工具

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mulesoft/mulesoft-dx --skill generate-connectivity-knowledge

安装后在 Claude Code 中输入/generate-connectivity-knowledge确认已加载。

附带文件references/examples.md

详细介绍

生成连接知识

此技能会为 Mule HTTP-Connector 流生成所需的连接知识,以便集成在 Exchange 中没有专用 Mule 连接器的 SaaS。它分三个阶段进行:研究 API、生成 OpenAPI 3.0 规范、针对实时服务验证每项操作,并在 connectivity-schema/<apiName>/ 下生成一个自包含文件夹,其中包含 api-reference.md、<apiName>.yaml 和占位文件 config.properties。

当 get_latest_connector.sh 未能为某个系统找到合适的连接器时,build-mule-integration 会在其第 3a 步(HTTP 回退分支)调用此技能。随后,流生成器会读取生成的知识,为 HTTP Request 操作配置正确的身份验证、分页和实体结构。

输出的使用者

  • build-mule-integration 第 2 阶段 — 使用 api-reference.md 中的 Authentication、Rate Limits、Use Cases 和 Entity Reference 部分生成 HTTP Request 配置和 DataWeave 转换。
  • 用户,合并后 — <apiName>.yaml 是真实的 OpenAPI 3.0 规范,可供用户发布到 Exchange 或输入其他工具。

此技能生成的每项内容都应至少服务于上述一类使用者。如果某条信息既不能帮助构造请求、验证响应、连接依赖项,也不能收集凭据,就不应包含在这里。

自主运行原则

研究和规范生成阶段会自主运行,不会提示用户。实时验证阶段也会自主运行,但以下四个强制暂停点除外:

  1. 收集凭据 — 如果 config.properties 不存在或缺少必需的键,技能会创建带占位符的文件,要求用户填写并等待。必须执行——不得跳过验证、编写占位报告或在没有凭据的情况下继续。
  2. 实体 ID — 如果某项操作需要引用现有实体,技能会要求用户提供这些实体。
  3. 确认破坏性操作 — 执行 DELETE 或具有破坏性的 PUT 之前,技能会警告用户相关后果并征求确认。
  4. 无法解决的失败 — 验证循环结束后,如果仍有操作失败,技能会询问用户如何继续(重试/保留/移除/取消)。

身份验证失败(401/403)会立即终止循环并显示停止报告;这不属于交互式暂停,循环会直接停止。

其他一切——操作选择、请求构造、执行、架构比较、错误处理和重试——都会静默完成。用户只会看到简要的进度行和最终结果。

凭据安全 — 强制要求

这些规则适用于整个工作流。违反规则属于严重失误。

  1. 绝不可读取、显示、回显、记录或推断 config.properties 中的凭据值。
  2. 要验证凭据键是否存在,请使用 grep -c '^KEY_NAME=' config.properties——这会返回计数(0 或 1),而不是值。
  3. 要将凭据注入 curl 命令,请使用内联 Shell 替换:$(grep '^KEY_NAME=' config.properties | cut -d'=' -f2-)。该值会通过 Shell 传递,但绝不会进入对话上下文。
  4. 如果 curl 命令的输出意外包含凭据(例如出现在错误消息中),请勿复述该输出。总结结果时不得包含敏感内容。

工作流

INPUTS → DOC_DISCOVERY → PRIMARY_ENDPOINTS → PRIMARY_ENTITIES → CRUD_COMPLETION
       → DEPENDENCY_ANALYSIS → SECONDARY_CRUD → ACTION_PLAN → DEEP_RESEARCH
       → API_REFERENCE_CONSOLIDATION → OPENAPI_SPEC_GENERATION
       → VALIDATION_PREREQUISITES → VALIDATION_LOOP → FINAL_REPORT

按顺序执行以下步骤。不得跳步——每一步都依赖上一步的输出。


步骤 1:输入

从 $ARGUMENTS 中解析以下内容;如果缺少,则询问用户:

  1. apiName — SaaS 平台 / API 名称,采用 kebab-case 格式(例如:canva-lms、jira、coda)。这将成为 connectivity-schema/ 下的子文件夹名称和 OpenAPI 文件名。
  2. useCases — 此集成需要执行的一项或多项具体操作。示例:
    • “获取最新课程,并在有新课程时发送通知”
    • “检索 Jira 工单并更新其状态”
  3. Project Folder (可选) — 写入输出文件的目录。默认为 <workspaceRoot>/connectivity-schema/<apiName>/。将 <workspaceRoot> 解析为当前 VS Code 工作区;如果没有打开工作区,则使用当前工作目录。
  4. documentation (可选) — 指向 API 文档的一个或多个 URL。提供后(例如,由调用此技能的技能提供),将在步骤 2 中直接使用这些 URL,而不是进行搜索。

确认第 1–2 项均已提供。如果缺少任一项,请询问用户。未收到这两项之前,不要继续。

在此技能余下部分中,{PROJECT_FOLDER} 均指已解析的 Project Folder。如果该文件夹尚不存在,请创建它。


步骤 2:发现文档

查找 Agent 在研究期间将阅读的 API 文档。

如果步骤 1 中提供了文档 URL: 使用 WebFetch 逐一确认 URL 可访问,且包含端点文档。如果所有提供的 URL 均有效,则将其用作文档来源,并跳至下面的选择步骤(第 4 步)。只有在提供的 URL 无法访问或不包含端点文档时,才使用 WebSearch 搜索。

  1. 使用 WebSearch 搜索 API 的官方文档。搜索以下内容:
    • 官方 REST API 参考(例如:"{apiName} REST API reference")
    • OpenAPI / Swagger 规范(例如:"{apiName} OpenAPI spec")
    • 开发者门户或 API 浏览器
  2. 优先选择机器可读的来源 — OpenAPI 规范和结构化 REST 参考比博客文章或教程更有用,因为它们包含下游 Agent 所需的准确字段类型、必填 / 可选标记和架构定义。
  3. 选择最权威的来源,并说明选择理由。通常需要两个来源:便于理解背景和示例的可读 API 参考,以及提供准确架构的机器可读规范。
  4. 使用 WebFetch 获取选定的文档页面,以确认页面可访问且包含端点文档。如果某个来源失效或没有帮助,请寻找替代来源。

至少确认有一个可访问的文档来源后,才能继续。

阅读 references/examples.md → “步骤 2:发现文档”,查看完整示例。


步骤 3:主要端点识别

将每个用例映射到具体的 API 端点。这些是用户明确要求的端点。

关键 — 按用例筛选。 此技能生成的规范应尽可能精简,涵盖用户的用例,以及一个连接测试端点(在步骤 11 中添加)。不要包含 API 提供的所有端点。目标是生成最小但忠实的规范,而不是全面的目录。

对于每个用例,阅读已确认的 API 文档并识别:

列需要记录的内容原因(下游使用者)
用例操作端点的功能为规范生成提供上下文
方法HTTP 方法(GET、POST、PUT、DELETE)规范生成会构建 OpenAPI 操作
路径包含参数占位符的确切路径规范生成和验证会据此构建 URL
路径参数参数名称和类型规范生成需要这些类型来构建 OpenAPI 路径项
是否有请求体端点是否接受请求体验证需要知道是否应发送请求体
内容类型通常为 application/json规范生成会填充内容类型

构建一个仅包含以下列的映射表:

| Use Case Action | Method | Path | Path Parameters | Has Body | Content Type |
|---|---|---|---|---|---|
| ... | GET | /resource/{id} | id (string) | No | application/json |

如果一个用例映射到多个端点(例如,更新 Jira 工单状态需要使用 Transitions API,而不是简单的 PUT),请将它们全部列出,并注明差异。

如果某个用例无法映射到端点,请将其标记出来并说明原因。

在将每个用例都映射到至少一个端点之前,不要继续。

阅读 references/examples.md → “步骤 3:主要端点识别”中的完整示例。


步骤 4:主要实体提取

识别主要端点操作的实体,并记录其标识符。

标识符字段对步骤 13 中的验证循环至关重要。创建测试实体时,验证循环需要知道响应中的哪个字段包含后续请求要使用的 ID。务必确认正确。

构建一个仅包含以下列的表格:

| Entity | Identifier Field | Alt Identifier | Role |
|---|---|---|---|
| Issue | id (string) | key (string, PROJ-123) | Primary |
| Project | id (string) | key (string, PROJ) | Secondary (dependency) |

无需单独列出 CRUD 覆盖缺口——步骤 5 的 CRUD 目录会通过 Source 列跟踪哪些操作来自用例,哪些来自 CRUD 补全。

在识别出所有主要实体及其标识符字段之前,不要继续。


步骤 5:CRUD 补全

对于每个主要实体,查找缺失 CRUD 操作对应的端点。验证循环需要这些端点来管理测试数据:

  • 创建 → test-setup — 在运行用例前创建测试实体
  • 列表/搜索 → test-validation — 验证操作是否成功
  • 删除 → test-cleanup — 测试后清理数据
  • 读取/更新 → 如果存在相应端点,则补全 CRUD 操作集

构建一个包含以下列的表格:

列需要记录的内容
操作创建、读取、更新、删除、列表
方法HTTP 方法
路径包含参数占位符的确切路径
路径参数参数名称和类型
是否有请求体布尔值
生命周期用途test-setup、test-validation、test-cleanup 或 —

如果 API 不支持某个 CRUD 操作(例如,没有 Delete 端点),请明确记录——验证循环需要知道这会如何影响清理策略。

在补全所有主要实体的 CRUD 缺口之前,不要继续。


步骤 6:依赖项分析

识别主要实体需要预先存在的实体。这是验证循环中最重要的阶段——它决定操作顺序、测试数据创建链,以及开始测试前必须设置哪些实体。

必须执行的依赖项测试

对于主要实体引用的每个实体,执行以下测试:

“如果我创建主要实体时不提供对该实体的引用,API 会返回错误吗?”

  • 是 → 次要实体 — 将其纳入。验证循环必须先创建此实体,再创建主要实体。
  • 否 → 排除 — 这是可选关系,跳过。
记录引用字段详情

对于每个必需依赖项,记录:

列记录内容原因
引用的实体依赖实体名称验证需要知道要创建什么
必需字段确切的 JSON 字段路径(例如 fields.project.id)验证需要在创建请求中填充此字段
引用格式使用 ID 还是 key验证需要知道应从依赖项的创建响应中提取哪个标识符
决策次级实体 / 预先存在 / 排除确定后续步骤
预先存在的依赖项

某些必需字段引用由系统管理的实体,这些实体无法通过 API 创建或删除(例如 Jira 中的问题类型、优先级、状态)。这些不是次级实体——测试会发现有效值,而不是创建它们。对于每个预先存在的依赖项,记录返回有效值的List/Get 端点。

递归遍历依赖树

次级实体本身也可能存在必需依赖项。递归应用相同的测试,直到到达可以独立创建(没有必需依赖项)的实体。

构建依赖关系图

创建 Mermaid 图,展示依赖树。必需依赖项使用实线箭头,预先存在的依赖项使用虚线箭头。每个箭头上都要注明字段引用。

记录所有决策

记录每项纳入、排除和预先存在的分类,并说明理由。此工作流完全自主——完成后,这些决策需要可供审查。

在完整依赖树绘制完毕且所有决策都已记录之前,不要继续。


步骤 7:次级实体 CRUD

对于步骤 6 中确定的每个次级实体,发现完整的 CRUD 端点。验证循环需要这些端点来:

  • 创建依赖链,从底向上(例如,先创建 Project,再创建 Issue)
  • 删除依赖链,从顶向下(例如,先删除 Issue,再删除 Project)

使用与步骤 5(CRUD 完成)相同的表格格式,包括每个次级实体的生命周期用途标签和标识符字段。

在所有次级实体都拥有完整的 CRUD 端点目录之前,不要继续。


步骤 8:行动计划

将所有发现整理为结构化行动计划,并按下游使用方分类。这是发现和规划阶段的最终产出。

按以下部分构建行动计划

1. 用于生成规范(步骤 11)

  • 主要端点目录——这些端点将成为 OpenAPI 操作。使用以下表格格式:
| Use Case Action | Method | Path | Path Parameters | Has Body | Content Type |
|---|---|---|---|---|---|
| {action} | {method} | {path} | {params or —} | {Yes/No} | {content type} |
  • 包含标识符字段的实体列表——这些实体将成为架构定义

2. 用于实时验证(步骤 12–13)

  • 完整的 CRUD 端点目录(主要端点 + 次要端点),并标注生命周期用途——验证循环使用 test-setup 端点创建测试数据,使用 test-cleanup 端点删除测试数据
  • 包含字段引用的依赖关系图(Mermaid 图)——用于确定操作顺序
  • 创建顺序(自底向上)和删除顺序(自顶向下)——每种顺序各用一行内联箭头表示法(→)(例如,创建 A → 创建 B → 创建 C),不要使用编号列表
  • 包含发现端点的预先存在依赖项——验证循环会调用这些端点获取有效值,而不是尝试创建
  • 决策日志——将所有依赖项决策(作为次要实体纳入、预先存在、排除)及其理由汇总到一个表格中,以便验证循环查看每个实体被纳入或排除的原因

3. 用于收集凭据(步骤 12)

  • 从文档中识别的身份验证方案(如果此阶段可确定):类型(Bearer、API Key、Basic、OAuth)、必需的凭据键、标头格式
  • 如果身份验证详情尚不明确,请将其记为步骤 9 深入研究的待解决项

4. 研究计划

  • 研究顺序:先研究次要实体(依赖树底部),再研究主要实体。这样,在记录主要实体时,其依赖项详情已经明确。
  • 范围:待研究的实体总数、发现的端点总数
  • 排除的实体及其理由
编写行动计划

使用 Write 工具将行动计划保存到 {PROJECT_FOLDER}/action-plan.md。此文件会保留发现阶段的工作,供深入研究阶段(步骤 9)使用。

阅读 references/examples.md → “Step 8: Action Plan”,查看完整示例。


步骤 9:深入研究

对于研究计划中的每个实体,阅读 API 文档并记录详细的架构、字段和行为,供下游使用方构造请求、验证响应、关联依赖项和收集凭据。

输入: 步骤 8 的行动计划({PROJECT_FOLDER}/action-plan.md)提供了研究顺序、端点目录、依赖关系图,以及步骤 2 中确认的文档来源。

文档来源优先级: 使用 OpenAPI 规范(如果步骤 2 中有提供)作为请求/响应架构和字段详情的主要来源——其中包含准确的类型、必填/可选标记和架构定义。使用易读的 API 参考文档补充分页模式、速率限制行为、副作用,以及规范中未涵盖的行为详情。如果没有 OpenAPI 规范,则所有内容均使用易读的文档。

重要: 严格按文档原样复制字段名称、类型和约束。不要推断或猜测字段详情。

处理顺序

遵循行动计划中的“研究计划”部分:

  1. 首先研究 API 级说明(身份验证方案和速率限制——这些适用于全局)
  2. 接着记录 预先存在的实体(轻量处理——仅记录发现架构)
  3. 按自底向上的顺序研究 次要实体(先研究依赖树底部的实体)
  4. 最后研究 主要实体

完成每个实体的研究后,立即将其写入输出文件。不要先在对话中累积所有研究内容再统一写入。

API 层级说明

在研究各个实体之前,先记录两个 API 层级类别。使用 WebFetch 获取 API 的身份验证和速率限制文档页面。

项目需要记录的内容原因(下游使用方)
身份验证类型Bearer、Basic、API Key、OAuth凭据收集需要了解注入模式
标头格式标头名称及值格式(精确内容)验证需要据此构造请求标头
必需凭据凭据键名称凭据收集会提示用户填写
基础 URLURL 格式(注明变量部分)验证需要据此构造请求 URL
全局速率限制每秒/分钟请求数验证需要据此控制请求频率
429 行为是否包含 Retry-After 标头?响应体格式是什么?验证需要据此实现退避机制
重试策略建议采用的方法验证需要据此重试失败的请求
预先存在的实体处理方式

预先存在的实体(在依赖关系分析中标记为 PRE-EXISTING)由系统管理,无法通过 API 创建或删除。测试应发现有效值,而非创建这些实体。

对于每个预先存在的实体,仅记录:

  1. 发现端点的响应架构——List/Get 端点会返回哪些字段
  2. 要提取的字段——下游使用方需要哪个字段(例如 id、name)及其类型

对于预先存在的实体,跳过请求架构(不涉及 Create/Update)、字段目录、实体引用、分页和副作用。

逐实体深入研究

对于每个次要实体和主要实体,研究并记录以下 6 个类别。身份验证方案和速率限制属于 API 层级,无需在每个实体中重复记录。

类别 1:请求架构

对于每个接受请求体的操作(通常是 Create 和 Update),记录准确的请求结构。

项目需要记录的内容
操作Create、Update 或其他接受请求体的操作
Content-Typeapplication/json、application/x-www-form-urlencoded 等
最小请求体有效请求所需的最小内容(仅含必填字段)
完整请求体所有字段,包括可选字段

每个操作按以下格式记录:

**Create — POST `/path`**
Content-Type: application/json

Minimal request body (required fields only):
{json}

Full request body (all fields):
{json}

如果某项操作不接受请求体(例如 DELETE),则在本节中跳过。

类别 2:响应架构

对于每个操作,记录响应结构,包括状态码。

项目需要记录的内容
操作Create、Read、List、Delete 等
成功状态码200、201、204 等
响应体准确的 JSON 结构(204 时写作“No response body”)
标识符位置实体 ID 在响应中的位置

每个操作按以下格式记录:

**Read — GET `/path/{id}` → 200**
{json}

**Create — POST `/path` → 201**
{json}

**Delete — DELETE `/path/{id}` → 204**
No response body.

对于 List 操作,展示响应封装结构(包含分页字段的包装结构)以及集合中的一个项目。

类别 3:字段目录

汇总所有操作中全部字段的表格。这是字段详情的唯一事实来源。

列需要记录的内容
字段JSON 路径(例如 fields.project.id)
类型string、number、boolean、array、object 或 enum
必填操作哪些操作需要此字段(Create、Update、两者或 —)
约束最大长度、格式模式、允许的枚举值
默认值省略字段时使用的默认值,或 —

按以下格式建立表格:

| Field | Type | Required for | Constraints | Default |
|---|---|---|---|---|
| `name` | string | Create | max 255 chars | — |
| `status` | enum | — | `active`, `inactive` | `active` |

对于枚举字段,列出所有有效值。如果枚举值超过 10 个,则列出有代表性的值,并注明“完整列表请参阅 API 文档”。

类别 4:实体引用

记录此实体如何引用其他实体。此信息为第 6 步的依赖关系分析补充字段级详情,验证循环需要这些详情来关联依赖项。

列需要记录的内容
字段保存引用的字段路径(例如 fields.project.id)
被引用实体被引用的实体
引用格式ID、key、name 或复合格式
是否必需是 / 否 / 预先存在

按以下格式建立表格:

| Field | Referenced Entity | Reference Format | Mandatory |
|---|---|---|---|
| `fields.project.id` | Project | ID (string) | Yes |
| `fields.assignee.accountId` | User | Account ID (string) | No |
类别 5:分页

说明 List/Search 端点如何处理分页。如果实体没有 List 端点,请写“没有 List 端点 — 不适用分页。”

分页检测顺序至关重要:

  1. 始终先检查基于游标的分页 — 查找:continuation、continuation_token、next_cursor、cursor、after、before、next_page_token、offset(当它是令牌/字符串而非数字时)。
  2. 区分偏移量和游标:偏移量使用数值(0、10、20……)。如果名为 offset 的参数包含 "eyJ0eXAi..." 之类的令牌/字符串值,则它属于基于游标的分页,而非偏移量分页。
  3. 某些 API 的响应中同时包含游标令牌和页面元数据(page_count、page_number)——实际分页机制仍是基于游标的。只要存在 continuation/cursor 令牌,就始终使用基于游标的分页。
  4. 仅当文档明确展示了“page”参数且不存在游标指示项时,才使用基于页码的分页。
  5. 每个端点必须且只能使用一种分页类型。绝不能混用类型。
  6. 搜索文档中的 "{apiName} pagination",查找官方模式。

对于每个 List 端点,请使用以下精确结构格式记录:

**List — GET `/path`**
- **Pagination type:** offset | cursor | page | timestamp | none
- **Items field:** {dot-notation path to items array, e.g., "data", "results", "values"}

然后只包含适用类型对应的字段:

对于游标分页:

- **Cursor param:** {query parameter name, e.g., "cursor", "after", "nextToken"}
- **Reference type:** marker | uri
- **Reference expression:** {dot-notation path to next cursor value, e.g., "pagination.nextCursor"}
  • 当响应包含游标值(令牌/字符串)时,使用 marker。
  • 当响应包含下一页的完整 URL 时,使用 uri。
  • 绝不能使用其他值作为引用类型——只能使用 marker 或 uri。

对于偏移量分页:

- **Offset param:** {query parameter name, e.g., "startAt", "offset"} — must be NUMERIC
- **Initial offset value:** {number, typically 0}

对于页码分页:

- **Page number param:** {query parameter name, e.g., "page", "pageNumber"}
- **Initial page number:** {number, typically 0 or 1}

对于时间戳分页:

- **Timestamp param:** {query parameter name, e.g., "since", "after"}
类别 6:副作用与行为

记录会影响下游 Agent 构造、执行或验证操作的行为。对于每项行为,请写明具体行为;如果不适用,则写“无”。

- **Delete behavior:** hard delete / soft delete / archive / deactivate / no delete endpoint
- **Cascade on delete:** deleting this entity also deletes {children} / no cascade
- **Immutable fields:** {field list} cannot be changed after creation / none
- **Async operations:** {operation} returns 202, poll {url} for completion / none
- **Conditional requirements:** {field} required only when {condition} / none
- **Non-standard patterns:** {any API-specific quirks, e.g., status changes via transitions}
编写深入研究

使用 Write 工具将深入研究结果保存到 {PROJECT_FOLDER}/api-reference.md。研究完每个实体后,立即写入该实体的章节——不要等所有研究完成后再统一写入。

文件结构如下:

# {Service} API Reference — Deep Research

## API-Level Notes
{auth scheme + rate limits}

## Pre-Existing Entities
### {Entity} [PRE-EXISTING]
{discovery schema only}

## Secondary Entities
### {Entity} [SECONDARY]
{6 categories}

## Primary Entities
### {Entity} [PRIMARY]
{6 categories}

只有当研究计划中的每个实体都已记录所有适用类别后,才能继续。


步骤 10:整合 api-reference.md

将操作计划(步骤 8)和深入研究(步骤 9)整合到一个独立完整的 api-reference.md 中。完成此步骤后,下游使用者(步骤 11 中的 OpenAPI 生成器、步骤 12–13 中的验证循环,以及调用 build-mule-integration 技能)只需使用这一个文件——无需再读取 action-plan.md。

输入
  • 步骤 8 的 {PROJECT_FOLDER}/action-plan.md
  • 步骤 9 的 {PROJECT_FOLDER}/api-reference.md(深入研究文件)
步骤
  1. 读取 action-plan.md 并提取:

    • 用例端点表(来自 §1“用于规范生成”)
    • 完整 CRUD 端点目录(来自 §2“用于实时验证”)
    • Mermaid 依赖关系图(来自 §2)
    • 创建顺序和删除顺序(来自 §2)
    • 预先存在的依赖项表(来自 §2)
    • 决策日志表(来自 §2)
    • 身份验证方案详情(来自 §3“用于凭证收集”)
    • 文档来源 URL(来自标题部分)
  2. 读取 api-reference.md(步骤 9 的深入研究)并记录:

    • API 级别说明的内容(身份验证方案 + 速率限制)——这将成为顶层的身份验证和速率限制章节
    • 所有实体章节(预先存在、次要、主要)及其完整类别详情
  3. 按照以下精确模板编写最终版 api-reference.md。使用 Write 工具覆盖步骤 9 的文件,写入整合后的内容。

输出模板

严格按照以下结构编写最终版 api-reference.md:

# {Service} API Reference

## Overview
- **Service:** {apiName}
- **API Version:** {version from documentation, e.g., "v3", "v1", "2023-08-01"}
- **Base URL:** {base URL from API-Level Notes}
- **Documentation:** {primary documentation URL from action plan header}

## Authentication
- **Type:** {Bearer / Basic / API Key / OAuth}
- **Header format:** {exact header pattern, e.g., `Authorization: Basic base64({email}:{api_token})`}
- **Required credentials:** {credential key names, e.g., `BASIC_USERNAME`, `BASIC_PASSWORD`}
{include any additional auth details from the deep research — alternative auth methods, transport requirements, test mode info}

## Rate Limits & Constraints
{Rate Limits content from Step 9 API-Level Notes — copy the full detail including global limits, burst limits, 429 behavior, retry strategy, endpoint-specific limits}

## Use Cases

{endpoint table from action plan §1, copied exactly:}

| Use Case Action | Method | Path | Path Parameters | Has Body | Content Type |
|---|---|---|---|---|---|
| ... | ... | ... | ... | ... | ... |

{include any deviation notes from the action plan}

## Entity Dependency Graph

{Mermaid diagram from action plan §2, copied exactly}

- **Creation order:** {bottom-up arrow notation from action plan}
- **Deletion order:** {top-down arrow notation from action plan}

**Pre-existing dependencies (discover, don't create):**

{pre-existing dependencies table from action plan §2, or "None — all mandatory dependencies can be created and deleted via the API." if no pre-existing deps}

**Decision log:**

{decision log table from action plan §2, copied exactly}

## Full CRUD Endpoint Catalog

{CRUD catalog table from action plan §2, copied exactly:}

| Entity | Operation | Method | Path | Lifecycle Purpose | Source |
|---|---|---|---|---|---|
| ... | ... | ... | ... | ... | ... |

## Entity Reference

### Pre-Existing Entities
#### {Entity} [PRE-EXISTING]
{discovery schema only — copied from Step 9}

### Secondary Entities
#### {Entity} [SECONDARY]
{all 6 categories — copied from Step 9}

### Primary Entities
#### {Entity} [PRIMARY]
{all 6 categories — copied from Step 9}
标题级别调整

步骤 9 会使用以下标题级别编写实体章节:

  • ## Pre-Existing Entities、## Secondary Entities、## Primary Entities
  • ### {Entity} [TYPE]
  • #### Category N: {name}

在最终输出中,这些章节位于 ## Entity Reference 父级标题之下,因此每个标题都要降一级:

  • ### Pre-Existing Entities、### Secondary Entities、### Primary Entities
  • #### {Entity} [TYPE]
  • ##### Category N: {name}
Entity Reference 中不应包含的内容

不要在 Entity Reference 章节中包含 ## API-Level Notes(Auth Scheme + Rate Limits)——这些内容已提取到顶层的 Authentication 和 Rate Limits 章节中。Entity Reference 章节应直接以 ### Pre-Existing Entities 开始(如果没有预先存在的实体,则以 ### Secondary Entities 开始)。

验证清单

完成此步骤前,请验证最终的 api-reference.md 包含:

  • 标题为 # {Service} API Reference(不带“Deep Research”后缀)
  • 包含带有 base URL 的 Overview 章节
  • 包含列出类型、标头格式和必需凭据的 Authentication 章节
  • 包含 Rate Limits & Constraints 章节
  • 包含列出输入中所有用例的 Use Cases 表格
  • 包含带有 Mermaid 图表的 Entity Dependency Graph
  • 包含创建顺序和删除顺序(内联箭头表示法)
  • 包含预先存在的依赖项表格(或“None”声明)
  • 包含 Decision log 表格
  • 包含完整的 CRUD Endpoint Catalog,并标明生命周期标签
  • Entity Reference 章节包含步骤 9 中的每个实体
  • 每个次要实体和主要实体都保留全部 6 个类别
  • 对预先存在的实体仅提供发现相关内容(不包含请求架构或字段目录)
  • Entity Reference 中没有重复的 API-Level Notes

请勿继续,直到清单中的所有项目都通过验证。


Step 11: 生成 OpenAPI 3.0 规范

读取步骤 10 整合后的 api-reference.md,并在 {PROJECT_FOLDER}/<apiName>.yaml 生成完整的 OpenAPI 3.0 规范。该规范必须准确反映 api-reference 中记录的每个操作、架构、参数和身份验证要求,不得包含其他内容。

要求
  • OpenAPI 版本为 3.0.x。
  • 完整的 info 部分:title 以“API”结尾,version 为语义化版本(例如 1.0.0),description 为一句祈使句。
  • servers 部分包含 base URL(如果 API 使用版本前缀,则包含该前缀)。
  • paths 部分仅包含 api-reference.md 的 Use Cases 表格中记录的端点——不要添加研究中未发现的端点。
  • components 部分包含:§Authentication 中的身份验证方案、可复用的请求/响应正文架构、通用参数、错误响应。
  • 对每个端点定义完整的参数(路径、查询、标头、正文)、完整的响应架构及数据类型、错误响应(4xx、5xx)和身份验证要求。
  • 如果 API 有明显的轻量级“ping”端点(例如 GET /me、GET /health),则添加一个连接测试端点。这个额外操作可让步骤 12 的前置条件在运行完整循环前验证凭据。如果 API 没有此类端点,则不要自行编造——步骤 12 将改用 paths 中的第一个 GET 端点。
关键路径和版本规则
  • API 版本(例如 /v3)必须放在 servers[].url 中,而不是端点路径中。
  • 从端点路径中移除所有 API 版本前缀。
  • 端点路径不得以斜杠结尾。

正确:

servers:
  - url: https://api.example.com/v3
paths:
  /users:
    get: ...
  /users/{id}:
    get: ...

错误:

servers:
  - url: https://api.example.com
paths:
  /v3/users:
    get: ...
  /users/{id}/:
    get: ...
其他规则
  • 每个操作都有一个唯一的 camelCase 格式 operationId(例如,listCourses、getCourseById)。
  • 每个操作都有一个 description(使用祈使语气,且为一个句子)。
  • 每个操作至少有一个请求示例和一个响应示例。
  • 每个架构中的每个属性都有一个 description。
  • 值受限的字符串使用 enum(不得使用未受约束的字符串)。
  • 适用时,每个对象架构都明确指定 required 字段。
  • 路径和查询参数都有描述和类型。

使用 Write 工具写入文件。不要向用户展示规范——立即继续执行第 12 步。


第 12 步:实时验证 — 前提条件

进入逐操作验证循环前,按顺序验证四项前提条件。如果任一项未通过,报告具体问题并停止。除非检查未通过,否则不要逐项说明检查过程。

1. OpenAPI 规范文件
  • 读取 {PROJECT_FOLDER}/<apiName>.yaml。
  • 验证其为有效的 YAML。
  • 验证其包含 openapi 键,且该键的值以 3. 开头(OpenAPI 3.x)。
  • 验证 paths 至少包含一个操作。
  • 统计操作总数——此数值为 M,也是进度行 (N/M) 中的分母。
2. api-reference.md
  • 读取 {PROJECT_FOLDER}/api-reference.md。
  • 验证其包含以下章节:Authentication、Entity Dependency Graph、Full CRUD Endpoint Catalog、Entity Reference。
  • 阅读 Authentication 章节并提取:
    • 身份验证类型(例如,Bearer token、Basic、API Key)
    • 标头格式(例如,Authorization: Bearer <TOKEN>)
    • 所需凭据键名(例如,CODA_API_TOKEN)
    • 对于 API Key 身份验证:注入位置——标头名称(例如,X-API-Key)或查询参数名称(例如,key、token)
3. config.properties

检查 {PROJECT_FOLDER}/config.properties 是否存在。

如果文件不存在——创建该文件:

  1. 使用在第 2 步中提取的凭据键名(例如,CODA_API_TOKEN,或 TRELLO_API_KEY 和 TRELLO_API_TOKEN)。

  2. 为每个键生成占位值:将键名转换为小写,用连字符替换下划线,并在前后分别加上 your- 和 -here(例如,CODA_API_TOKEN → your-coda-api-token-here)。

  3. 创建 {PROJECT_FOLDER}/config.properties,每个凭据占一行,格式为 KEY=placeholder:

    printf '%s\n' 'CODA_API_TOKEN=your-coda-api-token-here' > {PROJECT_FOLDER}/config.properties
    

    如果有多个键,请在一条命令中写入所有行:

    printf '%s\n' 'TRELLO_API_KEY=your-trello-api-key-here' 'TRELLO_API_TOKEN=your-trello-api-token-here' > {PROJECT_FOLDER}/config.properties
    
  4. 向用户报告并等待:

    Created config.properties with placeholder credentials:
    
      CODA_API_TOKEN=your-coda-api-token-here
    
    Please replace the placeholder value(s) with real credentials and let me know when ready.
    

    ▸ 等待——用户确认凭据已就绪前,不要继续。

  5. 用户确认后,继续执行下面的验证键。

验证键(文件创建且用户确认后执行;如果文件已存在,则立即执行):

  • 对第 2 步中识别的每个凭据键,验证该键是否存在:

    grep -c '^CREDENTIAL_KEY=' {PROJECT_FOLDER}/config.properties
    

    结果必须为 1。不要读取或显示其值。

4. 基础 URL
  • 阅读 api-reference.md 的 Overview 章节并提取 Base URL 值(例如,https://coda.io/apis/v1)。
  • 验证其以 https:// 或 http:// 开头。
前提条件检查

静默验证全部四项。如果全部通过,则继续执行第 13 步,不要逐项说明检查过程。如果任一项未通过,则向用户报告具体问题并停止。

▸ 停止——全部四项前提条件通过前,不要继续执行第 13 步。


第 13 步:实时验证 — 循环

前提条件通过后,在处理单个操作之前设置迭代循环。

枚举操作

按文档顺序遍历 OpenAPI 规范中的 paths 对象。对于每个路径,记录该路径上定义的每个 HTTP 方法(GET、POST、PUT、PATCH、DELETE)对应的 (method, path),作为一个操作。构建所有操作的有序列表。总数 = M。

提前收集实体 ID

进入循环前,扫描枚举列表中的所有操作,查找路径参数。对于每个唯一的路径参数名称:

  1. 对照 api-reference.md 的 Entity Reference 部分,确定该参数指代的实体。
  2. 构建去重后的 (parameter_name, entity_type, description) 集合。

如果集合非空,则只提示用户一次,收集所有值:

The operations in this spec require the following entity IDs:

- `docId` (string) — references a Doc entity. Used by 8 operations. Please provide an existing Doc ID.
- `pageIdOrName` (string) — references a Page entity. Used by 4 operations. Please provide an existing Page ID or name.

存储用户提供的值,以便在循环中重复使用。如果没有操作包含路径参数,则跳过此步骤。

循环计数器

初始化:completed = 0、passed = 0、fixed = 0、failed = 0、skipped = 0、auth_halted = false、any_2xx_seen = false。

对于枚举列表中的每个操作,按顺序重置该操作的重试状态:

  • attempt_count = 0 — 每次为此操作执行 curl 请求时递增。
  • retry_history = [] — 每次尝试后,追加:{ attempt_number, status_code, error_summary, fix_applied_if_any }。
  • last_failure_signature = null — 最近一次失败尝试中的 (status_code, error_message_key) 对。

然后,对每个操作执行以下步骤:

  1. 将当前操作设为 (method, path)。
  2. 操作分析 — 第 13.1 步。
  3. 请求执行与响应验证 — 第 13.2 步。
  4. 如果 auth_halted 为 true,则立即退出循环——不要继续执行步骤 5–9。跳至第 14 步。
  5. 递增 completed。
  6. 对结果分类(passed、fixed、failed 或 skipped),并更新相应计数器。
  7. 输出进度行:Validation: {completed}/{M} | passed {X} | fixed {Y} | failed {Z} — 仅当 skipped > 0 时,追加 | skipped {S}。
  8. 如果操作失败,输出详情行: ✗ {METHOD} {path} {status_code} — {reason}。
  9. 继续处理下一个操作。

处理完所有操作后(或因身份验证失败而中止循环后),继续执行第 14 步(最终报告)。

▸ STOP — 在收集完所有实体 ID(如有需要)之前,不要进入循环。

第 13.1 步 — 操作分析

从循环中读取当前操作,并提取构造 HTTP 请求所需的所有信息。

13.1.1 — 确定当前操作。 操作的 (method, path) 已由枚举确定。

13.1.2 — 提取操作定义。 从规范中提取:

  • HTTP 方法(GET、POST、PUT、DELETE、PATCH)。
  • 路径模板(例如 /docs/{docId}/pages/{pageIdOrName})。
  • 路径参数 — 对每个参数提取名称、类型和是否必填(是/否)。
  • 查询参数 — 对每个参数提取名称、类型、是否必填和默认值。
  • 请求正文架构 — 如果方法有 requestBody 定义(通常适用于 POST、PUT、PATCH)。提取必填字段及其类型。
  • 预期成功响应 — 规范 responses 部分中声明的 2XX 状态码(例如 200、201、202)。如果存在多个 2XX 状态码,请全部注明。
  • 响应正文架构 — responses.{status}.content.application/json.schema 下的架构。如果架构使用 $ref,则在规范中查找 components/schemas/{name} 以解析引用。如果未定义响应正文(例如 204),则注明“无正文”。
  • 安全要求 — 操作使用的安全方案(来自操作级或规范级 security 字段)。

13.1.3 — 替换实体 ID。 对于当前操作中的每个路径参数,将存储的值替换到路径模板中。如果某个路径参数未在枚举期间收集(意外出现的参数),则现在向用户询问。如果操作没有路径参数,则跳过此子步骤。

13.1.4 — 验证就绪状态。 继续之前,在内部确认已完整提取操作定义,并已提供所有必需的实体 ID。

第 13.2 步 — 请求执行与响应验证

构造 HTTP 请求,在实时 SaaS 上执行请求,并验证响应。

13.2.1 — 构造 curl 命令

根据操作定义构造 curl 命令。

URL。 将基础 URL 与路径模板组合,并用用户提供的值替换路径参数。 示例:https://coda.io/apis/v1/docs/AbCDeFGH/pages/canvas-abc123。

方法。 使用 -X 标志(例如,-X GET、-X POST)。

身份验证标头。 根据 api-reference.md 中的身份验证类型构造。使用 shell 替换从 config.properties 注入凭据:

  • Bearer 令牌:

    -H "Authorization: Bearer $(grep '^CODA_API_TOKEN=' {PROJECT_FOLDER}/config.properties | cut -d'=' -f2-)"
    
  • Basic 身份验证:

    -H "Authorization: Basic $(echo -n "$(grep '^API_USER=' {PROJECT_FOLDER}/config.properties | cut -d'=' -f2-):$(grep '^API_PASS=' {PROJECT_FOLDER}/config.properties | cut -d'=' -f2-)" | base64)"
    
  • API Key(标头):

    -H "{header_name}: $(grep '^API_KEY=' {PROJECT_FOLDER}/config.properties | cut -d'=' -f2-)"
    
  • API Key(查询参数): 将凭据追加为 URL 查询参数。第一个参数使用 ?,后续参数使用 &:

    "https://api.example.com/endpoint?{param_name}=$(grep '^API_KEY=' {PROJECT_FOLDER}/config.properties | cut -d'=' -f2-)"
    

    对于需要多个查询参数凭据的 API(例如,单独的 key 和 token 参数):

    "https://api.example.com/endpoint?key=$(grep '^TRELLO_API_KEY=' {PROJECT_FOLDER}/config.properties | cut -d'=' -f2-)&token=$(grep '^TRELLO_API_TOKEN=' {PROJECT_FOLDER}/config.properties | cut -d'=' -f2-)"
    

    如果 URL 已包含查询参数(来自 13.1.2 的必需查询参数),则使用 & 追加。

Content-Type 标头。 -H "Content-Type: application/json"(所有请求都要包含)。

请求正文。 如果操作需要正文(POST、PUT、PATCH),则仅使用规范请求正文架构中的必需字段,构造最简 JSON 载荷。使用符合字段类型和约束的逼真占位值。通过 -d '{...}' 传递。

响应捕获。 添加 -s -w "\n%{http_code}" -D /tmp/validation_headers.txt,以隐藏进度输出、在最后一行追加 HTTP 状态码,并将响应标头转储到临时文件,以便需要时检查(例如,429 响应中的 Retry-After)。

13.2.2 — 破坏性操作确认

执行 curl 命令前,检查当前操作是否具有破坏性:

  • DELETE(任何实体)——始终具有破坏性。
  • 会替换整个实体的 PUT——具有破坏性(会覆盖现有状态)。

PATCH 操作不视为具有破坏性——它们只应用部分更新,通常是安全的。POST(创建)操作不具有破坏性——它们会创建新实体,而不是修改现有实体。

如果操作具有破坏性:

  1. 执行前警告用户:

    ⚠️  Destructive operation: {METHOD} {path}
    This will {consequence} the {entity_type} with ID `{entity_id}`.
    This action may not be reversible.
    
    Proceed? (yes / skip)
    

    {consequence} 的取值为:

    • DELETE → "永久删除"
    • PUT → "覆盖所有字段"
  2. 如果用户回答“是”(或表达肯定的等效说法)→ 继续执行 13.2.3 并执行请求。

  3. 如果用户回答“跳过”(或表达否定的等效说法)→ 不要执行请求。将操作归类为已跳过。递增 skipped 计数器。输出包含跳过详情的进度行:

      ⏭ {METHOD} {path}  skipped — user declined destructive operation
    

    直接继续执行 13.2.7。不要将此操作计为失败。

如果操作不具有破坏性,则无需提示,直接继续执行 13.2.3。

13.2.3 — 执行请求

通过 Bash 工具运行 curl 命令。shell 替换会内联解析凭据——实际值不会出现在对话上下文中。

递增当前操作的 attempt_count。解析响应(13.2.4)后,如果状态码不是 2XX:向 retry_history 追加一条记录(包含 attempt_number、status_code、error_summary、fix_applied_if_any),并使用 (status_code, 响应正文中的关键错误详情) 更新 last_failure_signature。

13.2.4 — 解析响应

从 curl 输出中获取:

  • **状态码:**输出的最后一行(来自 -w "\n%{http_code}")。
  • **响应正文:**除最后一行外的所有行。如果为空,则响应不含正文。
  • **响应标头:**如错误处理程序需要(例如,429 响应中的 Retry-After),可从 /tmp/validation_headers.txt 获取。

确认状态码是否处于 2XX 范围(200–299)。如果状态码为 2XX,则设置 any_2xx_seen = true——此变量用于记录本次会话期间凭据至少成功使用过一次。如果状态码不是 2XX,则在记录结果前继续执行 13.2.5(错误响应架构检查)。

13.2.5 — 错误响应架构检查(仅非 2XX)

在对错误进行分类之前,检查错误响应正文是否符合规范中定义的错误架构:

  1. 在规范中查找实际状态码对应的错误响应架构:responses.{status_code}.content.application/json.schema。如果未为此特定状态码定义架构,也要检查 default 响应架构。
  2. 如果规范中不存在错误架构 → 跳过架构检查。
  3. 如果存在错误架构且响应包含正文 → 使用 13.2.7 分支 A(步骤 1–6)中的相同比较逻辑,将错误正文与架构进行比较。
  4. 如果发现不匹配 → 应用 13.2.7 中相同的自动修复策略,修正规范中的错误架构。将更新后的规范写入磁盘,并记录修复内容。
  5. 无需重新验证错误架构——错误本身仍然存在。Agent 只是在修正规范对错误响应格式的描述。

错误架构检查完成后,继续执行 13.2.6,对错误进行分类和处理。

13.2.6 — 错误原因处理(仅非 2XX)

根据状态码确定适当的操作。

401/403 — 授权/权限错误。凭据无效、已过期或权限不足。Agent 无法自主修复凭据——这是一项会终止整个验证循环的阻断性异常。

  1. 对失败情况进行分类:

    • 如果 any_2xx_seen == false → 永久性身份验证失败(凭据错误或权限不足)。
    • 如果 any_2xx_seen == true → 会话中途令牌过期(凭据此前有效,但现在已过期)。
  2. 记录身份验证失败:

    • 设置 auth_halted = true。
    • 记录当前操作 (method, path) 和状态码(401 或 403)。
    • 记录失败情况(永久性或会话中途)。
  3. 输出已暂停的进度行:

    Validation: {completed}/{M} | passed {X} | fixed {Y} | failed {Z} | AUTH HALTED
      ⛔ {METHOD} {path}  {status_code} — {reason from response body}
    

    使用 ⛔(而非 ✗),以在视觉上区分身份验证暂停和普通失败。

  4. 不要增加 completed 或 failed——该操作尚未完成处理。

  5. 不要继续执行 13.2.7 或 13.2.8。

  6. 返回验证循环;循环会检查 auth_halted 并退出到步骤 14。

**5XX(500–599)— 服务端错误。**SaaS 服务不可用或遇到服务端问题。这不是规范或请求的问题——Agent 无法修复。

  • 将其分类为失败,原因设为 “server error ({status_code})”(例如 “server error (503)”)。
  • 不要重试该操作。
  • 跳过 13.2.7,直接继续执行 13.2.8 以记录结果。

**404 — 未找到(实体 ID 补救)。**端点需要引用一个现有实体,但未找到该实体。这通常意味着在前期收集时提供的实体 ID 有误、已过期,或指向已删除的实体。

  1. 确定可疑的路径参数:

    • 从当前操作的路径模板中提取所有路径参数。
    • 对于每个路径参数,记录当前替换进去的值(来自已存储的实体 ID 映射)。
    • 如果路径包含多个参数,则根据响应正文推断未找到的是哪个实体。如果响应正文未指出哪个参数有误,优先怀疑最具体的(嵌套层级最深的)参数。
  2. 请用户提供修正后的实体 ID:

    如果有一个参数明显可疑:

    404 Not Found — {METHOD} {path}
    
    The API returned 404, which means the entity referenced by `{suspect_param}`
    (current value: `{current_value}`) was not found.
    
    Please provide a valid {entity_type} ID for `{suspect_param}`:
    

    如果多个路径参数都可能有误:

    404 Not Found — {METHOD} {path}
    
    The API returned 404. The following entity IDs may be incorrect:
    - `{param1}` (current value: `{value1}`) — {entity_type_1}
    - `{param2}` (current value: `{value2}`) — {entity_type_2}
    
    Please provide corrected values (or confirm if a value is correct):
    
  3. 更新已存储的实体 ID: 用户提供更正后的值后,更新已存储的实体 ID 映射,确保所有后续操作使用相同参数名时都会采用更正后的值。

  4. 重建并重试:

    • 使用更正后的实体 ID 重建 13.2.1 中的 curl 命令。
    • 如果操作具有破坏性(DELETE 或 PUT),则在执行前重新触发 13.2.2 中的破坏性操作确认。
    • 执行重建后的 curl 命令(13.2.3)并解析响应(13.2.4)。
  5. 评估重试结果:

    • 2XX 响应 → 更正后的 ID 有效。按正常流程继续执行 13.2.7,进行架构验证。
    • 再次出现 404(相同错误) → 将结果归类为失败,原因是 "404 — entity not found (user-provided ID also not found)"。不要再次询问用户。继续执行 13.2.8。
    • 出现不同的非 2XX 错误 → 按初始响应的处理方式,将新错误传入 13.2.5 和 13.2.6。
  6. 重试次数限制: 每次出现 404 时,只允许进行一次与用户交互的重试。如果重试仍返回 404,则立即判定失败。

400 — 错误请求(三层补救)。 API 因语法错误、缺少字段或值无效而拒绝了请求。Agent 将通过三个递进层级尝试自动补救。无需与用户交互;整个过程完全自动化。此处理程序中的所有重试均须遵循下方的重试策略。在每次重新执行 13.2.3 之前,验证 attempt_count < 10 并运行进度门控。

  1. 第 1 层 — 根据错误消息诊断:
    • 解析错误响应正文,提取可操作的详细信息(例如:"field X is required"、"invalid value for parameter Y"、"unknown field Z")。
    • 如果消息指出了具体字段、约束或格式问题:
      • 相应地修复请求(添加缺失字段、更正值或移除无效字段)。
      • 重新执行 curl 命令(13.2.3)并解析响应(13.2.4)。
      • 2XX → 继续执行 13.2.7(架构验证)。
      • 仍为 400 → 检查进度门控。如果没有进展,将结果归类为失败并继续执行 13.2.8。如果有进展,则升级至第 2 层。
      • 出现不同的非 2XX 错误 → 针对新的错误代码,将错误传入 13.2.5 和 13.2.6。400 层级处理流程不再继续。
    • 如果消息无法提供可操作的信息 → 不重试,直接跳至第 2 层。
  2. 第 2 层 — 查阅 api-reference.md:
    • 阅读 api-reference.md 中的相关章节:
      • 正在操作的实体对应的 Entity Reference — 必填字段、字段类型、枚举值和约束。
      • 当前端点对应的 CRUD Endpoint Catalog — 请求正文格式、必需参数。
    • 将当前请求与文档要求进行比较。
    • 找出差异,并重建请求以符合文档规定的格式。
    • 重新执行 curl 命令(13.2.3)并解析响应(13.2.4)。
    • 2XX → 继续执行 13.2.7。
    • 仍为 400 → 检查进度门控。如果没有进展,将结果归类为失败并继续执行 13.2.8。如果有进展,则升级至第 3 层。
    • 出现不同的非 2XX 错误 → 针对新的错误代码,将错误传入 13.2.5 和 13.2.6。
  3. 第 3 层 — 调研官方 API 文档:
    • 使用 WebSearch 和/或 WebFetch 查找此端点对应的官方 SaaS API 文档。
    • 查找以下信息:必填字段、字段格式/约束、有效值,以及 api-reference.md 中未涵盖的特定于 API 的验证规则。
    • 将发现的修正应用于请求。
    • 重新执行 curl 命令(13.2.3)并解析响应(13.2.4)。
    • 2XX → 继续执行 13.2.7。
    • 仍为 400 → 将结果归类为失败,原因是 "400 — {error message} (all remediation tiers exhausted)"。继续执行 13.2.8。
    • 出现不同的非 2XX 错误 → 针对新的错误代码,将错误传入 13.2.5 和 13.2.6。

429 — 请求过多(速率限制)。 API 正在限制请求速率。Agent 会自动等待并重试,无需与用户交互。

  1. 检查 Retry-After 标头:
    • 读取 /tmp/validation_headers.txt,查找 Retry-After 标头(不区分大小写)。
    • 如果值为整数(例如 Retry-After: 5)→ 等待该秒数。
    • 如果值为 HTTP 日期 → 计算距离该时间的秒数。如果日期已过,则按 0 处理。
    • **上限:**如果计算出的等待时间超过 120 秒,则限制为 120 秒。
    • 如果不存在 Retry-After 标头 → 使用指数退避(第 2 步)。
  2. 指数退避(不存在 Retry-After 标头时):
    • 第一次 429:等待 2 秒。
    • 连续第二次 429:等待 4 秒。
    • 连续第三次 429:等待 8 秒。
    • 继续翻倍,每次等待最多 120 秒。
  3. 等待并重试:
    • 通过 Bash 执行 sleep {seconds},等待计算出的时长。
    • 重新执行相同的 curl 命令(13.2.3)并解析响应(13.2.4)。
  4. 评估重试结果:
    • 2XX → 速率限制已解除。继续进行 13.2.7 的架构验证。
    • 再次返回 429 → 仍受速率限制。从第 1 步重复。
    • 其他非 2XX 状态码 → 针对新的状态码执行 13.2.5 和 13.2.6。429 重试序列不会继续。
  5. **进度门控例外:**连续出现 429 时跳过进度门控。每次重试前,确认 attempt_count < 10。
  6. **重试耗尽:**如果达到绝对上限(10 次尝试)后响应仍为 429,则将其归类为 failed,原因是 "429 — rate-limited (retry limit reached after {N} attempts)"。继续进行 13.2.8。
  7. **静默操作:**429 等待期间不要输出进度行。仅在操作完成时输出最终结果。

**所有其他非 2XX 状态码(例如 409 Conflict、422 Unprocessable Entity、405 Method Not Allowed)。**采用与 400 相同的三级修正措施。第 1 级检查错误代码对应的指导:

  • **409 Conflict:**查找资源名称/ID 冲突,并更改冲突值。
  • **422 Unprocessable Entity:**查找字段级验证失败,并更正字段。
  • **405 Method Not Allowed:**检查是否有 Allow 响应标头列出有效方法,并更正 HTTP 方法。

第 2 级和第 3 级与 400 相同。

重试策略

此统一框架适用于 13.2 中的所有重试场景。各错误处理程序(400、429、其他错误)和架构自动修复(13.2.7)均依据此框架做出重试决策。

**失败特征。**由 (HTTP status code, key error details) 组成的一对值。关键错误详情 = 响应正文中的主要错误消息或错误代码,忽略时间戳、请求 ID 或跟踪 ID 等动态内容。如果状态码和关键错误详情都匹配,则两次失败属于“相同”;任一项不同,则属于“不同”。

**进度门控。**在任何处理程序重新执行 13.2.3 之前,将当前失败特征与 last_failure_signature 比较:

  • 不同 = 有进展。允许重试(但仍受上限约束)。
  • 相同 = 没有进展。立即停止重试,将其归类为 failed(无法解决),并继续进行 13.2.8。

**429 例外。**连续收到 429 响应时跳过进度门控。429 表示暂时性状况(速率限制已生效),而非持续性故障。

**绝对上限。**每项操作最多 10 次尝试(1 次初始尝试 + 最多 9 次重试)。同一操作的所有处理程序共享 attempt_count。每次重新执行 13.2.3 之前,检查 attempt_count < 10。如果达到上限,则立即停止,无论是否有进展。

**重试耗尽行为。**重试停止时——无论是因为进度门控(失败相同),还是达到绝对上限——都将操作标记为 failed(无法解决),并包含:

  • attempt_count 总数。
  • 停止原因是“没有进展”(进度门控)还是“已达到重试上限”(绝对上限)。
  • 完整的 retry_history。

使用失败分类继续进行 13.2.8。

13.2.7 — 验证响应

根据响应是否包含正文进行分支处理。

分支 A:包含正文的 2XX 响应。 将实际响应 JSON 与规范中的响应架构进行比较:

  1. 解析响应正文为 JSON。如果解析失败,报告“响应不是有效的 JSON”并停止。
  2. 解析规范架构。 从规范中读取匹配状态码对应的响应架构。如果使用 $ref,则跟进引用至 components/schemas/{name} 并展开。继续解析任何嵌套的 $ref 引用。
  3. 比较字段。 对于响应中的每个字段:
    • 检查该字段是否定义在规范架构的 properties 中。
    • 如果已定义,检查 JSON 类型是否与架构类型匹配:
      • string ↔ 字符串
      • integer 或 number ↔ 数字
      • boolean ↔ 布尔值
      • array ↔ 数组
      • object ↔ 对象
    • 如果字段未定义在架构中,将其标记为额外字段。
  4. 检查必填字段。 对于架构 required 数组中的每个字段,确认响应中存在该字段。如果缺失,将其标记为缺失的必填字段。
  5. 检查嵌套对象(一级)。 对于架构中定义了 properties 的 object 类型字段,对嵌套对象重复执行步骤 3–4。
  6. 检查数组。 对于 array 类型字段,确认响应值为数组。如果架构定义了 items,则将数组的第一个元素与 items 架构进行比较(如果数组非空)。
  7. 确定结果:
    • 如果未发现不匹配项 → 分类为通过。继续执行 13.2.8。
    • 如果发现不匹配项 → 应用以下自动修复策略,然后重新验证。

自动修复策略(仅适用于分支 A):

不匹配类型修复策略
类型不匹配 — 规范声明的类型与响应返回的类型不同更新规范架构中该属性的 type,使其与响应中的实际类型一致。
额外字段 — 响应中存在该字段,但规范架构中没有将该字段作为可选属性添加到架构的 properties 中(不要添加到 required)。根据响应值推断类型。
缺失的必填字段 — 规范在 required 中列出了该字段,但响应中没有从架构的 required 数组中移除该字段。将该字段保留在 properties 中。
结构不匹配 — 嵌套对象/数组的结构与规范不同更新规范架构,使其符合实际结构。

一次性应用当前这组不匹配项的所有修复。修改 components/schemas/{name} 定义(而非内联响应架构),以便修复能传播到通过 $ref 引用同一架构的所有操作。使用 Edit 工具将更新后的规范写入磁盘。记录每项已应用的修复:{schema_name}.{field_path}: {mismatch_type} — {description of change}。

自动修复后重新验证:

  1. 重新执行 13.2.3 中的同一条 curl 命令(始终使用新响应)。
  2. 使用 13.2.4 中的逻辑解析响应。
  3. 如果响应仍为 2XX,则使用更新后的规范架构重新进行架构比较(分支 A 的步骤 1–6)。
  4. 评估:
    • 无不匹配项 → 分类为已修复。继续执行 13.2.8。
    • 仍有不匹配项,但与上一次尝试不同 → 取得进展。应用其他修复并重新验证。
    • 仍有不匹配项,且与上一次尝试完全相同 → 没有进展。分类为失败,原因是“架构不匹配(自动修复失败)”。继续执行 13.2.8。
    • 重新验证时响应不是 2XX → 分类为失败,并注明错误状态码和原因。继续执行 13.2.8。
  5. 架构自动修复重试与错误处理器共用 attempt_count — 总尝试次数不得超过 10 次。

分支 B:不包含正文的 2XX 响应。

  • 验证实际 HTTP 状态码是否与规范中的预期状态码一致。
  • 如果一致 → 分类为通过。
  • 如果不一致 → 分类为失败,原因是“状态码不匹配”(报告实际值与预期值)。
13.2.8 — 记录结果并报告进度

对结果进行分类:

  • passed — 2XX 响应,且架构匹配(或无响应正文,状态码匹配)。包括在修正 404 实体 ID 后成功的操作。
  • fixed — 2XX 响应,架构最初不匹配,但 Agent 自动修复了规范,且重新验证成功。
  • failed — 完成所有补救后仍返回非 2XX 响应,或返回 2XX 响应但重试后架构自动修复仍无法解决所有不匹配项。
  • skipped — 用户在 13.2.2 的确认提示后拒绝执行破坏性操作。

身份验证失败(401/403)不会到达此步骤——它们会在 13.2.6 中中止循环,并在第 14 步报告。

向用户输出一条进度行:

Validation: 1/5 | passed 1 | fixed 0 | failed 0
Validation: 2/5 | passed 1 | fixed 0 | failed 1
  ✗ POST /docs/{docId}/pages  400 — missing required field: name (3 attempts)
Validation: 3/5 | passed 2 | fixed 0 | failed 1

规则:

  • 每完成一个操作,输出一条进度行。
  • 仅对失败操作输出详细行(在循环期间)。当 attempt_count > 1 时,追加 ({attempt_count} 次尝试)。
  • 记录失败操作的 retry_history,以及已修复操作的修复摘要——第 14 步可能会在最终报告中输出这些信息。
  • 已修复的操作在进度中计为成功——循环期间不输出详细行。
  • Agent 仍在尝试补救时,不要输出详细行。

记录结果后,返回循环处理下一个操作。如果这是最后一个操作,则继续执行第 14 步。


第 14 步:最终报告与知识就绪

在验证循环处理完所有操作后,或身份验证失败导致循环提前中止后,执行此步骤。

身份验证失败 — 循环提前中止

如果 auth_halted 为 true,则显示身份验证失败报告,而不是常规摘要。

永久性身份验证失败(any_2xx_seen == false):

Auth failure — validation halted.

  ⛔ {METHOD} {path}  {status_code} — {reason}

The API returned {status_code} on the first operation attempted. The credentials in
config.properties may be invalid or lack permissions for this API.

Please verify the credentials and re-run validation.

会话中令牌过期(any_2xx_seen == true):

Auth failure — validation halted after {completed}/{M} operations.

  ⛔ {METHOD} {path}  {status_code} — {reason}

  Completed before failure: passed {X}, fixed {Y}, failed {Z}

The first {completed} operations were processed, but operation {completed+1} returned {status_code}.
This likely indicates the API token has expired mid-session.

Please refresh the token in config.properties and re-run validation.
The agent will re-validate all operations from the beginning.

显示身份验证失败报告后,停止。不要显示常规摘要,也不要询问“是否要重试?”

正常完成

先显示摘要行,再显示已修复、失败和跳过操作的详细行。已通过的操作不显示详细行。仅当 skipped > 0 时,追加 | skipped {S}。

详细行顺序:已修复的操作优先(✔),然后是失败操作(✗),最后是跳过的操作(⏭)。

Validation complete: 5/5 | passed 2 | fixed 1 | failed 1 | skipped 1

  ✔ GET /docs/{docId}  fixed — Doc.owner: type mismatch (object → string), Doc.sourceDoc: structural mismatch (string → object)
  ✗ POST /docs/{docId}/pages  400 — missing required field: name (3 attempts)
  ⏭ DELETE /docs/{docId}  skipped — user declined destructive operation

详细行规则:

  • 已修复(✔): ✔ {METHOD} {path} fixed — {fix_summary}。当 attempt_count > 1 时,追加 ({attempt_count} 次尝试)。
  • 失败(✗): ✗ {METHOD} {path} {status_code} — {reason}。当 attempt_count > 1 时,追加 ({attempt_count} 次尝试)。
  • 跳过(⏭): ⏭ {METHOD} {path} skipped — 用户拒绝执行破坏性操作。

如果存在失败操作(不包括跳过的操作),显示摘要并询问用户如何继续:

{N} operation(s) could not be validated. How would you like to proceed?

1. Provide additional information so I can retry the failed operations
2. Keep the failed operations in the spec as-is (no changes to their definitions)
3. Remove the failed operations from the spec and proceed with the corrected spec
4. Cancel — stop the validation process

用户选择选项后:

  • 选项 1: 显示每个失败操作的 retry_history,让用户了解已尝试过的内容。接受用户提供的补充信息,然后仅重新验证失败的操作。重新验证后,显示更新后的摘要;如果仍有失败,则重复此决策流程。
  • 选项 2: 按原样传递规范。验证期间应用的自动修复已写入磁盘。
  • 选项 3: 使用 Edit 工具从规范的 paths 对象中移除失败操作。将更新后的规范写入磁盘。
  • 选项 4: 停止。不要传递规范。

对于选项 1–3,规范定稿后,确认输出:

Knowledge ready: {PROJECT_FOLDER}
  - api-reference.md
  - {apiName}.yaml
  - config.properties

如果所有操作均已通过、已修复或已跳过(即 failed == 0),则报告摘要并确认输出,无需进一步与用户交互:

Knowledge ready: {PROJECT_FOLDER}
  - api-reference.md
  - {apiName}.yaml
  - config.properties

调用方(通常是 build-mule-integration 第 3a 步)会读取 api-reference.md,以指导 HTTP-Connector 配置和 DataWeave 转换;<apiName>.yaml 是经过更正并通过验证测试的 OpenAPI 规范。

评论

支持 Markdown