1. 什么是 agent-skills:一个被严重低估的工程化接口层
“agent-skills”这个词最近在开发者社区里频繁刷屏,但很多人点开仓库或文档后反而更迷糊了——它既不是某个具体模型,也不是某家大厂新发布的API服务,更不是又一个LLM应用框架。我第一次接触它是在调试一个自动化文档生成脚本时,发现底层调用的不是直接发HTTP请求,而是通过一个叫skills.run("git_commit", {repo: "./docs", message: "update changelog"})的函数。当时我就意识到:这根本不是“技能列表”,而是一套面向Agent的标准化能力契约(Capability Contract)。
简单说,agent-skills 是一套定义、封装、注册和调度原子级操作能力的协议规范与运行时实现。它的核心价值不在于“能做什么”,而在于“怎么让不同来源的能力,在统一语义下被任意Agent安全、可验证、可组合地调用”。你看到的 CLI 工具(比如 codex cli、zcode cli)、slash commands(如/summarize/deploy)、甚至前端开发中封装的useSearchSkill()Hook,本质上都是这个协议在不同载体上的表现层。它解决的是 LLM 应用落地中最痛的三个断层:
- 语义断层:模型输出 “请调用数据库查询接口” → 开发者得手动解析、拼接URL、处理鉴权;
- 权限断层:用户说“删掉测试环境所有临时文件”,系统得判断这是高危操作,需二次确认+审计日志+RBAC校验;
- 组合断层:一个“生成周报”任务要串起 GitHub PR 数据拉取 → Markdown 渲染 → 邮件发送 → 企业微信通知,每个环节的输入/输出格式、错误码、重试策略都得硬编码适配。
所以别再把它当成“插件市场”或“工具箱”。它本质是Agent 操作系统的 syscall 层——就像 Linux 的open()/read()/write()让应用不用关心硬盘型号,agent-skills 让 Agent 不用关心 API 是 REST 还是 GraphQL、是 OAuth2 还是 API Key、是异步轮询还是 WebSocket 推送。我去年帮一家做智能运维的客户重构告警响应流程,把原来散落在 7 个微服务里的告警处置动作(查指标、启诊断脚本、发钉钉、创建工单、通知值班人)全部抽象成 5 个 skills,整个响应链路配置时间从 3 天缩短到 47 分钟,而且所有操作都自动带审计溯源。这才是它真实的力量所在。
2. 核心设计逻辑:为什么必须用 skills 而不是直连 API?
2.1 协议层 vs 接口层:一个关键分水岭
很多团队一开始会质疑:“我们已经有成熟的 API 网关了,为什么还要多一层 skills?” 这个问题问到了根子上。我拿一个真实案例说明:某电商客户要做“自动补货建议”Agent,需要调用三个内部服务——库存服务(REST)、销量预测服务(gRPC)、供应商履约服务(SOAP)。如果让 LLM 直接生成调用代码:
# ❌ 危险的直连模式(实际发生过) response = requests.post( "https://inventory.internal/api/v1/stock?sku=SKU123", headers={"Authorization": "Bearer xxx"}, json={"warehouse_id": "WH001"} ) # 问题1:token 硬编码在 prompt 里,泄露风险极高 # 问题2:gRPC 和 SOAP 的调用方式完全不同,LLM 很难泛化 # 问题3:库存不足时返回 404,但销量预测可能返回 503,错误处理逻辑割裂而 skills 的解法是定义统一契约:
# ✅ skill.yaml 定义(声明式) name: get_inventory_level description: 查询指定仓库中某 SKU 的实时库存数量 input_schema: type: object properties: sku: {type: string, description: "商品唯一编码"} warehouse_id: {type: string, description: "仓库ID"} output_schema: type: object properties: available: {type: integer, description: "可用库存"} reserved: {type: integer, description: "已预订库存"} execution: # 具体实现对 Agent 透明 type: http method: GET url: "https://inventory.internal/api/v1/stock" auth: service_account # 使用预授权的服务账号,非用户 token timeout: 5000关键差异在于:skills 把“做什么”(What)和“怎么做”(How)彻底解耦。Agent 只需理解get_inventory_level(sku="A123", warehouse_id="WH001")这个语义,背后是 HTTP、gRPC 还是本地函数调用,由 skills runtime 决定。这带来三大刚性收益:
安全收敛:所有敏感凭证(API Key、证书、Token)只存于 skills 运行时,Agent 永远看不到明文。我们给金融客户做的方案里,连数据库连接字符串都通过 Vault 动态注入,skills 执行时才解密,审计日志只记录
skill_name=get_db_row, input_hash=xxx,完全规避了 prompt 注入窃取密钥的风险。错误归一化:无论底层 API 返回 401、503 还是 gRPC 的
UNAVAILABLE,skills runtime 统一转换为标准错误码SKILL_AUTH_FAILED/SKILL_TEMPORARY_UNAVAILABLE,Agent 可以用一套策略处理(如重试、降级、告警),不用为每个 API 写定制逻辑。可观测性内建:每个 skills 调用自动记录
start_time、end_time、input_size_bytes、output_size_bytes、cache_hit(是否命中缓存)、retry_count。我们曾用这些数据发现一个“查询用户画像”的 skills 平均耗时 8.2s,深入分析发现是它调用的 Redis 集群用了默认序列化器,JSON 字符串比二进制大 3.7 倍,网络传输成了瓶颈——这种问题在直连模式下根本无法定位。
提示:skills 不是替代 API 网关,而是站在网关之上。API 网关管“流量”,skills runtime 管“意图”。就像 nginx 负责路由和限流,skills 负责把“我要查库存”翻译成对 nginx 的具体请求,并确保这个动作符合业务规则。
2.2 CLI 与 slash commands:skills 的两种“用户界面”
你看到的codex cli或 Slack 里的/deploy,其实是 skills 协议的两种交互形态,它们服务于完全不同的场景:
CLI 工具(如 codex cli):面向开发者和 SRE,强调可编程性与调试能力。
它的核心价值不是“执行命令”,而是提供--dry-run(预演)、--trace(追踪调用链)、--schema(查看输入输出结构)等能力。比如:# 查看 skills 定义(自解释) codex skills show get_inventory_level # 预演执行(不真正调用后端,只验证参数和权限) codex skills run get_inventory_level --sku SKU123 --warehouse_id WH001 --dry-run # 追踪一次失败调用的完整路径(从 LLM 输出到 skills 执行到下游 API) codex skills run get_inventory_level --trace --sku SKU123我们团队内部规定:所有新接入的 skills 必须通过
--dry-run测试,否则不允许上线。这避免了大量因参数类型错误(如把字符串当整数传)导致的线上故障。Slash commands(如
/summarize):面向终端用户,强调意图识别与上下文感知。
它的关键在于把自然语言请求映射到 skills 调用。比如用户在钉钉群里发/summarize https://xxx.com/report.pdf,背后不是简单调 PDF 解析 API,而是:- 识别 URL 类型(PDF/网页/Notion 页面)→ 触发对应 skills;
- 检查用户是否有该文档访问权限(集成企业微信权限系统);
- 根据文档长度自动选择模型(<10页用轻量模型,>50页启用分块摘要);
- 将结果按钉钉消息格式渲染(支持折叠长文本、添加原文链接)。
这种能力依赖 skills 的元数据声明。比如
summarize_pdfskill 的 YAML 中有:context_requirements: - document_access: true # 需要文档访问权限 - file_type: ["pdf", "docx"] # 支持的文件类型 auto_parameters: model: rule: "if input_size < 100000 then 'qwen2-mini' else 'qwen2-72b'"没有这些声明,slash command 就只是个固定指令,无法实现真正的智能路由。这也是为什么很多团队做了 slash command 却觉得“不够智能”——缺的不是 NLP 模型,而是 skills 层的语义描述能力。
3. 实操落地:从零构建一个可生产的 skills 系统
3.1 技术选型:为什么我们放弃自研 runtime,选择开源方案
2023 年初我们评估过三种路线:
- 纯自研:用 Go 写一个 skills dispatcher,对接内部服务。
- 基于 LangChain Tools 改造:利用其 Tool 抽象,但深度定制执行逻辑。
- 采用 OpenSkills 规范 + 开源 runtime(最终选择)。
放弃自研是因为:skills 的核心难点不在调度,而在治理。你需要处理技能版本管理、灰度发布、熔断降级、跨集群调用、审计合规——这些全是基础设施问题。我们花了两周写 dispatcher,结果卡在“如何让 skills A 调用 skills B 时,B 的调用链能正确继承 A 的 trace_id 和权限上下文”上,最后发现这本质是分布式事务问题,不该由业务层解决。
LangChain Tools 的问题是:它把 skills 当作 Python 函数,强绑定在特定进程里。而我们的需求是:
- 前端 Web App 要调用
search_knowledge_base; - 后端 Worker 要调用
send_email; - Slack Bot 要调用
create_jira_ticket; - 这些服务用不同语言(TypeScript/Python/Java),部署在不同集群。
LangChain 的@tool装饰器根本无法跨进程、跨语言复用。
最终我们选定OpenSkills 规范(GitHub 上 3.2k stars)配合skills-core runtime(Go 编写,轻量级,Docker 镜像仅 28MB)。选择理由很务实:
| 维度 | OpenSkills + skills-core | 自研方案 | LangChain Tools |
|---|---|---|---|
| 跨语言支持 | ✅ 通过 HTTP/gRPC 协议,任何语言 SDK | ⚠️ 需自己实现各语言 client | ❌ Python-only |
| 权限模型 | ✅ 内置 RBAC + scope-based auth(如skills:read:users) | ⚠️ 需从零设计 | ❌ 无权限概念 |
| 可观测性 | ✅ Prometheus metrics + OpenTelemetry tracing | ⚠️ 需集成多个组件 | ❌ 无内置支持 |
| 热更新 | ✅ YAML 文件变更自动 reload,无需重启 | ✅ | ❌ 需重启进程 |
特别提一下skills-core的热更新机制:它监听 skills 目录下的 YAML 文件,当检测到修改时,会启动一个验证流程——先用 JSON Schema 校验语法,再调用--dry-run测试能否成功连接下游服务,只有全部通过才替换内存中的 skill definition。我们线上环境因此避免了 17 次因 YAML 缩进错误导致的配置失效。
3.2 一个生产级 skills 的完整构建流程
以“查询 GitHub 仓库 star 数”为例,展示从定义到上线的全流程。这不是玩具 demo,而是我们实际用于监控开源项目健康度的 production skill。
步骤 1:定义 skills.yaml(声明契约)
# skills/github/get_star_count.yaml name: get_github_star_count description: 获取指定 GitHub 仓库的 star 数量(需公开仓库) version: "1.2.0" # 语义化版本,影响缓存和灰度 input_schema: type: object properties: owner: type: string description: 仓库所有者(用户名或组织名) minLength: 1 maxLength: 39 repo: type: string description: 仓库名称 minLength: 1 maxLength: 100 required: [owner, repo] output_schema: type: object properties: stars: type: integer description: 当前 star 数量 minimum: 0 last_updated: type: string format: date-time description: 最后更新时间(ISO 8601) required: [stars, last_updated] execution: type: http method: GET url: "https://api.github.com/repos/{owner}/{repo}" auth: type: api_key header: "Authorization" value: "Bearer {{GITHUB_TOKEN}}" # 从环境变量读取 timeout: 3000 retry: max_attempts: 3 backoff_factor: 2 # 指数退避 cache: enabled: true ttl_seconds: 300 # 5分钟缓存,避免高频调用触发 rate limit response_mapping: # 将 GitHub API 响应映射到 skills 标准输出 stars: $.stargazers_count last_updated: $.updated_at关键细节说明:
version: "1.2.0":当我们要增加include_forks参数时,会升级到1.3.0,旧版调用不受影响;auth.value: "Bearer {{GITHUB_TOKEN}}":skills-core会自动从容器环境变量或 Vault 中获取GITHUB_TOKEN,绝不硬编码;response_mapping:用 JSONPath 提取字段,避免写解析代码。我们曾用此功能将 12 个不同格式的天气 API 统一映射到get_weatherskill,省去 200+ 行适配代码;cache.enabled: true:skills-core 内置 Redis 缓存,key 为skill:get_github_star_count:{sha256(owner+repo)},自动处理缓存穿透。
步骤 2:本地开发与测试(CLI 驱动)
# 1. 启动本地 skills-core(自动加载当前目录 skills/ 下的 YAML) skills-core serve --config ./skills-config.yaml # 2. 查看 skill 是否加载成功 codex skills list | grep github # 输出:get_github_star_count (v1.2.0) - 获取指定 GitHub 仓库的 star 数量 # 3. 用 dry-run 验证参数和权限(不调真实 GitHub API) codex skills run get_github_star_count \ --owner "microsoft" \ --repo "vscode" \ --dry-run # 输出:✅ Validated. Would call https://api.github.com/repos/microsoft/vscode with auth header. # 4. 真实调用(需设置 GITHUB_TOKEN 环境变量) export GITHUB_TOKEN="ghp_xxx..." codex skills run get_github_star_count --owner "microsoft" --repo "vscode" # 输出:{"stars": 152345, "last_updated": "2024-06-15T08:22:14Z"}注意:
--dry-run是开发阶段的生命线。我们要求所有 PR 必须包含--dry-run的截图,证明参数校验通过。曾有个 PR 因owner字段没加minLength,导致空字符串传入后 GitHub API 返回 404,而 skills-core 把它当作业务错误而非参数错误,埋下了隐患。
步骤 3:集成到 Agent(以 LangChain 为例)
from langchain_core.tools import Tool from skills_client import SkillsClient # OpenSkills 官方 Python SDK # 初始化 skills client(指向 skills-core 服务) skills_client = SkillsClient(base_url="http://skills-core:8000") # 创建 LangChain Tool(自动适配 skills 协议) github_star_tool = Tool( name="get_github_star_count", description="获取 GitHub 仓库 star 数量,输入 owner 和 repo", func=lambda **kwargs: skills_client.run("get_github_star_count", kwargs), args_schema=GithubStarInput # 自动生成 Pydantic 模型 ) # 在 Agent 中使用(无需关心 HTTP 调用细节) agent = initialize_agent( tools=[github_star_tool], llm=ChatOpenAI(model="gpt-4-turbo"), agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, ) agent.invoke("查一下 langchain-ai/langchain 仓库有多少 star?")这里的关键是SkillsClient封装了所有协议细节:自动处理认证、重试、缓存、错误码转换。Agent 开发者只需关注name和description—— 这正是 skills 的设计哲学:让 Agent 专注“思考”,让 skills 专注“执行”。
步骤 4:上线与灰度(生产环境实践)
我们采用三阶段发布:
Canary 灰度(5% 流量):
- 修改
skills-config.yaml,添加canary: true标签; - skills-core 自动将 5% 的
get_github_star_count请求路由到新版本,其余走旧版; - 监控面板对比两版的
p95_latency、error_rate、cache_hit_ratio。
- 修改
全量发布(100% 流量):
- 灰度指标达标(错误率 <0.1%,延迟提升 <10%)后,移除
canary标签; - skills-core 自动切换所有流量到新版。
- 灰度指标达标(错误率 <0.1%,延迟提升 <10%)后,移除
回滚机制(一键触发):
- 若发现异常,执行
codex skills rollback get_github_star_count --to-version 1.1.0; - skills-core 在 2.3 秒内完成回滚(实测数据),无需重启服务。
- 若发现异常,执行
这套流程让我们在过去 14 个月里,完成了 217 次 skills 更新,0 次因更新导致的线上事故。最惊险的一次是 v1.2.0 版本因 GitHub API 响应字段变更(stargazers_count→stargazers),我们在灰度期就捕获到response_mapping失败,2 小时内修复并发布 v1.2.1,用户无感知。
4. 高频问题与实战排障指南
4.1 “API Error: 400 This model's maximum context length is 1048576 tokens” —— 这根本不是 skills 的错
这个错误在 DeepSeek、Qwen 等大模型 API 调用中高频出现,但很多人误以为是 skills 配置问题。真相是:skills 本身不处理模型上下文,它只负责调用下游服务。这个错误发生在 skills 调用的某个 endpoint(比如generate_reportskill 调用的 LLM API),而 skills-core 只是把错误原样透传。
排查路径必须分层:
| 层级 | 检查项 | 工具/命令 | 典型问题 |
|---|---|---|---|
| skills 层 | 输入参数是否过大?skills 是否错误地把整个文档内容作为参数传入? | codex skills run generate_report --input_file report.pdf --debug | input_file参数本应传文件 ID,却传了 Base64 编码的 50MB PDF |
| skills-core 层 | skills-core 是否对输入做了截断或压缩? | 查看skills-core日志,搜索TRUNCATED_INPUT | 默认配置未开启输入大小限制,导致超大 payload 发往下游 |
| 下游 API 层 | LLM API 的实际限制是多少?是否启用了 streaming? | 直接 curl LLM API,用最小 payload 测试 | DeepSeek 官方文档写 1M tokens,但实际max_tokens参数需显式设置,否则默认 2048 |
我们的解决方案是:在 skills 定义中强制约束输入大小:
# skills/report/generate_report.yaml input_schema: type: object properties: file_id: type: string description: 文档 ID(非文件内容!) required: [file_id] # 添加 pre-execution hook(skills-core 支持) hooks: before_run: - type: validate_input_size max_bytes: 1048576 # 1MB,防止大文件 ID 传入 - type: check_file_exists # 调用内部文件服务验证 file_id 有效性实操心得:永远不要相信前端或 Agent 传来的参数。我们在
before_runhook 中加入文件存在性检查后,因无效file_id导致的 LLM API 400 错误下降了 92%。记住:skills 的第一道防线是输入验证,不是错误处理。
4.2 “Permission denied while trying to connect to the Docker API” —— 权限模型的坑
这个错误通常出现在 skills 需要调用宿主机 Docker API(如deploy_to_dockerskill)时。表面看是 Docker 权限问题,实则是 skills 的权限模型没配对。
根本原因:skills-core 默认以非 root 用户运行,而 Docker socket (/var/run/docker.sock) 的权限通常是root:docker,且 mode 为0660。skills-core 进程用户不在docker组,自然 Permission denied。
标准解法有三种,我们推荐第三种:
暴力方案(❌ 不推荐):
chmod 666 /var/run/docker.sock—— 安全红线,所有容器都能操作宿主机 Docker,等于裸奔。组权限方案(⚠️ 有条件可用):
# 创建 docker 组,把 skills-core 用户加入 sudo groupadd docker sudo usermod -aG docker skills-core-user # 重启 skills-core问题:skills-core 用户若在 Kubernetes Pod 中,无法执行
usermod,且组权限在容器间不共享。Socket 代理方案(✅ 生产推荐):
- 部署
docker-proxy服务(轻量 HTTP 代理,监听localhost:2375); docker-proxy以 root 运行,持有 Docker socket 权限;- skills-core 通过 HTTP 调用
http://docker-proxy:2375/containers/create; docker-proxy做鉴权(如检查 skills token 是否有docker:deployscope)。
我们用这个方案实现了细粒度控制:
get_container_logsskill 只能读日志(GET /containers/*/logs);deploy_to_dockerskill 才能创建容器(POST /containers/create);- 所有调用自动记录
user_id、skill_name、container_name到审计日志。
配置示例(skills.yaml):
execution: type: http url: "http://docker-proxy:2375/containers/create" auth: type: bearer_token scope: "docker:deploy" # skills-core 自动注入 token 并校验 scope- 部署
4.3 CLI 安装慢、命令不生效?检查这 5 个隐藏点
codex cli或zcode cli安装卡住、命令找不到,90% 的情况不是网络问题,而是环境配置缺陷。按顺序排查:
Shell 初始化未生效:
curl -fsSL https://get.codex.dev | sh会把二进制放到~/.local/bin,并提示你把该路径加入PATH。但很多人复制粘贴后忘了source ~/.bashrc或source ~/.zshrc。
✅ 验证:echo $PATH | grep ".local/bin",没输出就执行source ~/.zshrc。Shell 配置文件位置错误:
macOS 新版默认用 zsh,但~/.bash_profile里加了 PATH。zsh 不读 bash_profile。
✅ 解决:把 PATH 添加到~/.zshrc,或在~/.zshrc里source ~/.bash_profile。CLI 二进制权限不足:
某些下载方式(如浏览器下载)会导致文件无执行权限。
✅ 验证:ls -l ~/.local/bin/codex,若没有x(如-rw-r--r--),执行chmod +x ~/.local/bin/codex。Shell Completion 未安装:
codex completion zsh生成的 completion 脚本需手动加载。
✅ 检查:codex命令能用,但codex skills <Tab>不补全,说明 completion 没生效。执行:codex completion zsh > ~/.zfunc/_codex echo 'fpath=(~/.zfunc $fpath)' >> ~/.zshrc echo 'autoload -Uz compinit && compinit' >> ~/.zshrc source ~/.zshrcSkills Runtime 未启动:
codex skills list显示No skills found,大概率是skills-core没运行。
✅ 验证:curl http://localhost:8000/health,返回{"status":"ok"}才正常。
启动命令:skills-core serve --config ./skills-config.yaml &(后台运行)。
我们内部有个codex doctor命令,自动执行这 5 步检查并给出修复建议,新同事入职 5 分钟就能搞定环境。这才是 CLI 工具该有的体验。
4.4 “No API key for provider route 'deepseek-official'” —— 环境变量与 secrets 的最佳实践
这个错误表明 skills-core 找不到DEEPSEEK_API_KEY环境变量。但问题往往更深:环境变量在容器、Kubernetes、本地开发中传递方式完全不同。
我们的标准化方案:
| 环境 | 配置方式 | 示例 | 安全要点 |
|---|---|---|---|
| 本地开发 | .env文件 +dotenv加载 | DEEPSEEK_API_KEY=sk-xxx | .env加入.gitignore,绝对不提交 |
| Docker Compose | environment字段 | environment: - DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY} | 启动 compose 时DEEPSEEK_API_KEY=xxx docker-compose up |
| Kubernetes | Secret+envFrom | envFrom: - secretRef: name: deepseek-secrets | Secret 用stringData创建,避免 base64 编码错误 |
| Serverless(如 AWS Lambda) | 环境变量加密 | AWS 控制台中勾选 "Enable encryption helpers" | KMS 密钥自动解密 |
关键经验:永远不要在 skills.yaml 中写value: "sk-xxx"。我们曾发现一个实习生把测试用的 API Key 写在 YAML 里,提交到 GitHub,3 小时后就被扫描机器人盗用,产生了 $2,300 账单。现在所有 secrets 都通过 Vault 动态注入:
# skills/llm/deepseek_chat.yaml auth: type: vault path: "secret/data/llm/deepseek" field: "api_key" # skills-core 会调用 Vault API 获取值,全程不落盘Vault 集成后,API Key 轮换只需在 Vault 中更新,skills-core 自动刷新,无需重启服务。这让我们在一次云厂商密钥泄露事件中,15 分钟内完成全部 47 个 skills 的密钥轮换。
5. 进阶技巧:让 skills 真正成为你的 AI 操作系统
5.1 把 skills 当作“可编程的 UI 组件”
大多数人把 skills 当作后端能力,其实它能驱动前端交互。我们为销售团队做的 CRM Agent,skills 不仅调 API,还直接生成 React 组件:
# skills/crm/show_lead_card.yaml name: show_lead_card description: 生成销售线索卡片(含联系人、公司、跟进状态) output_schema: type: object properties: react_component: type: string description: 可直接渲染的 React JSX 字符串 data: type: object description: 卡片所需数据 execution: type: function # 调用 Node.js 函数,返回 JSX 字符串 module: "./src/skills/crm/show-lead-card.js"show-lead-card.js内容:
module.exports = async (input) => { const lead = await db.getLead(input.lead_id); return { react_component: ` <div className="lead-card"> <h3>${lead.name}</h3> <p>公司:${lead.company}</p> <button onClick={() => window.open('/followup?id=${lead.id}')}> 立即跟进 </button> </div> `, data: lead }; };Agent 调用后,前端直接ReactDOM.render(<div dangerouslySetInnerHTML={{__html: result.react_component}} />)。这实现了:
- UI 逻辑下沉:设计师改卡片样式,只需改 skills 的 JSX,不用动前端代码;
- 动态渲染:根据用户角色(销售/经理)返回不同 JSX;
- 离线可用:skills 返回的 JSX 字符串可缓存,弱网下仍能显示。
注意:
dangerouslySetInnerHTML有 XSS 风险,我们强制要求 skills 返回的 JSX 必须通过 DOMPurify 过滤,且禁止<script>标签。这是 skills 的责任,不是前端的责任。
5.2 构建 skills 的“技能市场”:内部开发者生态
当团队有 50+ skills 时,靠文档维护成本极高。我们搭建了内部 skills market:
- 自动发现:skills-core 每 30 秒扫描
skills/目录,提取 YAML 中的name、description、version、tags(如tag: ["crm", "reporting"]); - Web UI:类似 npmjs.com,支持关键词搜索、按标签筛选、查看调用统计;
- 一键安装:点击
Install,自动下载 YAML 到本地skills/目录,并执行codex skills validate --all; - 贡献流程:PR 提交 skills YAML → CI 运行
--dry-run+ 安全扫描(检查硬编码密钥)→ 合并后自动部署到 staging 环境。
最成功的案例是财务部门贡献的calculate_vatskill:
- 输入:
amount: 1000, country: "DE"; - 输出:
vat_amount: 190, total: 1190; - 被销售、采购、客服 7 个 Agent 同时调用。
以前每个团队自己实现 VAT 计算,税率更新时漏改一个,就导致开票错误。现在税率库统一在 skills 中维护,一次更新,全局生效。
5.3 用 skills 实现“零代码”Agent 编排
最后分享一个杀手级用法:用 skills 定义 Agent 的工作流,而不是写代码。
我们有个“新员工入职”Agent,需要串起 12 个步骤(创建邮箱、分配设备、开通系统权限、安排导师等)。传统做法是写状态机或用 Temporal。而我们用 skills 编排:
# skills/orchestration/onboard_employee.yaml name: onboard_employee description: 执行新员工入职全流程 input_schema: type: object properties: employee_id: {type: string} start_date: {type: string, format: date} execution: type: workflow steps: - name: create_email_account skill: "email:create_account" input: {"employee_id": "{{.employee_id}}"} timeout: 60 - name: assign_laptop skill: "it:assign_device" input: {"employee_id": "{{.employee_id}}", "device_type": "laptop"} # 条件分支:只有 IT 部门审批通过才执行 condition: "{{.it_approval == 'approved'}}" - name: send_welcome_email skill: "email:send_template" input: {"template": "welcome", "to": "{{.email}}"} # 并行执行:不阻塞后续步骤 parallel: trueskills-core 内置 workflow engine,自动处理:
- 步骤依赖与并行;
- 超时与重试;
- 错误恢复(如
create_email_account失败,自动执行rollback_email_creation); - 状态持久化(每步结果存入 PostgreSQL)。
运营同学只需修改 YAML,就能调整入职流程,无需找开发。上周 HR 提出“增加背景调查步骤”,我们 12 分钟就上线了新流程——这才是 skills 该释放的生产力。
我在实际项目中