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

资讯详情

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

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

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这里解释一下各个依赖的用途openaiPython SDK用于调用 OpenAI 兼容接口包括 Ollama 的本地接口。ollamaPython 客户端也可以直接调用 Ollama 的本地服务。fastapi和uvicorn用来把 Skill 封装成 HTTP 服务。jupyter用来做实验调试方便看到每一步的中间结果。4.3 磁盘与端口规划本地大模型文件通常有几个 GB建议预留至少 30GB 磁盘空间避免下载到一半空间不足。Ollama 默认端口是11434FastAPI 服务可以自定义端口比如8000。如果端口被占用启动时会报错后面常见问题部分会展开说。5. 把本地大模型跑起来Ollama 快速启动5.1 安装并拉起服务Ollama 是当前最简单的本地大模型运行方式安装后直接在终端执行ollama pull qwen2.5:7b ollama servepull会下载模型文件不同标签和版本所需空间不同具体以 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 Skill6.1 定义 Skill 函数这里我们做一个实际可跑的 Skillexecute_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_stdout和redirect_stderr来捕获运行结果。实际生产环境里如果要执行不可信代码必须放到 Docker 或沙箱容器中不能直接在宿主机上跑。6.2 组装 Tool Schema为了让大模型知道这个 Skill 的存在需要按照 Function Calling 的格式把这个函数描述成为 tooltools [ { 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 消息循环。基本流程是把用户消息加入 messages。请求大模型传入 tools。如果模型返回 tool_calls就执行对应 Skill把结果加入 messages。再次请求大模型直到模型不再返回 tool_calls。from openai import OpenAI client OpenAI( base_urlhttp://127.0.0.1:11434/v1, api_keyollama, ) 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( modelqwen2.5:7b, messagesmessages, toolstools, temperature0.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_agentif __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, host127.0.0.1, port8000)启动服务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_okTrue) 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(encodingutf-8) summary summarize_text(text) output_file Path(OUTPUT_DIR) / f{file_path.stem}_summary.txt output_file.write_text(summary, encodingutf-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_retries3, delay1.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效果比直接啃概念要好得多。
返回列表