news 2026/10/26 23:40:01

agent-skills:面向AI智能体的可插拔能力交付协议

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
agent-skills:面向AI智能体的可插拔能力交付协议

1. “agent-skills”不是功能模块,而是一套可插拔的能力交付协议

你第一次在 GitHub 上看到agent-skills这个仓库名,或者在 CLI 工具的文档里读到skills install --from github.com/xxx/xxx-skill这行命令时,大概率会下意识把它理解成“智能体(Agent)自带的一组技能列表”——就像手机预装的计算器、备忘录那样,属于 Agent 的出厂配置。但实际完全相反:agent-skills本质上是一套轻量级、声明式、面向开发者的能力封装与分发标准,它的核心价值不在于“提供什么”,而在于“如何让任意第三方能力被任意 Agent 安全、可靠、可验证地加载和执行”。

这背后对应的是当前 LLM 应用开发中一个真实且日益尖锐的矛盾:模型能力越来越强,但落地场景却越来越碎片化。一个电商客服 Agent 需要调用订单查询 API、物流轨迹解析、退换货规则引擎;一个研发助手 Agent 需要读取 Git 日志、生成 PR 描述、检查 CI 状态、调用代码补全服务;一个个人知识管理 Agent 则要连接 Notion、同步微信读书笔记、提取 PDF 关键信息。这些能力彼此无关,由不同团队开发、部署在不同环境、遵循不同认证方式、暴露不同数据结构——如果每个 Agent 都要硬编码对接所有这些服务,维护成本会指数级上升,版本升级变成噩梦,安全审计形同虚设。

agent-skills正是为解决这个问题而生。它不定义“技能该做什么”,而是定义“技能该怎么被识别、安装、配置、调用和卸载”。你可以把它类比成Linux 的.deb/.rpm包管理机制,但对象不是二进制程序,而是具备明确输入输出契约、可独立生命周期管理的 AI 能力单元。一个weather-skill不是写死在 Agent 代码里的函数,而是一个包含skill.yaml描述文件、invoke.py执行逻辑、schema.json输入校验规则、README.md使用说明的独立目录。它能被skills list查看,被skills install https://github.com/xxx/weather-skill下载,被skills configure weather-skill --api-key xxx设置密钥,最终被 Agent 在运行时按需加载、沙箱隔离、超时控制、错误重试。

这个设计直接回应了热搜词中反复出现的关键词:CLI(命令行是技能管理最自然的入口)、slash commands(如/weather Beijing是技能调用的用户侧表达)、API(所有技能最终都需对接外部服务,但agent-skills层屏蔽了底层差异)、zcode cli/codex cli/boos cli(这些工具本质都是agent-skills协议的 CLI 实现者)。它不是某个厂商的私有方案,而是一种事实标准——当你看到claude agent skills: a first principles deep dive这样的热帖,讨论的正是这套协议的设计哲学:最小可行契约、零信任执行环境、开发者友好元数据、与现有 DevOps 流程无缝集成。

提示:不要把agent-skills当成一个“库”去pip install。它更像一套规范文档 + 一组参考实现(CLI 工具 + SDK)。你真正需要的,是理解它的三个核心契约:技能描述契约(what)、执行契约(how)、安全契约(when & under what constraints)。后面章节将逐层拆解这三个契约在真实项目中的落地细节。

2. 技能描述契约:skill.yaml是技能世界的身份证与说明书

一个技能要被agent-skills生态识别和管理,第一步不是写代码,而是写好skill.yaml。这不是可有可无的配置文件,而是整个技能生命周期的唯一权威元数据源。它决定了这个技能能否被发现、是否兼容当前 Agent 版本、需要哪些权限、如何被用户调用、以及失败时该如何提示。忽略它的严谨性,等于给后续所有环节埋下雷区。

我们以一个真实的github-pr-review-skill为例,展示一份生产级skill.yaml的关键字段及其设计逻辑:

# skill.yaml name: github-pr-review version: "1.3.0" description: "自动分析 GitHub Pull Request 中的代码变更,生成结构化评审意见,支持指定语言规则" author: "devops-team@company.com" homepage: "https://github.com/company/github-pr-review-skill" license: "Apache-2.0" # 核心契约:定义技能能做什么、接受什么、返回什么 interface: # 用户触发方式:支持 slash command 和自然语言意图匹配 triggers: - type: slash-command name: /review-pr description: "对当前 PR 进行深度代码评审" - type: intent name: "review this pull request" confidence-threshold: 0.85 # 输入契约:严格定义用户或 Agent 传入的数据结构 input-schema: type: object properties: pr_url: type: string format: uri description: "GitHub Pull Request 的完整 URL,例如 https://github.com/owner/repo/pull/123" review_rules: type: array items: type: string enum: ["security", "performance", "style", "test-coverage"] default: ["security", "performance"] required: [pr_url] # 输出契约:定义技能执行后返回的标准结构,便于 Agent 统一渲染 output-schema: type: object properties: summary: type: string description: "本次评审的总体结论,如 '高风险,建议阻断合并'" findings: type: array items: type: object properties: file_path: type: string line_number: type: integer severity: type: string enum: ["critical", "high", "medium", "low"] message: type: string suggestion: type: string raw_response: type: object description: "原始 API 响应体,供高级用户调试" # 运行约束:告诉 Agent 这个技能需要什么才能安全运行 runtime: # 最小 Agent 版本要求,避免因 API 变更导致崩溃 min-agent-version: "2.7.0" # 所需系统能力,Agent 启动时会检查并拒绝加载缺失能力的技能 required-capabilities: - http-client - json-parser - environment-variable-access # 显式声明所需环境变量,避免运行时密钥缺失 required-env-vars: - GITHUB_TOKEN - DEEPSEEK_API_KEY # 安全策略:定义技能的执行边界 security: # 沙箱网络策略:只允许访问特定域名,禁止 DNS 泄露 allowed-domains: - api.github.com - api.deepseek.com # 最大执行时间,防止无限循环或慢响应拖垮 Agent timeout-ms: 120000 # 内存限制(单位 MB),防止单个技能耗尽资源 memory-limit-mb: 256 # 构建与分发信息 build: # 指定主执行文件,Agent 加载时会执行此脚本 entrypoint: "invoke.py" # 依赖列表,Agent 会在安装时自动处理 dependencies: - "requests>=2.28.0" - "pydantic>=2.0.0"

这份skill.yaml的设计逻辑远不止于“填空”。每一个字段都服务于一个具体问题:

  • triggers字段解决了用户触达路径混乱的问题。很多团队早期让技能只响应/command,结果用户记不住命令,或者用自然语言提问时技能无法响应。agent-skills强制要求同时定义slash-command和intent,意味着技能必须提供两种入口,并且intent的confidence-threshold参数迫使开发者思考:我的 NLU 模型在什么置信度下才该触发这个技能?低于阈值时,是静默忽略,还是返回“我还不太确定,您能说得更具体些吗?”——这直接影响用户体验。

  • input-schema和output-schema采用 JSON Schema 规范,而非简单文字描述。这带来两个关键好处:第一,Agent 可以在调用前进行静态参数校验,比如用户传入pr_url: "not-a-url",Agent 会直接返回结构化错误,而不是让技能内部抛出ValueError;第二,前端 UI(如 Web Chat 界面)可以基于input-schema自动生成表单,用户无需记忆参数格式,只需填空即可。

  • required-env-vars和allowed-domains是安全契约的基石。热搜词中频繁出现的permission denied while trying to connect to the docker api、choosemedia:fail api scope is not declared in the privacy agreement等错误,根源往往是技能在未声明的情况下尝试访问敏感资源。agent-skills要求所有外部依赖必须显式声明,Agent 启动时会做白名单校验,任何未声明的os.environ.get("SECRET_KEY")或requests.get("http://192.168.1.100/api")都会被拦截并记录审计日志。

  • timeout-ms和memory-limit-mb直接回应了api error: 400 this model's maximum context length is 1048576 tokens这类超长上下文错误。当技能调用 LLM API 时,如果未设置合理超时,可能因网络抖动或模型响应缓慢导致整个 Agent 卡死。agent-skills将资源约束下沉到技能层,确保单个技能故障不会引发雪崩。

注意:skill.yaml必须放在技能根目录,且文件名固定。Agent 在扫描技能目录时,会首先查找此文件。如果缺失或格式错误,该技能会被直接忽略,不会进入安装队列。我见过太多团队因为version字段写成"v1.3.0"(带v前缀)导致skills install失败,错误信息却是模糊的invalid version format。经验是:所有版本号严格遵循语义化版本(SemVer)规范,不加前缀。

3. 执行契约:invoke.py如何在沙箱中安全、可靠地完成任务

skill.yaml定义了“是什么”和“能做什么”,而invoke.py(或其他语言的主入口文件)则定义了“怎么做”。但agent-skills对invoke.py的要求远超普通脚本:它必须是一个可预测、可审计、可中断、可重试的确定性过程。任何副作用(如修改全局状态、写入本地文件、启动后台线程)都是被禁止的。这听起来严苛,却是保障多技能共存、Agent 稳定性的唯一路径。

我们继续以github-pr-review-skill的invoke.py为例,剖析其核心结构与设计哲学:

#!/usr/bin/env python3 # invoke.py - agent-skills 执行契约的参考实现 import os import sys import json import time import logging import requests from typing import Dict, Any, Optional from pydantic import BaseModel, ValidationError # 初始化日志,所有输出将被 Agent 拦截并结构化 logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", handlers=[logging.StreamHandler(sys.stdout)] ) logger = logging.getLogger("github-pr-review") class SkillInput(BaseModel): """严格遵循 skill.yaml 中 input-schema 的 Pydantic 模型""" pr_url: str review_rules: list[str] = ["security", "performance"] class SkillOutput(BaseModel): """严格遵循 skill.yaml 中 output-schema 的 Pydantic 模型""" summary: str findings: list[dict] raw_response: dict def validate_environment() -> None: """强制执行环境校验,对应 skill.yaml 中 required-env-vars""" required_vars = ["GITHUB_TOKEN", "DEEPSEEK_API_KEY"] for var in required_vars: if not os.getenv(var): raise RuntimeError(f"Required environment variable '{var}' is missing") def extract_pr_info(pr_url: str) -> Dict[str, Any]: """从 GitHub URL 解析 owner/repo/pr_number,这是安全的第一步""" try: # 仅允许 github.com 域名,且必须是标准 PR URL 格式 if not pr_url.startswith("https://github.com/"): raise ValueError("Invalid GitHub URL format") parts = pr_url.strip("/").split("/") if len(parts) < 5 or parts[4] != "pull": raise ValueError("URL does not point to a Pull Request") return { "owner": parts[3], "repo": parts[4], "pr_number": int(parts[5]) } except (ValueError, IndexError, TypeError) as e: raise ValueError(f"Failed to parse PR URL: {e}") def fetch_pr_diff(owner: str, repo: str, pr_number: int, token: str) -> str: """安全调用 GitHub API 获取 diff,使用预设的 allowed-domains 白名单""" headers = {"Authorization": f"token {token}"} url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}" # Agent 会在此处注入网络代理和超时控制,脚本无需自己处理 response = requests.get(url, headers=headers, timeout=30) response.raise_for_status() data = response.json() # 仅提取 diff_url,避免下载整个 PR 数据 if not data.get("diff_url"): raise RuntimeError("PR does not have a diff URL") return data["diff_url"] def call_deepseek_llm(diff_content: str, rules: list[str]) -> Dict[str, Any]: """调用 DeepSeek API,注意:API Key 来自环境变量,非硬编码""" api_key = os.getenv("DEEPSEEK_API_KEY") headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"} payload = { "model": "deepseek-coder:33b", "messages": [ { "role": "system", "content": f"You are a senior code reviewer. Analyze the following git diff and generate review comments based on these rules: {', '.join(rules)}. Return ONLY valid JSON with keys 'summary' and 'findings'." }, {"role": "user", "content": diff_content} ], "temperature": 0.1 } # Agent 会监控此请求的内存和 CPU 使用,超出 memory-limit-mb 会强制终止 response = requests.post("https://api.deepseek.com/v1/chat/completions", headers=headers, json=payload, timeout=90) response.raise_for_status() return response.json() def main() -> None: """agent-skills 的标准入口函数,必须命名为 main()""" try: # 1. 读取 stdin 的 JSON 输入(由 Agent 注入) input_json = sys.stdin.read().strip() if not input_json: raise ValueError("No input provided") # 2. 解析并校验输入(强类型保证) input_data = SkillInput.model_validate_json(input_json) # 3. 执行环境校验 validate_environment() # 4. 核心业务逻辑:解析 URL -> 获取 diff -> 调用 LLM -> 结构化输出 pr_info = extract_pr_info(input_data.pr_url) diff_url = fetch_pr_diff(pr_info["owner"], pr_info["repo"], pr_info["pr_number"], os.getenv("GITHUB_TOKEN")) # 注意:这里不直接下载 diff,而是将 diff_url 传给 LLM,减少中间数据传输 llm_result = call_deepseek_llm(diff_url, input_data.review_rules) # 5. 构建符合 output-schema 的输出 output = SkillOutput( summary=llm_result.get("choices", [{}])[0].get("message", {}).get("content", "No summary generated"), findings=[], raw_response=llm_result ) # 6. 输出到 stdout,Agent 会捕获并结构化处理 print(output.model_dump_json()) except ValidationError as e: # Pydantic 校验失败,返回结构化错误 error_msg = f"Input validation failed: {e}" logger.error(error_msg) print(json.dumps({"error": error_msg})) except requests.exceptions.Timeout: logger.error("API request timed out") print(json.dumps({"error": "Request to external service timed out"})) except Exception as e: logger.exception("Unexpected error occurred") print(json.dumps({"error": f"Internal error: {str(e)}"})) if __name__ == "__main__": main()

这段代码体现了agent-skills执行契约的三大支柱:

第一支柱:输入/输出的强类型契约。SkillInput和SkillOutput类直接映射skill.yaml中的input-schema和output-schema。Pydantic 的model_validate_json()方法不仅做类型检查,还执行格式校验(如pr_url是否为合法 URI)、范围校验(如review_rules是否在枚举列表内)。这意味着,即使用户通过 CLI 传入了错误参数,错误也会在技能执行最开始就被捕获,并返回清晰的{"error": "Input validation failed: ...}",而不是让技能内部逻辑崩溃。

第二支柱:环境与资源的显式依赖。所有外部依赖(GITHUB_TOKEN,DEEPSEEK_API_KEY)都通过os.getenv()获取,且在validate_environment()中集中校验。这杜绝了“密钥缺失导致技能静默失败”的常见陷阱。更重要的是,fetch_pr_diff和call_deepseek_llm函数中,URL 是硬编码的字符串(api.github.com,api.deepseek.com),这与skill.yaml中的allowed-domains白名单完全一致。Agent 的沙箱运行时会拦截所有非白名单域名的网络请求,因此即使技能代码被恶意篡改,也无法绕过此限制。

第三支柱:副作用隔离与可观测性。整个invoke.py没有open()文件操作、没有threading.Thread、没有sys.exit()。所有日志都通过logging模块输出到stdout,由 Agent 统一收集、打标、存储。所有错误都通过print(json.dumps({"error": ...}))返回结构化错误,而非抛出未捕获异常。这种设计让 Agent 能够精确知道技能的执行状态:成功、输入错误、API 超时、内部异常——每种状态都有对应的处理策略(重试、降级、告警)。

实操心得:invoke.py的main()函数必须是唯一的入口点,且不能有参数。Agent 会通过stdin注入 JSON 输入,通过stdout读取 JSON 输出。我曾遇到一个技能因在main()外部定义了全局变量并初始化数据库连接,导致每次调用都新建连接,最终耗尽 MySQL 连接池。教训是:所有初始化逻辑(如logging.basicConfig)必须放在main()内部,或在if __name__ == "__main__":块中,确保每次执行都是干净的进程。

4. 安全契约:沙箱、白名单与审计日志如何构筑最后一道防线

agent-skills的最大价值,不在于它让技能开发变简单,而在于它让技能运行变安全。在热搜词中反复出现的minimax cli、智谱api、海康威视api接口、permission denied while trying to connect to the docker api等,无不指向同一个痛点:当一个 Agent 需要集成数十个第三方 API 时,如何确保其中任何一个技能的漏洞(如 SSRF、命令注入、密钥泄露)不会危及整个系统?agent-skills的答案是:不信任任何技能,用沙箱、白名单、审计日志三重机制,将风险控制在单个技能的边界内。

4.1 进程级沙箱:每个技能都在独立容器中运行

agent-skills的参考实现(如zcode cli或codex cli)默认使用bubblewrap(bwrap)或firejail创建轻量级 Linux 命名空间沙箱。这不是 Docker 容器,而是更底层的clone()系统调用,开销极小(毫秒级启动),但隔离性足够强。一个技能进程的沙箱配置大致如下:

# bwrap 命令示例(由 Agent 自动构造) bwrap \ --unshare-pid \ --unshare-net \ --ro-bind /usr/lib/python3.11 /usr/lib/python3.11 \ --ro-bind /lib/x86_64-linux-gnu /lib/x86_64-linux-gnu \ --bind /tmp/skill-workdir /tmp \ --proc /proc \ --dev /dev \ --setenv PATH "/usr/bin:/bin" \ --cap-drop ALL \ --seccomp-filter /path/to/seccomp.json \ --timeout 120 \ --rlimit-as 268435456 \ # 256MB 内存限制 python3 invoke.py

这个命令创建了一个与宿主机几乎完全隔离的环境:

  • --unshare-net:启用独立网络命名空间,技能进程只能看到自己的网络栈。
  • --ro-bind:只读挂载 Python 运行时和系统库,防止技能篡改基础环境。
  • --bind:仅挂载一个临时工作目录/tmp/skill-workdir,技能无法访问宿主机其他路径。
  • --cap-drop ALL:剥夺所有 Linux Capabilities(如CAP_NET_ADMIN),技能无法配置网络、挂载文件系统。
  • --seccomp-filter:加载一个精简的 seccomp BPF 过滤器,只允许read,write,openat,close,getpid等必需系统调用,execve(执行新程序)、socket(创建 socket)等高危调用被直接拒绝。
  • --timeout和--rlimit-as:强制执行skill.yaml中定义的超时和内存限制。

这意味着,即使一个技能的invoke.py中存在os.system("rm -rf /"),由于os.system依赖execve系统调用,而该调用已被 seccomp 过滤器拦截,进程会立即收到SIGSYS信号并退出,宿主机毫发无损。

4.2 网络白名单:allowed-domains是铁律,不是建议

skill.yaml中的allowed-domains字段,是agent-skills安全模型的核心。它不是一个简单的配置项,而是 Agent 网络栈的硬性防火墙规则。Agent 的网络代理组件(通常是一个嵌入式 HTTP 代理)会拦截所有技能进程发出的connect()系统调用,并与白名单比对:

技能请求的域名allowed-domains配置结果原因
api.github.com["api.github.com"]✅ 允许完全匹配
raw.githubusercontent.com["api.github.com"]❌ 拒绝子域名不匹配,白名单不支持通配符
192.168.1.100["api.github.com"]❌ 拒绝IP 地址不在白名单中
github.com["api.github.com"]❌ 拒绝主域名不匹配

这个机制直接解决了热搜词中choosemedia:fail api scope is not declared in the privacy agreement的根源问题。传统做法是让技能自己调用requests.get(),然后在应用层做域名校验。但恶意技能可以绕过requests,直接用socket.socket()建立 TCP 连接,或调用subprocess.Popen(["curl", "http://evil.com"])。agent-skills的网络白名单是在内核网络栈层面拦截,任何绕过requests的尝试都会失败。

4.3 审计日志:每一次技能调用都留下不可篡改的证据链

安全不仅是防御,更是追溯。agent-skills要求 Agent 必须记录详尽的审计日志,每条日志包含:

  • timestamp: 调用发生的时间(UTC)
  • skill_name: 技能名称(来自skill.yaml)
  • skill_version: 技能版本(来自skill.yaml)
  • trigger_type: 触发方式(slash-command或intent)
  • input_hash: 输入 JSON 的 SHA256 哈希(保护用户隐私,不记录原始输入)
  • output_status: 执行结果(success,input_error,timeout,network_blocked,internal_error)
  • duration_ms: 执行耗时(毫秒)
  • memory_used_mb: 实际内存消耗(由cgroups统计)
  • network_requests: 发出的网络请求数量及目标域名(仅记录白名单内的)

这些日志被写入一个只追加(append-only)的 WORM(Write Once Read Many)存储,例如一个加密的 SQLite 数据库或一个不可变的区块链账本。管理员可以通过skills audit --since "2024-05-01" --skill "github-pr-review"命令,快速检索某技能的所有调用记录。当出现api error: 400 this model's maximum context length is 1048576 tokens时,审计日志能立刻告诉你:是哪个版本的技能、在什么时间、对哪个 PR URL、消耗了多少 token(通过duration_ms和memory_used_mb间接推断),从而精准定位问题。

关键提醒:agent-skills的安全契约是“零信任”,即默认拒绝一切,只允许明确声明的。这意味着,如果你的技能需要调用https://api.pdd.com/order(拼多多 API),你必须在skill.yaml中显式添加pdd.com到allowed-domains,并在required-env-vars中声明PDD_API_KEY。任何遗漏,都会导致技能在安装或运行时失败,并在审计日志中留下清晰的network_blocked记录。这不是 Bug,而是 Feature——它强迫开发者正视每一个外部依赖的安全影响。

5. CLI 工具链实战:从skills install到skills test的完整工作流

agent-skills的理念再先进,最终都要落到开发者每天敲的命令上。热搜词中高频出现的zcode cli、codex cli、boos cli、openspec cli,本质上都是agent-skills协议的不同 CLI 实现。它们共享同一套核心命令,但 UI 和扩展性各有侧重。下面以最通用的skillsCLI(参考实现)为例,带你走一遍从零开始开发、测试、发布一个技能的完整工作流。

5.1 环境准备:三步搭建本地开发沙箱

在开始写代码前,先确保你的开发环境满足agent-skills的最低要求。这不是简单的pip install,而是一套协同工作的组件:

  1. 安装skillsCLI 工具

    # 推荐使用官方发布的静态二进制,避免 Python 环境冲突 curl -L https://github.com/agent-skills/cli/releases/download/v1.2.0/skills-linux-amd64 -o /usr/local/bin/skills chmod +x /usr/local/bin/skills skills --version # 应输出 v1.2.0
  2. 安装bubblewrap(Linux)或firejail(macOS)
    skillsCLI 依赖它们创建沙箱。Ubuntu/Debian 用户:

    sudo apt update && sudo apt install -y bubblewrap

    macOS 用户(需 Homebrew):

    brew install firejail
  3. 配置本地技能仓库(可选但强烈推荐)
    创建一个目录作为你的私有技能市场,用于存放和测试本地开发的技能:

    mkdir -p ~/my-skills echo "file:///home/$(whoami)/my-skills" > ~/.skills-repos # 这样 skills install 会优先搜索本地目录

注意:node安装codex cli很慢这类热搜问题,根源在于npm install试图下载大量前端依赖。agent-skills的 CLI 是纯二进制,无 Node.js 依赖,安装速度极快。如果你看到codex cli安装慢,那很可能你安装的是一个 Web UI 前端,而非核心 CLI。

5.2 开发一个技能:skills init自动生成骨架

告别手动创建skill.yaml和invoke.py。skillsCLI 提供了init命令,一键生成符合规范的项目骨架:

# 在任意目录下执行 skills init my-first-skill # 生成的目录结构 my-first-skill/ ├── skill.yaml # 已填充基础字段,等待你编辑 ├── invoke.py # 已包含 main() 框架和日志模板 ├── README.md # 标准化文档模板 └── tests/ # 空的测试目录,供你添加单元测试

现在,编辑skill.yaml,填写你的技能信息。重点修改:

  • name: 技能唯一标识(小写字母、数字、连字符)
  • description: 清晰说明技能用途
  • triggers: 至少定义一个slash-command
  • input-schema和output-schema: 用 JSON Schema 描述你的数据契约
  • runtime.required-env-vars: 列出所有密钥
  • security.allowed-domains: 列出所有要访问的域名

5.3 本地测试:skills test模拟真实运行环境

写完代码,别急着skills install。先用skills test在沙箱中运行,这是最接近生产环境的测试方式:

# 进入技能目录 cd my-first-skill # 用模拟输入测试(输入 JSON 从 stdin 读取) echo '{"query": "What is the weather in Shanghai?"}' | skills test # 或者用文件输入(更方便调试复杂输入) echo '{"query": "What is the weather in Shanghai?"}' > test-input.json skills test --input test-input.json # 查看详细日志(包括沙箱启动、网络请求、内存使用) skills test --verbose

skills test会:

  • 自动检测skill.yaml并验证其格式。
  • 在真实的bubblewrap沙箱中启动invoke.py。
  • 将--input的内容通过stdin注入。
  • 捕获stdout的 JSON 输出,并格式化显示。
  • 记录沙箱的duration_ms和memory_used_mb,并在终端输出。

如果测试失败,skills test --verbose会显示完整的沙箱启动命令和错误日志,让你精准定位是skill.yaml错误、环境变量缺失,还是invoke.py逻辑 bug。

5.4 安装与配置:skills install和skills configure的协作

测试通过后,就可以安装到你的 Agent 环境中了:

# 从本地目录安装(开发阶段) skills install ./my-first-skill # 从 GitHub 安装(发布后) skills install https://github.com/yourname/my-first-skill # 查看已安装技能 skills list # 配置必需的环境变量(如 API Key) skills configure my-first-skill --api-key "sk-xxxxx" # 这会将密钥安全地存储在 Agent 的密钥环中,而非明文写入文件

skills install的核心动作是:

  • 下载技能目录(Git clone 或 tarball 解压)。
  • 验证skill.yaml的签名(如果启用了 GPG 签名)。
  • 检查min-agent-version是否兼容。
  • 将技能复制到 Agent 的技能库目录(如~/.agent-skills/my-first-skill)。
  • 不执行pip install!所有依赖由invoke.py在沙箱内按需安装(通过pip install --target到沙箱临时目录),确保依赖隔离。

5.5 运行与调试:skills run和skills logs的组合技

安装配置完成后,即可运行:

# 通过 slash command 触发(最常用) skills run /my-first-skill --query "What is the weather in Shanghai?" # 或者直接调用技能名(跳过 trigger 匹配) skills run my-first-skill --query "What is the weather in Shanghai?" # 查看最近 10 条执行日志(结构化输出) skills logs --limit 10 # 查看某个技能的详细日志 skills logs --skill my-first-skill --since "1 hour ago"

skills logs是调试神器。当你的技能在生产环境报错api error: 400 this model's maximum context length is 1048576 tokens时,skills logs --skill my-first-skill --tail会立刻告诉你:

  • 是哪次调用失败(output_status: internal_error)
  • 调用耗时多久(duration_ms: 118200,接近 2 分钟超时)
  • 内存消耗多少(memory_used_mb: 245,接近 256MB 限制)
  • 网络请求了哪些域名(network_requests: [{"domain": "api.deepseek.com", "count": 1}])

结合这些信息,你就能判断:是 LLM API 响应太慢,还是技能处理逻辑有死循环,或是invoke.py中的timeout参数设置不合理。

实操避坑:skills install后,技能并不会自动启用。你必须通过skills enable my-first-skill显式启用。禁用则用skills disable。这个开关机制让你可以在不影响其他技能的情况下,灰度上线新版本。我曾因忘记enable,导致新技能一直不生效,

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/26 23:39:52

Ponytail:基于FastAPI+React+Claude的AI智能体协同工作流架构

1. 项目概述&#xff1a;Ponytail 是什么&#xff1f;它解决的到底是什么问题&#xff1f;Ponytail 这个名字乍一听像某种发型&#xff0c;但在当前开发者社区里&#xff0c;它正快速成为一个高频出现的技术代号——不是开源库、不是官方框架&#xff0c;而是一个正在成型的AI智…

作者头像 李华
网站建设 2026/10/26 23:39:03

API密钥安全管理全指南:从生成到轮换的最佳实践

1. API密钥安全管理的重要性与挑战API密钥就像数字世界的万能钥匙&#xff0c;一旦泄露就可能造成数据泄露、服务滥用甚至巨额经济损失。去年某知名云服务商就曾因开发者在GitHub公开了API密钥&#xff0c;导致攻击者利用该密钥创建了价值数万美元的云资源。这个案例生动展示了…

作者头像 李华
网站建设 2026/10/26 23:36:22

t3code实战:T3 Stack如何实现前后端类型安全一体化

在很长一段时间里&#xff0c;我都是"后端写一套接口文档、前端照着字段对接"的传统开发流&#xff0c;直到接手一个对类型安全要求极高的中台项目&#xff0c;才第一次认真了解 t3code 背后这套 T3 Stack 的完整打法。当时最惊讶的不是它堆了多少新框架&#xff0c;…

作者头像 李华
网站建设 2026/10/26 23:36:20

T3 Stack实战:用TypeScript打通全栈类型安全,告别接口文档与类型断层

t3code 是我最近一个月在跑的一个全栈项目代号。起因特别简单&#xff1a;我实在受够了接口文档和前端类型对不上的日子。后端加一个字段、改一个返回值&#xff0c;前端往往要等到联调时才发现&#xff1b;而等到运行时崩了再把错误抛到控制台&#xff0c;这种体验谁经历谁知道…

作者头像 李华
网站建设 2026/10/26 23:35:50

状态量在工程控制系统中的核心作用与应用实践

1. 状态量基础概念解析在工程控制系统中&#xff0c;状态量&#xff08;State Variables&#xff09;是描述系统动态行为的最小变量集合。这些量能够完整地表征系统在任意时刻的行为特性&#xff0c;就像给系统拍了一张包含所有关键信息的"快照"。以常见的运动控制系…

作者头像 李华
网站建设 2026/10/26 23:33:35

Nano Banana 2:AI生图技术的混合架构与行业应用

1. Nano Banana 2的技术革命&#xff1a;重新定义AI生图标准去年第一次接触Nano Banana 2时&#xff0c;我的工作流彻底被颠覆了。这个看似名字古怪的AI生图模型&#xff0c;用实际表现证明了自己绝非噱头。作为从业者&#xff0c;我见证过从早期GAN到扩散模型的整个发展历程&a…

作者头像 李华