在 Genkit Go 中通过 Agent Skills 按需启用专业知识技能(Skills 首次出现附:技能)
基于大语言模型的智能体(Agent)正越来越多地被用于自动化复杂工作流。然而,随着其职责范围扩大,如何管理提示词(Prompt)上下文的规模逐渐成为挑战。将每份标准操作程序、参考指南和文档都加载到持久化上下文窗口中是不可持续的:这会消耗宝贵的令牌(Token),分散模型的注意力,并增加产生错误响应的可能性。
为了解决这个问题,我们在 TypeScript、Go、Dart 和 Python 版本的 Genkit 中增加了对 Agent Skills 的支持。本文将通过 Go 语言中的使用示例,详解如何在 Genkit 中使用 Agent Skills。Agent Skills 标准使开发者能够将专业知识封装成可发现的能力,智能体仅在需要时才会加载它们。它们就像是专业知识包,在后台静默待命,直到被需要的那一刻才被激活。
Agent Skills 简要回顾
Agent Skills 遵循渐进式信息披露原则,即信息仅在必要且安全时才会向模型展示。技能通过一个名为 SKILL.md 的文件定义,该文件包含两部分:前言(Frontmatter)和正文(Body)。前言包含技能描述及任何附加元数据,而正文部分则包含提供给模型的实际指令。此外,技能还可以包含引用文档或脚本等补充文件。
根据规范,技能在磁盘上的组织结构如下:
skill-name/
├── SKILL.md # 必需:元数据 + 指令
├── scripts/ # 可选:可执行代码
├── references/ # 可选:文档
├── assets/ # 可选:模板、资源
└── ... # 任何附加文件或目录
以下是一个技能前言(Frontmatter)示例:
---
name: adr-template
description: 在提议重大架构变更、记录代码库重构或解决设计/技术争论时激活此技能。使用此技能来编写和维护架构决策记录(Architecture Decision Records, ADRs),以保留工程上下文。
license: Apache-2.0
metadata:
author: example-org
version: "1.0"
---
起初,智能体框架将从 SKILL.md 文件中加载技能定义,但仅将前言(Frontmatter)部分暴露给智能体的系统提示词。这构成了智能体决定是否必须激活该技能所需的信息基础。随着对话的推进,智能体最终可能遇到需要该技能的场景,此时激活过程便启动,技能的完整正文将被加载。基于正文内容,智能体可能会确定并加载额外的引用文档或使用捆绑的脚本,从而完成针对该特定任务的完整信息披露周期。
此流程如下图所示:

借助渐进式信息披露,令牌消耗被推迟到绝对必要时。图表由 Gemini 3.1 Flash Image 生成。
这种渐进式信息披露模型提供了三个关键优势:
- 令牌效率(Token efficiency): Genkit 初始仅加载技能的元数据,仅当技能激活时才注入详细指令。
- 轻量化实现(Lean implementation): 技能是一组 Markdown 文件的集合,可以像代码一样分发,无需配置任何额外基础设施即可受益于技能。
- 资源捆绑(Resource bundling): 技能可以包含其自身的脚本(Python、Node.js、Bash),智能体可以执行这些脚本,确保其拥有执行任务的恰好合适的工具。
Go 版 Genkit 中的 Agent Skills
要理解 Agent Skills 如何在 Go 版 Genkit 中运作,我们必须先了解 Genkit 中间件架构。Genkit 中间件充当管道钩子,拦截并封装关键的模型生命周期阶段:
- 模型封装器(WrapModel): 在每次迭代中的每次模型 API 调用时触发一次,处理与模型调用本身相关的逻辑,如重试、回退和缓存。
- 工具封装器(WrapTool): 在每次工具执行时触发一次,并支持同一迭代中并发工具调用的并发执行。
- 生成封装器(WrapGenerate): 在每次工具循环迭代时触发一次(N 次工具调用意味着 N+1 次调用),处理需要查看整个对话的逻辑,例如重写、系统提示词注入和消息累积。
Agent Skills 正是在此钩子系统之上构建的。通过监控传入的提示词,中间件会检测匹配的描述并动态激活技能。
以下代码片段演示了如何为你的 Genkit 流程添加技能支持:
resp, err := genkit.Generate(ctx, g,
ai.WithPrompt("How do I run tests in this repo?"),
ai.WithUse(&middleware.Skills{SkillPaths: []string{"./skills"}}),
)
工作原理
技能使用分为三个不同阶段:
- 发现(Discovery): 使用技能中间件初始化 Genkit 时,系统会扫描你所配置的 SkillPaths 路径下的 SKILL.md 文件,并将其元数据注入系统提示词。
- 激活(Activation): 当用户请求匹配某个技能的描述时,Genkit 调用 use_skill 工具来检索当前任务所需的特定指令。
- 执行(Execution): SKILL.md 文件的全部内容,连同对捆绑资源(如脚本和引用文档)的访问权限,一并被加载到活跃上下文中,以引导模型完成精确的工作流程。
准备环境
安装 SDK
要在 Genkit 中开始使用 Agent Skills,请首先确保你已安装最新版本的 Genkit Go SDK:
go get github.com/firebase/genkit/go
安装 Genkit CLI
此步骤为可选但建议执行。在 macOS 或 Linux 上运行:
curl -sL cli.genkit.dev | bash
在 Windows 上,请从以下地址下载二进制文件:cli.genkit.dev
更多详情请参阅 https://cli.genkit.dev
将技能添加到基础流程中
安装 SDK 后,你可以注册技能中间件并在 Generate 调用期间提供它。以下代码示例定义了一个由 Genkit 流程驱动的食谱生成命令行工具:
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/firebase/genkit/go/ai"
"github.com/firebase/genkit/go/genkit"
"github.com/firebase/genkit/go/plugins/googlegenai"
"github.com/firebase/genkit/go/plugins/middleware"
"google.golang.org/genai"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: recipe <food|ingredient>")
os.Exit(1)
}
input := os.Args[1]
ctx := context.Background()
g := genkit.Init(ctx, genkit.WithPlugins(&googlegenai.GoogleAI{}, &middleware.Middleware{}))
recipeFlow := genkit.DefineFlow(g, "recipeFlow", func(ctx context.Context, input string) (string, error) {
prompt := fmt.Sprintf("Provide a recipe using %s", input)
return genkit.GenerateText(ctx, g,
ai.WithModel(googlegenai.ModelRef("googleai/gemini-flash-latest", &genai.GenerateContentConfig{
ThinkingConfig: &genai.ThinkingConfig{
ThinkingLevel: genai.ThinkingLevelLow,
},
})),
ai.WithSystem(
"You are a professional chef assistant with wide knowledge about recipes. "+
"The user will give you a food or ingredient and you need to respond with a recipe. "+
"Use specialized knowledge (skills) whenever possible. "+
"Respond with ASCII formatting optimized for terminal output (no markdown).",
),
ai.WithPrompt(prompt),
ai.WithUse(&middleware.Skills{SkillPaths: []string{"./skills"}}),
)
})
result, err := recipeFlow.Run(ctx, input)
if err != nil {
log.Fatalf("Error running flow: %v", err)
}
fmt.Println(result)
}
请注意,我们在 genkit.GenerateText 中使用 ai.WithUse 功能选项配置了 Skills 中间件。在实例化的 Skills 中间件中,我们通过 SkillPaths 映射了 ./skills 文件夹,此例中该文件夹包含两个技能:“banana-bread”和“cheese-bread”。
使用单词“cheese”运行该应用程序,会激活“cheese-bread”技能并返回相应的食谱:
$ go run main.go cheese
+-------------------------------------------------------------+
| TRADITIONAL BRAZILIAN CHEESE BREAD |
| (Pao de Queijo) |
+-------------------------------------------------------------+
Naturally gluten-free, crispy on the outside, and chewy inside.
===============================================================
INGREDIENTS
===============================================================
* Tapioca Flour (Sour Starch) .. 2 cups (240g)
* Whole Milk .................. 1/2 cup (120ml)
* Water ....................... 1/2 cup (120ml)
* Vegetable Oil ............... 1/3 cup (80ml)
* Salt ........................ 1 tsp
* Eggs (Room Temp) ............ 2 large
* Grated Parmesan/Queijo ...... 1.5 cups (150g)
===============================================================
EQUIPMENT
===============================================================
* Medium Saucepan
* Wooden Spoon
* Large Mixing Bowl
* Baking Sheet
* Parchment Paper or Greased Pan
===============================================================
INSTRUCTIONS
===============================================================
1. PREP: Preheat oven to 400°F (200°C). Line a baking sheet with parchment paper.
2. SCALD THE LIQUIDS: In a medium saucepan, combine milk, water, oil, and salt. Bring to a boil over medium-high heat, stirring occasionally.
3. COOK THE DOUGH: As soon as it boils, remove from heat. Pour all the tapioca flour in at once and stir vigorously with a wooden spoon until combined and no dry spots remain. The mixture will look clumpy and translucent. Let it rest for 5-10 minutes to cool slightly.
4. GRATE CHEESE: While the dough cools, finely grate your cheese of choice.
5. FORM THE DOUGH: Transfer the slightly cooled dough to a large mixing bowl. Add the eggs one at a time, beating vigorously after each addition. The dough will initially separate but will come together into a cohesive, sticky dough. Once smooth, add the cheese and mix well.
6. SHAPE: With lightly oiled hands, scoop tablespoon-sized portions of dough and roll into balls. Place on the prepared baking sheet, spacing them about 2 inches apart.
7. BAKE: Bake for 20-25 minutes until puffed and lightly golden. Avoid opening the oven door during the first 15 minutes to prevent them from deflating.
8. SERVE: Serve warm right out of the oven. The centers should be hollow, soft, and chewy.