에이전트 기술은 에이전트 에 특수한 기능 및 도메인 전문 지식을 제공하는 지침, 스크립트 및 리소스의 이식 가능한 패키지입니다. 기술은 개방형 사양을 따르고 점진적 공개 패턴을 구현하므로 에이전트는 필요할 때 필요한 컨텍스트만 로드합니다.
다음을 수행하려는 경우 에이전트 기술을 사용합니다.
- 패키지 도메인 전문 지식 - 재사용 가능한 이식 가능한 패키지로 전문 지식(비용 정책, 법적 워크플로, 데이터 분석 파이프라인)을 캡처합니다.
- 에이전트 기능 확장 - 핵심 지침을 변경하지 않고 에이전트에게 새로운 기능을 제공합니다.
- 일관성 보장 - 다단계 작업을 반복 가능하고 감사 가능한 워크플로로 전환합니다.
- 상호 운용성 활성화 - 다양한 대리 기술 호환 제품에서 동일한 기술을 재사용합니다.
기술 구조
기술은 리소스에 대한 선택적 하위 디렉터리가 있는 파일을 포함하는 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 프런트매터와 markdown 콘텐츠가 있어야 합니다.
---
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"
---
| 분야 | 필수 | Description |
|---|---|---|
name |
네 | 최대 64자 소문자, 숫자 및 하이픈만 해당됩니다. 하이픈으로 시작하거나 끝내거나 연속 하이픈을 포함해서는 안 됩니다. 부모 디렉터리 이름과 일치해야 합니다. |
description |
네 | 기술이 수행하는 기능 및 사용 시기. 최대 1024자 에이전트가 관련 작업을 식별하는 데 도움이 되는 키워드를 포함해야 합니다. |
license |
아니오 | 번들된 라이선스 파일에 대한 라이선스 이름 또는 참조입니다. |
compatibility |
아니오 | 최대 500자 환경 요구 사항(의도된 제품, 시스템 패키지, 네트워크 액세스 등)을 나타냅니다. |
metadata |
아니오 | 추가 메타데이터에 대한 임의의 키-값 매핑입니다. |
allowed-tools |
아니오 | 기술이 사용할 수 있는 미리 승인된 도구의 공간으로 구분된 목록입니다. 실험적 - 지원은 에이전트 구현마다 다를 수 있습니다. |
프런트매터 뒤의 markdown 본문에는 단계별 지침, 입력 및 출력 예제, 일반적인 에지 사례 또는 에이전트가 작업을 수행하는 데 도움이 되는 콘텐츠와 같은 기술 지침이 포함되어 있습니다. 500줄 미만으로 유지하고 SKILL.md 자세한 참조 자료를 별도의 파일로 이동합니다.
점진적 공개
에이전트 기술은 4단계 점진적 공개 패턴을 사용하여 컨텍스트 사용을 최소화합니다.
- Advertise (기술당 최대 100개 토큰) - 각 실행이 시작될 때 기술 이름과 설명이 시스템 프롬프트에 삽입되므로 에이전트는 사용 가능한 기술을 알 수 있습니다.
-
로드 (< 권장 토큰 5,000개) - 작업이 기술의 도메인과 일치하면 에이전트는 도구를 호출
load_skill하여 자세한 지침과 함께 전체 SKILL.md 본문을 검색합니다. -
필요한 경우 리소스 읽기 - 에이전트는 필요한 경우에만 보조 파일(참조, 템플릿, 자산)을 가져오기 위해 도구를 호출
read_skill_resource합니다. - 필요에 따라 스크립트 실행 - 에이전트가 도구를 호출하여 기술과 함께 번들링된 스크립트를 실행합니다.
이 패턴은 에이전트의 컨텍스트 창을 간결하게 유지하면서 요청 시 심층 도메인 지식에 액세스할 수 있도록 합니다.
비고
load_skill 는 항상 광고됩니다.
read_skill_resource 는 하나 이상의 기술에 리소스가 있는 경우에만 보급됩니다.
run_skill_script 는 하나 이상의 기술에 스크립트가 있는 경우에만 보급됩니다.
에이전트에 기술 제공
AgentSkillsProvider(C#) 및 SkillsProvider(Python)은 에이전트가 기술을 사용할 수 있도록 하는 컨텍스트 공급자입니다. 세 가지 기술 출처를 지원합니다.
- 파일 기반 - 파일 시스템 디렉터리에서 파일로 검색된 기술
-
코드 정의 -
AgentInlineSkill(C#) 또는Skill(Python)를 사용하여 코드에서 인라인으로 정의된 기술 -
클래스 기반 - C# 클래스에서
AgentClassSkill<T>파생된 기술(C#에만 해당)
한 공급자에서 여러 원본을 혼합하려면 (C# 전용 - AgentSkillsProviderBuilder 참조)를 사용합니다 .
파일 기반 기술
생성한 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);
경고
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을(를) 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;
using System.Text.Json;
static async Task<string> RunAsync(
AgentFileSkill skill,
AgentFileSkillScript script,
JsonElement? args,
IServiceProvider? serviceProvider)
{
var psi = new ProcessStartInfo("python3")
{
RedirectStandardOutput = true,
UseShellExecute = false,
};
psi.ArgumentList.Add(Path.Combine(skill.Path, script.Path));
if (args is { ValueKind: JsonValueKind.Array } json)
{
foreach (var element in json.EnumerateArray())
{
psi.ArgumentList.Add(element.GetString()!);
}
}
using var process = Process.Start(psi)!;
string output = await process.StandardOutput.ReadToEndAsync();
await process.WaitForExitAsync();
return output.Trim();
}
실행기는 검색된 각 스크립트를 로컬 하위 프로세스로 실행합니다. 파일 기반 스크립트는 문자열의 JSON 배열로 인수를 예상합니다. 각 배열 요소는 위치 명령줄 인수가 됩니다.
경고
SubprocessScriptRunner 은 데모용으로만 제공됩니다. 프로덕션 사용을 위해 다음을 추가하는 것이 좋습니다.
- 샌드박싱(예: 컨테이너 또는 격리된 실행 환경)
- 리소스 제한(CPU, 메모리, 벽시계 시간 제한)
- 실행 스크립트의 입력 유효성 검사 및 허용 목록
- 구조적 로깅 및 감사 추적
스크립트 검색 사용자 지정
기본적으로 공급자는 `.py` 하위 디렉터리에서 확장 `.js`, `.sh`, `.ps1`, `.cs`, `.csx`, 및 `scripts`가 포함된 스크립트를 인식합니다. 다음 기본값을 변경하는 데 사용합니다 AgentFileSkillsSourceOptions .
AgentFileSkillsSourceOptions 생성자에 전달하거나 빌더에 AgentSkillsProviderUseFileSkill / 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 검색됩니다.
경고
위의 실행기는 데모용으로만 제공됩니다. 프로덕션 사용을 위해 다음을 추가하는 것이 좋습니다.
- 샌드박싱(예: 컨테이너
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);
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 사용하여 함수를 리소스로 등록합니다. 이 함수는 에이전트가 리소스를 읽을 때마다 호출되므로 up-to-date 데이터를 반환할 수 있습니다. 동기화 및 비동기 함수는 모두 지원됩니다.
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 없이 사용하면 함수 이름이 리소스 이름이 되고 문서 문자열이 설명이 됩니다.
@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 없이 사용하면 함수 이름이 스크립트 이름이 되고 문서 문자열이 설명이 됩니다. 함수의 형식화된 매개 변수는 에이전트가 인수를 전달하는 데 사용하는 JSON 스키마로 자동으로 변환됩니다.
파일 기반 및 코드 정의 기술 결합
skill_paths와 skills를 둘 다 단일 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],
)
클래스 기반 기술
클래스 기반 기술을 사용하면 이름, 설명, 지침, 리소스 및 스크립트와 같은 모든 기술 구성 요소를 단일 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) 기술을 단일 공급자에 결합합니다. - 기술 필터링 - 조건자를 사용하여 기술을 포함하거나 제외합니다.
혼합 기술 유형
세 가지 기술 유형을 UseFileSkill, UseSkill, 및 UseFileScriptRunner을/를 연결하여 하나의 공급자로 결합합니다.
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,
});
비고
캐싱을 사용하지 않도록 설정하면 기술 콘텐츠가 자주 변경되는 경우 개발 중에 유용합니다. 프로덕션 환경에서 더 나은 성능을 위해 캐싱을 사용하도록 설정(기본값)으로 유지합니다.
종속성 주입
기술 리소스 및 스크립트 대리자는 에이전트 프레임워크가 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는 지침을 실행하는 방법을 결정합니다. 이는 에이전트가 창의적이거나 적응형이 되도록 하려는 경우에 이상적입니다. 워크플로를 사용하면 실행 경로를 명시적으로 정의합니다. 결정적이고 예측 가능한 동작이 필요한 경우 워크플로를 사용합니다.
- 복원력 - 기술은 단일 에이전트 턴 내에서 실행됩니다. 문제가 발생하면 전체 작업을 다시 시도해야 합니다. 워크플로는 검사점을 지원하므로 실패 후 마지막으로 성공한 단계에서 다시 시작할 수 있습니다. 전체 프로세스를 다시 실행하는 비용이 높은 경우 워크플로를 선택합니다.
- 부작용 - 작업이 멱등성이거나 위험이 낮은 경우, 기술을 적합하게 사용할 수 있습니다. 단계가 재시도 시 반복해서는 안 되는 부작용(이메일 보내기, 결제 청구)을 생성하는 경우 워크플로를 선호합니다.
- 복잡성 - 기술은 한 에이전트가 처리할 수 있는 집중적인 단일 도메인 작업에 가장 적합합니다. 워크플로는 여러 에이전트, 사용자 승인 또는 외부 시스템 통합을 조정하는 다단계 비즈니스 프로세스에 더 적합합니다.
팁 (조언)
일반적인 기준으로: AI가 작업을 수행하는 방법을 파악하려면 기술을 사용하세요. 실행되는 단계와 순서를 보장해야 하는 경우 워크플로를 사용합니다.