动态API集成Skill dynamic-api-integration

这个技能教导AI代理如何动态发现、解析和调用外部HTTP API,基于OpenAPI规范和工具模板,适用于Node.js和Claude Code代理。包含五个核心阶段:发现API端点、语义匹配用户意图、构建HTTP请求、执行API调用和链式迭代调用。关键词包括API集成、OpenAPI、HTTP请求、AI代理、工具调用、动态发现、迭代链式。

AI智能体 0 次安装 0 次浏览 更新于 3/10/2026

name: dynamic-api-integration description: 在运行时使用OpenAPI规范、工具模板和迭代链式调用,发现、解析和调用外部HTTP API。基于UTCP(通用工具调用协议)模式,适用于Node.js和Claude Code代理。 version: 1.0.0 model: sonnet invoked_by: both user_invocable: true tools: [Read, Write, Edit, Bash, WebFetch, WebSearch] best_practices:

  • 在构建请求之前,始终获取并验证OpenAPI规范
  • 所有API密钥和机密使用环境变量;切勿硬编码
  • 应用最大迭代次数防护,防止无限API调用循环
  • 截断或总结大型API响应,以保持在上下文预算内
  • 在调用前,语义匹配用户意图到API端点
  • 对临时失败显式处理错误,包含重试逻辑 error_handling: strict streaming: supported

模式:认知/提示驱动 — 无独立实用脚本;通过代理上下文使用。

动态API集成

概述

这个技能教导代理如何在运行时动态发现、解析和调用外部HTTP API。它基于通用工具调用协议(UTCP)模式,转换为Node.js / Claude Code工具模式。

核心工作流程(5阶段,受UTCP代理状态机启发):

  1. 发现 — 获取并解析OpenAPI/Swagger规范(或定义手动工具模板)。
  2. 匹配 — 语义映射用户意图到正确的API端点。
  3. 构建 — 构建HTTP请求,包含正确的方法、路径、参数、头部、正文和认证。
  4. 执行 — 通过Bash(curl)或WebFetch调用API并捕获响应。
  5. 链式 — 如果任务未完成,重新分析并执行另一个调用(最多到最大迭代次数)。

何时使用

使用此技能时:

  • 代理需要调用之前未使用的外部REST API
  • 用户提供API URL或OpenAPI规范URL,并希望提取数据
  • 代理必须在选择调用之前从规范中发现可用端点
  • 多个API调用需要迭代链式调用(搜索 -> 获取详情 -> 过滤)
  • 代理需要构建带有认证和参数的HTTP请求

不要使用时:

  • API已封装为MCP工具(直接使用MCP工具)
  • 集成是一次性硬编码调用(直接使用Bash curl)
  • API需要OAuth 2.0授权码流程,涉及用户交互重定向
  • API使用WebSocket或仅流式协议(非HTTP REST)

铁律

切勿在请求中硬编码API密钥 — 仅使用环境变量

如果发现自己在curl命令中键入API密钥,请停止。使用$ENV_VAR语法。


阶段1:发现 — 获取并解析API规范

选项A:OpenAPI/Swagger规范发现

当API提供OpenAPI规范时(大多数现代API提供):

# 步骤1:获取OpenAPI规范
WebFetch({
  url: "https://api.example.com/openapi.json",
  prompt: "提取所有API端点。为每个端点列出:HTTP方法、路径、描述、必需参数、可选参数、认证要求。返回为结构化列表。"
})

从规范中提取的内容:

字段 规范中的位置 目的
基础URL servers[0].url 所有请求的API根目录
端点 paths.* 可用操作
方法 paths.*.get/post/put/delete 每个端点的HTTP动词
参数 paths.*.*.parameters[] 查询、路径、头部参数
请求正文 paths.*.*.requestBody POST/PUT负载架构
认证 components.securitySchemes API密钥、Bearer、OAuth
响应架构 paths.*.*.responses.200 预期响应格式

常见OpenAPI规范位置:

  • https://api.example.com/openapi.json
  • https://api.example.com/swagger.json
  • https://api.example.com/v3/api-docs
  • https://api.example.com/.well-known/openapi.json
  • https://api.example.com/docs(HTML页面可能链接到规范)

选项B:手动工具模板(无规范可用)

当没有OpenAPI规范时,手动定义工具模板:

{
  "name": "search_books",
  "description": "通过查询搜索Open Library中的书籍",
  "base_url": "https://openlibrary.org/search.json",
  "method": "GET",
  "auth": null,
  "parameters": {
    "q": {
      "type": "string",
      "required": true,
      "in": "query",
      "description": "搜索查询(标题、作者、ISBN)"
    },
    "limit": {
      "type": "integer",
      "required": false,
      "in": "query",
      "description": "返回的最大结果数(默认10)"
    },
    "page": {
      "type": "integer",
      "required": false,
      "in": "query",
      "description": "分页的页码"
    }
  },
  "response_hint": "返回 { numFound, docs: [{ title, author_name, first_publish_year }] }"
}

工具模板JSON架构

工具模板格式(受UTCP manual_call_templates启发):

{
  "name": "string (必需) — 唯一工具标识符,小写下划线形式",
  "description": "string (必需) — 此工具的功能,用于语义匹配",
  "base_url": "string (必需) — 包括路径的完整URL",
  "method": "string (必需) — GET | POST | PUT | PATCH | DELETE",
  "content_type": "string (可选) — 默认: application/json",
  "auth": {
    "type": "string — api_key | bearer | basic | none",
    "header": "string — 头部名称(例如,X-Api-Key, Authorization)",
    "env_var": "string — 存储机密的环境变量名称",
    "prefix": "string (可选) — 例如,'Bearer ' 用于bearer认证"
  },
  "parameters": {
    "<param_name>": {
      "type": "string | integer | boolean | array | object",
      "required": "boolean",
      "in": "query | path | header | body",
      "description": "string — 此参数的作用",
      "default": "any (可选) — 未提供时的默认值"
    }
  },
  "response_hint": "string (可选) — 响应形状的简要描述"
}

阶段2:匹配 — 语义意图到端点映射

调用API前,将用户意图匹配到正确端点:

步骤1:理解用户目标

自问:用户想要什么数据?他们想执行什么操作?

步骤2:映射意图到端点

用户意图 可能的HTTP方法 端点模式
“查找 / 搜索 / 列出 / 获取” GET /search, /list, /{resource}
“创建 / 添加 / 注册” POST /{resource}
“更新 / 修改 / 更改” PUT 或 PATCH /{resource}/{id}
“删除 / 移除” DELETE /{resource}/{id}
“获取关于X的详情” GET /{resource}/{id}

步骤3:选择参数

  • 必需参数: 必须提供(检查规范/模板中的required: true)。
  • 可选参数: 仅在用户指定或改善结果时使用。
  • 路径参数: 替换到URL中(例如,/repos/{owner}/{repo})。
  • 查询参数: 追加为?key=value&key2=value2
  • 正文参数: 在POST/PUT/PATCH中作为JSON负载发送。

阶段3:构建 — 构建HTTP请求

请求构建检查清单

  1. URL: 基础URL + 路径 + 路径参数替换
  2. 方法: GET, POST, PUT, PATCH, DELETE
  3. 头部: Content-Type, Authorization, Accept, 自定义头部
  4. 查询参数: URL编码,追加到URL
  5. 正文: 用于POST/PUT/PATCH的JSON负载
  6. 认证: 从环境变量注入

认证模式

API密钥(头部):

curl -s -X GET "https://api.example.com/data?q=test" \
  -H "X-Api-Key: $API_KEY"

Bearer令牌:

curl -s -X GET "https://api.example.com/data" \
  -H "Authorization: Bearer $AUTH_TOKEN"

基础认证:

curl -s -X GET "https://api.example.com/data" \
  -u "$USERNAME:$PASSWORD"

无认证(公共API):

curl -s -X GET "https://api.example.com/data?q=test"

按方法请求模板

带查询参数的GET:

curl -s -X GET "https://api.example.com/search?q=test&limit=10&page=1" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $TOKEN"

带JSON正文的POST:

curl -s -X POST "https://api.example.com/items" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name": "新项目", "category": "工具", "price": 29.99}'

带路径参数的PUT:

curl -s -X PUT "https://api.example.com/items/123" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name": "更新项目", "price": 39.99}'

DELETE:

curl -s -X DELETE "https://api.example.com/items/123" \
  -H "Authorization: Bearer $TOKEN"

阶段4:执行 — 调用API并处理响应

使用Bash(curl) — 主要方法

# 执行并捕获响应 + HTTP状态
RESPONSE=$(curl -s -w "
%{http_code}" -X GET "https://api.example.com/search?q=test" \
  -H "Accept: application/json")
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | sed '$d')

echo "状态: $HTTP_CODE"
echo "正文: $BODY" | head -c 2000  # 截断到2KB以确保上下文安全

使用WebFetch — 当需要AI处理时

WebFetch({
  url: 'https://api.example.com/search?q=test',
  prompt:
    '提取前5个结果及其标题和描述。格式化为编号列表。',
});

何时使用哪个:

场景 工具 原因
需要原始JSON进行进一步处理 Bash(curl) 完全控制,可解析输出
需要总结/提取数据 WebFetch AI内联处理响应
需要检查HTTP状态码 Bash(curl) WebFetch抽象了状态
大型响应 (>50KB) Bash(curl)+ 截断 WebFetch可能在大型页面上超时
HTML页面(非JSON) WebFetch 将HTML转换为markdown

错误处理

HTTP状态码处理:

状态 含义 操作
200-299 成功 解析响应,继续
400 错误请求 检查参数,修复并重试
401 未授权 检查API密钥/令牌,重新认证
403 禁止 检查权限,报告给用户
404 未找到 检查URL/资源ID,尝试替代端点
429 速率限制 等待(检查Retry-After头部),然后重试
500-599 服务器错误 等待并重试最多3次

带指数退避的重试:

# 对临时错误的重试模式(429, 5xx)
for attempt in 1 2 3; do
  RESPONSE=$(curl -s -w "
%{http_code}" -X GET "$URL" -H "Authorization: Bearer $TOKEN")
  HTTP_CODE=$(echo "$RESPONSE" | tail -1)
  if [ "$HTTP_CODE" -lt 400 ]; then
    break  # 成功
  fi
  echo "尝试 $attempt 失败 ($HTTP_CODE),在 $((attempt * 2))s 后重试..."
  sleep $((attempt * 2))
done

响应处理

解析JSON响应(Bash):

# 从JSON响应中提取特定字段
echo "$BODY" | node -e "
  const data = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
  console.log('总计:', data.totalResults);
  data.items?.slice(0, 5).forEach((item, i) => {
    console.log(`\${i+1}. \${item.title} — \${item.description?.substring(0, 80)}`);
  });
"

截断大型响应:

# 安全性:切勿将>10KB的API响应传递到上下文中
BODY_TRUNCATED=$(echo "$BODY" | head -c 10000)
if [ ${#BODY} -gt 10000 ]; then
  echo "[截断: 响应为 $(echo "$BODY" | wc -c) 字节,显示前10KB]"
fi

阶段5:链式 — 迭代多调用工作流程

许多任务需要链式调用多个API。使用受UTCP启发的迭代模式:

链式模式

迭代1:搜索 -> 获取结果列表
迭代2:获取顶部结果的详情
迭代3:对结果执行操作
(最大迭代次数防护:在5次停止)

迭代防护(强制)

最大迭代次数 = 5

每次API调用前:
  如果 迭代计数 >= 最大迭代次数:
    停止。总结到目前为止收集的内容并响应。
  否则:
    执行调用,增加计数器,重新分析任务。

为什么重要: 没有迭代防护,代理可能无限循环调用API。UTCP使用默认3次;我们推荐5次用于更复杂的多步骤工作流程。

链式示例

示例1:搜索并获取详情

用户: “查找乔治·奥威尔的书籍《1984》的信息”

迭代1:
  调用: GET https://openlibrary.org/search.json?q=1984+george+orwell&limit=5
  结果: 找到5个匹配,顶部结果有关键字“/works/OL1168083W”

迭代2:
  调用: GET https://openlibrary.org/works/OL1168083W.json
  结果: 完整书籍详情(标题、描述、主题、封面)

任务完成: 返回总结的书籍信息。

示例2:GitHub — 查找并分析仓库

用户: “react仓库中最新的问题是什么?”

迭代1:
  调用: GET https://api.github.com/repos/facebook/react/issues?state=open&per_page=10&sort=created
  头部: Authorization: Bearer $GITHUB_TOKEN
  结果: 10个最新的开放问题

任务完成: 总结问题标题、标签和日期。

示例3:多API链式

用户: “查找关于AI安全的新闻并总结顶部文章”

迭代1:
  调用: GET https://newsapi.org/v2/everything?q=AI+safety&sortBy=publishedAt&pageSize=5
  头部: X-Api-Key: $NEWS_API_KEY
  结果: 5篇文章,带标题和URL

迭代2:
  调用: WebFetch({ url: articles[0].url, prompt: “用3个要点总结这篇文章” })
  结果: 文章摘要

任务完成: 返回文章标题 + 摘要。

现实世界API示例

GitHub API(Bearer令牌认证)

# 列出用户的仓库
curl -s -X GET "https://api.github.com/users/octocat/repos?sort=updated&per_page=5" \
  -H "Accept: application/vnd.github+json" \
  -H "Authorization: Bearer $GITHUB_TOKEN"

工具模板:

{
  "name": "github_list_repos",
  "description": "列出GitHub用户的仓库,按最近更新排序",
  "base_url": "https://api.github.com/users/{username}/repos",
  "method": "GET",
  "auth": {
    "type": "bearer",
    "header": "Authorization",
    "env_var": "GITHUB_TOKEN",
    "prefix": "Bearer "
  },
  "parameters": {
    "username": {
      "type": "string",
      "required": true,
      "in": "path",
      "description": "GitHub用户名"
    },
    "sort": {
      "type": "string",
      "required": false,
      "in": "query",
      "description": "排序字段:created, updated, pushed, full_name",
      "default": "updated"
    },
    "per_page": {
      "type": "integer",
      "required": false,
      "in": "query",
      "description": "每页结果数(最多100)",
      "default": 10
    }
  }
}

Open Library API(无认证)

# 搜索书籍
curl -s -X GET "https://openlibrary.org/search.json?q=george+orwell&limit=5" \
  -H "Accept: application/json"

JSONPlaceholder(测试/原型)

# GET所有帖子
curl -s https://jsonplaceholder.typicode.com/posts?_limit=5

# POST新项目
curl -s -X POST https://jsonplaceholder.typicode.com/posts \
  -H "Content-Type: application/json" \
  -d '{"title": "测试帖子", "body": "你好世界", "userId": 1}'

Weather API(API密钥认证)

# 获取当前天气
curl -s "https://api.open-meteo.com/v1/forecast?latitude=51.5074&longitude=-0.1278&current_weather=true"

大型响应的上下文管理

API响应可能非常大。应用这些规则以防止上下文溢出:

响应大小限制

响应大小 操作
< 5 KB 使用完整响应
5-20 KB 仅提取相关字段
20-50 KB 通过WebFetch或node脚本总结
> 50 KB 截断到前5KB + 计数剩余

提取模式(推荐用于大型响应)

# 而不是转储完整响应,提取所需内容
curl -s "https://api.example.com/search?q=test" | node -e "
  const data = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
  // 仅提取用户要求的内容
  const results = data.results.slice(0, 5).map(r => ({
    id: r.id,
    title: r.title,
    summary: r.description?.substring(0, 200)
  }));
  console.log(JSON.stringify(results, null, 2));
"

安全检查清单

  • [ ] 所有API密钥存储在环境变量中(切勿在代码/命令中)
  • [ ] 所有API调用使用HTTPS(认证请求切勿使用HTTP)
  • [ ] 使用前验证响应数据(检查状态码)
  • [ ] 不记录或写入用户机密到文件
  • [ ] 尊重速率限制(检查头部:X-RateLimit-Remaining)
  • [ ] 敏感响应数据(PII、令牌)不存储在内存文件中
  • [ ] 所有请求设置超时(curl --max-time 30

验证检查清单

完成动态API集成任务前:

  • [ ] 已获取API规范并识别端点
  • [ ] 用户意图已映射到正确端点和方法
  • [ ] 请求包含正确认证(如果需要)
  • [ ] 请求参数匹配API架构(必需参数存在)
  • [ ] 已检查HTTP状态码并处理错误
  • [ ] 如果> 5KB,响应已截断/总结
  • [ ] 迭代计数未超过最大迭代次数(5)
  • [ ] 任何命令或文件中未硬编码API密钥

反模式(避免)

反模式 为什么失败 正确方法
硬编码API密钥 安全风险,轮换时失效 所有命令中使用$ENV_VAR
未先阅读规范就调用API 错误端点,错误参数 先发现(阶段1)
传递完整100KB响应到上下文 上下文溢出,性能下降 截断/提取(阶段4)
链式调用无迭代防护 无限循环消耗令牌 始终强制执行最大迭代次数
猜测参数名称 400错误,浪费调用 构建前阅读规范/文档
忽略HTTP错误码 静默失败,错误结果 检查状态,处理4xx/5xx
当GET正确时使用POST API拒绝或创建意外资源 匹配方法到意图(阶段2)

快速参考卡

发现  → WebFetch(规范URL) 或定义手动工具模板
匹配     → 映射用户意图到端点 + 方法 + 参数
构建 → 构建curl命令,带URL、头部、认证、正文
执行   → Bash(curl)用于JSON,WebFetch用于HTML/总结
链式     → 重新分析任务,再次调用(最多5次迭代)

认证快速参考:

API密钥:  -H "X-Api-Key: $KEY"
Bearer:   -H "Authorization: Bearer $TOKEN"
基础认证:    -u "$USER:$PASS"
无认证:     (无需认证头部)

工具模板快速创建:

{
  "name": "...",
  "description": "...",
  "base_url": "...",
  "method": "GET",
  "auth": { "type": "api_key", "header": "...", "env_var": "..." },
  "parameters": { "q": { "type": "string", "required": true, "in": "query" } }
}

研究基础

此技能基于:

相关技能

  • auth-security-expert — OAuth 2.1, JWT, 加密模式
  • nodejs-expert — Node.js HTTP模式
  • debugging — API调用失败调查
  • research-synthesis — 集成前研究新API

内存协议

开始前: 阅读 .claude/context/memory/learnings.md

完成后:

  • 新API模式发现 -> .claude/context/memory/learnings.md
  • API问题/限制发现 -> .claude/context/memory/issues.md
  • API设计决策制定 -> .claude/context/memory/decisions.md
  • 可重用工具模板创建 -> 保存到 .claude/context/memory/named/api-templates.md

假设中断:如果不在内存中,则未发生。