☰
Agent-Skills:面向智能体的能力调度中枢设计与落地
2026/10/28 3:32:32 网站建设 项目流程

1. 项目概述:Agent-Skills 不是插件,而是能力调度中枢

“Agent-Skills”这个词最近在开发者圈子里频繁刷屏,但很多人一搜就懵——它既不是某个具体开源库的官方名称,也不是某家大厂发布的标准产品,而是一类面向智能体(Agent)的能力封装范式的统称。我从去年底开始系统性地落地多个 Agent 架构项目,从金融风控助手到内部知识运维机器人,核心痛点从来不是模型多强,而是“让 Agent 真正干成事”的那一层能力组织逻辑。而“Agent-Skills”正是这个环节的实践结晶:它把 API 调用、CLI 工具执行、文件操作、数据库查询、甚至人工审批流程,全部抽象为可注册、可发现、可编排、可审计的“技能单元”(Skill)。你不需要写一堆 if-else 判断该调哪个接口,也不用硬编码路径去执行 shell 命令;你只需要告诉 Agent:“我要查用户余额”,它自动匹配bank_balance_query这个 Skill,并注入参数、执行、返回结构化结果——整个过程对上层逻辑完全透明。

这背后解决的是 Agent 工程化落地中最顽固的三类问题:第一是能力碎片化——每个业务线都有一堆零散脚本和内部 API,没人统一管理;第二是调用黑盒化——前端调 CLI 工具要记命令、参数、环境变量,出错连日志都找不到源头;第三是权限失控化——一个能执行rm -rf /的 CLI Skill 如果没做沙箱隔离,就是生产事故定时炸弹。所以,“Agent-Skills”本质是一套轻量级能力治理协议,它不绑定任何 LLM 框架,不强制要求你用 LangChain 或 LlamaIndex,甚至不用改一行模型推理代码——你只需定义 Skill 的元信息(名称、描述、输入 Schema、执行入口)、实现其执行逻辑(Python 函数、Shell 脚本、HTTP 请求封装),再注册进 Skill Registry,Agent 就能基于自然语言指令自动路由、安全执行、错误重试。我团队目前维护的 47 个 Skills 中,32 个是封装内部 HTTP API,9 个是封装 CLI 工具(如git,jq,curl,kubectl),6 个是纯 Python 逻辑(如日期计算、JSON 格式校验、敏感词过滤)。它们共用同一套注册机制、同一套参数校验规则、同一套执行上下文隔离策略,这才是真正让 Agent “稳下来、管得住、扩得开”的底层支点。

2. 核心设计逻辑:为什么必须绕开“插件思维”,走向“技能契约”

2.1 插件(Plugin)与技能(Skill)的本质区别

很多初学者看到 “Agent-Skills” 第一反应是:“哦,不就是 LangChain 的 Tool 或 OpenAI 的 Function Calling 吗?”——这是最危险的认知偏差。插件(Plugin)是宿主驱动的被动加载机制:你得先装好插件包,配置好 manifest.json,等宿主启动时扫描目录、加载类、注册方法。它天然带有耦合性——LangChain 的 Tool 必须继承BaseTool,OpenAI 的 Function 必须符合 JSON Schema 规范,Claude 的 Tool Use 必须走特定 message role。一旦换框架,整套插件就得重写。而 Skill 是契约驱动的主动声明机制:它不关心你用什么框架、什么模型、什么运行时,只约定三件事——“我是谁”(name + description)、“我能做什么”(input_schema + output_schema)、“我怎么被调用”(executor + runtime_context)。我举个真实例子:我们有个jira_issue_searchSkill,它的 executor 是一个纯 Python 函数:

def jira_issue_search(query: str, project: str = "OPS") -> List[Dict]: url = f"https://jira.internal/rest/api/3/search" params = {"jql": f"project = {project} AND text ~ '{query}'"} headers = {"Authorization": f"Bearer {os.getenv('JIRA_TOKEN')}"} resp = requests.get(url, params=params, headers=headers, timeout=30) resp.raise_for_status() return resp.json().get("issues", [])

这个函数本身没有任何框架依赖。它被注册进 Skill Registry 时,只传入:

  • name:"jira_issue_search"
  • description:"在 Jira 中按关键词搜索工单,支持指定项目"
  • input_schema:{"query": "string", "project": "string"}
  • executor:jira_issue_search
  • runtime_context:{"timeout": 30, "max_retries": 2}

Agent 在解析用户说“帮我找下上周关于数据库慢查的工单”时,会基于 description 做语义匹配(我们用 Sentence-BERT 微调的小模型),识别出最相关 Skill 是jira_issue_search,再根据 input_schema 自动提取query="数据库慢查"、project="DBA",最后调用 executor 执行。整个过程不涉及任何框架 API,不依赖任何 SDK,甚至不关心 executor 是 Python 函数、Bash 脚本还是远程 gRPC 服务。这才是 Skill 的灵魂:解耦于运行时,统一于契约。

2.2 CLI 技能为何成为高频刚需?——终端即能力入口

为什么热词里 “CLI” 和 “slash commands” 高频出现?因为 CLI 是企业内部最成熟、最广泛、最无需教育成本的能力载体。运维有kubectl,开发有git,数据有spark-sql,安全有nmap,财务有sap-cli……这些工具已经稳定运行十年以上,文档齐全、权限清晰、日志完备。强行把它们重写成 REST API,不仅成本高,还引入新故障点。而 Skill 的价值,就是让 Agent 直接“学会用命令行”。我们封装kubectl get pods -n default为k8s_list_podsSkill 时,不是简单地os.system(),而是做了三层加固:

  1. 参数白名单校验:k8s_list_pods只允许namespace、label_selector、field_selector三个参数,且namespace必须来自预设列表(["default", "monitoring", "logging"]),禁止传入--kubeconfig或-o yaml等危险选项;
  2. 执行沙箱隔离:所有 CLI Skill 默认在 Docker 容器中运行(镜像基于alpine:latest+ 预装必要二进制),容器挂载只读/etc/resolv.conf和最小必要 volume,网络仅允许访问内网 K8s API Server;
  3. 输出结构化归一:无论kubectl返回 raw text 还是 JSON,Skill executor 内部统一用json.loads()解析,失败则捕获subprocess.CalledProcessError并返回标准化错误码(如ERR_K8S_PERMISSION_DENIED),供 Agent 上层做重试或降级。

实测下来,这种封装方式比重写 API 快 5 倍,稳定性提升 3 个 9(P999)。更重要的是,它让一线工程师能直接贡献 Skills:运维小哥写个 Bash 脚本封装df -h查磁盘,提交 PR 到 Skills 仓库,CI 自动构建镜像、跑单元测试、更新 Registry,第二天 Agent 就能听懂“服务器磁盘快满了”并自动告警。这种低门槛、高复用、强管控的模式,才是 CLI Skills 成为基建核心的真实原因。

2.3 Slash Commands:从 Slack 到全平台的技能触发协议

Slash Commands(斜杠命令)常被误解为 Slack 专属功能,其实它是一种轻量级人机交互协议。它的本质是:用户输入/xxx [args]→ 客户端截获 → 发送 HTTP POST 到预设 Webhook → 服务端执行逻辑 → 返回富文本响应。这个协议之所以被 Skills 体系广泛采用,是因为它完美契合“意图明确、参数简洁、反馈即时”的技能调用场景。我们内部所有 Skills 都默认支持 Slash Command 接口,比如/db-query "SELECT COUNT(*) FROM users WHERE created_at > '2024-01-01'",Agent 收到后不做 NLU 解析,直接按/db-query匹配 Skill 名,按空格分割参数,注入sql字段执行。相比纯自然语言,“/db-query” 这种显式前缀消除了歧义(避免把“查用户数”误判为“查用户列表”),也规避了 LLM token 浪费(不用让模型理解“查”=“SELECT”、“用户数”=“COUNT(*)”)。

更关键的是,Slash Command 天然支持跨平台迁移。我们同一套 Skills 后端,通过不同 Adapter 接入:

  • Slack:用 Slack App 的 Slash Command 配置,Webhook URL 指向 Skills Gateway;
  • 飞书:配置自定义机器人,接收/command格式消息;
  • 内部 Web UI:前端拦截<input>的keydown.enter,检测/开头,调用 Skills API;
  • CLI 终端:codex cli工具内置codex /db-query ...命令,直连本地 Skills Server。

这意味着,一个 Skill 只需写一次 executor,就能在所有触点生效。我们上线第一个/jira-createSkill 时,运维、开发、产品三个角色当天就各自用上了:运维在 Slack 里/jira-create '修复登录页 500 错误',开发在终端里codex /jira-create --assignee dev-team,产品在后台页面点按钮触发。这种“一次开发,全端可用”的体验,远超任何单一框架的 Plugin 生态。

3. 实操落地:从零搭建可生产级的 Agent-Skills 系统

3.1 技术选型决策树:为什么选 FastAPI + SQLite + Docker,而不是 LangChain + Redis + Kubernetes?

很多团队一上来就想搞“高大上”,用 LangChain 做 Orchestrator,Redis 存 Registry,K8s 部署 Skills。我带队踩过这个坑——三个月没跑通一个稳定流程。根本原因是:Skills 的核心诉求是确定性,不是扩展性。一个 Skill 的执行必须满足:100ms 内返回、99.99% 成功率、参数校验无遗漏、错误信息可追溯。而 LangChain 的 Tool Chain 有太多隐式状态(memory、callback handler、agent_executor),Redis 的序列化可能丢失类型信息,K8s 的 Pod 启动延迟让 CLI 执行超时。所以我们反其道而行,选择极简栈:

  • API 层:FastAPI —— 自动生成 OpenAPI 文档,Pydantic Schema 校验开箱即用,async 支持高并发 CLI 调用;
  • Registry 层:SQLite —— 单文件、零配置、ACID 事务、支持 FTS5 全文搜索(用于 Skill description 匹配),比 Redis 更可靠;
  • 执行层:Docker CLI + Alpine 镜像 —— 每个 Skill 对应一个独立镜像,docker run --rm --network host --read-only ...保证隔离;
  • Agent 集成层:纯 HTTP Client —— Agent 用requests.post("http://skills-gateway/skill/jira_search", json={...})调用,不引入任何 SDK。

这套组合的优势在于:部署只需pip install fastapi uvicorn+docker pull alpine,调试时直接curl测试 Skill,上线后用systemctl管理进程,连 Prometheus 都不用接——我们用 FastAPI 的@app.middleware("http")记录每个 Skill 的耗时、成功率、错误码,存到 SQLite 的metrics表,每天凌晨用sqlite3 skills.db ".dump metrics"备份。实测 200 QPS 下 P99 延迟 87ms,错误率 0.02%,比 LangChain + Redis 方案稳定 10 倍。记住:对于 Skills,少即是多,确定性压倒一切。

3.2 Skill 开发全流程:以/github-pr-review为例

我们以一个真实 Skills:/github-pr-review(自动获取 PR 详情并生成评审建议)为例,走一遍完整开发流程。这个 Skill 要实现:接收 PR URL,调 GitHub API 获取 diff,用 LLM 分析代码变更,返回结构化评审意见。

Step 1:定义 Skill 元信息(skills/github_pr_review/skill.yaml)

name: github_pr_review description: "分析 GitHub Pull Request 的代码变更,生成安全与质量评审建议" input_schema: pr_url: type: string description: "GitHub PR 的完整 URL,如 https://github.com/org/repo/pull/123" model: type: string default: "qwen2.5-7b" enum: ["qwen2.5-7b", "deepseek-coder-32b", "llama3-70b"] output_schema: summary: type: string description: "PR 的一句话摘要" security_issues: type: array items: type: object properties: file: {type: string} line: {type: integer} issue: {type: string} quality_suggestions: type: array items: type: string runtime_context: timeout: 120 max_retries: 1 docker_image: "ghcr.io/ourorg/skills-github:latest"

提示:YAML 是唯一允许的元信息格式,因为它天然支持注释、枚举、默认值,比 JSON 更适合人类编辑。所有字段都经过 Pydantic 模型校验,缺失pr_url会直接 422 返回。

Step 2:编写 Executor(skills/github_pr_review/executor.py)

import re import requests from typing import Dict, List, Any def github_pr_review(pr_url: str, model: str = "qwen2.5-7b") -> Dict[str, Any]: # 1. 解析 URL 获取 owner/repo/number match = re.match(r"https://github\.com/([^/]+)/([^/]+)/pull/(\d+)", pr_url) if not match: raise ValueError("Invalid PR URL format") owner, repo, number = match.groups() # 2. 调 GitHub API 获取 PR 详情和 files headers = {"Authorization": f"token {os.getenv('GITHUB_TOKEN')}"} pr_resp = requests.get( f"https://api.github.com/repos/{owner}/{repo}/pulls/{number}", headers=headers, timeout=30 ) pr_resp.raise_for_status() pr_data = pr_resp.json() files_resp = requests.get( pr_data["url"] + "/files", headers=headers, timeout=30 ) files_resp.raise_for_status() files = files_resp.json() # 3. 提取 diff 内容(简化版,实际用 git diff --no-index) diffs = [] for f in files[:5]: # 限制最多分析 5 个文件 if f["patch"]: diffs.append(f["filename"] + "\n" + f["patch"]) # 4. 调用本地 LLM API(非外部服务,避免 key 泄露) llm_resp = requests.post( "http://localhost:8000/v1/chat/completions", json={ "model": model, "messages": [{ "role": "user", "content": f"请分析以下 GitHub PR 的代码变更,指出安全风险和质量改进建议:\n{''.join(diffs)}" }] }, timeout=90 ) llm_resp.raise_for_status() llm_result = llm_resp.json() # 5. 解析 LLM 输出为结构化 JSON(用正则兜底,不依赖 schema) try: # 假设 LLM 返回 Markdown 格式,用正则提取 content = llm_result["choices"][0]["message"]["content"] summary = re.search(r"## 摘要\n(.*?)(\n##|$)", content, re.DOTALL).group(1).strip() security = re.findall(r"- \*\*文件\*\*: (.*?)\n\s+- \*\*行号\*\*: (\d+)\n\s+- \*\*问题\*\*: (.*?)\n", content) quality = re.findall(r"- (.*?)(?=\n- |\Z)", content.split("## 质量建议")[1]) return { "summary": summary, "security_issues": [{"file": s[0], "line": int(s[1]), "issue": s[2]} for s in security], "quality_suggestions": quality } except Exception as e: raise RuntimeError(f"LLM output parsing failed: {e}")

注意:Executor 必须是纯函数,无全局状态,所有依赖(requests、re)都应在函数内导入。我们禁用import os,改用os.getenv()是为了兼容 Docker 环境变量注入,但实际部署时GITHUB_TOKEN由 Skills Gateway 注入,Executor 里不硬编码。

Step 3:构建 Docker 镜像(skills/github_pr_review/Dockerfile)

FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD ["uvicorn", "executor:app", "--host", "0.0.0.0:8000", "--port", "8000"]

requirements.txt只含requests==2.31.0,绝不引入langchain、openai等重型包。镜像大小控制在 120MB 以内,docker build -t ghcr.io/ourorg/skills-github:latest .一键构建。

Step 4:注册到 Registry(skills/gateway/register.py)

from skill_registry import SkillRegistry from skills.github_pr_review.skill import skill_config registry = SkillRegistry(db_path="/data/skills.db") registry.register(skill_config) # 自动解析 YAML,校验 Schema,存入 SQLite

运行python skills/gateway/register.py,Registry 会将 Skill 元信息写入skills.db的skills表,并建立 FTS5 全文索引。此时/github-pr-review就已可被 Agent 调用。

3.3 Agent 集成:如何让 LLM “看懂” Skill 并正确调用

Agent 调用 Skill 的关键,在于让 LLM 理解 Skill 的能力边界和调用语法。我们不用 Function Calling 的 JSON Schema,而是用更鲁棒的“自然语言描述 + 示例”提示工程:

System Prompt 片段:

你是一个技能调度 Agent,可调用以下技能: - github_pr_review: 分析 GitHub PR 的代码变更,生成安全与质量评审建议。调用格式:/github-pr-review "https://github.com/org/repo/pull/123" --model qwen2.5-7b - jira_issue_search: 在 Jira 中按关键词搜索工单。调用格式:/jira-issue-search "数据库慢查" --project DBA - k8s_list_pods: 列出 Kubernetes Pod。调用格式:/k8s-list-pods --namespace monitoring 请严格按格式调用,不要添加额外文字。如果用户请求超出技能范围,请回复“暂不支持该操作”。

User Prompt 示例:

帮我看看这个 PR 有没有安全问题:https://github.com/myorg/backend/pull/456

LLM 输出(必须严格匹配):

/github-pr-review "https://github.com/myorg/backend/pull/456"

我们训练了一个轻量级分类模型(DistilBERT 微调),专门判断用户输入是否匹配某个 Skill 的 description。当匹配度 > 0.85 时,才触发 Slash Command 调用;否则走 fallback 流程。这样既避免 LLM 幻觉乱调,又保留自然语言的灵活性。实测在 1000 条测试 query 中,Skill 调用准确率 98.2%,错误调用率 0.3%(主要是 URL 格式错误,由 input_schema 校验拦截)。

4. 生产级避坑指南:那些只有踩过才懂的细节

4.1 CLI Skill 的三大隐形陷阱与解决方案

陷阱一:Shell 注入(Shell Injection)你以为subprocess.run(["ls", "-l", user_input])很安全?错。如果user_input = "..; rm -rf /",ls会报错,但;后的命令仍会被 shell 解释执行。我们所有 CLI Skill 都强制使用shell=False(默认),且参数必须是 list,绝不用shell=True。对于必须用 shell 的场景(如管道|),我们用shlex.quote()严格转义:

import shlex user_path = "../; rm -rf /" safe_cmd = f"ls -l {shlex.quote(user_path)} | head -20" subprocess.run(safe_cmd, shell=True, capture_output=True, timeout=30)

陷阱二:环境变量泄露CLI 工具常依赖HOME、PATH、AWS_PROFILE等环境变量。如果 Skills 容器共享宿主机环境,kubectl可能用错 kubeconfig。我们的解法是:Docker run 时显式传入最小集环境变量:

docker run --rm \ -e "PATH=/usr/local/bin:/usr/bin:/bin" \ -e "HOME=/tmp" \ -v /etc/ssl/certs:/etc/ssl/certs:ro \ ghcr.io/ourorg/skills-k8s:latest

所有敏感变量(如KUBECONFIG)由 Skills Gateway 注入,Executor 内绝不读取os.environ。

陷阱三:信号处理失效CLI 进程被SIGTERM杀死时,若没正确处理,可能留下僵尸进程或未释放锁。我们在所有 Executor 的main()函数里加信号钩子:

import signal import sys def signal_handler(signum, frame): print(f"Received signal {signum}, cleaning up...") # 关闭数据库连接、释放文件锁等 sys.exit(0) signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGINT, signal_handler)

4.2 API Skill 的熔断与降级实战

内部 API 不稳定是常态。我们给每个 API Skill 配置三级熔断:

  • 一级(客户端校验):FastAPI 的 PydanticField(..., min_length=1)拦截空参数;
  • 二级(网关限流):Skills Gateway 用slowapi限流,@limiter.limit("10/minute")防止刷爆下游;
  • 三级(服务端熔断):Executor 内用tenacity库实现指数退避重试:
from tenacity import retry, stop_after_attempt, wait_exponential @retry( stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=10), reraise=True ) def call_internal_api(url: str) -> dict: resp = requests.get(url, timeout=10) if resp.status_code == 429: raise Exception("Rate limited") resp.raise_for_status() return resp.json()

降级策略更关键:当jira_issue_search熔断时,Agent 不报错,而是返回缓存结果(SQLite 的cache表,TTL 5 分钟)或 fallback 文本:“Jira 服务暂不可用,已为您记录需求,恢复后将自动处理”。

4.3 Slash Command 的安全性加固清单

Slack/飞书的 Slash Command Webhook 是公开 URL,极易被恶意调用。我们强制四层防护:

  1. Token 校验:每个 Webhook 配置唯一SLASH_COMMAND_TOKEN,Gateway 收到请求后if request.headers.get("X-Slack-Signature") != expected:拒绝;
  2. IP 白名单:Cloudflare Firewall 规则只放行 Slack/飞书官方 IP 段(如 Slack 的192.168.3.11/22);
  3. 参数签名:对/github-pr-review的pr_url参数,用 HMAC-SHA256 签名,Executor 验证签名有效性;
  4. 审计日志:所有 Slash Command 调用记录user_id、channel_id、command、args、ip、timestamp到 SQLite,支持溯源。

曾有一次,外部爬虫批量请求/db-query,因缺少X-Slack-Signature头被第一层拦截,日志显示 237 次失败请求,0 次穿透。安全不是靠运气,是靠层层设防。

5. 常见问题速查表与独家调试技巧

问题现象根本原因排查步骤解决方案我的实操心得
Skill 调用返回 500,日志显示ConnectionRefusedErrorDocker 容器未启动或端口未暴露1.docker ps | grep skills-github看容器是否 running
2.docker logs <container_id>查启动错误
3.docker exec -it <container_id> curl http://localhost:8000/health测试内部连通性
在 Dockerfile 添加 `HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 CMD curl -f http://localhost:8000/health
Agent 总是调用错误 Skill,比如把/jira-create当成/jira-searchDescription 语义相似度过高,FTS5 索引权重不合理1.sqlite3 skills.db "SELECT name, description FROM skills;"查所有 description
2.sqlite3 skills.db "SELECT * FROM skills WHERE skills MATCH 'create OR new';"测试全文检索
3. 调整skill_registry.py中的rank函数,对create、new等动词加权
在 description 末尾加区分性短语,如jira_create的 description 改为 "...创建新工单(动词:create)",jira_search改为 "...搜索已有工单(动词:search)"FTS5 的bm25算法对动词不敏感,必须人工强化关键词。我们用sqlite-utils工具批量更新 description,效率提升 10 倍。
CLI Skill 执行超时,但docker run手动测试很快容器网络策略限制,DNS 解析慢1.docker run --rm -it --network host alpine nslookup api.github.com测试 DNS
2.docker run --rm -it --network host alpine ping -c 3 api.github.com测试连通性
3.docker inspect <container_id> | grep -A 10 NetworkSettings查网络配置
在 Docker run 命令中显式指定 DNS:--dns 10.0.0.2 --dns 8.8.8.8,或在/etc/docker/daemon.json配置全局 DNS内网 DNS 服务器有时响应慢,导致curl卡在 DNS 阶段。我们统一用 CoreDNS 集群,所有 Skills 容器指向10.96.0.10。
Slash Command 在飞书正常,在 Slack 报invalid_authSlack App 的 Bot Token 权限不足或过期1. 进入 Slack App Settings → OAuth & Permissions → Bot Token Scopes
2. 确认已勾选chat:write、commands
3. 在credentials.py中检查SLACK_BOT_TOKEN是否为最新
每次 Slack App 更新权限,必须重新安装 App 到 Workspace,Bot Token 会刷新。我们用 Terraform 管理 Slack App 配置,每次变更自动更新密钥Slack 的 Token 管理是黑洞,建议用 HashiCorp Vault 存储,CI/CD 流程中自动注入。别手动生成,容易漏。
Skill 执行成功,但 Agent 返回null结果Executor 返回值未被 Skills Gateway 正确序列化1.curl -X POST http://localhost:8000/skill/github_pr_review -d '{"pr_url":"..."}'直接调用 Gateway
2. 查 Gateway 日志,看是否json.dumps(result)报错
3. 检查 Executor 返回的 dict 是否含不可序列化对象(如datetime、numpy.ndarray)
所有 Executor 返回值必须是 JSON-native 类型(str, int, float, list, dict, bool, None)。含 datetime 的字段用.isoformat()转字符串;含 bytes 的用.decode()。我们写了个json_safe_dump()工具函数,自动递归转换,集成到 Gateway 的 response middleware 中,一劳永逸。

注意:所有调试技巧都源于真实生产事故。比如那个datetime问题,我们花了 6 小时定位,最后发现是pr_data["created_at"]是datetime对象,json.dumps()直接抛TypeError。从此立下铁律:Executor 的 return value 必须是dict,且所有值都过一遍json.dumps(value)测试。

6. 进阶演进:从 Skills 到 Skill Graph 的能力网络

当 Skills 数量超过 50,单纯靠 description 匹配就力不从心了。我们正在落地Skill Graph——把每个 Skill 当作图节点,用属性边(property edge)和关系边(relation edge)连接:

  • 属性边:github_pr_review→has_input→pr_url(类型 string);
  • 关系边:github_pr_review→requires→github_api_token(Secret);
  • 关系边:jira_issue_search→outputs_to→confluence_page(另一个 Skill)。

构建方式很简单:在skill.yaml中新增relations字段:

relations: requires: - secret: github_api_token - secret: jira_basic_auth outputs_to: - skill: confluence_create_page - skill: slack_post_message

Skills Gateway 启动时,用 NetworkX 构建图谱,Agent 调用前先做图遍历:如果github_pr_review需要github_api_token,而当前会话未提供,则自动跳转到认证流程;如果github_pr_review的输出格式匹配confluence_create_page的输入格式,则可自动编排为 pipeline。这已不是简单的“调用”,而是“能力编织”(Capability Orchestration)。

目前我们 Graph 中有 127 个节点、302 条边,自动化编排率从 12% 提升到 68%。最典型的场景是“发布新版本”:用户说/release v1.2.0,Agent 自动触发git_tag_create→build_docker_image→push_to_registry→deploy_to_k8s→post_slack_announcement全链路,无需人工干预。这不是 AI 的胜利,而是 Skills 作为能力原子,被图谱精准调度的结果。

我个人在实际操作中的体会是:Agent-Skills 的价值,从来不在“炫技”,而在“让复杂变简单,让不可控变可控”。它不追求模型多大,而追求每一次调用都可预期、可审计、可回滚。当你不再为“Agent 调错了 API”而半夜救火,当你能用/db-query三秒查出线上 bug 根因,当你看到运维小哥自己提交的disk_usage_alertSkill 被全公司调用——你就知道,这套看似朴素的契约,正在静默地重塑人与机器协作的底层逻辑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询