举例说明,一个“发送邮件”的 Skill 应该包含哪些必要字段和约束?
面试官:“你能具体举例,设计一个‘发送邮件’的 Skill,说说它应该包含哪些必要的元信息字段和约束吗?”
候选人:
“当然。‘发送邮件’看似简单,但要让 Agent 安全、准确地自动调用它,元信息需要覆盖身份标识、意图触发、参数定义、安全限制、协作依赖这几个维度。我按照之前提到的分层结构,结合实际业务场景,设计这样一个 Skill 的元信息。
一、基础身份字段
首先是让系统唯一识别并找到这个 Skill:
{
"name": "send_email",
"version": "1.3.0",
"category": "communication",
"tags": ["email", "smtp", "notification", "send"],
"owner": "infra-comm-team"
}
这里 category 和 tags 帮助 Agent 在做粗粒度筛选时快速定位,version 则支持多版本共存和灰度升级。
二、意图与描述 —— 让 Agent 明白“何时该用它”
这部分是 Skill 被精准触发的关键。
{
"description": {
"short": "发送一封邮件",
"long": "根据指定的收件人、主题、正文内容,通过公司 SMTP 服务发送邮件。支持抄送、密送和附件。",
"trigger_examples": [
"帮我发一封邮件给张三",
"把周报发送给 manager@example.com",
"通知团队明天开会"
],
"semantic_vector": "预计算向量或由模型实时生成"
}
}
-
trigger_examples不只是关键词,更是给语义匹配模型用的种子样本。用户说“通知团队明天开会”,Agent 发现和这个示例高度相似,就会激活这个 Skill。 -
long描述会更详细,用于当有多个候选 Skill 时的二次精确比对。
三、输入参数定义 —— 参数语义与约束
这是 Agent 能否正确调用 Skill 的核心,必须清晰到可以让模型从自然语言中提取参数。
{
"parameters": [
{
"name": "to",
"type": "array[string]",
"required": true,
"description": "收件人邮箱地址列表",
"validation": "^[\\w.-]+@[\\w.-]+\\.\\w+$",
"max_items": 50
},
{
"name": "cc",
"type": "array[string]",
"required": false,
"description": "抄送邮箱地址列表",
"max_items": 20
},
{
"name": "bcc",
"type": "array[string]",
"required": false,
"description": "密送邮箱地址列表",
"max_items": 20
},
{
"name": "subject",
"type": "string",
"required": true,
"description": "邮件主题,不超过 200 字符",
"max_length": 200
},
{
"name": "body",
"type": "string",
"required": true,
"description": "邮件正文,支持纯文本和 HTML",
"max_length": 102400
},
{
"name": "attachments",
"type": "array[object]",
"required": false,
"description": "附件列表,每个附件包含文件名和文件 ID",
"max_items": 10,
"sub_schema": {
"file_id": { "type": "string", "required": true },
"filename": { "type": "string", "required": true }
}
}
]
}
设计要点:
-
参数必填性:
to、subject、body是必须的,如果缺失 Agent 必须主动反问。 -
格式校验:邮箱地址用正则表达式,防止非法地址。
-
数量限制:收件人不超过 50 人,附件不超过 10 个,避免滥用。
-
长度限制:主题 200 字符、正文 100KB,保护后端服务。
四、安全与约束 —— 不可逾越的红线
这是防止误用或恶意调用的关键。
{
"preconditions": {
"required_capabilities": ["user_authenticated"],
"rate_limit": {
"max_calls_per_user_day": 200,
"max_calls_per_organization_minute": 1000
},
"timeout_ms": 15000,
"retry_policy": {
"max_retries": 2,
"backoff": "exponential",
"retryable_errors": ["NETWORK_TIMEOUT", "SMTP_TEMP_FAILURE"]
}
},
"authorization": {
"allow_sender_override": false,
"sender_address": "noreply@company.com",
"require_dkim": true
},
"audit": {
"log_level": "full",
"retain_logs_days": 90
}
}