尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Agent Skills实战:用Python构建可复用的AI技能与API服务

Agent Skills实战:用Python构建可复用的AI技能与API服务 2026年如果你还停留在“写Prompt调用大模型”的状态那基本还停留在Agent浪潮的上一站。现在更值得学的是Agent Skills——把工具、提示词、执行流程打包成可复用的“技能”让智能体自己决定什么时候调用、怎么调用、调用完之后怎么把结果接回主线任务。这次我们直接聊实战Agent Skills是什么、和普通Prompt模板有什么区别、如何用Python从零实现一个最小Skill再把它封装成HTTP服务接入业务系统。这篇不是概念科普而是带你跑通一条完整的代码路线。文章内容会覆盖Agent Skills 的定义、结构和核心思路一套最小可运行的项目代码Skill定义 LLM调用 Agent循环如何把它包装成API服务、处理批量任务开发中的性能观察、常见排错和工程化建议。整个教程的代码都以通用Python工程为模板LLM调用走OpenAI兼容接口。你只需要准备好Python环境和一个可用的模型接口云API或本地模型都行就能跟着跑。1. Agent Skills 核心能力速览能力项说明项目类型AI Agent 开发范式 / 工具封装方案功能定位把提示词、工具函数、执行流程封装成可复用技能开发语言Python 为主运行环境CPU即可开发调试若LLM本地部署需独立显卡LLM 来源云API或本地OpenAI兼容服务核心优势一次开发多次复用Agent 自主决策调用扩展方式新增 Skill 定义 实现函数无需改主循环API 服务可基于 FastAPI / Flask 二次封装批量任务通过目录扫描或队列消费实现适合人群LLM 应用开发者、Agent 框架初学者、自动化流程开发者从材料看这个方向目前已经被多个大模型团队作为官方能力推进。吴恩达的Agent Skills教程发布后相关讨论热度很高。2026年版的学习路径也不再是“看概念”而是“跑代码”。下面我们直接进入开发。2. Agent Skills 和普通提示词模板的本质区别很多初学者会把Agent Skills理解成“一段写好的Prompt”这是最大的误区。普通提示词模板是一个静态文本模型每次拿到它的行为都是一次性推理。比如你写一段“你是翻译助手把用户输入翻译成英文”它只是一个指令没有工具调用能力也没有状态管理。Agent Skills 的差异在于它包含三种元素描述Description告诉Agent“这个技能什么时候用、能做什么”。工具函数Function真正执行的代码比如查数据库、计算文件大小、调用HTTP接口。参数SchemaParameter SchemaLLM调工具时按什么样的结构传参。Agent在执行用户任务时会根据当前对话状态从注册的多个Skill中自主选择是否调用某个技能。这才是“技能”的含义它不是被用户直接触发而是被Agent在推理过程中动态决策触发。用一个例子说明类型做法普通Prompt“你是一个文件整理助手当用户输入文件目录时请列出文件大小。”Agent Skill定义一个list_files(path)函数并写清描述“当需要查看目录文件、检查文件大小或整理文件时调用该技能”Agent根据用户意图自己决定是否调用。后者具备组合能力。你可以定义10个Skill让Agent在对话中连续调用它们完成“读取文件 - 抽取关键信息 - 生成摘要 - 发送通知”这种多步骤任务。这也是2026年版Agent开发最值得掌握的一点** Skill 是可复用的原子能力Agent 是编排执行的控制器。**3. 适用场景与使用边界3.1 适合解决什么问题企业内部知识库问答把“文档检索”“数据库查询”“权限验证”分别做成SkillAgent按需调用。自动化办公生成周报、整理Excel、批量发邮件每个能力封装成Skill。代码生成与代码执行Skill调用代码解释器Agent验证代码结果。内容生产流程调用搜索、抓取网页、生成图片、排版发布。个人助理把定时任务、天气查询、日程管理全部封装成稳定技能。3.2 不适合什么场景单轮简单问答直接调用模型接口就够了不需要引入Agent和Skill。需要绝对确定性的流程Agent的决策有随机性如果是银行核心交易、医疗诊断等场景建议用传统工作流做强制流程控制。超大上下文单次推理Skill是为多步骤组合设计的如果所有逻辑都在一次性Prompt内完成就不需要它。3.3 使用边界与合规提醒开发Agent Skills时有一点必须说在前面如果Skill需要访问用户文件、数据库、私人信息必须获得用户授权并且设置最小权限。如果Skill用于生成人脸、声音、文案等必须确保素材版权合规。对外提供API服务时要加鉴权避免被滥用。批量调用模型服务时要注意模型服务的并发限制和内容安全政策。4. 环境准备与前置条件开发Agent Skills不需要很重的硬件。核心开发过程是写Python代码调试时调用一个LLM服务即可。4.1 推荐环境清单环境项推荐配置说明操作系统Windows 10/11、macOS、Linux均可Python版本3.10代码用到typing和dataclass包管理pip / uv / conda任意一种LLM服务OpenAI兼容API也可以是本地vLLM / Ollama等网络能访问LLM服务即可本地部署则无需公网磁盘空间代码不到10MB若本地模型则需几十GB以上如果你用本地大模型建议显存至少覆盖你要加载的模型体积。7B量化模型大约需要6GB以上显存实测必须以本机为准。如果只是学Skill机制用云API最省事。4.2 创建项目目录mkdir agent-skills-demo cd agent-skills-demo mkdir skills mkdir data mkdir outputs目录规划skills/存放Skill定义和实现代码data/放测试文件outputs/放结果文件。4.3 安装依赖pip install openai python-dotenv fastapi uvicorn我们使用openai调用LLM接口python-dotenv管理环境变量fastapiuvicorn把Agent封装成HTTP服务。5. 从零实现一个最小 Agent Skills 系统下面我们实现一套最精简但结构完整的系统总共四个核心文件。5.1 定义 Skill 数据结构文件skill_base.pyfrom dataclasses import dataclass, field from typing import Callable, Any dataclass class Skill: name: str description: str parameters: dict func: Callable[..., Any] examples: list field(default_factorylist) def to_tool_json(self) - dict: 转换成LLM函数调用格式 return { type: function, function: { name: self.name, description: self.description, parameters: self.parameters, } }5.2 编写两个示例 Skill文件skills/basic_skills.pyimport os import json import hashlib from typing import List def list_file_sizes(path: str .) - str: 列出指定目录下所有文件的大小 results [] for name in os.listdir(path): full_path os.path.join(path, name) if os.path.isfile(full_path): size os.path.getsize(full_path) results.append({file: name, size_bytes: size}) return json.dumps(results, ensure_asciiFalse, indent2) def compute_text_hash(text: str) - str: 计算文本的MD5哈希值 return hashlib.md5(text.encode(utf-8)).hexdigest() def get_file_skills() - List[Skill]: file_skill Skill( namelist_file_sizes, description当用户需要查看某个目录下的文件列表、检查文件大小、统计目录占用时需要调用这个技能。, parameters{ type: object, properties: { path: {type: string, description: 要列出的目录路径} }, required: [path] }, funclist_file_sizes, examples[帮我看看当前目录下有哪些文件各占多少空间] ) hash_skill Skill( namecompute_text_hash, description当用户需要对一段文本计算MD5哈希值时调用这个技能。, parameters{ type: object, properties: { text: {type: string, description: 要计算哈希的文本} }, required: [text] }, funccompute_text_hash, examples[帮我给 hello world 算一下MD5。] ) return [file_skill, hash_skill]5.3 实现 Agent 主循环这是核心部分。Agent做的事情是接收用户消息把所有Skill描述发给LLMLLM决定是否调用Skill并返回结构化参数我们执行Skill函数把结果返回给LLMLLM根据执行结果生成最终回复。文件agent.pyimport json from typing import List, Optional from openai import OpenAI from skill_base import Skill from skills.basic_skills import get_file_skills class SimpleAgent: def __init__(self, model: str gpt-4o-mini, base_url: Optional[str] None): self.client OpenAI(base_urlbase_url) if base_url else OpenAI() self.model model self.skills: dict[str, Skill] {} def register_skill(self, skill: Skill): self.skills[skill.name] skill def register_skills(self, skill_list: List[Skill]): for skill in skill_list: self.register_skill(skill) def _build_tools(self) - list: return [skill.to_tool_json() for skill in self.skills.values()] def run(self, user_message: str, max_steps: int 5, verbose: bool True) - str: messages [ { role: system, content: 你是一个智能助手。你可以使用工具来完成任务。 如果你需要调用工具请按函数调用格式返回。 }, {role: user, content: user_message} ] for step in range(max_steps): response self.client.chat.completions.create( modelself.model, messagesmessages, toolsself._build_tools(), tool_choiceauto ) message response.choices[0].message if verbose: print(f[Step {step 1}] 模型回复: {message.content}) if message.tool_calls: for tool_call in message.tool_calls: print(f 调用技能: {tool_call.function.name}) if not message.tool_calls: return message.content or messages.append(message) for tool_call in message.tool_calls: skill_name tool_call.function.name arguments json.loads(tool_call.function.arguments) skill self.skills.get(skill_name) if not skill: result f错误: 技能 {skill_name} 不存在 else: try: result skill.func(**arguments) except Exception as e: result f技能执行出错: {str(e)} messages.append({ role: tool, tool_call_id: tool_call.id, content: str(result) }) return 已达到最大执行步数任务未完成。 if __name__ __main__: agent SimpleAgent() agent.register_skills(get_file_skills()) response agent.run(帮我看看当前目录下有哪些文件各占多少空间) print(\n最终回复) print(response)5.4 运行测试python agent.py如果一切正常你会看到类似这样的流程输出[Step 1] 模型回复: None 调用技能: list_file_sizes [Step 2] 模型回复: 当前目录下的文件如下 - skill_base.py: 2215 字节 - agent.py: 3451 字节 ...这里你可以非常直观地看到Agent的决策路径LLM判断“用户想了解文件大小”于是调用list_file_sizes技能拿到结果后组织成自然语言回答。如果模型输出不稳定可以在消息中加入Skill的examples作为少样本示例提高调用准确率。6. 扩展更多技能让 Agent 处理复合任务上面的两个技能都偏向“查询型”。在实际开发中Agent Skills 更常见的用法是组合型任务。举例我们增加一个write_file技能让Agent具备“查看文件 - 提取信息 - 写入汇总文件”的能力。新增代码到skills/basic_skills.pydef write_text_file(filename: str, content: str) - str: 把内容写入指定文件 if not filename.endswith(.txt): filename .txt with open(filename, w, encodingutf-8) as f: f.write(content) return f文件已写入: {filename} write_skill Skill( namewrite_text_file, description当用户需要把文本内容保存为一个文件时调用这个技能。, parameters{ type: object, properties: { filename: {type: string, description: 目标文件名}, content: {type: string, description: 要保存的文本内容} }, required: [filename, content] }, funcwrite_text_file, )然后注册进Agentagent.register_skill(write_skill)测试输入帮我统计一下当前目录里所有Python文件的大小然后把统计结果写入 output.txt。Agent 会先调用list_file_sizes再调用write_text_file。两个技能之间不需要你写任何额外代码LLM会自动完成参数传递。这正是Agent Skills最核心的价值。7. 将 Agent Skills 封装为 API 服务在真实项目中Agent不会只在命令行里运行而是要给其他系统调用。我们使用 FastAPI 封装一个标准接口。文件api_server.pyfrom fastapi import FastAPI from pydantic import BaseModel from agent import SimpleAgent from skills.basic_skills import get_file_skills app FastAPI(titleAgent Skills Demo API) agent SimpleAgent() agent.register_skills(get_file_skills()) session_memory {} class ChatRequest(BaseModel): message: str session_id: str default app.post(/chat) def chat(req: ChatRequest): if req.session_id not in session_memory: session_memory[req.session_id] [] session_memory[req.session_id].append({role: user, content: req.message}) reply agent.run(req.message) session_memory[req.session_id].append({role: assistant, content: reply}) return { session_id: req.session_id, reply: reply } app.get(/skills) def list_skills(): return {skills: list(agent.skills.keys())} if __name__ __main__: import uvicorn uvicorn.run(app, host0.0.0.0, port8000)启动API服务python api_server.py然后另开一个终端测试curl -X POST http://127.0.0.1:8000/chat \ -H Content-Type: application/json \ -d {message: 帮我看看当前目录下有哪些文件, session_id: test1}返回结果{ session_id: test1, reply: 当前目录下的文件包括agent.py、skill_base.py、api_server.py ... }这个接口可以轻松接进企业微信机器人、Web应用、自动化脚本等。如果要做批量任务只需循环调用/chat接口。比如import requests tasks [ 统计data目录下所有文件大小, 计算文本 Hello 的MD5, ] for task in tasks: resp requests.post(http://127.0.0.1:8000/chat, json{ message: task, session_id: fbatch-{task[:5]} }) print(resp.json()[reply])8. 资源占用与性能观察8.1 观察哪些指标Agent Skills 系统的性能瓶颈通常不在代码本身而在LLM推理延迟每轮对话至少一次模型请求多技能组合需要两到三次请求。Token消耗工具描述和工具返回结果都会占用上下文。状态大小对话历史越长Token成本越高。8.2 如何设计实验观察先用简单任务记录一次调用的总耗时和Token消耗。增加一个需要两次技能调用的复合任务对比耗时和Token增长。检查工具返回内容是否过大比如list_file_sizes返回所有文件信息在大目录下会产生大量Token。8.3 优化手段给Tool返回结果做截断超过一定长度只保留摘要。对话历史做滑动窗口只保留最近若干轮。技能描述写精简减少每轮请求的固定Token开销。多次技能调用之间使用tool_choice: none强制结束避免Agent反复调用。9. 常见问题与排查方法问题现象可能原因排查方式解决方案模型不调用任何技能Skill描述不够具体或参数Schema错误对比当前模型支持的tool格式优化description补全examples技能调用时参数缺失LLM没有按Schema生成参数查看完整LLM返回简化参数数量必填参数写清楚技能执行报错函数内部没有做类型校验在func内打印传入参数增加try/except和参数默认值上下文越来越大工具返回值太大或历史未裁剪打印messages长度和Token数对工具返回做截断裁剪历史API调用超时模型响应慢或网络问题设置timeout参数调大timeout增加重试并发请求互相干扰全局Agent实例共享状态检查是否有共享变量每次请求创建Agent或用session隔离批量任务卡住部分任务触发死循环设置max_steps上限增加step超时和条件判断一个大坑是很多模型对工具描述非常敏感。如果你写的描述是“列出文件大小”模型可能不知道该在什么场景调用如果写成“当用户询问任何与文件信息、目录内容、磁盘占用有关的问题时调用”调用准确率会明显提升。10. 工程化最佳实践开发Agent Skills不能只停留在Demo阶段真正接入业务系统需要注意以下几点。10.1 Skill 目录设计建议每个Skill保持单一职责skills/ file_operations/ __init__.py list_files.py write_files.py move_files.py text_processing/ __init__.py summarize.py translate.py web_tools/ __init__.py fetch_url.py10.2 增加执行日志每个Skill调用都应该记录调用时间输入参数返回结果长度是否成功。这样能快速定位是LLM决策错误还是Skill代码错误。10.3 设置权限边界如果Skill要执行系统命令或写文件务必限定可操作目录避免Agent因为误导性Prompt产生危险操作。例如allowed_root /path/to/sandbox def safe_path(path): real_path os.path.realpath(path) if not real_path.startswith(allowed_root): raise PermissionError(路径越界) return real_path10.4 成本控制为每轮对话设置Token预算超过预算自动终止。调用LLM前先过滤掉当前任务用不到的Skill减少上下文负载。10.5 数据合规如果用Agent Skills处理用户上传的文件、图片或音视频要明确告知用户用途并在任务结束后按策略删除临时数据。批量生成、批量处理的内容发布前必须人工复核。11. 总结与下一步Agent Skills值得最先验证的功能是“多技能组合调用”。先做一个包含文件操作和文本处理的最小系统让Agent自动完成“读取文件-抽取内容-保存结果”的全流程。跑通之后你就能体会到它和普通Prompt模板的本质区别你不再写死执行步骤而是交给Agent动态编排。最容易踩的坑有两个一个是Skill描述写得含糊导致模型不调用或乱调用另一个是忘记裁剪上下文导致长会话后Token成本飙升。开发阶段就先把日志和控制参数加上能省掉大量排查时间。下一步你可以尝试的方向接入更多数据源数据库查询、对象存储、HTTP API。增加多轮记忆用向量库保存历史任务状态。把Skill发布成独立微服务多个Agent共享同一组技能。引入人工审核机制Agent执行关键操作前需要审批确认。这篇的代码已经能构成一个最小可运行框架直接拿去做二次开发也够用。建议先跑通单技能再加组合任务最后再考虑接入业务系统。
返回列表