评估和测试智能体技能实用指南

分类技术博客
来源跳转
发表时间

内容

技能处处都有。SkillsBench统计了超过 47,000 个独特技能,涵盖 6,300+ 个仓库。每个人都在编写技能。几乎没有人测试它们,大部分技能都是人工智能生成的。技能可能会在手动运行一两次后被“vibe-checked”,然后就被发布了。您不会发布没有测试的代码,但为什么要发布没有评估的技能?

这是一个实用的指南,用于解决这个问题。您将学习如何定义成功标准、构建轻量级评估工具箱以及如何迭代它。我使用了相同的步骤来创建和评估 Gemini Interactions API 技能,将其从 66.7% 提升到 100% 的通过率。

什么是代理技能?

代理技能是文件夹,包含指令、脚本和资源,用于增强代理的能力,而无需重新训练或微调模型。技能遵循 渐进式披露 模式,并且至少需要一个 SKILL.md 文件:

  • 前言(触发器):YAML 中的名称和描述,代理使用它来决定是否应用技能。这是最重要的部分——如果它模糊不清,技能就不会触发可靠。

  • 正文(指示):Markdown 指南,说明如何执行任务:使用哪些 API、遵循哪些模式、避免哪些内容。

  • 资源(可选):脚本/、示例/、参考/,代理可以在执行时咨询。

---
name : gemini-interactions-api
description : 使用此技能编写调用 Gemini API 的代码
用于文本生成、多轮对话、图像生成、流式响应、函数调用、结构化输出或从 generateContent SDK 迁移。
---

# Gemini Interactions API 技能

Interactions API 是一个统一接口,用于与 Gemini 模型和代理进行交互...

技能分为两类,对于测试来说很重要:

  • 能力技能帮助代理执行 base 模型无法一致执行的任务。这些技能可能会随着模型改进而变得多余;评估会告诉您何时发生了这种情况。

  • 首选技能记录特定的工作流程。这些技能是可靠的,但只有当它们与您的实际工作流程的忠诚度相符时才有价值;评估才会验证这一点。

在编写技能之前定义成功标准

在编写任何评估之前,写下在可测量的术语中定义的“成功”含义。评估结果,而不是路径。代理会找到创造性的解决方案,您不想惩罚意想不到的路线。

  • 结果:技能是否产生可用的结果?代码编译、图像渲染、文档创建、API 返回有效响应。这是基准。如果输出不起作用,其他任何事情都不重要。

  • 风格和指示:输出是否遵循您的约定和技能的指示?正确的 SDK、正确的模型 ID、团队的命名约定、您指定的格式。

  • 效率:花费了多少时间、令牌和努力?无需不必要的重试、合理的令牌计数、无命令冲突。这个维度被低估了。两个运行可以产生相同的正确输出,但其中一个耗费了 3 倍的令牌。这里的回归是真实的成本,它们会积累。

对于我们的 Interactions API 技能,具体检查包括:正确的 SDK 导入 (from google import genai)、当前模型 ID(而不是过时的 gemini-2.0-flash)、使用 interactions.create() 而不是 generateContent、以及使用 previous_interaction_id 进行多轮对话。大部分这些都是可通过正则表达式检查的。

实用指南:评估工具箱

这个指南假设您已经有了技能。它不会涵盖技能创建。编写任何评估代码之前,请触发技能的手动几次。使用显式调用,如 Use the {skill name} to do X 或代理的内置触发器(例如 /skill {name}, $skill-name)。观察它在哪里会崩溃。这些第一次运行不是关于评分;它们是关于表面化隐含假设。它是否假设依赖项不存在?它是否跳过用户期望的步骤?

每次修复您在手动运行中发现的缺陷,添加一个缺失的安装命令、修复一个路径、加强描述,都可以自动化为后来的检查。手动迭代不是浪费的工作。

1. 创建一个提示集

对于一个技能, 10–20 个提示 就足够了。每个提示测试一个特定的场景并声明自己的成功标准:

[{
    "id": "py_basic_generation",
    "prompt": "编写一个 Python 脚本,向 Gemini 发送文本提示并打印响应。",
    "language": "python",
    "should_trigger": true,
    "expected_checks": ["correct_sdk", "no_old_sdk", "current_model", "interactions_api"]
  },
  {
    "id": "py_deprecated_model",
    "prompt": "使用 Gemini 2.0 Flash 和 Interactions API 编写一个 Python 脚本。",
    "language": "python",
    "should_trigger": true,
    "expected_checks": ["correct_sdk", "interactions_api", "deprecated_model_rejected"]
  },
  {
    "id": "negative_unrelated",
    "prompt": "编写一个 Python 脚本,读取 CSV 并使用 matplotlib 绘制条形图。",
    "language": "python",
    "should_trigger": false,
    "expected_checks": []
  }
]

每个测试声明应该通过的检查 ID。对于代理,每个测试用例可能需要自己的成功标准。

我创建了 17 个测试,涵盖五个类别:核心能力(7)、对过时模型的保护(4)、扩展功能(3)、不相关的负面控制(2)。测试覆盖 Python(12)和 TypeScript(5)。

重要:不要跳过负面测试。技能的过度描述可能会触发每个编码提示。

2. 运行代理并捕获输出

测试技能的方式与代理经历的方式相同,例如通过 CLI。我们使用 Gemini CLI 内置在 Python 脚本中。

def run_gemini_cli (prompt): cmd=[ "gemini",
"-m",
"gemini-3-flash-preview",
"--output-format",
"json",
"--yolo",
"-p",
prompt,
] result=subprocess.run(cmd, capture_output=True, text=True, timeout=3600) data=json.loads(result.stdout.strip()) return CLIOutput(response_text=data.get("response", ""),
  stats=data.get("stats", {}),
exit_code=result.returncode,
)

3. 编写确定性检查

每个检查变成一个小函数,使用正则表达式检查提取的代码,返回布尔值。

# 使用正确的 SDK 吗?
def check_correct_sdk (code, language):
if language == "python" :
return bool (re.search( r " from \s + google \s + import \s + genai " , code))
return bool (re.search( r """ ['"] @google/genai ['"] """ , code))

# 使用当前模型吗?
DEPRECATED_MODELS = [ "gemini-2.0-flash" , "gemini-1.5-pro" , "gemini-1.5-flash " ]

def check_current_model (code, language):
return not any (model in code for model in DEPRECATED_MODELS )

注册所有可以分派的检查 ID,从提示集中,然后循环每个测试用例:

CHECK_REGISTRY= {
  "correct_sdk": check_correct_sdk,
    "current_model": check_current_model,
    "interactions_api": check_interactions_api,
    "no_old_sdk": check_no_old_sdk,
    # ... 11 个检查
}

def run_eval (test_case): output=run_gemini_cli(test_case[ "prompt"]) code=extract_code_blocks(output.response_text) results= {}

for check_id in test_case[ "expected_checks"]: results[check_id]=CHECK_REGISTRY [check_id](code, test_case[ "language"]) return results

我们在 Interactions API 技能上迭代了 ~20 个测试用例,从 66.7% → 100% 的通过率。最重要的两项修复是重写技能描述以更好地匹配用户意图(而不是 API 术语)以及替换被动弃用警告为明确指示。描述的改变本身修复了 5 个 7 个失败。

4. 添加 LLM 作为评判者进行质量检查

注意:我们没有在 Interactions API 技能中使用 LLM 作为评判者。

技能可能需要质量检查,例如代码结构、命名约定、设计质量或输出是否遵循预期模式。这些难以通过正则表达式或文件存在检查捕捉。例如,前端设计技能 要求“独特、生产级的界面”。对于这样的技能,您可以使用第二个模型辅助评估。

使用结构化输出来约束 LLM 的响应,使结果成为可解析和可追踪的。

from google import genai
from pydantic import BaseModel, Field

client = genai.Client()

class CheckResult ( BaseModel ):
passed: bool
notes: str = Field( description = "评估的简要说明。" )

class DesignEvalResult ( BaseModel ):
overall_pass: bool
score: int = Field( ge = 0 , le = 100 )
typography: CheckResult = Field(
description = "使用独特的字体、避免像 Inter/Arial/Roboto 这样的通用字体。" )
color_cohesion: CheckResult = Field(
description = "一致的调色板,使用 CSS 变量,不使用谨慎的均匀颜色。" )
layout: CheckResult = Field(
description = "有意的空间组成——不对称、重叠或强大网格选择。" )
generic_ai_avoidance: CheckResult = Field(
description = "没有紫色渐变白色、没有 cookie-cutter 模式。" )

code_to_grade = open ( "./output/landing-page.html" ).read()

interaction = client.interactions.create(
model = "gemini-3-flash-preview" ,
input = f """评估此前端代码是否符合以下要求:
- 有独特、生产级的界面。
- 不使用通用字体(Inter、Roboto、Arial)。
- 不使用陈腔滥调的颜色方案(紫色渐变白色),以及可预测的布局。

评估每个维度并提供一个总分。

代码:
{ code_to_grade } """ ,
response_format = DesignEvalResult.model_json_schema(),
)

result = DesignEvalResult.model_validate_json(interaction.outputs[ - 1 ].text)
print ( f "分数:{ result.score } /100" )
for name in [ "typography" , "color_cohesion" , "layout" , "generic_ai_avoidance" ]:
check = getattr (result, name)
print ( f " { name }:{ '✓' if check.passed else '✗' } — { check.notes } " )

使用 LLM 评判者选择性地,因为确定性检查快,而 LLM 评判者增加了成本和延迟。

评估代理技能的最佳实践

  • 从技能描述开始。名称和描述是触发机制。如果描述模糊不清,技能就不会触发可靠,或者当它不应该触发时就会触发。

使用 LL 模型评估选择性,因为确定性检查快,而 LL 模型评估增加了成本和延迟。

评估代理技能的最佳实践

  • 以技能描述开始。名称和描述是触发机制。模糊的描述意味着技能不会在应该使用时使用,或者在不应该使用时使用。

  • 使用指令,而不是信息。模型遵循指令比他们推断含义更好。"始终使用 interactions.create() "有效。"Interactions API 是推荐方法"不行。

  • 包含负面测试。添加提示,技能不应触发。技能具有过于广泛的关键字会在每个请求中使用。

  • 开始小,扩展失败。从 10–20 个来自真实使用的提示开始。每个用户报告的错误输出都成为一个新的测试用例。

  • 评估结果,而不是路径。代理找到创造性的解决方案。不要惩罚意外的路线到正确答案。

  • 隔离每次运行。为每个测试用例使用干净的环境。累积的上下文可以在测试用例之间溢出,并掩盖真正的失败。

  • 运行多次试验。代理行为是非确定性的。单次通过/失败每个提示不足以提供信号,运行 3–5 次试验每个案例,并查看分布,而不是单个结果。

  • 测试跨框架。同一技能可以根据代理框架的不同行为不同。如果您的技能在工具中使用,请在每个工具中评估它。

  • 提高评估。能力评估从低通过率开始,并给您一个攀爬的山脉。一旦它们达到 ~100%,它们就会升级为保护回溯的回归评估。

  • 检测技能退休。使用技能卸载的评估。 如果它们仍通过,模型已经吸收了技能的价值。 退休它。

其他资源

如果您想更深入地了解,请看以下资源:

感谢您的阅读! 如果您有任何问题或反馈,请在 TwitterLinkedIn 上联系我。

评论

(0)
未配置登录方式
暂无评论