什么是Skill——让Agent真正"动手干活"的秘密

前言

看过前面几篇文章的朋友应该知道,Agent是一个能自主思考、完成任务的AI助手。但有个问题一直没细说:

Agent靠什么来完成任务?光靠大模型"想"是不够的。

答案就是今天要聊的主角——Skill(技能)。

这篇文章用最通俗的语言,带你搞清楚Skill是什么、为什么需要它、怎么用它,文末附完整代码示例,跟着做就能跑起来。


一、用一个比喻理解Skill

把Agent想象成一个聪明的员工:

  • 大模型(LLM)是他的大脑,负责思考和判断
  • Skill是他的双手,负责真正执行操作

光有大脑不够,得有手才能干活。

员工 Agent
大脑(思考判断) 大模型(LLM)
双手(执行操作) Skill(技能)
完成的任务结果 Agent的输出

为什么大模型本身不够用?

大模型就像一位"超级博学的专家",他知识渊博,但有一个致命缺陷:他被困在文字世界里。

他不能:

  • 上网查今天的实时新闻
  • 查询你公司数据库里的订单
  • 发送一封邮件
  • 计算复杂的数学公式(准确率不稳定)

Skill就是给他装上"手"和"眼睛",让他能真正与现实世界交互。

没有Skill的Agent = 聊天机器人

有了Skill的Agent = 真正会干活的AI助手


二、Skill的工作原理

Agent执行一个任务的完整流程

Agent调用Skill执行流程

关键点

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 装饰器做了三件事:

  1. 把这个函数注册为一个Agent可以调用的Skill
  2. 把函数名 add_numbers 作为Skill的名称
  3. 把注释 计算两个数字的和 作为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会自动执行以下步骤:

  1. 分析问题:需要知道美元汇率
  2. 调用 get_exchange_rate("USD") → 得到 1 USD = 7.24 CNY
  3. 调用 multiply(150, 7.24) → 得到 1086.0
  4. 整合回答: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架构关系图

七、总结

问题 答案
Skill是什么? Agent能执行的一项具体操作,本质是一个Python函数
为什么需要Skill? 大模型无法访问实时数据和外部系统,Skill弥补这个缺陷
怎么定义Skill? 用 @tool 装饰器包装函数,写清楚描述
Agent如何使用Skill? 根据描述自动判断何时调用、如何传参
Skill的设计原则? 功能单一、描述精准、返回有意义的内容

掌握了Skill,你就掌握了扩展Agent能力的核心方法。理论上,只要能写成函数的操作,都可以变成Skill,赋予Agent无限可能。

下一篇文章,我们将实战演练一个带多个Skill的完整Agent项目,从用户提问到最终交付结果,完整跑通整个流程。


如果这篇文章对你有帮助,欢迎点赞收藏!有疑问欢迎在评论区留言,我会一一解答。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容