ADK 智能体技能¶
Supported in ADKPython v1.25.0TypeScript v0.6.1Go v1.2.0Experimental
智能体 技能 (Skill) 是一个自包含的功能单元,ADK 智能体可以使用它来执行特定任务。智能体技能封装了任务所需的必要指令、资源和工具,基于智能体技能规范 (Agent Skill specification)。技能的结构允许它增量加载,以最小化对智能体运行上下文窗口的影响。
实验性
技能功能是实验性的。欢迎你通过相应的 ADK GitHub 仓库提供反馈:ADK Python,ADK TypeScript,ADK Go。
开始使用¶
使用 SkillToolset 类让你的智能体可以使用一个或多个技能。你可以在代码中定义技能或从文件系统加载技能。
import pathlib
from google.adk import Agent
from google.adk.skills import load_skill_from_dir
from google.adk.tools import skill_toolset
weather_skill = load_skill_from_dir(
pathlib.Path(__file__).parent / "skills" / "weather_skill"
)
my_skill_toolset = skill_toolset.SkillToolset(
skills=[weather_skill],
additional_tools=[get_weather_tool],
)
root_agent = Agent(
model="gemini-flash-latest",
name="skill_user_agent",
description="An agent that can use specialized skills.",
instruction=(
"You are a helpful assistant that can leverage skills to perform tasks."
),
tools=[
my_skill_toolset,
],
)
有关带有技能的 ADK 智能体的完整代码示例,包括基于文件的和内联的技能定义,请参阅代码示例 skills_agent。
import {Agent, FunctionTool, SkillToolset, loadSkillFromDir} from '@google/adk';
import * as path from 'node:path';
import {z} from 'zod';
const weatherSkill = await loadSkillFromDir(
path.join(__dirname, 'skills/weather_skill')
);
const getWeatherTool = new FunctionTool({
name: 'get_weather',
description: 'Gets the weather for a given location.',
parameters: z.object({
location: z.string().describe('The city and state, e.g. San Francisco, CA'),
}),
execute: async ({location}) => {
return {
location,
temperature: '72°F',
condition: 'Sunny',
};
},
});
const mySkillToolset = new SkillToolset([weatherSkill], {
additionalTools: [getWeatherTool],
});
const rootAgent = new Agent({
model: 'gemini-flash-latest',
name: 'skill_user_agent',
description: 'An agent that can use specialized skills.',
instruction:
'You are a helpful assistant that can leverage skills to perform tasks.',
tools: [mySkillToolset],
});
export default rootAgent;
import (
"context"
"os"
"google.golang.org/adk/agent/llmagent"
"google.golang.org/adk/tool/skilltoolset/skill"
"google.golang.org/adk/tool/skilltoolset"
"google.golang.org/adk/tool"
)
mySkillToolset, err := skilltoolset.New(ctx, skilltoolset.Config{
Source: skill.NewFileSystemSource(os.DirFS("./skills")),
})
if err != nil {
// handle error
}
rootAgent, err := llmagent.New(llmagent.Config{
Name: "skill_user_agent",
Model: model,
Description: "An agent that can use specialized skills.",
Instruction: "You are a helpful assistant that can leverage skills to perform tasks.",
Toolsets: []tool.Toolset{mySkillToolset},
})
if err != nil {
// handle error
}
有关完整示例,请参阅 skills 中的代码示例。
理解技能¶
技能功能允许你创建技能指令和资源的模块化包,智能体可以根据需要加载。这种方法有助于你组织智能体的能力,并由于仅在需要时加载指令而优化上下文窗口。技能的结构分为三个级别:
- L1 (元数据): 提供用于技能发现的元数据。此信息定义在
SKILL.md文件的 Frontmatter 部分,包括技能名称和描述等属性。 - L2 (指令): 包含技能的主要指令,当技能被智能体触发时加载。此信息定义在
SKILL.md文件的正文中。 - L3 (资源): 包括其他资源,如参考材料、资产和脚本,可以根据需要加载。这些资源组织在以下目录中:
references/:具有扩展指令、工作流或指南的其他 Markdown 文件。assets/:资源材料,如数据库模式、API 文档、模板或示例。scripts/:智能体运行环境支持的可执行脚本。
技能目录结构¶
以下目录结构展示了在你的 ADK 智能体项目中包含技能的推荐方式。下面显示的 example-skill/ 目录以及任何并行的技能目录,必须遵循智能体技能规范的文件结构。仅 SKILL.md 文件是必需的。
my_agent/
agent.py (or agent.ts / main.go)
.env
skills/
example-skill/ # Skill
SKILL.md # main instructions (required)
references/
REFERENCE.md # 详细的 API 参考
FORMS.md # 表单填写指南
*.md # 领域特定信息
assets/
*.* # 模板、图像、数据
scripts/
*.py # 实用脚本 (Python)
*.js # 实用脚本 (JavaScript)
*.ts # 实用脚本 (TypeScript)
技能来源¶
在代码中定义技能¶
你可以在智能体代码中定义技能,如下所示。
from google.adk.skills import models
greeting_skill = models.Skill(
frontmatter=models.Frontmatter(
name="greeting-skill",
description=(
"A friendly greeting skill that can say hello to a specific person."
),
),
instructions=(
"Step 1: Read the 'references/hello_world.txt' file to understand how"
" to greet the user. Step 2: Return a greeting based on the reference."
),
resources=models.Resources(
references={
"hello_world.txt": "Hello! So glad to have you here!",
"example.md": "This is an example reference.",
},
),
)
import {Agent, Skill, SkillToolset} from '@google/adk';
const greetingSkill: Skill = {
frontmatter: {
name: 'greeting-skill',
description: 'A friendly greeting skill that can say hello to a specific person.',
},
instructions:
"Step 1: Read the 'references/hello_world.txt' file to understand how to greet the user. Step 2: Return a greeting based on the reference.",
resources: {
references: {
'hello_world.txt': 'Hello! So glad to have you here!',
'example.md': 'This is an example reference.',
},
},
};
const mySkillToolset = new SkillToolset([greetingSkill]);
const rootAgent = new Agent({
model: 'gemini-flash-latest',
name: 'greeting_agent',
description: 'An agent that uses an inline greeting skill.',
instruction: 'You are a helpful assistant that uses skills to greet people.',
tools: [mySkillToolset],
});
export default rootAgent;
Note
ADK Go 目前不提供内联技能的标准 Source,尽管将来可能会添加。
要直接在代码中定义技能,你必须自己实现 skill.Source
接口,如下所示。
import (
"context"
"io"
"slices"
"strings"
"google.golang.org/adk/tool/skilltoolset/skill"
)
// 静态内存中 skill.Source 的示例实现:
type StaticSource struct{}
func (s *StaticSource) ListFrontmatters(ctx context.Context) ([]*skill.Frontmatter, error) {
return []*skill.Frontmatter{
{Name: "greeting-skill", Description: "A friendly greeting skill that can say hello to a specific person."},
}, nil
}
func (s *StaticSource) LoadFrontmatter(ctx context.Context, name string) (*skill.Frontmatter, error) {
if name != "greeting-skill" {
return nil, skill.ErrSkillNotFound
}
return &skill.Frontmatter{Name: "greeting-skill", Description: "A friendly greeting skill that can say hello to a specific person."}, nil
}
func (s *StaticSource) LoadInstructions(ctx context.Context, name string) (string, error) {
if name != "greeting-skill" {
return "", skill.ErrSkillNotFound
}
return "Step 1: Read the 'references/hello_world.txt' file to understand how to greet the user. Step 2: Return a greeting based on the reference.", nil
}
func (s *StaticSource) ListResources(ctx context.Context, name, subpath string) ([]string, error) {
if name != "greeting-skill" {
return nil, skill.ErrSkillNotFound
}
if !slices.Contains([]string{"", ".", "references", "references/"}, subpath) {
return nil, skill.ErrResourceNotFound
}
return []string{"references/hello_world.txt", "references/example.md"}, nil
}
func (s *StaticSource) LoadResource(ctx context.Context, name, resourcePath string) (io.ReadCloser, error) {
if name != "greeting-skill" {
return nil, skill.ErrSkillNotFound
}
switch resourcePath {
case "references/hello_world.txt":
return io.NopCloser(strings.NewReader("Hello! So glad to have you here!")), nil
case "references/example.md":
return io.NopCloser(strings.NewReader("This is an example reference.")), nil
default:
return nil, skill.ErrResourceNotFound
}
}
Note
Source 接口可以由任何数据存储(例如数据库)支持,以支持动态用例,如实时更新和个性化。
从文件系统读取技能¶
import pathlib
from google.adk.skills import load_skill_from_dir
from google.adk.tools import skill_toolset
greeting_skill = load_skill_from_dir(
pathlib.Path(__file__).parent / "skills" / "greeting-skill"
)
weather_skill = load_skill_from_dir(
pathlib.Path(__file__).parent / "skills" / "weather-skill"
)
my_skill_toolset = skill_toolset.SkillToolset(
skills=[weather_skill, greeting_skill],
)
import (
"os"
"google.golang.org/adk/tool/skilltoolset/skill"
"google.golang.org/adk/tool/skilltoolset"
)
// ...
source := skill.NewFileSystemSource(os.DirFS("./skills"))
// 此示例未使用任何可选包装器,但你可以根据需要
// 使用它们,例如:
// source, _, err = skill.WithFrontmatterPreloadSource(ctx, source)
// source, _, err = skill.WithCompletePreloadSource(ctx, source)
// 有关这些及其他包装器的更多信息,请参阅
// https://pkg.go.dev/google.golang.org/adk/tool/skilltoolset/skill#Source。
skillToolset, err := skilltoolset.New(ctx, skilltoolset.Config{
Source: source,
})
if err != nil {
// handle error
}
下一步¶
查看这些用于构建带有技能的智能体的资源: