前言
看过前面几篇文章的朋友应该知道,Agent是一个能自主思考、完成任务的AI助手。但有个问题一直没细说:
Agent靠什么来完成任务?光靠大模型"想"是不够的。
答案就是今天要聊的主角——Skill(技能)。
这篇文章用最通俗的语言,带你搞清楚Skill是什么、为什么需要它、怎么用它,文末附完整代码示例,跟着做就能跑起来。
一、用一个比喻理解Skill
把Agent想象成一个聪明的员工:
- 大模型(LLM)是他的大脑,负责思考和判断
- Skill是他的双手,负责真正执行操作
光有大脑不够,得有手才能干活。
| 员工 | Agent |
|---|---|
| 大脑(思考判断) | 大模型(LLM) |
| 双手(执行操作) | Skill(技能) |
| 完成的任务结果 | Agent的输出 |
为什么大模型本身不够用?
大模型就像一位"超级博学的专家",他知识渊博,但有一个致命缺陷:他被困在文字世界里。
他不能:
- 上网查今天的实时新闻
- 查询你公司数据库里的订单
- 发送一封邮件
- 计算复杂的数学公式(准确率不稳定)
Skill就是给他装上"手"和"眼睛",让他能真正与现实世界交互。
没有Skill的Agent = 聊天机器人
有了Skill的Agent = 真正会干活的AI助手
二、Skill的工作原理
Agent执行一个任务的完整流程

关键点
Agent在调用Skill时,整个过程是自动的——你不需要告诉它"先查汇率再计算",它自己会根据Skill的描述判断该用哪个、按什么顺序用。
三、常见的Skill类型
Skill本质上是一个函数,可以封装任何操作。实际开发中最常见的有五类:
| 类型 | 功能 | 例子 |
|---|---|---|
| 搜索类 | 获取实时信息 | 搜索新闻、查天气、查股价 |
| 计算类 | 精确数学计算 | 数学公式、统计分析 |
| 数据类 | 读写数据 | 查询数据库、读取文件 |
| 通信类 | 与外部系统交互 | 发邮件、调用第三方API |
| 工具类 | 使用特定工具 | 操作浏览器、执行代码 |
四、代码示例:从零写一个Skill
最简单的例子
在LangChain中,用 @tool 装饰器定义一个Skill只需要几行代码:
from langchain.tools import tool
@tool
def add_numbers(a: int, b: int) -> int:
"""计算两个数字的和"""
return a + b
就这么简单。@tool 装饰器做了三件事:
- 把这个函数注册为一个Agent可以调用的Skill
- 把函数名
add_numbers作为Skill的名称 - 把注释
计算两个数字的和作为Skill的描述,让Agent知道什么时候该用它
完整示例:汇率换算Agent
这个示例展示如何让Agent自动组合多个Skill完成一个任务:
from langchain.tools import tool
from langchain_openai import ChatOpenAI
from langchain.agents import create_react_agent, AgentExecutor
from langchain import hub
from dotenv import load_dotenv
import os
load_dotenv()
# --- 定义 Skill ---
@tool
def multiply(a: float, b: float) -> float:
"""计算两个数字的乘积,用于数学计算"""
return a * b
@tool
def get_exchange_rate(currency: str) -> str:
"""
获取指定货币兑人民币的汇率。
参数 currency 支持: USD(美元)、EUR(欧元)、JPY(日元)
"""
rates = {
"USD": "7.24",
"EUR": "7.85",
"JPY": "0.048"
}
rate = rates.get(currency.upper())
if rate:
return f"1 {currency.upper()} = {rate} CNY"
return f"未找到货币 {currency} 的汇率"
# --- 创建 Agent ---
tools = [multiply, get_exchange_rate]
llm = ChatOpenAI(
model="deepseek-chat",
api_key=os.getenv("DEEPSEEK_API_KEY"),
base_url="https://api.deepseek.com"
)
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# --- 测试 ---
result = executor.invoke({"input": "我有150美元,换成人民币是多少?"})
print("\n最终答案:", result["output"])
运行后,Agent会自动执行以下步骤:
- 分析问题:需要知道美元汇率
- 调用
get_exchange_rate("USD")→ 得到1 USD = 7.24 CNY - 调用
multiply(150, 7.24)→ 得到1086.0 - 整合回答:
150美元约等于1086元人民币
整个过程你只需要问问题,Agent自己决定调用哪些Skill、按什么顺序。
五、Skill设计的三个原则
写好Skill有三个关键原则,新手很容易在这里踩坑:
原则1:功能单一
每个Skill只做一件事。
❌ 不好的设计(功能太复杂):
@tool
def do_everything(task: str) -> str:
"""搜索网络、计算数字、发送邮件、查数据库"""
# 函数太臃肿,Agent不知道该怎么用
pass
✅ 好的设计(职责清晰):
@tool
def search_web(query: str) -> str:
"""在网络上搜索信息,返回相关结果摘要"""
pass
@tool
def send_email(to: str, subject: str, body: str) -> bool:
"""向指定邮箱发送邮件,成功返回True"""
pass
原则2:描述要精准
Skill的注释(docstring)是Agent决定"要不要调用它"的唯一依据。描述写得不清楚,Agent就会用错Skill。
# 描述太模糊,Agent不知道什么情况该用
@tool
def get_data(input: str) -> str:
"""获取数据"""
pass
# 描述清晰,Agent能准确判断何时调用
@tool
def query_order_status(order_id: str) -> str:
"""根据订单号查询订单状态,返回:待支付/已支付/已发货/已完成"""
pass
原则3:返回值要有意义
Skill的返回值会被Agent"读取",要返回有用的文字信息,而不是错误码或 None。
# 不好:Agent看到None不知道发生了什么
return None
# 好:Agent能理解并处理
return "查询失败:订单号格式不正确,应为10位数字"
六、Skill与Agent的关系图

七、总结
| 问题 | 答案 |
|---|---|
| Skill是什么? | Agent能执行的一项具体操作,本质是一个Python函数 |
| 为什么需要Skill? | 大模型无法访问实时数据和外部系统,Skill弥补这个缺陷 |
| 怎么定义Skill? | 用 @tool 装饰器包装函数,写清楚描述 |
| Agent如何使用Skill? | 根据描述自动判断何时调用、如何传参 |
| Skill的设计原则? | 功能单一、描述精准、返回有意义的内容 |
掌握了Skill,你就掌握了扩展Agent能力的核心方法。理论上,只要能写成函数的操作,都可以变成Skill,赋予Agent无限可能。
下一篇文章,我们将实战演练一个带多个Skill的完整Agent项目,从用户提问到最终交付结果,完整跑通整个流程。
如果这篇文章对你有帮助,欢迎点赞收藏!有疑问欢迎在评论区留言,我会一一解答。