news 2026/9/8 3:15:12

Agent Skills实战:从工具调用到本地部署的可复用技能封装指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agent Skills实战:从工具调用到本地部署的可复用技能封装指南

这次我们来看 Agent Skills。它不是某个具体模型,而是吴恩达在 2025 年反复强调的智能体开发方法论:把大模型从“能聊天”变成“能干活”。网上很多人把它总结成一句话:Agent = 大模型 + 记忆 + 规划 + 工具调用,而 Agent Skills 就是里面那组可以被复用、组合、独立部署的“工具模块”。

这个主题最值得关注的点有三个:一是它把复杂的大模型应用拆成了标准化技能,像搭积木一样组合;二是它不挑硬件,CPU 也能玩,有显卡推理更快,很适合本地部署试验;三是它直接和代码实战挂钩,可以用 OpenAI 兼容接口、Ollama 或者常见云厂商 API 快速跑通一个带工具调用的 Agent。

这篇文章会从概念讲起,然后给出一套可落地的本地部署流程:先启动一个本地大模型服务,再写一个支持工具调用的 Agent 代码,封装一个“执行 Python 代码”的 Skill,接着测试接口和批量任务,最后补充性能观察、常见问题排查和最佳实践。

1. Agent Skills 核心能力速览

能力项说明
项目类型AI Agent 开发方法论 / 技能封装范式
来源背景吴恩达在公开课程与博客中强调的 Agent 设计思路,配套多门实战课程
核心能力工具调用、任务规划、反思修正、记忆管理、多智能体协作
推荐硬件CPU 可入门;有 NVIDIA GPU 推理更快
显存需求取决于所选本地模型,常见 7B 量化模型约 8GB 以内显存可跑,实际以部署为准
支持平台Windows、Linux、macOS
启动方式Python 脚本直接运行、Jupyter Notebook、FastAPI 服务、Ollama 后台服务
是否支持 API支持,可通过 OpenAI 兼容接口或自定义 FastAPI 接口调用
是否支持批量任务支持,可用脚本循环处理输入目录中的多个文件
适合场景代码生成后自动执行、文档批量处理、检索问答、报表生成、测试自动化

从材料看,Agent Skills 的最大优势不是某个功能的实现,而是它的“可组合性”。你可以把一个 Skill 单独写好,然后在不同 Agent 工作流里复用,不需要每次重新训练模型。

2. Agent Skills 是什么:从提示词到可复用技能

2.1 从 Prompt 到 Agent

传统大模型用法是写一段提示词,模型输出一段文字。这种方式适合问答,但不适合“干活”。因为干活通常需要查数据库、执行代码、调用外部 API、读取文件、定时轮询等能力,而这些是模型本身做不了的。

Agent 的出现就是为了解决这个问题。Agent 是一个有“感知-决策-行动”闭环的系统:它接收用户任务,调用大模型做推理和规划,然后通过 Skill 去执行具体动作,再把执行结果反馈给模型,决定下一步做什么。

这里的关键区别是:Prompt 是一次性输入,Agent 是循环过程;Prompt 是文本模板,Agent 是可运行的程序。

2.2 Agent Skills 与 Function Calling 的关系

Agent Skills 在工程上的核心实现方式之一,就是 Function Calling,也就是工具调用。开发者把每个 Skill 定义成一个函数,同时把这个函数的名称、参数结构的 JSON Schema 提供给大模型。模型生成回复时,不再只是输出文本,而是可以输出一个“调用指令”:我应该调用 execute_python,参数是 某个代码字符串。

这个机制让模型拥有了“外部手脚”。常见的 Agent Skill 包括:

Skill 名称职责典型用途
代码执行器运行 Python 代码并返回结果数据分析、爬虫、脚本测试
文档检索器从本地文档库中搜索相关内容知识库问答、合同审查
数据查询器查询数据库或表格报表生成、业务分析
HTTP 请求器调用外部 API天气查询、订单查询、消息发送
文件操作器读写本地文件批量处理、格式转换
反思修正器检查上一轮输出并修正错误代码调试、内容审核

每一种 Skill 都是一个小模块,可以单独测试,也可以组合使用。

2.3 四种典型设计模式

吴恩达在公开演讲中多次介绍过 Agent 的几种设计模式,这套思路也可以直接套用到 Agent Skills 的工程实现上:

  • 直接输出模式:模型一步生成最终结果,适合简单任务。
  • 工具调用模式:模型根据用户请求调用一个或多个 Skill,这是 Agent 的核心模式。
  • 反思模式:模型先生成结果,再自己检查、指出问题并修正,适合代码生成和写作。
  • 规划模式:模型先把大任务拆成子任务,再逐个执行,适合复杂流程。

实际开发时,这几种模式经常混用:先规划,再调用工具,再做一次反思修正。Skill 就是这些模式里的“执行单元”。

3. 适用场景与使用边界

3.1 适合谁用

Agent Skills 适合以下几类人:

  • 想给 ChatGPT 类应用加“动手能力”的开发者;
  • 需要把内部知识库、数据库、脚本能力接入大模型的工程师;
  • 刚接触大模型应用开发、想从提示词工程进阶到 Agent 开发的初学者;
  • 需要批量处理文档、代码、数据的运维和测试人员。

3.2 能解决什么问题

最直接的收益是省掉重复劳动。以前你要写一个固定流程脚本,现在可以写一个 Agent Skill,让大模型根据用户输入动态决定要不要调用它。比如“帮我统计数据并画图”这个任务,模型可以先调用数据查询器拿数据,再调用代码执行器画图,最后返回一张图和一个解释文本,全流程不需要人手工切换工具。

3.3 使用边界与合规提醒

  • Agent 会随意外呼接口、执行代码,所以在公网环境部署时必须做权限控制,比如限制请求来源、增加 API Key、使用内网隔离。
  • 代码执行类 Skill 不要直接运行不可信代码,否则可能造成系统破坏或数据泄露。
  • 涉及人脸、声音、版权素材、个人隐私数据时,必须确认数据来源和授权范围。
  • Agent 输出结果不代表事实正确,商用前要做人工复核。

4. Agent Skills 本地部署环境准备

4.1 环境清单

开始之前,先确认本机环境:

  • 操作系统:Windows 10/11、Ubuntu 20.04+ 或 macOS 12+。
  • Python 版本:建议 3.10 或 3.11。
  • Node.js:可选,部分 Agent 框架会用到。
  • 包管理工具:pip 和 conda 二选一。
  • 模型推理服务:推荐 Ollama,也可以使用 vLLM 或 LM Studio。
  • GPU 环境:如果使用 NVIDIA 显卡,建议安装新版驱动和 CUDA 工具包;如果不装 GPU,模型会走 CPU,推理速度会慢一些。

4.2 安装 Python 依赖

创建一个项目目录,并在其中创建虚拟环境:

mkdir agent-skills-demo cd agent-skills-demo python -m venv venv # Windows 激活 venv\Scripts\activate # Linux / macOS 激活 source venv/bin/activate

安装核心依赖:

pip install openai ollama fastapi uvicorn ipython requests

这里解释一下各个依赖的用途:

  • openai:Python SDK,用于调用 OpenAI 兼容接口,包括 Ollama 的本地接口。
  • ollama:Python 客户端,也可以直接调用 Ollama 的本地服务。
  • fastapiuvicorn:用来把 Skill 封装成 HTTP 服务。
  • jupyter:用来做实验调试,方便看到每一步的中间结果。

4.3 磁盘与端口规划

本地大模型文件通常有几个 GB,建议预留至少 30GB 磁盘空间,避免下载到一半空间不足。Ollama 默认端口是11434,FastAPI 服务可以自定义端口,比如8000。如果端口被占用,启动时会报错,后面常见问题部分会展开说。

5. 把本地大模型跑起来:Ollama 快速启动

5.1 安装并拉起服务

Ollama 是当前最简单的本地大模型运行方式,安装后直接在终端执行:

ollama pull qwen2.5:7b ollama serve

pull会下载模型文件,不同标签和版本所需空间不同,具体以 Ollama 官方仓库为准。serve启动后,Ollama 会在本地提供 API 服务。

5.2 用 curl 验证接口

服务启动后,用 curl 发一个测试请求:

curl http://127.0.0.1:11434/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen2.5:7b", "messages": [ {"role": "user", "content": "你好,请做一个自我介绍"} ] }'

注意,这里api_key可以随便填,因为 Ollama 本地服务默认不做鉴权。如果接口能正常返回结果,说明本地模型服务已经跑通。

5.3 没有 GPU 怎么办

没有 GPU 时,Ollama 会默认使用 CPU 推理,可以工作,但速度会慢。建议优先选择 1.5B 或 3B 的小模型做功能验证,跑通后再切换更大的模型。显存占用需要结合量化方式和上下文长度判断,通常来说模型越小、上下文越短,占用越低。

6. 代码实战:写一个支持工具调用的 Agent Skill

6.1 定义 Skill 函数

这里我们做一个实际可跑的 Skill:execute_python,它负责接收一段 Python 代码并执行,把标准输出和返回值返回给 Agent。

import io import sys import contextlib def execute_python(code: str) -> str: """执行一段 Python 代码,返回标准输出和返回值。""" output = io.StringIO() error = io.StringIO() result = None try: with contextlib.redirect_stdout(output), contextlib.redirect_stderr(error): exec(code, {"__name__": "__main__"}, {}) except Exception as e: error.write(f"执行出错: {e}") final_result = "" if output.getvalue(): final_result += f"标准输出:\n{output.getvalue()}\n" if error.getvalue(): final_result += f"错误信息:\n{error.getvalue()}\n" return final_result.strip() or "无输出"

这里使用了contextlib.redirect_stdoutredirect_stderr来捕获运行结果。实际生产环境里如果要执行不可信代码,必须放到 Docker 或沙箱容器中,不能直接在宿主机上跑。

6.2 组装 Tool Schema

为了让大模型知道这个 Skill 的存在,需要按照 Function Calling 的格式,把这个函数描述成为 tool:

tools = [ { "type": "function", "function": { "name": "execute_python", "description": "执行一段 Python 代码,适合做计算、数据处理、文件读取等操作。", "parameters": { "type": "object", "properties": { "code": { "type": "string", "description": "要执行的 Python 代码" } }, "required": ["code"] } } } ]

这段 JSON 是模型和程序之间的“接口契约”。模型看到这段描述后,如果判断任务需要执行代码,就会返回一个 tool_calls 调用请求。

6.3 实现 Agent 主循环

现在编写核心的 Agent 消息循环。基本流程是:

  1. 把用户消息加入 messages。
  2. 请求大模型,传入 tools。
  3. 如果模型返回 tool_calls,就执行对应 Skill,把结果加入 messages。
  4. 再次请求大模型,直到模型不再返回 tool_calls。
from openai import OpenAI client = OpenAI( base_url="http://127.0.0.1:11434/v1", api_key="ollama", ) def run_agent(user_prompt: str, max_iterations: int = 5) -> str: messages = [{"role": "user", "content": user_prompt}] for step in range(max_iterations): response = client.chat.completions.create( model="qwen2.5:7b", messages=messages, tools=tools, temperature=0.2, ) message = response.choices[0].message # 如果没有工具调用请求,说明模型已经给出最终答案 if not message.tool_calls: return message.content # 把模型发出的工具调用请求加入历史 messages.append(message.model_dump()) # 逐个执行工具调用 for tool_call in message.tool_calls: if tool_call.function.name == "execute_python": args = tool_call.function.arguments # 注意:arguments 是 JSON 字符串,需要解析 import json code = json.loads(args)["code"] tool_result = execute_python(code) messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": tool_result, }) return "达到最大迭代次数,任务结束。"

这个主循环是最小可用的 Agent 原型。max_iterations很重要,不加限制的话,模型可能会陷入“执行-出错-再执行”的死循环。

6.4 运行效果验证

写一个 test 脚本调用上面的run_agent

if __name__ == "__main__": result = run_agent("请计算 1 加到 100 的结果,并给出代码。") print(result)

跑起来之后,你会看到 Agent 的输出。如果配置正确,本地模型会先返回一个 tool_calls 调用请求,主循环执行代码后把结果返回给模型,模型再基于执行结果给出最终回答。判断成功的标准是输出里包含“5050”这个结果,而不只是模型“猜”出一个答案。

如果失败,最常见的情况是本地模型不支持工具调用,或者 Qwen 模型在 Ollama 中的工具调用支持不完整。可以换一个更大的模型,或者把 prompt 改成“请用少量代码计算 1 到 100 的和”,让模型直接输出代码,再手动执行。

7. 接口 API 与批量任务实战

7.1 把 Skill 封装成 FastAPI 服务

除了在 Python 脚本里直接调用,还可以把 Skill 封装成 HTTP 接口,方便给前端、定时任务或第三方工具调用。

先创建一个skill_server.py文件:

from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class ExecuteRequest(BaseModel): code: str @app.post("/v1/skills/execute_python") def execute_python_api(req: ExecuteRequest): result = execute_python(req.code) return { "status": "ok", "output": result } if __name__ == "__main__": import uvicorn uvicorn.run(app, host="127.0.0.1", port=8000)

启动服务:

uvicorn skill_server:app --host 127.0.0.1 --port 8000

然后用 curl 测试接口:

curl -X POST http://127.0.0.1:8000/v1/skills/execute_python \ -H "Content-Type: application/json" \ -d '{"code": "print(21 * 2)"}'

如果返回结果里有42,说明接口已经跑通。这个接口可以被外部 Agent 编排系统调用,也可以在前端页面直接请求。

7.2 批量任务设计

批量任务是 Agent Skills 比较实用的场景。这里演示一个最常用的批量处理流程:遍历输入目录中的所有.txt文件,让 Agent 对每个文件做摘录总结,然后保存到输出目录。

import os from pathlib import Path INPUT_DIR = "./inputs" OUTPUT_DIR = "./outputs" os.makedirs(OUTPUT_DIR, exist_ok=True) def summarize_text(text: str) -> str: prompt = f"请用 3 句话总结下面的文本:\n\n{text}" return run_agent(prompt) for file_path in Path(INPUT_DIR).glob("*.txt"): text = file_path.read_text(encoding="utf-8") summary = summarize_text(text) output_file = Path(OUTPUT_DIR) / f"{file_path.stem}_summary.txt" output_file.write_text(summary, encoding="utf-8") print(f"已完成: {file_path.name}")

批量任务有几个注意点:

  • 给每个文件加上超时控制,避免某个文件耗时过长导致整个脚本卡住。
  • 记录日志和已处理列表,中途失败后可以跳过已完成文件,继续重跑。
  • 控制并发数,不要一次性开几十个线程请求本地模型,否则显存或 CPU 会被打满。

7.3 增加失败重试

在批量场景下,网络抖动或模型输出异常都可能出现。一个简单可靠的模式是加重试装饰器:

import time from functools import wraps def retry(max_retries: int = 3, delay: float = 2.0): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): for attempt in range(max_retries): try: return func(*args, **kwargs) except Exception as e: print(f"第 {attempt + 1} 次调用失败: {e}") if attempt == max_retries - 1: raise time.sleep(delay) return wrapper return decorator @retry(max_retries=3, delay=1.0) def call_agent_once(prompt: str) -> str: return run_agent(prompt)

不要一开始就把重试次数设得很大,否则批量任务会卡在坏数据上。推荐先重试 2 到 3 次,失败的任务单独记录到一个failed.txt清单,最后统一排查。

8. 资源占用与性能观察

8.1 观察工具

本地跑 Agent 时,重点观察两个指标:内存/显存占用和单次请求耗时。

  • 终端里可以用nvidia-smi查看 GPU 显存和利用率;如果没有 GPU,用系统任务管理器看内存和 CPU。
  • Ollama 提供ollama ps命令,可以直接看到当前加载了哪些模型、显存占用情况。
  • 在代码里可以给请求加计时,把每次调用的耗时记录下来。
ollama ps

如果发现显存占用一直很高,可以卸载不用的模型,或者在 Ollama 配置里限制并发请求数。

8.2 影响性能的因素

从实战经验看,下面几个因素对性能影响最大:

  • 模型大小:7B 模型比 1.5B 模型慢很多,显存占用也更高。
  • 上下文长度:messages 里历史消息越长,推理越慢。
  • 工具调用轮数:每次函数执行后都要再请求一次模型,环节越多耗时越长。
  • 输出长度:max_tokens越大,单次生成时间越长。
  • 并发数:多个线程同时请求时,如果显存不足,会出现排队或报错。

建议第一次先用小模型、短上下文、并发数为 1 的场景跑通整个链路,再逐步增加复杂度。

9. Agent Skills 常见问题与排查方法

问题现象可能原因排查方式解决方案
Ollama 服务启动后接口无法访问端口被占用或服务未启动查看终端日志,执行 `netstat -anofindstr 11434`
模型下载慢或失败网络问题或模型文件过大检查网络连通性,查看磁盘剩余空间先下载小模型如qwen2.5:1.5b,或检查镜像源
Agent 不返回工具调用本地模型不支持 Function Calling打印 model 层原始返回,查看tool_calls字段换用更大模型,或降低模型版本要求
工具调用参数解析失败arguments不是合法 JSON打印tool_call.function.arguments原生内容使用json.loads前先做字符串清洗
Agent 陷入无限循环缺少最大迭代限制检查主循环里max_iterations参数增加迭代上限,超限后返回当前结果
中文输出被截断max_tokens设置过小检查返回的finish_reason是否为length调大max_tokens
批量任务中途卡住单条数据超时或模型响应慢在调用处加日志,记录当前处理文件增加超时控制,把失败任务单独记录
服务端口一直报占用错误上一次进程没有正常退出查看进程列表,确认端口对应的 PID杀掉残留进程或换个新端口

10. 最佳实践与安全边界

10.1 工程规范

第一次上手工装 Agent Skills 的时候,建议先建立一套最小可运行模板,统一管理模型配置和 Skill 注册表。比如可以在一个skills.py文件里维护所有 Skill 函数和对应的工具描述,不要散落在不同 Notebook 里,这样后面加新 Skill 只需要改一处。

批量任务要加日志和失败重试,不要让脚本“静默失败”。每个任务处理前打印输入文件路径、开始时间和结束时间;失败时把异常信息写入单独日志文件。否则大批量处理完成后,很难判断哪些文件成功、哪些被跳过了。

10.2 权限与风险控制

Agent Skill 有执行能力,所以权限控制不能偷懒:

  • 代码执行 Skill 必须做沙箱隔离,至少使用 Docker 容器运行,避免在宿主机上直接执行任意代码。
  • HTTP 请求 Skill 要限制目标地址,不能允许模型任意访问内网 IP,否则可能被用来做内网探测。
  • API 服务不能直接暴露到公网,至少要加 API Key 鉴权,并限制来源 IP。
  • 工具调用的执行结果不能无条件信任,Agent 的“我认为执行成功”不等于真的成功,关键步骤要人工确认。

10.3 数据与版权合规

如果 Agent 要处理文档、图像、音视频等素材,必须先确认素材来源和授权情况。涉及人脸图像、声音克隆、版权文字时,要确保已经获得合法授权,不能随便用抓取的数据做训练或自动化处理。

11. 总结与下一步建议

Agent Skills 最值得尝试的点,是它把大模型从“文本生成器”变成了“任务执行器”。你不需要重新训练模型,只需要把现有能力封装成标准化的 Skill,再通过工具调用机制组合起来,就可以完成很多以前需要写大量脚本才能完成的自动化任务。

上手第一步先别追求复杂,优先验证一件事:本地模型能不能在对话中返回tool_calls。这一步跑通后,后面所有东西都顺了。最容易踩的坑也在这里:很多小模型虽然能聊天,但不一定完整支持 Function Calling,遇到这种情况不要死磕,直接换支持工具调用的模型或版本。

后续可以继续扩展的方向包括:给 Agent 加短期记忆,让它在多个任务间记住上下文;把多个 Skill 编排成完整工作流,实现“规划-执行-反思”的闭环;再把 Skill 服务化部署到内网,接入定时任务或消息队列,做成真正可用的自动化系统。

建议先照着文章里的最小原型跑一遍:Ollama 启动、Agent 主循环、execute_python 工具调用、批量处理脚本。跑通之后,再根据自己的实际场景加业务 Skill,效果比直接啃概念要好得多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 3:15:10

从航母弹射系统之争,看技术选型的可靠性与成本逻辑

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/8 3:15:08

电力标准中的UML实战:从CIM模型到Java与数据库落地

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/8 3:12:42

回溯算法优化实战:从n皇后理解剪枝与位运算

如果让我从刷题生涯里挑一道“看起来很难、想通了其实就那一层窗户纸”的题目,n皇后绝对排得上号。我第一次在刷题网站里看到它的时候,脑子里第一反应是:这不就是八皇后换了个更大的棋盘吗,模拟搜索不就行了?真动手写了…

作者头像 李华
网站建设 2026/9/8 3:11:59

骚扰电话源头:关闭手机这两个开关,切断信息泄露链路

相信很多人都有过这样的经历:白天刚在网上留过一次手机号,晚上就收到自称“物业”、“银行”、“装修公司”的陌生来电;明明只是注册了一个 App,没过几天,对方就能准确说出你的姓氏和模糊住址。更诡异的是,…

作者头像 李华
网站建设 2026/9/8 3:11:52

用OpenCV程序化绘制比赛对阵图:从坐标计算到中文渲染

简介:这是一套结合数据库与OpenCV的比赛对阵图自动生成方案,面向具备一定C基础、希望实践数据可视化和图像处理的开发者。项目围绕比赛信息读取、数据预处理、对阵图绘制与自动化更新展开,覆盖参赛队伍存储、轮次划分、胜负颜色标识等常见场景…

作者头像 李华
网站建设 2026/9/8 3:10:48

GitHub热榜涨星项目深度解析:从API抓取到技术趋势洞察

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华