Agent Skills 傻瓜式教程:从零到一构建智能体技能(附完整代码实践)
1. 引言:什么是 Agent Skills?
在当今的 AI 应用开发中,智能体(Agent)已成为连接大语言模型(LLM)与现实世界任务的关键桥梁。而Agent Skills(智能体技能)则是赋予智能体执行特定、可复用任务的能力模块。你可以把它想象成给一个“大脑”(LLM)安装的“手”和“工具包”。
为什么需要 Skills?
- 模块化:将复杂任务拆解为独立的技能,便于开发、测试和复用。
- 专业化:每个技能专注于一件事,如搜索、计算、调用 API,效果更佳。
- 可扩展:可以像搭积木一样,为智能体组合不同的技能来完成复杂工作流。
本教程将采用LangChain框架,带你从零开始,手把手创建、组合并使用 Agent Skills。即使你是初学者,也能跟着代码一步步实现。
2. 环境准备与工具安装
首先,确保你的开发环境已就绪。
2.1 创建项目并安装依赖
打开终端,执行以下命令:
# 创建项目目录mkdiragent-skills-tutorialcdagent-skills-tutorial# 创建虚拟环境(推荐)python-mvenv venv# 激活虚拟环境# Windows:venv\Scripts\activate# macOS/Linux:sourcevenv/bin/activate# 安装核心依赖pipinstalllangchain langchain-openai python-dotenv2.2 配置 API 密钥
我们需要一个 LLM 作为智能体的“大脑”。这里使用 OpenAI 的模型。在项目根目录创建.env文件,并填入你的 OpenAI API Key:
# .env OPENAI_API_KEY=sk-your-openai-api-key-here然后,在代码中加载环境变量:
# config.pyimportosfromdotenvimportload_dotenv load_dotenv()OPENAI_API_KEY=os.getenv("OPENAI_API_KEY")assertOPENAI_API_KEY,"请检查 .env 文件中的 OPENAI_API_KEY 配置"3. 创建你的第一个 Skill:计算器
我们从最简单的开始——创建一个能进行数学计算的技能。
3.1 定义 Skill 函数
一个 Skill 本质上是一个可被智能体调用的函数。我们创建一个calculator_skill.py文件:
# skills/calculator_skill.pyimportmathimportredefcalculate(expression:str)->str:""" 计算数学表达式。 支持加减乘除、乘方、括号及常见数学函数。 Args: expression (str): 数学表达式,如 "2 + 3 * (4 - 1)" Returns: str: 计算结果或错误信息 """# 安全考虑:移除可能危险的字符,只保留数学表达式允许的字符safe_expression=re.sub(r'[^0-9+\-*/().^πesincoqrtanlg\s]','',expression)try:# 替换常见的数学常数和函数为 Python 可识别的形式safe_expression=safe_expression.replace('^','**').replace('π','math.pi')safe_expression=safe_expression.replace('sin','math.sin').replace('cos','math.cos').replace('tan','math.tan')safe_expression=safe_expression.replace('log','math.log10').replace('ln','math.log')safe_expression=safe_expression.replace('sqrt','math.sqrt')# 使用 eval 计算(注意:在生产环境中应对输入做更严格的限制或使用安全库)result=eval(safe_expression,{"__builtins__":{}},{"math":math})returnf"计算结果:{expression}={result}"exceptExceptionase:returnf"计算错误:无法解析表达式 '{expression}'。错误详情:{e}"3.2 将函数包装为 LangChain Tool
LangChain 通过Tool类将函数封装成智能体可识别的工具。
# skills/calculator_tool.pyfromlangchain.toolsimportToolfrom.calculator_skillimportcalculate calculator_tool=Tool(name="Calculator",func=calculate,description="""用于计算数学表达式。输入应为一个字符串格式的数学表达式。 支持运算符:+, -, *, /, ** (乘方), ()。 支持函数:sin, cos, tan, log (以10为底), ln (自然对数), sqrt。 支持常数:π (pi)。 示例输入:"2 * (3 + 5)", "sin(π/2)", "sqrt(16)"。""")现在,你的第一个 Skill——计算器就创建好了!它已经可以被智能体调用了。
4. 创建第二个 Skill:网络搜索
智能体经常需要获取最新信息。我们使用DuckDuckGoSearchRun来创建一个搜索技能。
4.1 安装搜索依赖并创建工具
pipinstallduckduckgo-search# skills/search_tool.pyfromlangchain.toolsimportDuckDuckGoSearchRun search_tool=DuckDuckGoSearchRun(name="WebSearch",description="""在互联网上搜索最新信息。当你需要回答关于实时事件、新闻、最新数据或未知领域的问题时,请使用此工具。 输入应为明确的搜索查询词。""")5. 组装智能体并测试技能
有了技能(Tool)之后,我们需要创建一个智能体,并把这些技能“装配”给它。
5.1 初始化 LLM 和工具列表
# agent/assemble_agent.pyfromlangchain_openaiimportChatOpenAIfromskills.calculator_toolimportcalculator_toolfromskills.search_toolimportsearch_toolimportconfig# 1. 初始化 LLM(智能体的大脑)llm=ChatOpenAI(model="gpt-4o-mini",# 或 "gpt-3.5-turbo"openai_api_key=config.OPENAI_API_KEY,temperature=0# 降低随机性,使输出更确定)# 2. 组装工具列表tools=[calculator_tool,search_tool]5.2 创建并运行智能体
LangChain 提供了高级的create_react_agent来快速构建一个能使用工具的智能体。
# agent/run_agent.pyfromlangchainimporthubfromlangchain.agentsimportcreate_react_agent,AgentExecutorfromagent.assemble_agentimportllm,tools# 3. 拉取一个预设的 ReAct 提示词模板prompt=hub.pull("hwchase17/react")# 4. 创建智能体agent=create_react_agent(llm,tools,prompt)# 5. 创建执行器agent_executor=AgentExecutor(agent=agent,tools=tools,verbose=True,# 打印详细的思考过程,便于调试handle_parsing_errors=True# 优雅处理解析错误)# 6. 运行测试!if__name__=="__main__":# 测试计算技能result1=agent_executor.invoke({"input":"请计算 15 的平方加上 20 除以 4 等于多少?"})print("\n--- 测试1 结果 ---")print(result1["output"])# 测试搜索技能result2=agent_executor.invoke({"input":"今天北京天气怎么样?"})print("\n--- 测试2 结果 ---")print(result2["output"])# 测试组合技能(需要推理和计算)result3=agent_executor.invoke({"input":"搜索一下欧元对人民币的最新汇率,然后计算100欧元能换多少人民币?"})print("\n--- 测试3 结果 ---")print(result3["output"])运行python agent/run_agent.py,你将看到智能体一步步思考(因为verbose=True),决定调用哪个工具,并最终给出答案。
6. 进阶:创建自定义复杂 Skill(天气预报)
让我们创建一个更复杂、更实用的 Skill:通过调用公开 API 获取天气预报。
6.1 定义天气 Skill 函数
这里我们使用open-meteo.com的免费 API。
# skills/weather_skill.pyimportrequestsimportjsonfromtypingimportDict,Anydefget_weather(city:str)->str:""" 根据城市名获取当前天气情况。 Args: city (str): 城市名称,如 "北京", "Shanghai" Returns: str: 格式化后的天气信息字符串 """# 第一步:将城市名转换为经纬度(使用地理编码API)geocode_url=f"https://geocoding-api.open-meteo.com/v1/search?name={city}&count=1"try:geo_response=requests.get(geocode_url,timeout=10)geo_data=geo_response.json()ifnotgeo_data.get("results"):returnf"错误:未找到城市 '{city}' 的地理信息。"location=geo_data["results"][0]latitude=location["latitude"]longitude=location["longitude"]city_name=location["name"]# 第二步:用经纬度获取天气weather_url=(f"https://api.open-meteo.com/v1/forecast?"f"latitude={latitude}&longitude={longitude}"f"¤t_weather=true")weather_response=requests.get(weather_url,timeout=10)weather_data=weather_response.json()current=weather_data["current_weather"]temperature=current["temperature"]wind_speed=current["windspeed"]weather_code=current["weathercode"]# 将天气代码转换为描述(简化版)weather_desc=_decode_weather_code(weather_code)return(f"{city_name}当前天气:\n"f"- 温度:{temperature}°C\n"f"- 天气状况:{weather_desc}\n"f"- 风速:{wind_speed}km/h")exceptrequests.exceptions.RequestExceptionase:returnf"网络请求错误:{e}"except(KeyError,json.JSONDecodeError)ase:returnf"解析API响应时出错:{e}"def_decode_weather_code(code:int)->str:"""将 WMO 天气代码转换为描述性文字。"""weather_map={0:"晴朗",1:"大部分晴朗",2:"局部多云",3:"多云",45:"有雾",48:"有雾",51:"小雨",61:"雨",80:"阵雨",95:"雷暴",}returnweather_map.get(code,"未知")6.2 包装为 Tool 并更新智能体
# skills/weather_tool.pyfromlangchain.toolsimportToolfrom.weather_skillimportget_weather weather_tool=Tool(name="GetWeather",func=get_weather,description="获取指定城市的当前天气情况。输入应为城市名称,例如 '北京' 或 'New York'。")更新你的assemble_agent.py,将weather_tool加入工具列表:
# agent/assemble_agent.py (更新后)fromlangchain_openaiimportChatOpenAIfromskills.calculator_toolimportcalculator_toolfromskills.search_toolimportsearch_toolfromskills.weather_toolimportweather_tool# 新增importconfig llm=ChatOpenAI(model="gpt-4o-mini",openai_api_key=config.OPENAI_API_KEY,temperature=0)# 现在有三个技能了!tools=[calculator_tool,search_tool,weather_tool]再次运行智能体,试试问它:“上海和北京的天气哪个更暖和?”
7. 技能组合与工作流设计
真正的威力在于技能的组合。智能体可以自主决定调用多个技能来完成复杂任务。
7.1 示例:旅行规划助手
假设用户问:“我计划下周末去杭州旅行,帮我查一下杭州的天气,并计算一下如果酒店每晚500元,住3晚需要多少钱?”
智能体的思考链(ReAct)会是:
- Thought: 用户需要两个信息:杭州天气和住宿费用。我需要先获取天气,再计算费用。
- Action: 调用
GetWeather,输入“杭州”。 - Observation: 获得杭州天气结果。
- Thought: 现在需要计算住宿费用:500元/晚 * 3晚。
- Action: 调用
Calculator,输入“500 * 3”。 - Observation: 获得计算结果1500。
- Thought: 我已经获得了所有信息,可以组织最终答案了。
- Final Answer: 给出包含天气和费用的完整回答。
你不需要手动编写这个流程,create_react_agent和 LLM 会协作自动完成。
8. 调试与最佳实践
8.1 处理错误
- 解析错误:设置
handle_parsing_errors=True。 - 工具错误:在你的 Skill 函数内部做好异常捕获,返回友好的错误信息。
- 超时:为网络请求设置合理的
timeout。
8.2 编写清晰的工具描述
description字段至关重要,它是 LLM 决定是否以及如何调用该工具的主要依据。描述应:
- 明确工具的用途和边界。
- 说明输入格式和示例。
- 指出何时使用(和何时不使用)。
8.3 项目结构建议
保持清晰的代码结构有利于维护:
agent-skills-tutorial/ ├── .env ├── config.py ├── skills/ # 存放所有技能 │ ├── __init__.py │ ├── calculator_skill.py │ ├── calculator_tool.py │ ├── search_tool.py │ ├── weather_skill.py │ └── weather_tool.py ├── agent/ # 智能体组装与运行 │ ├── __init__.py │ ├── assemble_agent.py │ └── run_agent.py └── README.md9. 下一步:扩展你的技能库
你已经掌握了创建和使用 Agent Skills 的核心流程。可以尝试创建更多技能:
- 数据库查询技能:连接 MySQL/PostgreSQL,执行 SQL。
- 文件操作技能:读写本地文件,总结 PDF/Word 内容。
- 邮件发送技能:通过 SMTP 发送邮件。
- 专属 API 技能:连接你的企业内部系统。
记住原则:一个技能,一个职责。保持简单和专注,你的智能体就会越来越强大。
10. 完整代码仓库
本教程的所有代码已整理在一个 GitHub 仓库中,你可以直接克隆并运行:git clone https://github.com/your-username/agent-skills-tutorial.git
(注:请将仓库地址替换为你自己的。仓库中应包含.env.example文件供参考。)
希望这篇“傻瓜式”教程能帮你顺利入门 Agent Skills 的世界。动手修改代码、添加新技能,是学习的最佳方式。祝你构建出功能强大的智能体!
