AI Agent Skill(技能)开发全指南(3/5):从原理到搭建你的第一个 Skill
2026/7/22 17:02:51 网站建设 项目流程

摘要:随着大模型(LLM)从“聊天机器人”向“智能体(Agent)”演进,Skill(技能)已经成为 AI 能够真正操作现实世界的核心载体。本文将系统讲解 Skill 的技术本质、架构设计、通信协议(Function Calling / MCP)、开发全流程,并手把手带你从零构建一个可运行的 “天气查询 Skill”,最后探讨企业级 Skill 生态的构建思路。


一、什么是 Skill?—— 重新定义 AI 的能力边界

1.1 从 Chatbot 到 Agent:为什么需要 Skill?

早期的 ChatGPT 类应用本质上是一个文本预测引擎。它拥有海量的世界知识,但它被囚禁在数字世界里。它无法告诉你现在的天气,无法帮你订外卖,也无法查询你的私人日程。

Skill 就是打破这层壁垒的钥匙。

  • 没有 Skill 的 LLM:大脑发达,但手脚瘫痪。

  • 拥有 Skill 的 LLM:拥有了眼睛(视觉识别)、耳朵(语音识别)、手(执行 API 调用)和脚(导航)。

定义:Skill 是一种封装了特定业务能力、可被 AI Agent 动态发现、理解并调用的标准化接口模块。它允许大模型将用户的自然语言意图转化为具体的程序指令,从而完成感知、决策和执行。

1.2 Skill vs Plugin vs Function Calling vs Tool

这几个术语经常混用,但它们处于不同的抽象层级:

术语

定位

关系

Tool (工具)

最底层的具体实现。一段代码或一个 API 端点。

Skill 的组成部分。

Function Calling

一种技术机制(由 OpenAI 定义)。告诉模型有哪些函数可用,让模型输出调用这些函数的 JSON 参数。

实现 Skill 调用的主流技术手段。

Plugin (插件)

早期的概念(如 ChatGPT Plugins)。通常包含 API 描述文件和清单文件。

Skill 的早期形态,现多已被 Function Calling 和 MCP 取代。

Skill (技能)

业务视角的封装。它不仅仅是一个函数,可能包含鉴权、缓存、错误处理、业务逻辑编排。

面向 Agent 的最终交付物。

一句话总结:我们使用Function Calling(或 MCP)技术,将底层的Tools​ 封装成业务级的Skills,供 Agent 使用。

1.3 Skill 的核心特征

  1. 自描述性 (Self-Describing):Skill 必须包含一个清晰的 Schema(模式),告诉 AI 它是干什么的,需要什么参数,返回什么结果。

  2. 幂等性 (Idempotency):理想情况下,多次调用同一个 Skill 产生的副作用应该是相同的(例如,查询天气是只读的,天然幂等;转账则需要通过唯一 ID 防止重复扣款)。

  3. 安全性 (Security):Skill 往往涉及数据隐私和系统权限,必须有严格的沙箱机制和权限控制。

  4. 可组合性 (Composability):高级 Agent 可以将多个 Skill 串联起来(ReAct 模式),完成复杂任务。


二、Skill 的技术原理与架构

2.1 经典的交互流程 (ReAct + Function Calling)

一个典型的 Skill 调用流程如下:

  1. 用户输入:"北京今天适合穿什么衣服?"

  2. 意图识别:LLM 分析发现,要回答这个问题,需要先知道北京的天气。

  3. 工具选择:LLM 在系统提示词(System Prompt)提供的 Skill 列表中,找到了get_weather这个 Skill。

  4. 参数提取:LLM 提取出参数:location = "Beijing"

  5. 输出指令:LLM 停止生成自然语言,转而输出一段结构化的 JSON:{"name": "get_weather", "arguments": {"location": "Beijing"}}

  6. 执行代码:后端程序解析这段 JSON,调用真实的get_weather("Beijing")函数(可能是调用第三方天气 API)。

  7. 返回结果:函数返回"Sunny, 25°C"

  8. 二次推理:后端将结果塞回对话上下文,LLM 再次接管,结合天气数据生成最终回答:"北京今天晴天,25度,建议穿轻薄的长袖衬衫。"

2.2 Skill 的系统架构

一个生产级的 Skill 架构通常包含以下层次:

┌─────────────────────────────────────────────┐ │ AI Agent / Orchestrator │ │ (负责思考、规划、调用 Skill) │ └───────────────────────┬─────────────────────┘ │ JSON Instruction ┌───────────────────────▼─────────────────────┐ │ Skill Gateway / Proxy │ │ (鉴权、限流、日志、参数校验) │ └───────────────────────┬─────────────────────┘ │ Internal Call ┌───────────────────────▼─────────────────────┐ │ Skill Executor │ │ ┌─────────┐ ┌─────────┐ ┌─────────────────┐│ │ │ Weather │ │ Search │ │ Internal DB CRUD││ │ │ Skill │ │ Skill │ │ Skill ││ │ └─────────┘ └─────────┘ └─────────────────┘│ └───────────────────────┬─────────────────────┘ │ HTTP/gRPC ┌───────────────────────▼─────────────────────┐ │ External Services (APIs) │ │ (Weather.com, Google, Internal RPC) │ └─────────────────────────────────────────────┘

2.3 两种主流协议:OpenAI Function Calling vs MCP

2.3.1 OpenAI Function Calling

这是目前最普及的方案。开发者定义一个 JSON Schema 来描述函数。

优点:生态成熟,各大模型厂商(OpenAI, Anthropic, Gemini, 国产大模型)基本都兼容。

缺点:强依赖于 Prompt Engineering,缺乏标准化的生命周期管理。

2.3.2 MCP (Model Context Protocol)

由 Anthropic 提出的开放协议,旨在成为 AI 应用的“USB-C”接口。MCP 定义了一个标准的客户端-服务器架构。

  • MCP Host:Claude Desktop, IDE 等。

  • MCP Client:Host 内的连接器。

  • MCP Server:封装了具体 Skill 的服务端。

优点:解耦彻底,支持双向通信(Server 可以主动请求资源),更适合复杂的本地工具集成(如操作文件系统、数据库)。

缺点:相对较新,生态还在建设中。

本文后续示例将主要基于 OpenAI Function Calling 风格,因为这是目前 Web 服务开发中最通用的方式。


三、Skill 的设计哲学与最佳实践

3.1 单一职责原则 (SRP)

一个 Skill 只做一件事。

❌ 错误示例:handle_user_request(处理查询、修改、删除用户)。

✅ 正确示例:query_user_by_id,update_user_email

3.2 良好的命名与描述 (Naming & Description)

LLM 不是编译器,它是通过语义来理解 Skill 的。命名和描述比代码本身更重要。

  • 函数名:使用动词+名词,如calculate_loan_interest

  • 描述:详细解释功能、适用场景和限制。

    • 差:Get weather.

    • 好:Retrieves the current weather for a specified city. Use this when the user asks about temperature, humidity, or weather conditions. Note: Supports Chinese and English city names.

3.3 参数设计的艺术

  1. 枚举约束 (Enums):如果参数是固定的几个值,一定要用enum,这能极大降低幻觉。

    • 例如:unit参数只能是["celsius", "fahrenheit"]

  2. 必填与选填:区分required字段。对于非必填项,在描述中说明默认值。

  3. 自然语言兜底:有时候用户会说“明天”而不是日期。可以在 Skill 内部做一个日期解析层,或者让 LLM 调用一个专门的parse_dateSkill。

3.4 防御性编程

永远不要相信 LLM 的输出。

  • 类型校验:即使 Schema 定义了 Integer,也要在代码中验证。

  • 范围校验:如果是查询分页,检查 page_size 是否超过上限。

  • 注入防护:如果 Skill 涉及数据库查询,防止 SQL 注入(虽然 LLM 输出的是参数,但仍需警惕)。


四、动手实践:搭建你的第一个 Skill

接下来,我们将使用Python + FastAPI​ 搭建一个简单的 Web 服务,并实现一个“天气查询 Skill”

4.1 环境准备

确保安装了 Python 3.9+。

mkdir my_first_skill && cd my_first_skill python -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate pip install fastapi uvicorn httpx openai python-dotenv

创建.env文件存放 API Key:

OPENAI_API_KEY="sk-your_key_here" # 或者使用兼容 OpenAI 接口的国内模型 # OPENAI_BASE_URL="https://api.moonshot.cn/v1"

4.2 步骤一:编写 Skill 的核心逻辑(Tool)

我们先不关心 AI,直接写一个纯粹的天气查询函数。

创建weather_tool.py

import httpx import os from typing import Dict, Any # 这里使用 Open-Meteo (免费,无需 API Key) # 但为了演示,我们假设有一个需要 Key 的商业 API 逻辑 # 实际调用:https://api.weatherapi.com/v1/current.json?key=KEY&q=Beijing class WeatherService: def __init__(self): # 为了演示,我们不真的调用收费 API,而是 Mock 数据 # self.api_key = os.getenv("WEATHER_API_KEY") # self.base_url = "https://api.weatherapi.com/v1" pass async def get_current_weather(self, location: str, unit: str = "celsius") -> Dict[str, Any]: """ 模拟获取当前天气。 在实际应用中,这里会调用 httpx 请求第三方 API。 """ # Mock Data based on location mock_db = { "beijing": {"temp_c": 25, "condition": "Sunny", "humidity": 40}, "shanghai": {"temp_c": 28, "condition": "Cloudy", "humidity": 70}, "new york": {"temp_c": 15, "condition": "Rainy", "humidity": 90} } loc_key = location.lower() if loc_key not in mock_db: return {"error": f"Weather data for '{location}' not found."} data = mock_db[loc_key] # 单位转换 temp = data["temp_c"] if unit == "fahrenheit": temp = (temp * 9/5) + 32 return { "location": location, "temperature": round(temp, 1), "unit": unit, "condition": data["condition"], "humidity": data["humidity"] } # 实例化服务 weather_service = WeatherService()

4.3 步骤二:定义 Skill 的 Schema(说明书)

这是最关键的一步。我们需要告诉 LLM 如何调用这个函数。

创建skill_definition.py

SKILL_SCHEMA = { "name": "get_current_weather", "description": "Get the current weather for a specific location. Use this whenever the user asks about the weather, temperature, or climate conditions in a city.", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "The city name, e.g., 'Beijing', 'London', 'New York'. Support both Chinese and English.", }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "The temperature unit. Defaults to celsius.", }, }, "required": ["location"], }, } # 将所有 Skill 汇总 AVAILABLE_SKILLS = [SKILL_SCHEMA] # 映射 Skill 名称到实际的执行函数 SKILL_EXECUTORS = { "get_current_weather": weather_service.get_current_weather }

4.4 步骤三:搭建 FastAPI 服务与 Agent 逻辑

现在,我们将 Skill 挂载到一个 Web 服务中,并处理与 LLM 的交互。

创建main.py

from fastapi import FastAPI, HTTPException from pydantic import BaseModel from openai import AsyncOpenAI from dotenv import load_dotenv import json import traceback from weather_tool import weather_service from skill_definition import AVAILABLE_SKILLS, SKILL_EXECUTORS load_dotenv() app = FastAPI(title="My First AI Skill Server") # 初始化 OpenAI Client client = AsyncOpenAI() class ChatRequest(BaseModel): message: str history: list[dict] = [] # 用于维护多轮对话 @app.post("/chat") async def chat_endpoint(request: ChatRequest): try: messages = request.history + [ {"role": "user", "content": request.message} ] # 第一轮:让 LLM 决定是否需要调用 Skill response = await client.chat.completions.create( model="gpt-3.5-turbo", # 或者 "moonshot-v1-8k" messages=messages, tools=[{"type": "function", "function": s} for s in AVAILABLE_SKILLS], tool_choice="auto", # 自动决定是否调用工具 ) response_message = response.choices[0].message # 检查是否有工具调用请求 if response_message.tool_calls: # 执行 Skill tool_call = response_message.tool_calls[0] function_name = tool_call.function.name if function_name not in SKILL_EXECUTORS: raise HTTPException(status_code=400, detail=f"Unknown skill: {function_name}") # 解析参数 arguments = json.loads(tool_call.function.arguments) # 执行对应的函数 function_response = await SKILL_EXECUTORS[function_name](**arguments) # 将消息历史拼接起来 # 1. 用户的原始请求 # 2. LLM 返回的带有 tool_calls 的消息 # 3. 工具执行的结果 messages.append(response_message) messages.append({ "tool_call_id": tool_call.id, "role": "tool", "name": function_name, "content": json.dumps(function_response, ensure_ascii=False), }) # 第二轮:将工具结果发回给 LLM,让它生成最终回复 final_response = await client.chat.completions.create( model="gpt-3.5-turbo", messages=messages, ) return { "role": "assistant", "content": final_response.choices[0].message.content, "debug": { "skill_called": function_name, "arguments": arguments, "raw_result": function_response } } else: # 如果不需要调用工具,直接返回 LLM 的回复 return { "role": "assistant", "content": response_message.content } except Exception as e: print(traceback.format_exc()) raise HTTPException(status_code=500, detail=str(e)) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)

4.5 步骤四:运行与测试

  1. 启动服务:

    python main.py
  2. 使用 curl 或 Postman 测试:

    curl -X POST "http://localhost:8000/chat" \ -H "Content-Type: application/json" \ -d '{ "message": "北京今天多少度?", "history": [] }'

预期返回结果

{ "role": "assistant", "content": "北京今天的气温是25°C,天气晴朗。", "debug": { "skill_called": "get_current_weather", "arguments": { "location": "北京", "unit": "celsius" }, "raw_result": { "location": "北京", "temperature": 25.0, "unit": "celsius", "condition": "Sunny", "humidity": 40 } } }

🎉恭喜!你已经成功构建了第一个 AI Skill。


五、进阶:构建企业级 Skill 生态

当你有了 10 个、100 个 Skill 时,上述简单的架构将面临挑战。企业级落地需要考虑更多维度。

5.1 Skill 注册中心 (Registry)

不能把所有的 Skill Schema 都硬编码在代码里。需要一个中心化的注册表(可以是数据库或配置文件)。

# skills/weather.yaml name: get_current_weather version: 1.0.0 description: ... endpoint: http://internal-api/weather auth: api_key schema: type: object properties: ...

服务启动时,自动扫描并加载这些配置。

5.2 权限与隔离 (Auth & Isolation)

  • 用户级权限:用户 A 不能调用用户 B 的私有 Skill(如查询私人日历)。

  • 租户隔离:SaaS 环境下,Tenant A 的 Skill 不能被 Tenant B 看到。

  • 沙箱机制:如果 Skill 允许用户上传代码执行(极端危险),必须使用 Docker 或 WASM 进行强隔离。

5.3 异步 Skill (Async Skills)

有些任务耗时很长,比如“生成一张复杂的海报”或“训练一个模型”。

此时不能让 LLM 等待 HTTP 响应。

解决方案:异步回调机制

  1. LLM 调用create_poster_taskSkill。

  2. Skill 立即返回一个task_id:“任务已提交,ID 为 xxx”。

  3. 后台 Worker 执行任务。

  4. 任务完成后,通过 WebSocket 或 Webhook 通知 Agent,Agent 再告知用户。

5.4 RAG + Skill 的结合

很多时候,用户的问题既需要知识检索,又需要工具调用。

例如:“帮我总结一下昨天关于 Q3 财报的邮件,并对比去年同期数据。”

  • RAG:检索昨天关于 Q3 财报的邮件内容。

  • Skill:调用query_database获取去年同期的财务数据。

  • LLM:融合两者生成总结。

这需要在 Prompt 层面进行精细编排,或者使用 LangChain/LlamaIndex 等框架的 Agent 模块。

5.5 监控与可观测性 (Observability)

你需要知道:

  • 哪个 Skill 调用最多?(热门功能)

  • 哪个 Skill 经常失败?(稳定性问题)

  • Token 消耗在哪里?(成本控制)

  • LLM 是否产生了幻觉参数?(质量评估)

建议使用 OpenTelemetry 或类似工具,为每个 Skill 调用生成 Trace ID。


六、常见陷阱与避坑指南

  1. 过度依赖 LLM 的推理能力:不要把复杂的业务逻辑完全交给 LLM 去判断。Skill 内部要有完整的校验和兜底逻辑。

  2. 忽略负面反馈:当 Skill 执行失败时,返回给 LLM 的错误信息要友好且具有指导性。例如,不要只返回404,而是返回{"error": "City not found, please check spelling or suggest nearby cities."}。这样 LLM 才能修正后重试。

  3. 上下文窗口溢出:Skill 返回的数据可能很大(例如长文档)。需要对返回内容进行截断、压缩或摘要,防止超出模型的上下文限制。

  4. 循环调用:Agent 可能会陷入死循环(调用 A -> 调用 B -> 发现需要 A -> 调用 A...)。需要设置最大调用步数(Max Steps),例如 ReAct 循环最多 10 次。


七、未来展望:Skill 将走向何方?

  1. 标准化 (Standardization):MCP 等协议的成熟将使得 Skill 像 NPM 包一样流通。你将不再需要从头写天气 Skill,而是直接pip install mcp-weather-server

  2. GUI 自动化:Skill 不再局限于 API 调用。结合 Computer Use 模型(如 Claude 3.5 Sonnet),Skill 可以直接操作图形界面,点击按钮、填写表单,从而控制那些没有开放 API 的老旧软件。

  3. 自主进化:未来的 Agent 或许能够根据用户的需求,自动编写新的 Skill 代码并进行测试部署(Code -> Test -> Deploy),实现真正的自我进化。

  4. 去中心化市场:开发者可以将自己编写的优质 Skill 放到区块链上进行确权、交易和分发,形成一个繁荣的 AI 技能经济生态。


八、总结

Skill 是 AI Agent 的基石。它将大模型从“纸上谈兵”的理论家,变成了能够“撸起袖子加油干”的实干家。

构建 Skill 的过程,本质上是将人类的业务逻辑翻译成机器可执行、AI 可理解的接口。这要求我们不仅要懂后端开发,还要懂 Prompt Engineering,更要懂 AI 的行为模式。

回顾我们的第一个 Skill:

  1. 定义逻辑:编写了get_current_weather函数。

  2. 定义接口:创建了 JSON Schema,作为 AI 的“说明书”。

  3. 编排流程:实现了 ReAct 循环(思考 -> 调用 -> 观察 -> 回答)。

这看似简单的三步,正是通往通用人工智能应用的第一步。希望这篇长文能为你打开 AI Skill 开发的大门,期待你构建出改变世界的智能应用!


附录:推荐阅读与工具

  • OpenAI Function Calling Docs: 官方文档永远是最好的起点。

  • Model Context Protocol (MCP): Anthropic 的最新协议,值得关注。

  • LangChain Tools: 提供了大量开箱即用的 Tool 封装。

  • FastAPI: 构建 Skill 后端服务的首选框架。

  • Pydantic: 数据验证的利器,非常适合定义 Skill 参数模型。

📚 附录链接补全

  1. OpenAI Function Calling Docs

OpenAI 中文文档

https://platform.openai.com/docs/guides/function-calling

官方指南,含 Schema 定义、多工具调用、stream 模式等最新写法。

  1. Model Context Protocol (MCP)

    https://modelcontextprotocol.io

    Anthropic 主导的开放协议,SDK(Python / TypeScript)和 Server 样例都在这里。

  2. LangChain Tools

    https://python.langchain.com/docs/concepts/tools/

    LangChain 的 Tool / ToolCall / Agent 编排文档,开箱即用的 Tool 封装大全。

  3. FastAPI

    https://fastapi.tiangolo.com

    官方文档,含依赖注入、Pydantic 集成、异步路径,搭 Skill 后端首选。

  4. Pydantic

    https://docs.pydantic.dev

    V2 文档,重点看BaseModelFieldmodel_validator——Skill 参数校验的核心。

本文涵盖了从原理到实战的内容。如果需要我针对特定场景(如企业内部系统、电商客服)为你设计一个更复杂的进阶版 Skill,请评论区留言!

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

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

立即咨询