Postman API秒变Codex智能体Skill:OpenAPI+Skill实战指南
把Postman里调试好的API集合直接变成智能体Codex能调用的Skill这件事我前前后后折腾了小两周。最开始的想法特别朴素后端服务有一堆接口我平时都是靠Postman保存请求、切环境、测参数墙上的工作流已经很熟练了。可一旦想让Codex接管这些API它就像个手动党不给它一份“说明书”它永远只会乱猜URL、拼错请求头。后来我找到一条还算顺的路用Postman作为API资产入口把接口整理成OpenAPI描述再包一层Skill外壳让Codex看一眼就能自己调用。今天就把这套思路和完整实操步骤写出来适合那些已经用Postman管接口、又想把自己的服务能力开放给AI智能体的人。1. 这个项目到底要做什么从Postman里的API到Codex的Skill一步打通1.1 为什么说Postman是最好的API素材源我见过很多团队搞“智能体接入内部API”第一步就卡在素材整理上有的让智能体直接读后端代码结果代码里藏着十几个环境变量读半天也不知道线上地址是什么有的让AI助手对着文档网站硬啃文档更新不及时模型就被带偏。可Postman不一样绝大多数开发者的日常接口联调、测试、场景编排都是在Postman里完成的。集合Collection里已经有了完整的请求方法、路径、请求头、请求体示例、参数说明甚至连环境变量、鉴权方式都是现成的。我的经验是与其从零写一份给智能体看的API说明书不如直接把Postman里已经调通的请求“翻译”成标准格式。所有接口是否可用、是否鉴权、返回结构长什么样Postman集合已经用最真实的方式记录下来了。你甚至不需要额外去问后端同事“这里为什么要有这个Header”你翻一下当时调试成功的请求就知道了。1.2 Codex Skill是什么一段让智能体学会“按说明书办事”的封装聊Codex Skill之前先澄清一个概念在AI编程智能体的语境里Skill并不是一个高深的东西。它更像是一份“岗位培训手册”把某个特定领域要怎么做、有哪些工具、哪些边界约束以结构化文件的形式告诉智能体。让智能体在遇到对应场景时不是凭空发挥而是按手册去调用能力。打个比方Skill就像是给新员工的一本《客户系统操作手册》里面有目标、有流程、有你能用的API清单也有哪些操作不能碰。Codex读到SKILL.md之后会把这些信息当作上下文的一部分遇到相关任务就知道“该去调用哪个接口、怎么组装请求”。而我们要做的就是把Postman里的API能力精心打包成这么一份手册。这样Codex就不再只是一个纯粹写代码的助手它能直接操作真实的业务系统完成查询、创建、修改数据等任务。1.3 思路拆解API能力 → OpenAPI描述 → Skill外壳整个项目其实就是一条流水线我会反复用到三个层次第一层是API能力本身以Postman集合为源头既有请求细节也有调试验证记录。第二层是API描述用OpenAPI规范也就是Swagger规范把每个接口的路径、参数、响应模型、鉴权方式统一描述出来。这是目前绝大多数智能体、代码生成工具、接口平台都能识别的“通用语言”。第三层是Skill外壳在OpenAPI描述外面再补上SKILL.md这样的技能说明文件告诉Codex什么时候该用这套API、怎么编排请求、有哪些坑要避开。用一句话概括就是把Postman里的接口资产先翻译成机器可读的OpenAPI文件再裹上智能体需要的“使用说明书”。后面的所有内容都是围绕这条流水线展开的。2. 动手前先搞清楚的核心机制2.1 OpenAPI规范Postman和智能体之间的通用语言没有OpenAPI之前一个接口要传递给另一个系统最常见的方式是复制一份“接口文档Word”或者截个Postman的请求截图。可这些对智能体来说都不够结构化模型要么理解不了截图里的文字要么得靠猜测去解析参数。OpenAPI解决了这个问题它用一套固定的YAML或JSON结构描述API机器和人包括大模型都能读。具体来说OpenAPI文件会包含这几块关键信息openapi版本号比如3.0.3。info接口服务的标题、版本、描述。servers可用的服务地址也就是baseUrl。paths每个路径的HTTP方法、操作ID、参数、请求体、响应结构。components复用的安全方案、响应模型、参数模型。只要有了这样一份文件Codex或者其他智能体就能推断出“查订单用GET /orders”“创建订单用POST /orders”并且清楚该往body里塞什么字段。我一直觉得OpenAPI就是接口界的“书架分类标签”它让本来散落各处的接口信息有了一套统一的索引规则。我实际操作时不会手写OpenAPI而是从Postman导出。Postman本身支持导出Collection v2.1也支持直接导出OpenAPI 3.0格式文件。导出后再用编辑器扫一眼该补的描述补上基本就够了。2.2 Skill文件结构SKILL.md 接口定义 运行脚本上一篇内容已经提到Skill不能只是一个OpenAPI文件还要有足够的上下文。我最终采用的目录结构是这样~/.codex/skills/company-erp-api/ ├── SKILL.md ├── openapi.yaml ├── config.json └── scripts/ └── api_wrapper.py这里每个文件的职责非常清晰SKILL.md是技能的入口用自然语言描述“这个技能能做什么、什么场景下调用、有哪些注意事项”Codex会优先读取它。openapi.yaml是接口的机器可读定义Codex根据它来拼接请求。config.json存放动态配置比如服务器地址、环境标识、超时时间这些信息不该写死在Skill描述里。scripts/api_wrapper.py是一个轻量封装把OpenAPI定义和实际HTTP调用连接起来处理认证注入、错误码转换等逻辑。我见过一些人只放一个SKILL.md把接口信息全写在里面短小的工具还行但只要是超过三五个接口的服务智能体就开始懵因为它无法从长篇大论的描述里稳定提取参数。所以我的建议是SKILL.md负责“决策”OpenAPI负责“细节”脚本负责“执行”三者各干各的。2.3 认证、参数、分页这些老问题怎么在Skill里体现用Postman测接口的时候认证经常是“Pre-request Script”里动态算出来的或者直接放在环境变量里。到了Skill里这个问题必须重新设计因为智能体不能像人一样手动在Postman里换Token。我在实际项目中把认证方式分成三类处理静态Token直接存在config.json里Skill加载时读取并注入请求头。动态Token需要先调用登录接口获取这时我会在api_wrapper.py里写一个缓存Token的逻辑过期后自动重新获取。签名认证比如某些内部系统要求每个请求加上时间戳和签名这类逻辑不适合让智能体思考我会把签名算法封装到脚本里只给智能体一个“无感调用”的接口。参数和分页也一样。OpenAPI里可以定义page、page_size、limit这些参数可智能体不一定知道“第一页从哪里取”。经验是在SKILL.md里明确写一句话“列表接口默认请求第一页如需更多数据请通过分页参数递增页码。”这样Codex就不会傻乎乎把所有结果一次性拉完。3. 实操把Postman集合变成Codex能用的Skill3.1 第一步在Postman里把接口调通并导出OpenAPI这一步看起来基础却是整个流程的命根子。我建议在Postman里建一个独立的Collection专门放需要开放给智能体的接口每个请求都要保证“当前环境”下调试通过。检查项包含URL路径正确、请求方法正确、请求头里有必要的Content-Type、鉴权信息能通过、Body示例能跑通。准备工作做完后导出操作如下选中目标Collection点击右侧的“...”菜单。选择“Export Collection”。在导出格式里选择“OpenAPI 3.0”或“OpenAPI 2.0”我建议直接选3.0。导出后会得到一个JSON文件建议再把内容转成YAML方便阅读很多工具如swagger-cli可以直接转换。导出之后一定不要直接用先检查几个地方servers里的地址是否是你真正要用的Postman经常会把环境变量里的URL带出来但可能有格式残留。operationId是否唯一Codex调用接口时往往靠operationId区分操作缺失或重复都会造成混乱。请求体示例是否存在OpenAPI里没有example的话智能体就得靠字段名猜值概率不高。提示Postman导出OpenAPI本质上是把Collection里的请求、参数、示例组织成统一描述。如果发现导出的文件结构不完整大多数原因是Postman集合本身缺少请求示例或参数描述并不是导出功能有问题。下面是我导出后简化过的示例openapi: 3.0.3 info: title: Company ERP API version: 1.0.0 servers: - url: https://api.example.local/v1 paths: /orders/{order_id}: get: operationId: getOrderDetail parameters: - name: order_id in: path required: true schema: type: string responses: 200: description: 获取订单详情成功3.2 第二步搭建Skill目录和SKILL.md拿到OpenAPI文件后我才会正式创建Skill目录。目录名不要用中文也不要用空格Codex读取文件路径时纯净的短横线命名最稳。我用的命名规则是服务名-功能域名比如erp-orders-api。在目录下新建SKILL.md里面用结构化、带明确触发条件的方式描述技能。参考格式如下--- name: erp-orders-api description: 提供订单查询、创建、更新能力。当用户需要查询订单详情、批量拉取订单列表、创建新订单时使用。 --- # ERP订单管理API技能 ## 适用场景 - 用户询问“某个订单现在什么状态” - 用户要求“查最近一周的订单” - 用户需要“创建一个新订单” ## 关键约定 - 查询订单列表时默认按创建时间倒序 - 调用创建订单接口前必须先确认商品SKU是否存在 - 所有接口都需要在请求头注入 Access-Token脚本会自动完成 - 订单金额为整数单位是分不要转成元 ## 接口入口 完整接口定义请读取 openapi.yaml不要自行修改接口路径。这里我特别注重“关键约定”这个板块。智能体有了这些约定才不会做出特别反直觉的操作。比如订单金额单位是分这要是不写清楚模型完全可能把100元当成100传递导致数据错误。3.3 第三步把openapi.yaml和工具描述对接起来光有SKILL.md还不够因为Codex虽然知道有这些接口但具体怎么拼请求、怎么处理响应还得靠openapi.yaml配合config.json和脚本。config.json我一般这样写{ base_url: https://api.example.local/v1, access_token: 这里是动态占位符, token_endpoint: /auth/login, timeout_seconds: 15 }脚本部分api_wrapper.py的核心逻辑非常简单读取OpenAPI文件里的paths信息根据方法名拼接URL注入Token发HTTP请求返回解析后的JSON。这里我给出一个简化版本import json import requests import yaml CONFIG_PATH config.json OPENAPI_PATH openapi.yaml with open(CONFIG_PATH, r, encodingutf-8) as f: config json.load(f) with open(OPENAPI_PATH, r, encodingutf-8) as f: spec yaml.safe_load(f) TOKEN None def _ensure_token(): global TOKEN if TOKEN: return TOKEN resp requests.post(config[base_url] config[token_endpoint]) TOKEN resp.json()[access_token] return TOKEN def call_operation(operation_id: str, params: dict None, body: dict None): for path, methods in spec[paths].items(): for method, detail in methods.items(): if detail.get(operationId) operation_id: url config[base_url] path headers {Accept: application/json, Authorization: fBearer {_ensure_token()}} resp requests.request( method.upper(), url, headersheaders, paramsparams, jsonbody, timeoutconfig[timeout_seconds], ) resp.raise_for_status() return resp.json() raise ValueError(foperation {operation_id} not found)这里我只做了一件核心的事情把“该怎么调接口”的重复劳动从智能体手里拿掉。Codex不需要自己写requests请求只需要确认调用哪个操作、传什么参数。对模型来说少一点低层次的编码多一点高层次的意图理解可靠性会高很多。如果你不想写代码也可以不建脚本直接在SKILL.md里写明“用Python的requests库调用openapi.yaml中的接口”让Codex自己生成代码。但是那样每次都会浪费一些上下文token而且可能每次生成的调用方式都不一样。我推荐至少封装一个稳定版本。3.4 第四步在Codex里测试调用Skill目录和文件都准备好之后我建议先在Codex里做一组冒烟测试不要直接上生产。我一般会连续测试这几个场景让Codex直接描述这个Skill是干什么的看它能不能准确读出来。让它根据SKILL.md里的“适用场景”触发某个查询接口。让它主动读取openapi.yaml并描述某个接口需要哪些参数。让它创建一个资源再查回来验证写操作链路。测试时如果Codex完全没反应先检查Skill目录是否放到了正确的加载路径。有些版本是从某个配置目录读取有些版本需要你在对话开头显式提到这个Skill名称。我在实际测试环境里只要在对话中说出“使用erp-orders-api技能”就能触发但每个环境不太一样这一点我会在第4节展开。还有一个很重要的测试点要让Codex知道“不需要让用户手动输入Token”。因为我们的目标是让API能力被智能体透明地使用而不是每次都要用户提供密钥。把Token藏在脚本和配置里既方便又安全。4. 踩过的坑和常见问题实录4.1 OpenAPI导出的兼容性问题Postman导出的OpenAPI文件我遇到最多的两个问题一是路径参数和请求体字段描述为空二是响应定义过于简单。空描述会导致智能体在调用时不知道参数含义只能靠猜。解决办法很简单导出后我会花半小时人工过一遍OpenAPI文件把每个参数的description补全把响应的example加上。千万别嫌麻烦这一步的投入能帮你节省后面排查“为什么智能体传了错误类型参数”的时间。另外Postman的“Collection v2.1”格式和“OpenAPI”格式不是一回事。你要是选了Collection v2.1会发现Codex根本读不出标准的paths结构。一定要在导出时正确选择OpenAPI格式。4.2 认证信息差点被写进Skill文件第一次做的时候我图方便直接把Token写进了SKILL.md结果Codex在回答用户问题时直接把Token也当作示例输出给了用户。虽然那是测试环境的Token但也吓得我立刻改成了脚本注入的方式。现在的原则是所有密钥、Token、签名算法一律不进入SKILL.md正文。config.json只保留占位符或者运行时加载的本地密钥签名算法放在脚本里SKILL.md只描述“系统会自动完成认证”。这样做还有另一个好处——哪怕你把SKILL.md直接公开分享也不会泄密。4.3 智能体“自作主张”传错参数当接口参数比较多时Codex有时会脑补出一些不存在的字段或者把日期字符串格式传错。比如我有个接口约定日期是YYYY-MM-DD但Codex却传了2025/01/01。这不是模型蠢而是OpenAPI文件里缺少明确的格式约束。解决方法是给OpenAPI参数加上format和example并且在SKILL.md里再强调一次格式约定。比如parameters: - name: start_date in: query required: true description: 开始日期格式为 YYYY-MM-DD example: 2025-04-01有了双重保险Codex几乎不会再改格式。如果还是传错就在SKILL.md的“关键约定”里再加一条更醒目的规则。4.4 权限边界与技能失效排查给智能体开放API能力最让人担心的是它会顺手做掉一些不该做的操作。比如我只是让它查询订单它却自己调用了删除接口。要避免这个问题我通常会这么做在OpenAPI文件里只保留智能体允许调用的路径不需要的路径直接删掉而不是靠描述去劝它别用。在SKILL.md里写清楚“本技能只允许查询操作禁止更新和删除”。在脚本层做白名单校验call_operation里维护一个允许调用的operation_id列表不在列表里的直接拒绝。如果Codex明明该用Skill却完全没反应先不要怀疑模型按下面几步排查检查Skill目录是否在正确路径文件名是否用了特殊字符。检查SKILL.md的name字段是否唯一两个Skill重复描述会互相干扰。在对话里手动提到技能名看能否被触发。查看OpenAPI文件是否能被正确解析可以用python -c import yaml; yaml.safe_load(open(openapi.yaml))验证。5. 我的最终心得与后续扩展5.1 什么场景最适合用这套方案我自己试下来这套“Postman导出OpenAPI Skill外壳”的组合最适用的场景是你有一批已经稳定运行的HTTP接口并且希望智能体在业务中能像人一样去操作它们。比如内部订单查询、用户数据同步、内容发布、指标查看等。这些API通常已经有Postman集合管理接口数量在几个到几十个之间用Skill方式整理并接入性价比很高。反过来如果接口还在频繁变动或者压根没有稳定环境那我建议先别接智能体。Skill文件里的示例和约定一旦接口变更就会变成误导信息。接口不稳定的时候维护成本比收益高。5.2 后续还可以这样扩展对于这套方案我不会停在单个Skill上。后面可以考虑几个方向多个Skill统一管理把不同业务域的Skill组织成独立目录然后用一个总索引文件让Codex知道“查订单用订单技能查库存用库存技能”。从Postman到Git的自动化流程Postman集合可以通过API或命令行工具同步更新OpenAPI文件纳入Git仓库技能更新走代码评审流程。增加测试用例在每个Skill里放一个sample_tests.shCodex在修改Skill相关代码后可以自动跑一遍接口冒烟测试确保可用性。最后分享一个实际操作中的小技巧SKILL.md的描述不要写得太“全”。很多人在写技能时巴不得把所有情况都列一遍结果描述过长反而模糊了核心触发词。我发现最适合的长度是150到300字之间把最核心的“何时用、怎么用、别做什么”讲清楚就行。剩下的细节交给OpenAPI和脚本去兜底。这个度跟我前面说的“SKILL.md负责决策不要负责执行细节”是完全一致的。