十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Agent Skills实战指南:从零构建可运行的AI Agent应用

Agent Skills实战指南:从零构建可运行的AI Agent应用 很多人学完大模型基础概念后都会卡在同一个地方“我知道 Agent 是什么也知道要调用工具但真正让我从零写一个能用的 Agent还是不知道第一步该往哪走。”网上关于吴恩达 Agent Skills 的讨论很多但大部分内容要么只讲概念要么只贴代码没有解释真正能“照着做、做得通、还能理解为什么这样做”的教程非常少。这篇文章就围绕 Agent Skills 这条主线从核心概念、工具调用原理、环境准备到完整代码实战、组合编排、排错清单和工程建议一步步带你搭出一个可运行的 Agent 应用。相信学完后你不仅知道 Agent Skills 是什么还能在本地跑通自己的第一个 Agent 项目。1. 背景与核心概念1.1 从 Agent 到 Agent Skills先来理解什么是 AI Agent。用一句话概括Agent 是一个能感知环境、做出决策并执行动作的智能体。它不像普通对话机器人那样“问一句答一句”而是可以在目标驱动下自主规划步骤、调用外部工具、观察结果并根据结果继续行动直到完成任务。吴恩达在 DeepLearning.AI 相关课程和多次技术分享中反复强调一个观点大模型本身只是一个“思考引擎”真正让它落地到业务场景的是模型与工具、技能、工作流的结合。所谓 Agent Skills可以理解为一组可复用、结构化的能力封装。它不像传统函数那样只能被固化的代码调用而是可以被大模型在运行时动态选择、组合和执行。举个例子你写了一个send_email函数。传统程序员会通过 if-else 或接口硬编码去调用它但在 Agent Skills 体系里你把send_email描述成一项“技能”包括它的功能说明、参数结构、适用场景模型就会在需要发送邮件的时候自动生成一条调用指令由运行时去执行真正的函数。1.2 Agent Skills 解决什么问题没有 Agent Skills 之前开发 Agent 主要有三个痛点每次都要定义一套工具协议。项目 A 和项目 B 的工具格式不同切换成本高。模型不知道怎么用工具。即使你提供了函数模型也不清楚什么时候该调、参数该填什么。技能难以复用。不同 Agent 之间很难共享能力导致重复开发。Agent Skills 的提出本质上是把“工具”升级为“技能层”。技能既包含函数本身的实现也包含让模型理解如何使用该函数的描述信息甚至还可以包含私有提示词、校验逻辑、子流程等。模型看到的是结构化技能列表背后执行的是可靠的代码逻辑。用一张简单的对照表说明对比项传统函数Agent Skills调用方代码显式调用模型动态判断调用是否包含使用说明通常没有包含完整描述与参数Schema是否可复用跨项目复用困难可打包、可共享、可组合与模型的关系无关模型在生成过程中主动选择1.3 常见应用场景Agent Skills 在以下场景中非常实用个人助理类帮助用户查天气、定日程、发邮件、管理文件。数据分析类Agent 根据用户问题自动选择 SQL 查询、Python 计算、图表绘制等技能。知识库问答Agent 判断何时需要检索向量数据库何时直接回答。软件工程辅助自动读文件、改代码、跑测试、看报错。工作流自动化将审批、通知、报表等动作封装成技能由 Agent 按流程触发。这些场景的共同点是模型需要“动起来”而不只是“说”。Agent Skills 就是让模型安全、稳定、可控地动起来的关键桥梁。2. 环境准备与版本说明在动手写代码之前先把运行环境准备好。本节不写死具体版本号因为大模型 SDK 和依赖库更新频繁你应以实际安装版本为准但整体思路是通用的。2.1 基础环境本文示例以 Python 为主推荐使用 Python 3.10 及以上版本。原因很简单新版 Python 对类型注解和异步语法支持更好很多 Agent 框架也逐步放弃旧版本兼容。操作系统不限Windows、macOS、Linux 都可以。但如果你在 Linux 服务器上运行注意开放相关网络权限并确保 Python 环境已正确安装。检查 Python 版本python --version如果还没安装 Python建议从官网下载安装包安装时勾选“Add Python to PATH”。国内用户也可以使用 Anaconda 管理环境。2.2 依赖库安装本文的实战案例会直接调用大模型 API并模拟工具调用。核心依赖如下openai用于调用支持 Function Calling 的大模型接口。python-dotenv用于管理 API Key 等环境变量。安装命令pip install openai python-dotenv如果你使用的是国内大模型服务商提供的 OpenAI 兼容接口写法完全一样只需要修改base_url和api_key。在后面的实战部分会看到具体配置方式。2.3 项目结构建议创建以下目录结构agent-skills-demo/ ├── .env ├── skills/ │ ├── __init__.py │ ├── time_skill.py │ ├── calculator_skill.py │ └── file_skill.py ├── agent.py └── requirements.txt其中skills目录用来存放每个技能的实现文件agent.py是 Agent 核心运行逻辑。先把结构建好后面写代码时直接对号入座。3. Agent Skills 的核心机制3.1 工具调用Function Calling原理要理解 Agent Skills必须先理解大模型工具调用Function Calling机制。在不使用工具时流程是“用户提问 - 模型生成文本”。使用工具后流程变成了用户提问。模型根据问题判断是否需要调用某个工具如果需要则生成一个结构化调用请求而不是直接生成最终答案。应用代码收到调用请求后执行真实的函数拿到结果。应用把函数结果回传给模型。模型结合函数结果生成最终回答。这个过程中模型本身并不会执行代码它只负责“决定调用什么、参数填什么”。真正的执行发生在你的应用代码里。这种设计既保证了灵活性又保证了安全性因为调用什么函数、如何执行控制权始终在你手中。3.2 Skill 的组成一个完整的 Skill 通常包含三个部分技能名称唯一标识例如get_current_time、search_docs。功能描述用自然语言描述技能用途模型根据这段描述判断是否适合调用。参数结构使用 JSON Schema 定义参数名、类型、是否必填、含义等。以大模型 API 的格式来看一个技能大致长这样{ type: function, function: { name: get_current_time, description: 获取当前的日期和时间适合用户询问现在几点或今天的日期时调用, parameters: { type: object, properties: { timezone: { type: string, description: 时区名称例如 Asia/Shanghai } }, required: [timezone] } } }模型在看到这份描述后如果用户问“现在几点了”就会尝试生成如下调用{ name: get_current_time, arguments: {\timezone\: \Asia/Shanghai\} }你的代码解析这个调用执行对应函数再把结果返回给模型。3.3 为什么叫 Skills 而不是 Tools工具是孤立的而技能是体系化的。吴恩达强调 Agent Skills 的重点之一是让开发者用结构化的方式把多个工具整合成一个“能力包”并且可以在不同项目中复用。比如“文件操作技能包”可以包含读文件、写文件、列目录、搜索文件等一组工具“数据分析技能包”可以包含执行 SQL、运行 Python、生成图表等。这种分类思想很接近程序员熟悉的“模块化开发”外部暴露的是技能名称内部是多个函数和逻辑的组合。Agent 不需要关心每个技能的代码实现只需要理解“什么场景用什么技能”。4. 快速上手构建第一个 Agent Skills 实战下面进入代码环节。我们开发一个“效率助手 Agent”包含三个初始技能获取时间、数学计算、读取文件。每一步都会给出完整代码和解释。4.1 配置环境变量在项目根目录创建.env文件OPENAI_API_KEY你的API密钥 OPENAI_BASE_URLhttps://api.openai.com/v1 OPENAI_MODELgpt-4o-mini如果你使用 OpenAI 官方服务直接填写你的 Key。如果你使用国内兼容服务将OPENAI_BASE_URL改成服务商提供的地址即可。为了配置安全建议将.env加入.gitignore避免密钥泄露。4.2 定义技能模块先在skills/__init__.py中保持空文件将目录变成 Python 包。创建skills/time_skill.py# 文件路径skills/time_skill.py from datetime import datetime from zoneinfo import ZoneInfo def get_current_time(timezone: str Asia/Shanghai) - str: 获取指定时区的当前日期和时间。 Args: timezone: 时区名称例如 Asia/Shanghai。 Returns: 格式化后的时间字符串。 try: now datetime.now(ZoneInfo(timezone)) return now.strftime(%Y-%m-%d %H:%M:%S) except Exception as e: return f获取时间失败请检查时区名称{e} SKILL_DEFINITION { type: function, function: { name: get_current_time, description: 获取指定时区的当前日期和时间适合查询当前时间、日期、星期的场景, parameters: { type: object, properties: { timezone: { type: string, description: 时区名称例如 Asia/Shanghai默认 Asia/Shanghai, } }, required: [timezone], }, }, }创建skills/calculator_skill.py# 文件路径skills/calculator_skill.py import ast import operator # 支持的基础运算符 ALLOWED_OPERATORS { ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv, ast.Pow: operator.pow, ast.Mod: operator.mod, ast.USub: operator.neg, } def safe_eval(expression: str) - str: 安全计算数学表达式只允许基础四则运算和幂运算。 Args: expression: 数学表达式字符串例如 1 2 * 3。 Returns: 计算结果字符串。 try: tree ast.parse(expression, modeeval) def _eval(node): if isinstance(node, ast.Expression): return _eval(node.body) if isinstance(node, ast.BinOp) and type(node.op) in ALLOWED_OPERATORS: left _eval(node.left) right _eval(node.right) return ALLOWED_OPERATORS[type(node.op)](left, right) if isinstance(node, ast.UnaryOp) and type(node.op) in ALLOWED_OPERATORS: return ALLOWED_OPERATORS[type(node.op)](_eval(node.operand)) if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)): return node.value raise ValueError(表达式包含不允许的运算符或值) result _eval(tree) return str(result) except Exception as e: return f计算失败{e} SKILL_DEFINITION { type: function, function: { name: calculate_expression, description: 计算数学表达式支持加、减、乘、除、幂运算适合处理算术问题, parameters: { type: object, properties: { expression: { type: string, description: 数学表达式例如 1 2 * 3, } }, required: [expression], }, }, }这里故意没有直接使用eval而是用 Python AST抽象语法树解析并白名单校验避免执行任意代码。在 Agent 的 Tool 设计中这个习惯非常重要永远不要相信模型生成的字符串是可以直接执行的代码。创建skills/file_skill.py# 文件路径skills/file_skill.py import os from pathlib import Path def read_file(file_path: str) - str: 读取文本文件内容适合总结文档、提取信息等场景。 Args: file_path: 文件路径。 Returns: 文件内容。 try: path Path(file_path) if not path.exists(): return f文件不存在{file_path} if path.is_dir(): return f路径是目录不是文件{file_path} # 限制读取大小防止超大文件撑爆上下文 if path.stat().st_size 100 * 1024: return 文件超过 100KB请先拆分后再读取 return path.read_text(encodingutf-8) except Exception as e: return f读取文件失败{e} def list_directory(directory: str) - str: 列出指定目录下的文件和子目录名称。 Args: directory: 目录路径。 Returns: 目录内容列表。 try: path Path(directory) if not path.exists() or not path.is_dir(): return f目录不存在{directory} return \n.join(os.listdir(path)) except Exception as e: return f列出目录失败{e} SKILL_DEFINITIONS [ { type: function, function: { name: read_file, description: 读取文本文件内容适合总结文件内容、抽取关键信息的场景, parameters: { type: object, properties: { file_path: { type: string, description: 要读取的文件绝对路径或相对路径, } }, required: [file_path], }, }, }, { type: function, function: { name: list_directory, description: 列出指定目录下的文件与子目录适合查看项目结构或寻找文件的场景, parameters: { type: object, properties: { directory: { type: string, description: 要查看的目录路径, } }, required: [directory], }, }, }, ]把所有技能定义汇总到skills/__init__.py中# 文件路径skills/__init__.py from .time_skill import SKILL_DEFINITION as TIME_SKILL from .calculator_skill import SKILL_DEFINITION as CALCULATOR_SKILL from .file_skill import SKILL_DEFINITIONS as FILE_SKILL_DEFINITIONS ALL_SKILL_DEFINITIONS [TIME_SKILL, CALCULATOR_SKILL] FILE_SKILL_DEFINITIONS4.3 编写 Agent 主循环现在编写agent.py它是整个 Agent 的核心。主循环思路如下将用户消息发送给模型同时携带所有技能定义。如果模型返回tool_calls说明它决定调用某个技能。遍历每个 tool call解析函数名和参数找到并执行对应的 Python 函数。将执行结果以tool消息回传给模型。模型收到结果后或者继续调用其他技能或者生成最终答案。设置最大循环次数防止死循环。完整代码如下# 文件路径agent.py import json import os from dotenv import load_dotenv from openai import OpenAI from skills import ALL_SKILL_DEFINITIONS from skills.calculator_skill import safe_eval from skills.file_skill import list_directory, read_file from skills.time_skill import get_current_time load_dotenv() # 初始化客户端 client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL, https://api.openai.com/v1), ) MODEL_NAME os.getenv(OPENAI_MODEL, gpt-4o-mini) # 函数名到实际函数的映射表 FUNCTION_MAP { get_current_time: get_current_time, calculate_expression: safe_eval, read_file: read_file, list_directory: list_directory, } MAX_ITERATIONS 5 def run_agent(user_input: str) - str: messages [ { role: system, content: 你是一个效率助手可以通过调用技能帮助用户完成获取时间、数学计算、文件读取等任务。如果用户的需求不明确请主动询问。, }, {role: user, content: user_input}, ] for _ in range(MAX_ITERATIONS): response client.chat.completions.create( modelMODEL_NAME, messagesmessages, toolsALL_SKILL_DEFINITIONS, tool_choiceauto, ) message response.choices[0].message # 如果没有工具调用说明模型已给出最终回答 if not message.tool_calls: return message.content or 模型未返回内容 # 将模型消息加入上下文 messages.append( { role: assistant, content: message.content, tool_calls: [ { id: tc.id, type: function, function: { name: tc.function.name, arguments: tc.function.arguments, }, } for tc in message.tool_calls ], } ) # 逐个执行工具调用 for tool_call in message.tool_calls: function_name tool_call.function.name function_args json.loads(tool_call.function.arguments or {}) if function_name not in FUNCTION_MAP: result f未知技能{function_name} else: try: result FUNCTION_MAP[function_name](**function_args) except Exception as e: result f技能执行出错{e} messages.append( { role: tool, tool_call_id: tool_call.id, content: str(result), } ) return 已达最大迭代次数任务未完成请简化问题或检查技能调用逻辑。 if __name__ __main__: while True: user_input input(请输入你的问题输入 exit 退出) if user_input.strip().lower() exit: break answer run_agent(user_input) print(\nAI, answer, \n)上述代码有几个设计点值得注意tool_calls需要按结构回传包含id、type、function.name和function.arguments。工具执行结果必须使用roletool消息并用tool_call_id关联对应调用。MAX_ITERATIONS是一个安全阀防止模型在调用链中陷入死循环。函数参数从字符串解析为字典后通过**function_args动态传入所以每个函数参数名必须和 JSON Schema 中的属性名一致。4.4 运行与验证在项目根目录准备一个测试文件例如notes/meeting.md# 项目例会纪要 会议时间2026 年 3 月 10 日 参会人张三、李四、王五 议题 1. 确认 Agent Skills 技术方案 2. 分配开发任务 3. 确定下周一上线然后运行python agent.py依次输入几个测试问题测试 1时间查询请输入你的问题输入 exit 退出现在北京时间几点模型会判断需要调用get_current_time执行后返回一个示例回答AI 当前北京时间为 2026-03-10 14:30:25。测试 2数学计算请输入你的问题输入 exit 退出帮我计算 (12 34) * 5 等于多少模型会调用calculate_expression得到结果 230然后组织成自然语言回答。测试 3文件操作请输入你的问题输入 exit 退出读取 notes/meeting.md 并总结会议内容。模型会先调用read_file读取文件内容后再生成会议纪要总结。你也可以尝试问“查看 notes 目录下有哪些文件”让它调用list_directory。4.5 结果说明从这个简单示例可以看出Agent Skills 的价值在于你不用把每个功能用 if-else 硬编码到对话里只要写好函数和定义模型会自动判断调用方式。技能之间可以自由组合。比如用户说“看看目录里有什么文件然后总结每个文件的内容”模型会先调用list_directory再根据文件名逐个调用read_file。技能描述写得越清楚模型选择就越准确。描述不清时模型可能会在需要计算时错误地调用时间技能。5. 进阶实战多技能组合与编排上面是单技能调用实际项目中更常见的是多技能组合编排。本节设计一个“本地项目体检 Agent”它需要完成三个动作列出目录结构、读取关键描述文件、检查是否存在 README。过程中模型需要连续两次甚至三次调用技能这能帮你理解多步编排的运行逻辑。5.1 需求分析用户输入一个目录路径Agent 需要输出目录下的文件清单。README 文件是否存在。如果存在读取前几行内容并概括项目用途。这个任务需要两个技能list_directory和read_file。模型必须先列目录然后决定读取哪个文件。5.2 编写编排函数我们不需要新写技能只需在agent.py中增加一个场景提示词让模型按照特定流程执行。更好的做法是把它封装成独立脚本project_doctor.py# 文件路径project_doctor.py import json import os from dotenv import load_dotenv from openai import OpenAI from skills import ALL_SKILL_DEFINITIONS from skills.file_skill import list_directory, read_file load_dotenv() client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL, https://api.openai.com/v1), ) MODEL_NAME os.getenv(OPENAI_MODEL, gpt-4o-mini) FUNCTION_MAP { list_directory: list_directory, read_file: read_file, } MAX_ITERATIONS 6 def project_doctor(project_path: str) - str: messages [ { role: system, content: ( 你是一个项目结构检查助手。你的任务流程是\n 1. 先调用 list_directory 查看指定目录。\n 2. 根据目录内容判断是否存在 README 或说明文件。\n 3. 如果存在调用 read_file 读取该文件。\n 4. 最后总结项目用途。\n 请严格按照流程执行。 ), }, {role: user, content: f请检查这个项目的结构{project_path}}, ] for _ in range(MAX_ITERATIONS): response client.chat.completions.create( modelMODEL_NAME, messagesmessages, toolsALL_SKILL_DEFINITIONS, tool_choiceauto, ) message response.choices[0].message if not message.tool_calls: return message.content or 模型未返回内容 messages.append( { role: assistant, content: message.content, tool_calls: [ { id: tc.id, type: function, function: { name: tc.function.name, arguments: tc.function.arguments, }, } for tc in message.tool_calls ], } ) for tool_call in message.tool_calls: function_name tool_call.function.name function_args json.loads(tool_call.function.arguments or {}) if function_name not in FUNCTION_MAP: result f未知技能{function_name} else: try: result FUNCTION_MAP[function_name](**function_args) except Exception as e: result f技能执行出错{e} messages.append( { role: tool, tool_call_id: tool_call.id, content: str(result), } ) return 检查过程超过最大迭代次数请检查目录是否包含过多嵌套。 if __name__ __main__: import sys path sys.argv[1] if len(sys.argv) 1 else . result project_doctor(path) print(result)运行方式python project_doctor.py /path/to/your/project5.3 观察多步调用过程为了看清模型每一步在做什么可以临时打印function_name和function_args。这一步对调试非常有帮助print(f调用技能{function_name}, 参数{function_args})你会发现模型生成第一条工具调用后会“暂停”等待结果拿到结果后再决定下一步。这种“思考-行动-观察”的循环就是 ReAct 模式的简化体现。5.4 编排的常见模式多技能组合通常有几种模式模式说明示例顺序执行前一个技能的结果是下一个技能的输入先列目录再读文件条件执行根据结果决定是否调用如果存在 README 才读取并行执行多个独立技能同时调用同时查时间和算价格迭代执行重复执行同一技能直到完成分页读取大量数据在实际开发中优先让模型自己决定使用哪种模式但你可以在系统提示词中给出流程约束减少模型“犯迷糊”的概率。6. 常见问题与排查思路无论新手还是老手在使用 Agent Skills 时都会遇到各类问题。下面整理几个高频问题及排查思路。6.1 模型返回空 tool_calls现象用户问题明明需要调用技能但模型直接给出了文字回答没有生成tool_calls。可能原因技能描述不够清晰模型没意识到该调用技能。模型版本较老不支持 Function Calling。技能名称或参数和函数实际实现不匹配。解决思路检查模型是否支持工具调用。优化技能描述。例如不要写“处理时间”而写“当用户询问当前时间、日期或星期时调用”。在系统提示词中强调“如果需要查询实时信息必须调用工具”。6.2 参数解析报错现象执行函数时报TypeError提示缺少参数或参数类型错误。可能原因JSON Schema 中的required列表中包含了模型未生成的必填参数。模型的arguments字符串不合法 JSON。参数名拼写不一致。解决思路解析前先json.loads并 try-except 捕获异常。尽量给每个参数提供默认值减少必填参数数量。对比FUNCTION_MAP中函数签名和 JSON Schema 中的属性名保持完全一致。6.3 Agent 循环调用不结束现象模型反复调用技能无法生成最终回答直到MAX_ITERATIONS被触发。可能原因工具结果不完整模型拿不到足够信息。系统提示词没有明确“结果足够时停止调用”。有些技能天然需要多步循环步数超过预设值。解决思路在系统提示词中增加“如果信息已充足请直接给出最终答案”。增加最大迭代次数或对不同任务动态设置次数。检查工具返回结果是否被正确传递是否因为长度截断导致信息丢失。6.4 上下文过长导致超限现象连续多轮调用后API 报context_length_exceeded。可能原因工具返回内容过大塞入了大量文本。历史消息累积过快。解决思路工具返回结果做截断例如只返回前 2000 字符。使用摘要替代全文。及时清理过旧的历史消息或使用支持自动裁剪的封装库。6.5 高频问题速查表问题现象常见原因解决思路模型不调用工具技能描述不清模型太弱优化描述更换模型工具函数抛异常参数格式错误函数健壮性差增加 try-except校验参数API 连接失败密钥错误网络不通base_url 错误检查 .env 配置与密钥权限响应速度慢技能太多模型选择困难精简技能列表分类路由结果不准确工具执行结果没回传检查 tool 消息格式6.6 排查清单遇到问题不要慌按以下顺序检查API 层密钥是否正确、余额是否充足、模型是否支持工具调用。格式层messages 是否严格遵循协议尤其是 tool_calls 和 tool 消息格式。技能层函数名、参数名、描述信息是否一致。逻辑层FUNCTION_MAP 是否正确映射所有技能名。数据层工具返回的数据是否完整、是否被截断。7. 工程实践与安全建议把 Agent Skills 从 Demo 推向生产环境需要额外考虑稳定性、安全性和可维护性。以下经验来自真实工程中常见的踩坑点非常建议一一看过。7.1 技能设计规范技能命名要语义化例如search_customer_by_name比query1好得多因为模型是通过描述和名称理解技能的。每个技能只做一件事避免“万能函数”。如果函数内部逻辑复杂把它拆成多个更细粒度的技能。参数 Schema 要精确参数名统一使用小写加下划线例如file_path。对每个属性都要写清楚描述包括单位、格式、取值范围。设置required时尽量少能让模型直接填的不要设必填。7.2 安全边界最小权限原则Agent 的技能相当于给模型的“手”。模型可能会误解指令产生恶意或错误调用。因此每一项技能都必须遵循最小权限原则文件技能只允许读写白名单目录禁止访问/etc、系统盘根目录等敏感位置。数据库技能只允许执行白名单 SQL禁止DROP、DELETE等高危操作。外部请求技能必须校验 URL 域名防止 SSRF服务端请求伪造。发送邮件、转账等技能必须增加二次确认机制。可以在技能函数内部加一层权限校验。例如def safe_read_file(file_path: str) - str: allowed_root Path(/data/allowed) real_path Path(file_path).resolve() if not real_path.is_relative_to(allowed_root): return 权限不足只能读取 /data/allowed 目录下的文件 return read_file(str(real_path))7.3 日志与追踪Agent 的链路比普通接口更长出现问题很难直接复现。推荐在每个环节埋点记录模型发送的完整消息注意脱敏。记录模型生成的每个 tool call技能名、参数、耗时、返回值。记录每次循环的轮次方便判断是否死循环。为每次对话生成一个conversation_id把日志串联起来。示例日志格式[2026-03-10 14:30:25] [trace_idabc123] [step1] tool_call: get_current_time args: {timezone: Asia/Shanghai} result: 2026-03-10 14:30:25 cost: 0.42s7.4 上下文与成本控制每次工具调用都会增加消息长度token 成本随之上升。建议工具返回结果设置最大长度。历史消息做摘要而不是全量保存。对不需要多轮工具去重结果。监控每次调用的 token 消耗。7.5 测试策略Agent 的输出天然有随机性测试不能只靠“跑一次看结果”。建议做单元测试每个技能函数单独测试确保参数和返回值稳定。场景测试设计 20 个典型用户问题验证模型是否选择了正确技能。回归测试每次修改技能描述后重跑场景测试防止描述变化导致模型选错。容错测试模拟工具返回异常、API 超时等边界情况。7.6 生产发布注意事项上线前检查API Key 是否放入了密钥管理服务而不是写死在代码中。技能目录是否配置了访问控制避免模型读到敏感配置。是否设置了超时时间和重试策略。是否限制了 Agent 的调用频率和并发量。是否准备人工干预通道在 Agent 连续失败时自动熔断。这些细节往往决定着一个 Agent 项目是“能跑”还是“能用”。8. 总结与学习路线本文从 Agent Skills 的概念讲起聊了工具调用机制、Skill 的组成然后通过一个“效率助手 Agent”和一个“项目体检 Agent”两个实战案例演示了如何定义技能、运行 Agent 主循环、观察多步编排。最后整理了高频报错、排查清单和工程安全建议。你现在应该掌握的核心能力包括理解 Agent Skills 与普通函数、普通工具调用的区别。会写标准的技能定义 JSON Schema。会实现一个带 Function Calling 循环的 Agent 主程序。能够排查工具调用中最常见的参数错误、死循环和上下文超限问题。知道生产环境中如何限制技能权限、记录日志和做回归测试。接下来可以继续深入的方向记忆机制让 Agent 在多轮对话中记住关键信息而不是每次都重复传完整上下文。RAG 结合把检索增强生成封装成检索技能让 Agent 自动决定何时查询知识库。多 Agent 协作将不同技能分配给不同角色的 Agent由主 Agent 负责调度。流式输出把模型回复改成流式提升用户体验。更低延迟的本地部署尝试在本地运行支持工具调用的开源模型减少外部 API 依赖。学习路线上的建议是不要急着去背一堆框架也不要只盯着“Agent 能做什么”的演示视频。先把本文的代码手打一遍理解 Function Calling 的协议细节再逐步加法加一个技能、加一段记忆、加一个子 Agent。每加一块都重新跑一遍场景测试。把最基础的一条链路打通你对 Agent Skills 的理解会明显上一个台阶。最后补充一句实践体会写技能描述比写函数本身更花时间但这项投入非常值。模型的判断能力依赖你的描述质量。好的技能描述就是最好的 Agent“产品文档”。希望这篇教程能帮你少踩一些坑早点跑通自己的第一个 Agent Skills 项目。
返回列表