エージェント スキル は、エージェントに特化した機能とドメインの専門知識を提供する、命令、スクリプト、リソースの移植可能なパッケージです。 スキルはオープン仕様に従い、段階的な開示パターンを実装して、エージェントが必要なときに必要なコンテキストのみを読み込みます。
次の状況では、エージェント スキルを使用します。
- パッケージ ドメインの専門知識 - 再利用可能なポータブル パッケージとして、専門的な知識 (経費ポリシー、法的ワークフロー、データ分析パイプライン) をキャプチャします。
- エージェントの機能を拡張する - エージェントのコア命令を変更することなく、新しい機能をエージェントに提供します。
- 一貫性を確保 する - 複数ステップのタスクを、反復可能で監査可能なワークフローに変換します。
- 相互運用性を有効にする - 異なるエージェント スキル互換製品間で同じスキルを再利用します。
スキルの構造
スキルは、SKILL.md ファイルや、リソースのためのオプションのサブディレクトリを含むディレクトリです。
expense-report/
├── SKILL.md # Required — frontmatter + instructions
├── scripts/
│ └── validate.py # Executable code agents can run
├── references/
│ └── POLICY_FAQ.md # Reference documents loaded on demand
└── assets/
└── expense-report-template.md # Templates and static resources
SKILL.md 形式
SKILL.md ファイルには、YAML frontmatter とそれに続くマークダウン コンテンツが含まれている必要があります。
---
name: expense-report
description: File and validate employee expense reports according to company policy. Use when asked about expense submissions, reimbursement rules, or spending limits.
license: Apache-2.0
compatibility: Requires python3
metadata:
author: contoso-finance
version: "2.1"
---
| Field | 必須 | [説明] |
|---|---|---|
name |
イエス | 最大 64 文字。 小文字、数字、ハイフンのみ。 先頭または末尾にハイフンを使用したり、連続するハイフンを含めたりすることはできません。 親ディレクトリ名と一致する必要があります。 |
description |
イエス | スキルが実行する内容と、それを使用するタイミング。 最大 1024 文字。 エージェントが関連するタスクを識別するのに役立つキーワードを含める必要があります。 |
license |
いいえ | バンドルされたライセンス ファイルへのライセンス名または参照。 |
compatibility |
いいえ | 最大 500 文字。 環境要件 (目的の製品、システム パッケージ、ネットワーク アクセスなど) を示します。 |
metadata |
いいえ | 追加のメタデータに対するキーと値の任意のマッピング。 |
allowed-tools |
いいえ | スキルが使用する可能性がある、事前に承認されたツールのスペースで区切られた一覧。 試験段階 — サポートは、エージェントの実装によって異なる場合があります。 |
フロントマッターの後のマークダウン本文には、スキル命令 (ステップ バイ ステップ ガイダンス、入力と出力の例、一般的なエッジ ケース、エージェントがタスクを実行するのに役立つコンテンツ) が含まれています。
SKILL.md 500 行以下にし、詳細な参照マテリアルを別のファイルに移動します。
段階的な開示
エージェント スキルは、コンテキストの使用を最小限に抑えるために、4 段階のプログレッシブ開示パターンを使用します。
- アドバタイズ (スキルあたり最大 100 トークン) — スキル名と説明は、各実行の開始時にシステム プロンプトに挿入されるため、エージェントは使用可能なスキルを認識します。
-
読み込み (< 5,000 トークンを推奨) — タスクがスキルのドメインと一致すると、エージェントは
load_skillツールを呼び出して、詳細な手順で完全な SKILL.md 本文を取得します。 -
リソースの読み取り (必要に応じて) — エージェントは
read_skill_resourceツールを呼び出して、必要な場合にのみ補助ファイル (参照、テンプレート、資産) をフェッチします。 -
スクリプトの実行 (必要に応じて) - エージェントは
run_skill_scriptツールを呼び出して、スキルにバンドルされたスクリプトを実行します。
必要に応じてドメインの深い知識にアクセスできるようにしつつ、このパターンはエージェントのコンテキスト ウィンドウを簡素に保ちます。
注
load_skill は常にアドバタイズされます。
read_skill_resource は、少なくとも 1 つのスキルにリソースがある場合にのみアドバタイズされます。
run_skill_script は、少なくとも 1 つのスキルにスクリプトがある場合にのみアドバタイズされます。
エージェントにスキルを提供する
AgentSkillsProvider (C#) と SkillsProvider (Python) は、エージェントがスキルを使用できるようにするコンテキスト プロバイダーです。 次の 3 つのスキル ソースがサポートされています。
-
ファイル ベース — ファイルシステム ディレクトリ内の
SKILL.mdファイルから検出されたスキル -
Code-defined —
AgentInlineSkill(C#) またはSkill(Python) を使用してコード内でインラインで定義されたスキル -
クラスベース —
AgentClassSkill<T>から派生する C# クラスにカプセル化されたスキル (C# のみ)
1 つのプロバイダーで複数のソースを混在する場合は、 AgentSkillsProviderBuilder を使用します (C# のみ — Builder: 高度なマルチソース シナリオを参照)。
ファイル ベースのスキル
スキルを含むディレクトリを指す AgentSkillsProvider を作成し、エージェントのコンテキスト プロバイダーに追加します。 スクリプト ランナーを渡して、スキル ディレクトリにあるファイル ベースのスクリプトの実行を有効にします。
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using OpenAI.Responses;
string endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!;
string deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
// Discover skills from the 'skills' directory
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"));
// Create an agent with the skills provider
AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
.GetResponsesClient()
.AsAIAgent(new ChatClientAgentOptions
{
Name = "SkillsAgent",
ChatOptions = new()
{
Instructions = "You are a helpful assistant.",
},
AIContextProviders = [skillsProvider],
},
model: deploymentName);
Warnung
DefaultAzureCredential は開発には便利ですが、運用環境では慎重に考慮する必要があります。 運用環境では、待機時間の問題、意図しない資格情報のプローブ、フォールバック メカニズムによる潜在的なセキュリティ リスクを回避するために、特定の資格情報 ( ManagedIdentityCredential など) を使用することを検討してください。
複数のスキル ディレクトリ
プロバイダーを単一の親ディレクトリに指定できます。 SKILL.md を含む各サブディレクトリは、スキルとして自動的に検出されます。
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "all-skills"));
または、パスの一覧を渡して、複数のルート ディレクトリを検索します。
var skillsProvider = new AgentSkillsProvider(
[
Path.Combine(AppContext.BaseDirectory, "company-skills"),
Path.Combine(AppContext.BaseDirectory, "team-skills"),
]);
プロバイダーは、最大 2 つのレベルの深さまで検索します。
リソース検出のカスタマイズ
既定では、プロバイダーは、拡張機能の .md、 .json、 .yaml、 .yml、 .csv、 .xml、および .txt を持つリソースを references および assets サブディレクトリで認識します。
AgentFileSkillsSourceOptionsを使用して、次の既定値を変更します。
var fileOptions = new AgentFileSkillsSourceOptions
{
AllowedResourceExtensions = [".md", ".txt"],
ResourceDirectories = ["docs", "templates"],
};
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
fileOptions: fileOptions);
スクリプトの実行
SubprocessScriptRunner.RunAsyncを 2 番目の引数として渡してAgentSkillsProviderし、ファイル ベースのスクリプトの実行を有効にします。
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
SubprocessScriptRunner.RunAsync);
SubprocessScriptRunner.RunAsync は、次とほぼ同じです。
// Simplified equivalent of what SubprocessScriptRunner.RunAsync does internally
using System.Diagnostics;
static async Task<string> RunAsync(AgentSkill skill, AgentSkillScript script, IDictionary<string, object?>? args)
{
var psi = new ProcessStartInfo("python3")
{
RedirectStandardOutput = true,
UseShellExecute = false,
};
psi.ArgumentList.Add(Path.Combine(skill.Path, script.Path));
if (args != null)
{
foreach (var (key, value) in args)
{
if (value is not null)
{
psi.ArgumentList.Add($"--{key}");
psi.ArgumentList.Add(value.ToString()!);
}
}
}
using var process = Process.Start(psi)!;
string output = await process.StandardOutput.ReadToEndAsync();
await process.WaitForExitAsync();
return output.Trim();
}
ランナーは、検出された各スクリプトをローカル サブプロセスとして実行し、エージェントによって提供される JSON 引数をコマンド ライン フラグとして転送します。
Warnung
SubprocessScriptRunner はデモ目的 でのみ提供されます。 運用環境で使用する場合は、次の追加を検討してください。
- サンドボックス (コンテナーや分離された実行環境など)
- リソース制限 (CPU、メモリ、ウォール クロック タイムアウト)
- 実行可能スクリプトの入力検証と許可リスト
- 構造化されたログ記録と監査証跡
スクリプト検出のカスタマイズ
既定では、プロバイダーは、.py サブディレクトリ内の拡張機能.js、.sh、.ps1、.cs、.csx、およびscriptsを持つスクリプトを認識します。
AgentFileSkillsSourceOptionsを使用して、次の既定値を変更します。
AgentFileSkillsSourceOptionsをAgentSkillsProviderコンストラクターまたはビルダーのUseFileSkill / UseFileSkillsに渡します。
var fileOptions = new AgentFileSkillsSourceOptions
{
AllowedScriptExtensions = [".py"],
ScriptDirectories = ["scripts", "tools"],
};
// Via constructor
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
fileOptions: fileOptions);
// Via builder
var skillsProvider = new AgentSkillsProviderBuilder()
.UseFileSkill(Path.Combine(AppContext.BaseDirectory, "skills"), options: fileOptions)
.Build();
ファイル ベースのスキル
スキルを含むディレクトリを指す SkillsProvider を作成し、エージェントのコンテキスト プロバイダーに追加します。
import os
from pathlib import Path
from agent_framework import SkillsProvider
from agent_framework.openai import OpenAIChatCompletionClient
from azure.identity.aio import AzureCliCredential
# Discover skills from the 'skills' directory
skills_provider = SkillsProvider(
skill_paths=Path(__file__).parent / "skills"
)
# Create an agent with the skills provider
agent = OpenAIChatCompletionClient(
model=os.environ["AZURE_OPENAI_CHAT_COMPLETION_MODEL"],
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
credential=AzureCliCredential(),
).as_agent(
name="SkillsAgent",
instructions="You are a helpful assistant.",
context_providers=[skills_provider],
)
複数のスキル ディレクトリ
プロバイダーを単一の親フォルダーに指定できます。 SKILL.md を含む各サブフォルダーはスキルとして自動的に検出されます。
skills_provider = SkillsProvider(
skill_paths=Path(__file__).parent / "all-skills"
)
または、パスの一覧を渡して、複数のルート ディレクトリを検索します。
skills_provider = SkillsProvider(
skill_paths=[
Path(__file__).parent / "company-skills",
Path(__file__).parent / "team-skills",
]
)
プロバイダーは、最大 2 つのレベルの深さまで検索します。
リソース検出のカスタマイズ
既定では、 SkillsProvider は、拡張機能 .md、 .json、 .yaml、 .yml、 .csv、 .xml、および .txtを持つリソースを認識します。 各スキル フォルダー内のすべてのサブディレクトリをスキャンします。
resource_extensionsを渡して、認識されるファイルの種類を変更します。
skills_provider = SkillsProvider(
skill_paths=Path(__file__).parent / "skills",
resource_extensions=(".md", ".txt"),
)
スクリプトの実行
ファイル ベースのスクリプトの実行を有効にするには、 script_runner を SkillsProviderに渡します。
SkillScriptRunner プロトコルを満たす任意の同期または非同期呼び出し可能な呼び出しを使用できます。
from pathlib import Path
from agent_framework import Skill, SkillScript, SkillsProvider
def my_runner(skill: Skill, script: SkillScript, args: dict | None = None) -> str:
"""Run a file-based script as a subprocess."""
import subprocess, sys
cmd = [sys.executable, str(Path(skill.path) / script.path)]
if args:
for key, value in args.items():
if value is not None:
cmd.extend([f"--{key}", str(value)])
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
return result.stdout.strip()
skills_provider = SkillsProvider(
skill_paths=Path(__file__).parent / "skills",
script_runner=my_runner,
)
ランナーは、解決済みのSkill、SkillScript、およびオプションのargs辞書を受け取ります。 ファイル ベースのスクリプトは、スキル ディレクトリ内の .py ファイルから自動的に検出されます。
Warnung
上記のランナーはデモンストレーション目的 でのみ提供されます。 運用環境で使用する場合は、次の追加を検討してください。
- サンドボックス (コンテナー、
seccomp、firejailなど) - リソース制限 (CPU、メモリ、ウォール クロック タイムアウト)
- 実行可能スクリプトの入力検証と許可リスト
- 構造化されたログ記録と監査証跡
注
スクリプトを使用したファイル ベースのスキルが提供されていても、 script_runner が設定されていない場合、 SkillsProvider は ValueErrorを発生させます。
コード定義スキル
SKILL.md ファイルから検出されたファイル ベースのスキルに加えて、AgentInlineSkillを使用してコード内でスキルを完全に定義できます。 コード定義スキルは、次の場合に役立ちます。
- スキル コンテンツは動的に生成されます (データベースや環境からの読み取りなど)。
- スキル定義は、それらを使用するアプリケーション コードと共に保持する必要があります。
- 静的ファイルを提供するのではなく、読み取り時にロジックを実行するリソースが必要です。
基本的なコード スキル
名前、説明、および手順を含む AgentInlineSkill を作成します。
.AddResource()を使用してリソースをアタッチします。
using Microsoft.Agents.AI;
var codeStyleSkill = new AgentInlineSkill(
name: "code-style",
description: "Coding style guidelines and conventions for the team",
instructions: """
Use this skill when answering questions about coding style, conventions, or best practices for the team.
1. Read the style-guide resource for the full set of rules.
2. Answer based on those rules, quoting the relevant guideline where helpful.
""")
.AddResource(
"style-guide",
"""
# Team Coding Style Guide
- Use 4-space indentation (no tabs)
- Maximum line length: 120 characters
- Use type annotations on all public methods
""");
var skillsProvider = new AgentSkillsProvider(codeStyleSkill);
動的リソース
ファクトリ デリゲートを .AddResource() に渡して、実行時にコンテンツを計算します。 デリゲートは、エージェントがリソースを読み取るたびに呼び出されます。
var projectInfoSkill = new AgentInlineSkill(
name: "project-info",
description: "Project status and configuration information",
instructions: """
Use this skill for questions about the current project.
1. Read the environment resource for deployment configuration details.
2. Read the team-roster resource for information about team members.
""")
.AddResource("environment", () =>
{
string env = Environment.GetEnvironmentVariable("APP_ENV") ?? "development";
string region = Environment.GetEnvironmentVariable("APP_REGION") ?? "us-east-1";
return $"Environment: {env}, Region: {region}";
})
.AddResource(
"team-roster",
"Alice Chen (Tech Lead), Bob Smith (Backend Engineer)");
コード定義スクリプト
.AddScript()を使用して、実行可能スクリプトとしてデリゲートを登録します。 コード定義スクリプトは、直接デリゲート呼び出しとして インプロセスで 実行されます。 スクリプト ランナーは必要ありません。 デリゲートの型指定されたパラメーターは、エージェントが引数を渡すために使用する JSON スキーマに自動的に変換されます。
using System.Text.Json;
var unitConverterSkill = new AgentInlineSkill(
name: "unit-converter",
description: "Convert between common units using a conversion factor",
instructions: """
Use this skill when the user asks to convert between units.
1. Review the conversion-table resource to find the correct factor.
2. Use the convert script, passing the value and factor from the table.
3. Present the result clearly with both units.
""")
.AddResource(
"conversion-table",
"""
# Conversion Tables
Formula: **result = value × factor**
| From | To | Factor |
|------------|------------|----------|
| miles | kilometers | 1.60934 |
| kilometers | miles | 0.621371 |
| pounds | kilograms | 0.453592 |
| kilograms | pounds | 2.20462 |
""")
.AddScript("convert", (double value, double factor) =>
{
double result = Math.Round(value * factor, 4);
return JsonSerializer.Serialize(new { value, factor, result });
});
var skillsProvider = new AgentSkillsProvider(unitConverterSkill);
注
コード定義スキルとファイル ベースまたはクラスベースのスキルを 1 つのプロバイダーで組み合わせるには、 AgentSkillsProviderBuilder を使用します。 「Builder: 高度なマルチソース シナリオ」を参照してください。
SKILL.md ファイルから検出されたファイル ベースのスキルに加えて、Python コードでスキルを完全に定義できます。 コード定義スキルは、次の場合に役立ちます。
- スキル コンテンツは動的に生成されます (データベースや環境からの読み取りなど)。
- スキル定義は、それらを使用するアプリケーション コードと共に保持する必要があります。
- 静的ファイルを提供するのではなく、読み取り時にロジックを実行するリソースが必要です。
基本的なコード スキル
名前、説明、および命令の内容を含む Skill インスタンスを作成します。 必要に応じて、静的コンテンツ SkillResource インスタンスをアタッチします。
from textwrap import dedent
from agent_framework import Skill, SkillResource, SkillsProvider
code_style_skill = Skill(
name="code-style",
description="Coding style guidelines and conventions for the team",
content=dedent("""\
Use this skill when answering questions about coding style,
conventions, or best practices for the team.
"""),
resources=[
SkillResource(
name="style-guide",
content=dedent("""\
# Team Coding Style Guide
- Use 4-space indentation (no tabs)
- Maximum line length: 120 characters
- Use type annotations on all public functions
"""),
),
],
)
skills_provider = SkillsProvider(skills=[code_style_skill])
動的リソース
@skill.resource デコレーターを使用して、関数をリソースとして登録します。 この関数は、エージェントがリソースを読み取るたびに呼び出されるため、最新のデータを返すことができます。 同期関数と非同期関数の両方がサポートされています。
import os
from agent_framework import Skill
project_info_skill = Skill(
name="project-info",
description="Project status and configuration information",
content="Use this skill for questions about the current project.",
)
@project_info_skill.resource
def environment() -> Any:
"""Get current environment configuration."""
env = os.environ.get("APP_ENV", "development")
region = os.environ.get("APP_REGION", "us-east-1")
return f"Environment: {env}, Region: {region}"
@project_info_skill.resource(name="team-roster", description="Current team members")
def get_team_roster() -> Any:
"""Return the team roster."""
return "Alice Chen (Tech Lead), Bob Smith (Backend Engineer)"
引数 (@skill.resource) なしでデコレーターを使用すると、関数名がリソース名になり、docstring が説明になります。
@skill.resource(name="...", description="...")を使用して明示的に設定します。
コード定義スクリプト
@skill.scriptデコレーターを使用して、スキルの実行可能スクリプトとして関数を登録します。 コード定義スクリプトは インプロセスで 実行され、スクリプト 実行プログラムは必要ありません。 同期関数と非同期関数の両方がサポートされています。
from agent_framework import Skill
unit_converter_skill = Skill(
name="unit-converter",
description="Convert between common units using a conversion factor",
content="Use the convert script to perform unit conversions.",
)
@unit_converter_skill.script(name="convert", description="Convert a value: result = value × factor")
def convert_units(value: float, factor: float) -> str:
"""Convert a value using a multiplication factor."""
import json
result = round(value * factor, 4)
return json.dumps({"value": value, "factor": factor, "result": result})
引数 (@skill.script) なしでデコレーターを使用すると、関数名がスクリプト名になり、docstring が説明になります。 関数の型指定されたパラメーターは、エージェントが引数を渡すために使用する JSON スキーマに自動的に変換されます。
ファイル ベースのスキルとコード定義スキルの組み合わせ
skill_pathsとskillsの両方を 1 つのSkillsProviderに渡します。 ファイルベースのスキルが最初に検出されます。コード定義スキルが既存のファイルベースのスキルと同じ名前を持つ場合、コード定義スキルはスキップされます。
from pathlib import Path
from agent_framework import Skill, SkillsProvider
my_skill = Skill(
name="my-code-skill",
description="A code-defined skill",
content="Instructions for the skill.",
)
skills_provider = SkillsProvider(
skill_paths=Path(__file__).parent / "skills",
skills=[my_skill],
)
クラスベースのスキル
クラスベースのスキルを使用すると、すべてのスキル コンポーネント (名前、説明、命令、リソース、スクリプト) を 1 つの C# クラスにバンドルできます。
AgentClassSkill<T> (クラスT) から派生し、自動検出のためにプロパティに[AgentSkillResource]とメソッドに[AgentSkillScript]注釈を付けます。
using System.ComponentModel;
using System.Text.Json;
using Microsoft.Agents.AI;
internal sealed class UnitConverterSkill : AgentClassSkill<UnitConverterSkill>
{
public override AgentSkillFrontmatter Frontmatter { get; } = new(
"unit-converter",
"Convert between common units using a multiplication factor. Use when asked to convert miles, kilometers, pounds, or kilograms.");
protected override string Instructions => """
Use this skill when the user asks to convert between units.
1. Review the conversion-table resource to find the correct factor.
2. Use the convert script, passing the value and factor from the table.
3. Present the result clearly with both units.
""";
[AgentSkillResource("conversion-table")]
[Description("Lookup table of multiplication factors for common unit conversions.")]
public string ConversionTable => """
# Conversion Tables
Formula: **result = value × factor**
| From | To | Factor |
|------------|------------|----------|
| miles | kilometers | 1.60934 |
| kilometers | miles | 0.621371 |
| pounds | kilograms | 0.453592 |
| kilograms | pounds | 2.20462 |
""";
[AgentSkillScript("convert")]
[Description("Multiplies a value by a conversion factor and returns the result as JSON.")]
private static string ConvertUnits(double value, double factor)
{
double result = Math.Round(value * factor, 4);
return JsonSerializer.Serialize(new { value, factor, result });
}
}
クラスベースのスキルを AgentSkillsProviderに登録します。
var skill = new UnitConverterSkill();
var skillsProvider = new AgentSkillsProvider(skill);
[AgentSkillResource]属性がプロパティまたはメソッドに適用される場合、その戻り値は、エージェントがリソースを読み取るときにリソース コンテンツとして使用されます。読み取り時にコンテンツを計算する必要がある場合はメソッドを使用します。
[AgentSkillScript]がメソッドに適用されると、エージェントがスクリプトを呼び出すときにメソッドが呼び出されます。
[Description]のSystem.ComponentModelを使用して、エージェントの各リソースとスクリプトを記述します。
注
AgentClassSkill<T> では、属性ベースの検出が適合しないシナリオのコレクションとして、 Resources と Scripts のオーバーライドもサポートされています。
ビルダー: 高度なマルチソース シナリオ
単一ソースの単純なシナリオでは、 AgentSkillsProvider コンストラクターを直接使用します。 次のいずれかが必要な場合は、 AgentSkillsProviderBuilder を使用します。
-
混合スキルの種類 - ファイル ベース、コード定義 (
AgentInlineSkill)、クラスベース (AgentClassSkill) のスキルを 1 つのプロバイダーで結合します。 - スキル のフィルター処理 — 述語を使用してスキルを含めるか除外します。
混合スキルの種類
UseFileSkill、UseSkill、UseFileScriptRunnerを連結して、1 つのプロバイダーに 3 つのスキルの種類をすべて結合します。
var skillsProvider = new AgentSkillsProviderBuilder()
.UseFileSkill(Path.Combine(AppContext.BaseDirectory, "skills")) // file-based skills
.UseSkill(volumeConverterSkill) // AgentInlineSkill
.UseSkill(temperatureConverter) // AgentClassSkill
.UseFileScriptRunner(SubprocessScriptRunner.RunAsync) // runner for file scripts
.Build();
スキルフィルタリング
UseFilterを使用して、条件を満たすスキルのみを含めます。たとえば、共有ディレクトリからスキルを読み込み、試験的なスキルは除外します。
var approvedSkillNames = new HashSet<string> { "expense-report", "code-style" };
var skillsProvider = new AgentSkillsProviderBuilder()
.UseFileSkill(Path.Combine(AppContext.BaseDirectory, "skills"))
.UseFilter(skill => approvedSkillNames.Contains(skill.Frontmatter.Name))
.Build();
スクリプトの承認
AgentSkillsProviderOptions.ScriptApprovalを使用して、人間の承認の背後にあるすべてのスクリプト実行をゲートします。 有効にすると、エージェントは一時停止し、すぐに実行するのではなく、承認要求を返します。
var skillsProvider = new AgentSkillsProvider(
skillPath: Path.Combine(AppContext.BaseDirectory, "skills"),
options: new AgentSkillsProviderOptions
{
ScriptApproval = true,
});
ビルダーが構成したプロバイダーでスクリプトの承認を有効にするには、次の UseScriptApprovalを使用します。
var skillsProvider = new AgentSkillsProviderBuilder()
.UseFileSkill(Path.Combine(AppContext.BaseDirectory, "skills"))
.UseScriptApproval(true)
.Build();
require_script_approval=TrueのSkillsProviderを使用して、人間の承認の背後にあるすべてのスクリプト実行をゲートします。 エージェントは、すぐに実行するのではなく、承認要求を一時停止して返します。
from agent_framework import Agent, Skill, SkillsProvider
# Create provider with approval enabled
skills_provider = SkillsProvider(
skills=[my_skill],
require_script_approval=True,
)
# Run the agent — script calls pause for approval
result = await agent.run("Deploy version 2.5.0 to production", session=session)
# Handle approval requests
while result.user_input_requests:
for request in result.user_input_requests:
print(f"Script: {request.function_call.name}")
print(f"Args: {request.function_call.arguments}")
approval = request.to_function_approval_response(approved=True)
result = await agent.run(approval, session=session)
スクリプトが拒否されると (approved=False)、エージェントはユーザーが辞退したことを通知され、それに応じて応答できます。
カスタム システム プロンプト
既定では、スキル プロバイダーは、使用可能なスキルを一覧表示するシステム プロンプトを挿入し、 load_skill と read_skill_resourceを使用するようにエージェントに指示します。 このプロンプトは、次のようにカスタマイズできます。
var skillsProvider = new AgentSkillsProvider(
skillPath: Path.Combine(AppContext.BaseDirectory, "skills"),
options: new AgentSkillsProviderOptions
{
SkillsInstructionPrompt = """
You have skills available. Here they are:
{skills}
{resource_instructions}
{script_instructions}
"""
});
注
カスタム テンプレートには、 {skills} (スキル リスト)、 {resource_instructions} (リソース ツール ヒント)、および {script_instructions} (スクリプト ツール ヒント) プレースホルダーが含まれている必要があります。 リテラルの中括弧は{{および}}としてエスケープする必要があります。
skills_provider = SkillsProvider(
skill_paths=Path(__file__).parent / "skills",
instruction_template=(
"You have skills available. Here they are:\n{skills}\n"
"Use the `load_skill` function to get skill instructions.\n"
"Use the `read_skill_resource` function to read skill files."
),
)
注
カスタム テンプレートには、スキル リストが挿入される {skills} プレースホルダーと、スクリプト関連の命令が挿入される {runner_instructions} プレースホルダーが含まれている必要があります。
キャッシュ動作
既定では、スキル ツールと命令は最初のビルドの後にキャッシュされます。
DisableCaching = trueにAgentSkillsProviderOptionsを設定して、すべての呼び出しで強制的に再構築します。
var skillsProvider = new AgentSkillsProvider(
Path.Combine(AppContext.BaseDirectory, "skills"),
options: new AgentSkillsProviderOptions
{
DisableCaching = true,
});
注
キャッシュの無効化は、スキル コンテンツが頻繁に変更される開発時に役立ちます。 運用環境では、パフォーマンスを向上させるためにキャッシュを有効のままにします (既定値)。
依存関係の挿入
スキル リソースとスクリプト デリゲートは、Agent Framework によって自動的に挿入される IServiceProvider パラメーターを宣言できます。 これにより、スキルは、スキル定義にハードコーディングすることなく、データベース クライアント、構成、ビジネス ロジックなどのアプリケーション サービスを解決できます。
セットアップ
アプリケーション サービスを登録し、IServiceProvider パラメーターを使用してビルドされたservicesをエージェントに渡します。
using Microsoft.Extensions.DependencyInjection;
// Register application services
ServiceCollection services = new();
services.AddSingleton<ConversionService>();
IServiceProvider serviceProvider = services.BuildServiceProvider();
// Create the agent and pass the service provider
AIAgent agent = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
.GetResponsesClient()
.AsAIAgent(
options: new ChatClientAgentOptions
{
Name = "ConverterAgent",
ChatOptions = new() { Instructions = "You are a helpful assistant." },
AIContextProviders = [skillsProvider],
},
model: deploymentName,
services: serviceProvider);
DI を使用したコード定義スキル
IServiceProviderまたはAddResourceデリゲートでパラメーターとしてAddScriptを宣言します。フレームワークは、エージェントがリソースを読み取ったりスクリプトを実行したりすると、フレームワークによって自動的に解決され、挿入されます。
var distanceSkill = new AgentInlineSkill(
name: "distance-converter",
description: "Convert between distance units (miles and kilometers).",
instructions: """
Use this skill when the user asks to convert between miles and kilometers.
1. Read the distance-table resource for conversion factors.
2. Use the convert script to compute the result.
""")
.AddResource("distance-table", (IServiceProvider sp) =>
{
return sp.GetRequiredService<ConversionService>().GetDistanceTable();
})
.AddScript("convert", (double value, double factor, IServiceProvider sp) =>
{
return sp.GetRequiredService<ConversionService>().Convert(value, factor);
});
DI を使用したクラスベースのスキル
[AgentSkillResource]または[AgentSkillScript]を使用してメソッドに注釈を付け、IServiceProvider パラメーターを宣言します。フレームワークはリフレクションを介してこれらのメンバーを検出し、サービス プロバイダーを自動的に挿入します。
internal sealed class WeightConverterSkill : AgentClassSkill<WeightConverterSkill>
{
public override AgentSkillFrontmatter Frontmatter { get; } = new(
"weight-converter",
"Convert between weight units (pounds and kilograms).");
protected override string Instructions => """
Use this skill when the user asks to convert between pounds and kilograms.
1. Read the weight-table resource for conversion factors.
2. Use the convert script to compute the result.
""";
[AgentSkillResource("weight-table")]
[Description("Lookup table of multiplication factors for weight conversions.")]
private static string GetWeightTable(IServiceProvider serviceProvider)
{
return serviceProvider.GetRequiredService<ConversionService>().GetWeightTable();
}
[AgentSkillScript("convert")]
[Description("Multiplies a value by a conversion factor and returns the result as JSON.")]
private static string Convert(double value, double factor, IServiceProvider serviceProvider)
{
return serviceProvider.GetRequiredService<ConversionService>().Convert(value, factor);
}
}
ヒント
クラスベースのスキルは、 コンストラクターを介して依存関係を解決することもできます。
ServiceCollectionにスキル クラスを登録し、newを直接呼び出す代わりにコンテナーから解決します。
services.AddSingleton<WeightConverterSkill>();
var weightSkill = serviceProvider.GetRequiredService<WeightConverterSkill>();
これは、スキル クラス自体が、リソースおよびスクリプト デリゲートが使用するものを超えるサービスを挿入する必要がある場合に便利です。
**kwargsを受け入れるリソース関数とスクリプト関数は、agent.run()に渡されたランタイム キーワード引数を自動的に受け取ります。 これにより、スキル関数は、構成、ユーザー ID、サービス クライアントなどのアプリケーション コンテキストにアクセスできます。スキル定義にハードコーディングする必要はありません。
ランタイム引数の受け渡し
function_invocation_kwargsをagent.run()に渡して、フレームワークがリソースおよびスクリプト関数に転送するキーワード引数を指定します。
response = await agent.run(
"How many kilometers is 26.2 miles?",
function_invocation_kwargs={"precision": 2, "user_id": "alice"},
)
kwargs を使用したリソース関数
リソース関数が **kwargsを宣言すると、フレームワークは、エージェントがリソースを読み取るたびにランタイム キーワード引数を転送します。
from typing import Any
from agent_framework import Skill
project_info_skill = Skill(
name="project-info",
description="Project status and configuration information",
content="Use this skill for questions about the current project.",
)
@project_info_skill.resource(name="environment", description="Current environment configuration")
def environment(**kwargs: Any) -> Any:
"""Return environment config, optionally scoped to a user."""
user_id = kwargs.get("user_id", "anonymous")
env = os.environ.get("APP_ENV", "development")
return f"Environment: {env}, Caller: {user_id}"
**kwargsを持たないリソース関数は、引数なしで呼び出され、ランタイム コンテキストを受け取りません。
kwargs を使用したスクリプト関数
スクリプト関数が **kwargs を宣言すると、フレームワークはランタイム キーワード引数をエージェントによって提供される args と共に転送します。
import json
from typing import Any
from agent_framework import Skill
converter_skill = Skill(
name="unit-converter",
description="Convert between common units using a conversion factor",
content="Use the convert script to perform unit conversions.",
)
@converter_skill.script(name="convert", description="Convert a value: result = value × factor")
def convert_units(value: float, factor: float, **kwargs: Any) -> str:
"""Convert a value using a multiplication factor.
Args:
value: The numeric value to convert (provided by the agent).
factor: Conversion factor (provided by the agent).
**kwargs: Runtime keyword arguments from agent.run().
"""
precision = kwargs.get("precision", 4)
result = round(value * factor, precision)
return json.dumps({"value": value, "factor": factor, "result": result})
エージェントは、ツール呼び出しvalueを介してfactorとargsを提供します。アプリケーションは、precisionを介してfunction_invocation_kwargsを提供します。
**kwargsを持たないスクリプト関数は、エージェントによって提供される引数のみを受け取ります。
セキュリティのベスト プラクティス
エージェント スキルは、プロジェクトに取り込むサードパーティのコードと同様に扱う必要があります。スキル命令はエージェントのコンテキストに挿入され、スキルにはスクリプトを含めることができるため、オープンソースの依存関係に対して行うのと同じレベルのレビューとガバナンスを適用することが不可欠です。
-
使用前に確認 する — デプロイする前にすべてのスキル コンテンツ (
SKILL.md、スクリプト、リソース) を読み取ります。 スクリプトの実際の動作が、指定された意図と一致することを確認します。 安全性ガイドラインのバイパス、データの流出、またはエージェント構成ファイルの変更を試みる敵対的な指示を確認します。 - ソース信頼 - 信頼できる作成者または審査済みの内部共同作成者からのスキルのみをインストールします。 明確な由来、バージョン管理、アクティブなメンテナンスを備えたスキルやツールを優先します。 人気のあるパッケージを模倣する入力ミスのスキル名を警戒してください。
- サンドボックス - 分離された環境で実行可能スクリプトを含むスキルを実行します。 ファイルシステム、ネットワーク、システム レベルのアクセスを、スキルに必要なもののみに制限します。 機密性の高い操作を実行する前に、明示的なユーザー確認が必要です。
- 監査とログ 記録 - 読み込まれるスキル、読み取られるリソース、実行されるスクリプトを記録します。 これにより、問題が発生した場合にエージェントの動作を特定のスキル コンテンツに戻す監査証跡が提供されます。
スキルとワークフローを使用するタイミング
エージェント スキルと エージェント フレームワーク ワークフロー はどちらもエージェントが実行できる機能を拡張しますが、基本的に異なる方法で動作します。 要件に最も適したアプローチを選択します。
- 制御 — スキルを使用して、AI が命令の実行方法を決定します。 これは、エージェントをクリエイティブまたはアダプティブにする場合に最適です。 ワークフローでは、実行パスを明示的に定義します。 確定的で予測可能な動作が必要な場合は、ワークフローを使用します。
- 回復性 - 1 つのエージェント ターン内でスキルが実行されます。 何かが失敗した場合は、操作全体を再試行する必要があります。 ワークフローは チェックポイント処理をサポートしているため、失敗後に最後に成功した手順から再開できます。 プロセス全体の再実行コストが高い場合は、ワークフローを選択します。
- 副作用、スキルは、操作が同じ結果を保証するか低リスクである場合に適しています。 再試行時に繰り返してはならない副作用 (電子メールの送信、支払いの請求) がステップによって発生する場合は、ワークフローを優先します。
- 複雑さ — スキルは、1 つのエージェントが処理できる集中型の単一ドメイン タスクに最適です。 ワークフローは、複数のエージェント、人間の承認、または外部システム統合を調整する複数ステップのビジネス プロセスに適しています。
ヒント
経験則として、AI にタスクの実行 方法 を把握させる場合は、スキルを使用します。 実行するステップと順序を保証する必要がある場合は、ワークフローを使用します。