Skill 是什么?——给AI装个“能力插件”,就像给手机装App一样简单

在线体验各类最新模型,更有模型 免费Token 额度领取!
立即体验
简介: 本文手把手教你从0到1打造AI“Skill”插件系统,将大模型升级为可扩展的万能工具箱:解耦能力、热插拔新增功能、跨项目复用、团队并行开发。含快递查询实战、超时熔断、输入防呆、并发安全等生产级要点,助你构建高可用AI应用。

从0到1手写一个Skill,把大模型变成你的“万能工具箱”

01 一个让我失眠的夜晚
去年有个需求,让我熬了三个通宵。

业务方说要做一个“智能客服”,但要求特别拧巴——既要能查订单、退换货,又要能根据用户的历史行为做个性化推荐,还得实时对接库存系统。当时我们用的是某主流大模型的API,模型本身挺聪明,但一碰到“查库存”这种需要实时数据的活儿就开始胡编乱造。

那会儿业内还没有特别成熟的Agent框架,我试了Function Calling,写了十几套prompt模板,甚至自己撸了一个简单的RAG流程。结果呢?代码越写越臃肿,prompt越改越拧巴,每次加一个新能力就跟重构整个系统似的。

直到我接触到“Skill”这个概念。

说白了,Skill就是把AI的某项“专项能力”打包成一个独立的插件。想让它查天气?装个Weather Skill。想让它操作Jira?装个Jira Skill。想让它拉取数据库里的实时报表?写个SQL Skill就完事了。

就像给手机装App一样,装上就能用,不用了就卸掉,核心系统干干净净。

今天我就把自己在这块踩过的坑、总结的经验,一次性倒给你。

02 Skill到底是什么?用一个例子说透
别被“Skill”这个花哨名字唬住,它的技术本质其实就三层:

一层接口:定义好输入输出规范(输入什么参数,输出什么格式)
一层执行逻辑:内部干活的代码(调API、查数据库、跑算法都行)
一层注册机制:让AI“知道”有这个能力存在,以及什么时候该调用它
我画个简单的对比你就懂了:

对比项
传统Function Calling
Skill插件
新增能力
改prompt + 改代码 + 重新部署
放一个Skill文件进去,热加载
复用性
每个项目重新写一遍
跨项目拷贝即用
调试难度
跟大段的系统代码混在一起
独立运行,日志隔离
团队协作
前后端、算法互相锁死
各写各的Skill,最后组装
打个你肯定懂的比方:传统方式是给汽车发动机舱里硬塞新零件,Skill是给车尾挂一个快拆拖斗。 拖斗里装什么都可以,装错了摘下来换一个就行,发动机舱(核心系统)一根线都不用动。

03 手把手:10分钟写一个“查快递”Skill
光说不练假把式。下面我用Python写一个真实的Skill,让大模型能查询快递物流信息。

Step 1:定义Skill的“说明书”

每个Skill必须告诉AI三件事:我能干什么、我需要什么参数、我返回什么格式。

skill_express.py

from typing import Optional, Dict, Any
from pydantic import BaseModel, Field

1. 定义输入参数的结构

class ExpressInput(BaseModel):
tracking_number: str = Field(description="快递单号,支持中通/圆通/顺丰")
carrier: Optional[str] = Field(
default="auto",
description="快递公司编码,可选:zto/yto/sf,默认自动识别"
)

2. 定义输出的结构(让AI知道能拿到什么信息)

class ExpressOutput(BaseModel):
status: str = Field(description="物流状态:已揽收/运输中/派送中/已签收")
location: str = Field(description="最新位置")
timestamp: str = Field(description="更新时间")
details: list = Field(description="完整物流轨迹列表")
Step 2:写执行逻辑(真正的“干活代码”)

注意,我这里为了演示,用了Mock数据。真实场景下,这里对接的是快递100、菜鸟裹裹或者顺丰开放平台的API。

import httpx
import re
from datetime import datetime

class ExpressSkill:
"""快递查询技能"""

def __init__(self):
    # 真实场景这里放API密钥
    self.api_key = "your_kuaidi100_api_key"
    self.base_url = "https://api.kuaidi100.com/query"

def execute(self, input: ExpressInput) -> ExpressOutput:
    # 自动识别快递公司(真实场景用正则或算法)
    carrier = input.carrier
    if carrier == "auto":
        carrier = self._detect_carrier(input.tracking_number)

    # 调用快递查询API(这里用Mock演示)
    # 实际开发中换成:requests.get(self.base_url, params={...})
    raw_data = self._mock_query(input.tracking_number, carrier)

    # 数据清洗 + 格式转换
    return ExpressOutput(
        status=raw_data["status"],
        location=raw_data["location"],
        timestamp=datetime.now().isoformat(),
        details=raw_data["traces"]
    )

def _detect_carrier(self, tn: str) -> str:
    # 简单识别逻辑:顺丰12位纯数字,中通12位数字字母混合...
    if re.match(r'^\d{12}$', tn):
        return"sf"
    elif re.match(r'^[A-Za-z0-9]{12}$', tn):
        return"zto"
    else:
        return"yto"

def _mock_query(self, tn: str, carrier: str) -> dict:
    # Mock数据,真实场景替换为API调用
    return {
        "status": "派送中",
        "location": "广州市天河区体育西路营业点",
        "traces": [
            {"time": "2026-07-06 08:30", "content": "快递员正在派送中,预计今日送达"},
            {"time": "2026-07-05 22:15", "content": "到达广州转运中心"},
            {"time": "2026-07-05 14:20", "content": "已从深圳发出"},
        ]
    }

Step 3:注册到AI(最关键的一步)

这一步决定了AI在什么时候、以什么方式调用你的Skill。我用LangChain的Tool装饰器来注册:

from langchain.tools import tool
from langchain.schema import Tool

方式一:用装饰器快速注册

@tool
def query_express(tracking_number: str, carrier: str = "auto") -> str:
"""
查询快递物流信息。
tracking_number: 快递单号
carrier: 快递公司编码(zto/yto/sf),不填则自动识别
"""
skill = ExpressSkill()
result = skill.execute(ExpressInput(
tracking_number=tracking_number,
carrier=carrier
))
returnf"物流状态:{result.status}\n最新位置:{result.location}\n轨迹详情:\n" + "\n".join(
[f" {d['time']} {d['content']}"for d in result.details]
)

方式二:手动注册为Tool(更灵活,适合复杂场景)

express_tool = Tool(
name="快递查询",
func=lambda tn, c="auto": query_express(tn, c),
description="用于查询快递物流信息,输入单号和可选快递公司编码"
)
Step 4:接入大模型(让AI“学会”用这个Skill)

from langchain.agents import initialize_agent, AgentType
from langchain_openai import ChatOpenAI

初始化模型

llm = ChatOpenAI(model="gpt-4", temperature=0)

把Skill塞进Agent的工具箱

tools = [query_express] # 可以继续添加其他Skill

agent = initialize_agent(
tools=tools,
llm=llm,
agent=AgentType.OPENAI_FUNCTIONS,
verbose=True# 调试时打开,能看清AI的思考过程
)

测试

response = agent.invoke({
"input": "帮我查一下单号SF1234567890的快递到哪了?"
})
print(response["output"])
运行结果:

物流状态:派送中
最新位置:广州市天河区体育西路营业点
轨迹详情:
2026-07-06 08:30 快递员正在派送中,预计今日送达
2026-07-05 22:15 到达广州转运中心
2026-07-05 14:20 已从深圳发出
看到没?AI自动识别了“查快递”的意图,提取了单号,调用了我们的Skill,然后把结果整理成可读的文字。全程没改一行核心系统代码。

04 进阶:Skill设计的3个“要命”细节
上面那个Demo能跑通,但离“生产级”还差得远。我在线上环境被这3个问题坑过不止一次,你最好提前知道。

细节1:超时控制 + 熔断
Skill调用外部API如果挂了,整个Agent会跟着卡死。必须加超时:

import asyncio
from functools import wraps

def with_timeout(seconds=10):
def decorator(func):
@wraps(func)
asyncdef wrapper(args, **kwargs):
try:
returnawait asyncio.wait_for(
func(
args, **kwargs),
timeout=seconds
)
except asyncio.TimeoutError:
return"【系统提示】该Skill响应超时,请稍后重试或尝试其他方式"
return wrapper
return decorator

用法

@with_timeout(5)
asyncdef query_express_async(tn: str):

# 异步请求快递API
pass

细节2:输入校验的“防呆设计”
用户输入的快递单号千奇百怪,空格、换行、中文括号全都有。我吃过亏,用户输入“SF 1234567890”中间有个空格,正则直接匹配失败。

def sanitize_tracking_number(raw: str) -> str:
"""清洗用户输入,只保留数字和字母"""
return re.sub(r'[^A-Za-z0-9]', '', raw.strip())
还有,Skill里一定要有fallback。识别不出快递公司就用“中通”兜底,查不到数据就返回明确的“未查询到”而不是抛异常。

细节3:并发安全
如果你的AI同时处理多个用户的请求,Skill内部如果有共享状态(比如缓存、数据库连接池),必须注意线程安全。

import threading

class ExpressSkill:
_cache = {}
_cache_lock = threading.Lock()

def execute(self, input: ExpressInput):
    # 读缓存要加锁
    with self._cache_lock:
        if input.tracking_number in self._cache:
            return self._cache[input.tracking_number]

    # 查询逻辑...

    # 写缓存也要加锁
    with self._cache_lock:
        self._cache[input.tracking_number] = result
    return result

05 团队协作:Skill的“集市模式”
我们团队现在有6个人,分别维护不同的Skill。前端写“页面操作Skill”,后端写“数据查询Skill”,算法组写“推荐Skill”。大家互不干扰,最后通过一个统一的Skill Registry(注册中心)聚合起来。

目录结构长这样:

skills/
├── registry.yaml # 所有Skill的注册清单
├── express/
│ ├── skill.py
│ ├── config.yaml
│ └── tests/
├── jira/
│ ├── skill.py
│ └── README.md
├── sql_analytics/
│ ├── skill.py
│ └── queries/
└── weather/
├── skill.py
└── requirements.txt # 每个Skill可以有自己的依赖
每个Skill独立维护自己的版本、依赖、测试用例。集成测试只测“调用接口是否正常”,不管内部实现。

这是最像“App Store”的地方——各个Skill独立开发、独立发布,主系统只认接口契约。

06 写在最后:Skill不是银弹,但它是方向
老实说,Skill这套模式不是没有代价。它增加了系统整体的复杂度——你得维护注册中心、做热加载、处理版本兼容。如果你的业务只有两三个AI能力,硬编码比搞Skill架构快得多。

但当你的AI能力超过5个、团队超过3个人的时候,Skill带来的解耦收益会指数级增长。我们现在的系统里跑了17个Skill,涵盖客服、运维、数据分析三个领域,新增一个能力从“改核心代码+全量回归”变成了“写Skill+注册”,周期从2周压缩到2天。

如果你正准备在项目中引入AI能力,我的建议是:

前3个能力硬编码,先跑通业务,理解真实需求
到第4-5个能力时,回头抽象出Skill接口,把前3个也迁过来
第6个以后,所有新能力一律以Skill形式接入
这样既不会过度设计,又能平滑过渡到插件化架构。

最后,送给你我写在团队Wiki首页的一句话:

“Skill化的本质,是把AI从一个‘什么都懂但什么都做不精’的泛泛之辈,变成一个‘随时可以请外援’的团队指挥官。”

下次有机会,我再写一篇《Skill的异步调度与分布式部署实战》,讲讲我们怎么把Skill跑在K8s上、以及如何用RabbitMQ做Skill的任务队列。感兴趣的朋友可以点个关注,咱们下回见。

相关文章
|
11天前
|
人工智能 JSON 自然语言处理
让教学更智慧:用阿里云百炼工作流,自动生成中小学教材内容#小有可为#有温度的AI
通过可视化工作流编排,将大模型推理能力转化为标准化的教学内容生成引擎。教师只需输入教材标题和适用学段,即可自动获得结构完整、符合课程标准的章节内容,大幅降低备课门槛,助力教育资源均衡化。
489 126
|
20天前
|
Linux 程序员 数据格式
【2026最新】Notepad++下载、安装和使用一篇搞定(附中文版安装包)
Notepad++ 是一款免费开源、轻量高效的 Windows 文本编辑器,支持 C/Python/HTML 等 80+ 语言语法高亮、代码折叠、正则替换、编码转换及插件扩展,专为程序员与文本处理用户打造,完美替代系统记事本。(239字)
|
5天前
|
人工智能 缓存 安全
Claude Code 封号真实原因曝光,这次彻底不装了,直接针对国内开发者的账号下手?
Claude Code 封号潮背后:逆向扒出客户端隐写区域标记,Anthropic 政策收紧叠加 DeepSeek 7 月涨价,国产替代更紧迫。
|
14天前
|
存储 人工智能 监控
QoderWork完全指南:从入门到精通,把“AI实习生”变成你的全能工作搭档
阿里云2026年推出的桌面端AI工作助手QoderWork,不止聊天,更可动手干活:本地运行、安全可控,支持文件整理、数据分析、PPT生成、网页开发等;内置专家套件、多Agent协作与自定义Skills,让AI真正成为你身边的“AI实习生”。
|
6天前
|
人工智能 安全 程序员
终于,Claude Code 封号的原因被曝光了!竟然针对中国用户,植入隐形代码?!
通俗易懂地揭秘 Claude Code 封号的手段,分享一些自己对 AI 编程困境的思考,Codex、Cursor、DeepSeek、智谱 GLM、甚至是豆包,都有所行动了
380 1
|
7天前
|
人工智能 安全 Cloud Native
Higress 新发布:AI Gateway 能力增强,Gateway API 及其推理扩展持续打磨
增强 AI 网关能力,持续打磨 Gateway API 及其推理扩展。
353 124
|
15天前
|
机器学习/深度学习 人工智能 调度
🐴 HappyHorse 1.1 现已上线阿里云百炼!快来查收模型使用指南,现在调用享 6 折~
HappyHorse 1.1 是新一代视频生成大模型,全面升级动态表现力、角色一致性、指令遵循、视觉质感与音画协同能力。支持I2V/T2V/R2V三类生成,适配短剧、电商广告、品牌营销等场景,提供高质、流畅、可控的AI视频生产力。
867 5
🐴 HappyHorse 1.1 现已上线阿里云百炼!快来查收模型使用指南,现在调用享 6 折~