AI Agent 技能(Skill)详解:从概念到实现

返回

技能(Skill)是 AI Agent 的核心能力单元,决定了 Agent 能做什么。本文系统讲解技能的设计与实现。

一、什么是 AI Agent 技能?

1.1 定义

Skill(技能)= Agent 能够执行的特定能力或任务

用一个比喻理解:

  • LLM = 大脑(思考、决策)
  • Skill = 手脚(执行具体动作)
  • Agent = 完整的人(大脑 + 手脚)

1.2 技能 vs 工具 vs 函数

概念范围例子
Function(函数)最底层,代码级别calculate_sum(a, b)
Tool(工具)封装好的功能模块计算器、搜索引擎
Skill(技能)最高层,可能组合多个工具”数据分析”、“写报告”
技能 = 工具的组合 + 业务逻辑 + 决策能力

例子:"数据分析"技能
├─ 调用 Python 执行代码
├─ 调用图表库生成可视化
├─ 调用文件读写保存结果
└─ 用 LLM 生成分析报告

1.3 技能的核心特征

特征描述例子
目标导向完成特定目标”订机票”、“写邮件”
可复用多次调用,参数不同每次订不同的机票
可组合多个技能组合成工作流订票 + 订酒店 = 旅行规划
可解释Agent 知道什么时候用根据用户意图选择技能

二、技能的分类

2.1 按能力类型分类

┌─────────────────────────────────────────────────────────────────┐
│                      技能分类体系                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  1. 信息获取类                                                   │
│     • 搜索技能:搜索互联网、数据库查询                           │
│     • 读取技能:读取文件、API 调用                               │
│     • 监控技能:监控数据变化、告警通知                           │
│                                                                 │
│  2. 内容创作类                                                   │
│     • 写作技能:写文章、写邮件、写报告                           │
│     • 编程技能:写代码、代码审查、调试                           │
│     • 设计技能:生成图片、设计图表                               │
│                                                                 │
│  3. 任务执行类                                                   │
│     • 操作技能:文件操作、数据库操作                             │
│     • 交互技能:发送邮件、发送消息                               │
│     • 调度技能:定时任务、工作流编排                             │
│                                                                 │
│  4. 分析决策类                                                   │
│     • 分析技能:数据分析、趋势预测                               │
│     • 决策技能:方案评估、风险评估                               │
│     • 推理技能:逻辑推理、问题诊断                               │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

2.2 按复杂度分类

等级描述例子实现难度
L1 原子技能单一功能,直接调用工具天气查询、文件读取
L2 组合技能组合 2-3 个工具搜索 + 总结、查询 + 分析⭐⭐
L3 工作流技能多步骤,有分支逻辑旅行规划、项目管理⭐⭐⭐
L4 自主技能能自主规划和调整自主研究、自主学习⭐⭐⭐⭐

2.3 常见技能示例

领域技能名称输入输出
办公写邮件主题、收件人、要点格式化邮件
办公会议纪要会议录音/文字纪要文档
开发代码审查代码文件审查报告
开发Bug 诊断错误日志、代码问题定位 + 修复建议
数据数据分析数据文件分析报告 + 图表
数据数据清洗原始数据清洗后数据
生活旅行规划目的地、时间、预算行程单
生活健康管理体检数据健康建议

三、技能的设计模式

3.1 基础模式:单工具技能

class WeatherSkill:
    """天气查询技能 - 单工具调用"""
    
    name = "weather_query"
    description = "查询指定城市的天气"
    
    def __init__(self, api_key):
        self.api_key = api_key
    
    def execute(self, city: str) -> dict:
        """执行技能"""
        # 1. 调用天气 API
        response = requests.get(
            f"https://api.weather.com/{city}",
            headers={"Authorization": self.api_key}
        )
        
        # 2. 格式化结果
        result = {
            "city": city,
            "temperature": response.json()["temp"],
            "condition": response.json()["condition"],
            "humidity": response.json()["humidity"]
        }
        
        return result
    
    def to_llm_format(self) -> dict:
        """转换为 LLM 可调用的格式"""
        return {
            "name": self.name,
            "description": self.description,
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名称,如'北京'、'上海'"
                    }
                },
                "required": ["city"]
            }
        }

3.2 组合模式:多工具技能

class ResearchSkill:
    """研究技能 - 组合多个工具"""
    
    name = "research"
    description = "研究一个主题,生成报告"
    
    def __init__(self, search_tool, scrape_tool, summarize_tool):
        self.search = search_tool      # 搜索工具
        self.scrape = scrape_tool      # 网页抓取工具
        self.summarize = summarize_tool  # 总结工具
    
    def execute(self, topic: str, depth: int = 3) -> str:
        """执行研究技能"""
        # 步骤 1: 搜索相关信息
        search_results = self.search.run(
            query=topic,
            num_results=depth
        )
        
        # 步骤 2: 抓取关键内容
        contents = []
        for result in search_results:
            content = self.scrape.run(url=result["url"])
            contents.append(content)
        
        # 步骤 3: 总结生成报告
        report = self.summarize.run(
            topic=topic,
            sources=contents
        )
        
        return report
    
    def to_llm_format(self) -> dict:
        return {
            "name": self.name,
            "description": self.description,
            "parameters": {
                "type": "object",
                "properties": {
                    "topic": {
                        "type": "string",
                        "description": "研究主题"
                    },
                    "depth": {
                        "type": "integer",
                        "description": "研究深度(搜索多少篇文献)",
                        "default": 3
                    }
                },
                "required": ["topic"]
            }
        }

3.3 工作流模式:有状态技能

class TravelPlanningSkill:
    """旅行规划技能 - 多步骤工作流"""
    
    name = "travel_planning"
    description = "规划一次旅行,包括交通、住宿、行程"
    
    def __init__(self, flight_tool, hotel_tool, attraction_tool):
        self.flight = flight_tool
        self.hotel = hotel_tool
        self.attraction = attraction_tool
    
    def execute(self, params: dict) -> dict:
        """
        执行旅行规划
        
        params: {
            "origin": "北京",
            "destination": "东京",
            "dates": "2024-04-01 到 2024-04-07",
            "budget": 10000,
            "preferences": ["美食", "购物", "文化"]
        }
        """
        plan = {
            "destination": params["destination"],
            "dates": params["dates"],
            "flights": [],
            "hotels": [],
            "activities": [],
            "budget_breakdown": {}
        }
        
        # 步骤 1: 查询航班
        plan["flights"] = self._search_flights(params)
        
        # 步骤 2: 查询酒店
        plan["hotels"] = self._search_hotels(params)
        
        # 步骤 3: 规划活动
        plan["activities"] = self._plan_activities(params)
        
        # 步骤 4: 预算分配
        plan["budget_breakdown"] = self._allocate_budget(
            plan, params["budget"]
        )
        
        return plan
    
    def _search_flights(self, params: dict) -> list:
        """查询航班(私有方法)"""
        # 实现细节...
        pass
    
    def _search_hotels(self, params: dict) -> list:
        """查询酒店"""
        pass
    
    def _plan_activities(self, params: dict) -> list:
        """规划活动"""
        pass
    
    def _allocate_budget(self, plan: dict, total: float) -> dict:
        """分配预算"""
        pass

3.4 自主模式:带规划技能

class AutonomousResearchSkill:
    """自主研究技能 - 能自己规划步骤"""
    
    name = "autonomous_research"
    description = "自主研究一个复杂问题"
    
    def __init__(self, llm, tools: dict):
        self.llm = llm
        self.tools = tools  # 可用工具集合
    
    def execute(self, question: str, max_steps: int = 10) -> str:
        """自主执行研究"""
        
        # 初始化
        context = []
        steps_taken = 0
        
        while steps_taken < max_steps:
            # 步骤 1: 思考下一步做什么
            thought = self._think(question, context)
            
            # 步骤 2: 决定是否继续
            if thought["action"] == "conclude":
                break
            
            # 步骤 3: 选择并执行工具
            tool_result = self._execute_tool(
                thought["tool"],
                thought["params"]
            )
            
            # 步骤 4: 更新上下文
            context.append({
                "step": steps_taken,
                "thought": thought,
                "result": tool_result
            })
            
            steps_taken += 1
        
        # 生成最终报告
        report = self._generate_report(question, context)
        return report
    
    def _think(self, question: str, context: list) -> dict:
        """用 LLM 思考下一步"""
        prompt = f"""
        问题:{question}
        已收集信息:{context}
        
        请决定下一步:
        1. 需要搜索什么信息?
        2. 还是已经有足够信息可以得出结论?
        
        返回 JSON: {{"action": "search/conclude", "tool": "...", "params": {{}}}}
        """
        response = self.llm.generate(prompt)
        return json.loads(response)
    
    def _execute_tool(self, tool_name: str, params: dict):
        """执行选定的工具"""
        tool = self.tools[tool_name]
        return tool.run(**params)
    
    def _generate_report(self, question: str, context: list) -> str:
        """生成最终报告"""
        pass

四、技能的实现框架

4.1 LangChain Skills(2026 版)

from langchain.agents import tool
from langchain_core.tools import BaseTool

# 方式 1:用装饰器定义工具(LangChain 0.3.x)
@tool
def calculate_bmi(weight: float, height: float) -> str:
    """计算 BMI 指数
    
    Args:
        weight: 体重(kg)
        height: 身高(m)
    
    Returns:
        BMI 值和健康建议
    """
    bmi = weight / (height ** 2)
    
    if bmi < 18.5:
        advice = "偏瘦,建议增加营养"
    elif bmi < 24:
        advice = "正常,继续保持"
    elif bmi < 28:
        advice = "偏胖,建议控制饮食"
    else:
        advice = "肥胖,建议就医咨询"
    
    return f"BMI: {bmi:.1f}, 建议:{advice}"

# 方式 2:继承 BaseTool 类(更灵活)
class WeatherTool(BaseTool):
    name: str = "weather_query"
    description: str = "查询指定城市的天气"
    
    def _run(self, city: str) -> str:
        # 实现天气查询逻辑
        return f"{city}今天晴天,25 度"
    
    async def _arun(self, city: str) -> str:
        # 异步实现
        return await asyncio.to_thread(self._run, city)

# 注册到 Agent
tools = [calculate_bmi, WeatherTool()]

4.2 AutoGen Skills

from autogen import register_function

def search_web(query: str) -> str:
    """搜索互联网"""
    # 实现搜索逻辑
    pass

def analyze_data(file_path: str) -> dict:
    """分析数据文件"""
    # 实现分析逻辑
    pass

# 注册技能
register_function(
    search_web,
    caller=agent,
    executor=agent,
    name="web_search",
    description="搜索互联网获取信息"
)

register_function(
    analyze_data,
    caller=agent,
    executor=agent,
    name="data_analysis",
    description="分析 CSV/Excel 数据文件"
)

4.3 自定义 Skill 基类

from abc import ABC, abstractmethod
from typing import Any, Dict, Optional

class Skill(ABC):
    """技能基类"""
    
    name: str
    description: str
    version: str = "1.0.0"
    
    @abstractmethod
    def execute(self, **kwargs) -> Any:
        """执行技能"""
        pass
    
    @abstractmethod
    def to_llm_format(self) -> Dict:
        """转换为 LLM 可调用的格式"""
        pass
    
    def validate(self, **kwargs) -> bool:
        """验证输入参数"""
        # 默认实现,可被子类重写
        return True
    
    def before_execute(self, **kwargs):
        """执行前钩子"""
        pass
    
    def after_execute(self, result: Any):
        """执行后钩子"""
        pass
    
    def run(self, **kwargs) -> Any:
        """完整执行流程(推荐调用此方法)"""
        # 1. 验证参数
        if not self.validate(**kwargs):
            raise ValueError("参数验证失败")
        
        # 2. 执行前钩子
        self.before_execute(**kwargs)
        
        # 3. 执行技能
        result = self.execute(**kwargs)
        
        # 4. 执行后钩子
        self.after_execute(result)
        
        # 5. 返回结果
        return result


# 使用示例
class EmailSkill(Skill):
    name = "send_email"
    description = "发送邮件"
    
    def execute(self, to: str, subject: str, body: str) -> dict:
        # 实现邮件发送逻辑
        return {"status": "success", "message_id": "xxx"}
    
    def to_llm_format(self) -> dict:
        return {
            "name": self.name,
            "description": self.description,
            "parameters": {
                "type": "object",
                "properties": {
                    "to": {"type": "string", "description": "收件人邮箱"},
                    "subject": {"type": "string", "description": "邮件主题"},
                    "body": {"type": "string", "description": "邮件正文"}
                },
                "required": ["to", "subject", "body"]
            }
        }

五、技能注册与发现

5.1 技能注册表

class SkillRegistry:
    """技能注册表"""
    
    def __init__(self):
        self._skills: Dict[str, Skill] = {}
    
    def register(self, skill: Skill):
        """注册技能"""
        self._skills[skill.name] = skill
        print(f"✅ 已注册技能:{skill.name} v{skill.version}")
    
    def unregister(self, skill_name: str):
        """注销技能"""
        if skill_name in self._skills:
            del self._skills[skill_name]
            print(f"❌ 已注销技能:{skill_name}")
    
    def get(self, skill_name: str) -> Optional[Skill]:
        """获取技能"""
        return self._skills.get(skill_name)
    
    def list_skills(self) -> list:
        """列出所有技能"""
        return [
            {
                "name": skill.name,
                "description": skill.description,
                "version": skill.version
            }
            for skill in self._skills.values()
        ]
    
    def to_llm_format(self) -> list:
        """转换为 LLM 可用的技能列表"""
        return [skill.to_llm_format() for skill in self._skills.values()]


# 使用示例
registry = SkillRegistry()

# 注册技能
registry.register(WeatherSkill())
registry.register(EmailSkill())
registry.register(ResearchSkill())

# Agent 使用
agent_skills = registry.to_llm_format()

5.2 技能配置文件

# skills.yaml
skills:
  - name: weather_query
    class: skills.weather.WeatherSkill
    enabled: true
    config:
      api_key: ${WEATHER_API_KEY}
      default_units: metric
  
  - name: email_send
    class: skills.email.EmailSkill
    enabled: true
    config:
      smtp_server: smtp.gmail.com
      smtp_port: 587
  
  - name: data_analysis
    class: skills.data.AnalysisSkill
    enabled: false  # 暂时禁用
    config:
      max_file_size: 10MB

5.3 动态加载技能

import importlib
import yaml

class SkillLoader:
    """技能加载器"""
    
    @staticmethod
    def load_from_config(config_path: str) -> SkillRegistry:
        """从配置文件加载技能"""
        registry = SkillRegistry()
        
        with open(config_path, 'r') as f:
            config = yaml.safe_load(f)
        
        for skill_config in config.get('skills', []):
            if not skill_config.get('enabled', True):
                continue
            
            # 动态导入类
            module_path, class_name = skill_config['class'].rsplit('.', 1)
            module = importlib.import_module(module_path)
            skill_class = getattr(module, class_name)
            
            # 实例化技能
            skill = skill_class(**skill_config.get('config', {}))
            
            # 注册
            registry.register(skill)
        
        return registry

六、技能测试与评估

6.1 单元测试

import unittest

class TestWeatherSkill(unittest.TestCase):
    
    def setUp(self):
        self.skill = WeatherSkill(api_key="test_key")
    
    def test_execute_valid_city(self):
        """测试有效城市"""
        result = self.skill.execute(city="北京")
        self.assertIn("temperature", result)
        self.assertIn("condition", result)
    
    def test_execute_invalid_city(self):
        """测试无效城市"""
        with self.assertRaises(Exception):
            self.skill.execute(city="无效城市")
    
    def test_llm_format(self):
        """测试 LLM 格式"""
        format = self.skill.to_llm_format()
        self.assertEqual(format["name"], "weather_query")
        self.assertIn("parameters", format)

6.2 集成测试

class TestResearchSkillIntegration(unittest.TestCase):
    
    def test_full_workflow(self):
        """测试完整工作流"""
        skill = ResearchSkill(
            search_tool=MockSearch(),
            scrape_tool=MockScrape(),
            summarize_tool=MockSummarize()
        )
        
        report = skill.execute(topic="AI 发展趋势", depth=2)
        
        # 验证报告结构
        self.assertGreater(len(report), 0)
        self.assertIn("总结", report)
        self.assertIn("关键点", report)

6.3 评估指标

指标描述目标值
成功率技能执行成功的比例>95%
准确率结果符合预期的比例>90%
响应时间平均执行时间<5 秒
调用次数被 Agent 调用的频率持续监控
用户满意度用户对结果的评分>4/5

🎯 面试回答版本

面试官问:“你如何设计和实现 AI Agent 的技能?“

标准回答(2-3 分钟)

技能是 AI Agent 的核心能力单元,我主要从几个层面设计:

【分类设计】
按复杂度分 L1-L4 四个等级:
L1 原子技能(单一功能)、L2 组合技能(2-3 个工具)、
L3 工作流技能(多步骤)、L4 自主技能(能自己规划)。

【设计模式】
常用四种模式:
1. 单工具模式:直接封装一个 API 或函数
2. 组合模式:组合多个工具完成复杂任务
3. 工作流模式:有状态、多步骤的业务流程
4. 自主模式:用 LLM 自主规划执行步骤

【实现框架】
我常用 LangChain 的@tool 装饰器,
或者自定义 Skill 基类,包含 execute、validate、
to_llm_format 等标准方法。

【技能管理】
用注册表统一管理,支持动态加载、配置化、
版本控制。每个技能有完整的单元测试和集成测试。

【实际应用】
我在项目中实现了 XX 个技能,包括数据分析、
邮件发送、报告生成等,成功率达到 95% 以上。

高频追问

追问参考回答
”技能和工具有什么区别?“工具是底层功能,技能是高层能力,一个技能可以组合多个工具。
“如何保证技能执行安全?“参数验证、权限控制、执行超时、结果审计。
“技能执行失败怎么办?“重试机制、降级方案、错误上报、人工介入。
“如何评估技能效果?“成功率、准确率、响应时间、用户满意度等指标。

相关阅读: