.NET: Add .NET Anthropic Claude Skills sample (#3497)

* Initial plan

* Add Claude Skills sample and integration tests for Anthropic

- Add Agent_Anthropic_Step04_UsingSkills sample demonstrating pptx skill usage
- Add integration tests for skills functionality
- Update README.md with new sample reference
- Update solution file to include new sample project

Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com>

* Simplify Anthropic Skills sample with AsAITool and add file download

* Remove excessive comments from integration tests

* Update README with correct model name and syntax

* Fix Anthropic SDK 12.3.0 API changes: APIKey->ApiKey, SkillListPageResponse->SkillListPage, Data->Items

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com>
This commit is contained in:
Copilot
2026-02-04 17:49:49 +00:00
committed by GitHub
Unverified
parent e8902c0d11
commit de78348d76
6 changed files with 334 additions and 0 deletions
+1
View File
@@ -131,6 +131,7 @@
<Project Path="samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step01_Running/Agent_Anthropic_Step01_Running.csproj" />
<Project Path="samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step02_Reasoning/Agent_Anthropic_Step02_Reasoning.csproj" />
<Project Path="samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step03_UsingFunctionTools/Agent_Anthropic_Step03_UsingFunctionTools.csproj" />
<Project Path="samples/GettingStarted/AgentWithAnthropic/Agent_Anthropic_Step04_UsingSkills/Agent_Anthropic_Step04_UsingSkills.csproj" />
</Folder>
<Folder Name="/Samples/GettingStarted/AgentWithMemory/">
<File Path="samples/GettingStarted/AgentWithMemory/README.md" />
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\src\Microsoft.Agents.AI.Anthropic\Microsoft.Agents.AI.Anthropic.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,127 @@
// Copyright (c) Microsoft. All rights reserved.
// This sample demonstrates how to use Anthropic-managed Skills with an AI agent.
// Skills are pre-built capabilities provided by Anthropic that can be used with the Claude API.
// This sample shows how to:
// 1. List available Anthropic-managed skills
// 2. Use the pptx skill to create PowerPoint presentations
// 3. Download and save generated files
using Anthropic;
using Anthropic.Core;
using Anthropic.Models.Beta;
using Anthropic.Models.Beta.Files;
using Anthropic.Models.Beta.Messages;
using Anthropic.Models.Beta.Skills;
using Anthropic.Services;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
string apiKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY") ?? throw new InvalidOperationException("ANTHROPIC_API_KEY is not set.");
// Skills require Claude 4.5 models (Sonnet 4.5, Haiku 4.5, or Opus 4.5)
string model = Environment.GetEnvironmentVariable("ANTHROPIC_MODEL") ?? "claude-sonnet-4-5-20250929";
// Create the Anthropic client
AnthropicClient anthropicClient = new() { ApiKey = apiKey };
// List available Anthropic-managed skills (optional - API may not be available in all regions)
Console.WriteLine("Available Anthropic-managed skills:");
try
{
SkillListPage skills = await anthropicClient.Beta.Skills.List(
new SkillListParams { Source = "anthropic", Betas = [AnthropicBeta.Skills2025_10_02] });
foreach (var skill in skills.Items)
{
Console.WriteLine($" {skill.Source}: {skill.ID} (version: {skill.LatestVersion})");
}
}
catch (Exception ex)
{
Console.WriteLine($" (Skills listing not available: {ex.Message})");
}
Console.WriteLine();
// Define the pptx skill - the SDK handles all beta flags and container configuration automatically
// when using AsAITool(), so no manual RawRepresentationFactory configuration is needed.
BetaSkillParams pptxSkill = new()
{
Type = BetaSkillParamsType.Anthropic,
SkillID = "pptx",
Version = "latest"
};
// Create an agent with the pptx skill enabled.
// Skills require extended thinking and higher max tokens for complex file generation.
// The SDK's AsAITool() handles beta flags and container config automatically.
ChatClientAgent agent = anthropicClient.Beta.AsAIAgent(
model: model,
instructions: "You are a helpful agent for creating PowerPoint presentations.",
tools: [pptxSkill.AsAITool()],
clientFactory: (chatClient) => chatClient
.AsBuilder()
.ConfigureOptions(options =>
{
options.RawRepresentationFactory = (_) => new MessageCreateParams()
{
Model = model,
MaxTokens = 20000,
Messages = [],
Thinking = new BetaThinkingConfigParam(
new BetaThinkingConfigEnabled(budgetTokens: 10000))
};
})
.Build());
Console.WriteLine("Creating a presentation about renewable energy...\n");
// Run the agent with a request to create a presentation
AgentResponse response = await agent.RunAsync("Create a simple 3-slide presentation about renewable energy sources. Include a title slide, a slide about solar energy, and a slide about wind energy.");
Console.WriteLine("#### Agent Response ####");
Console.WriteLine(response.Text);
// Display any reasoning/thinking content
List<TextReasoningContent> reasoningContents = response.Messages.SelectMany(m => m.Contents.OfType<TextReasoningContent>()).ToList();
if (reasoningContents.Count > 0)
{
Console.WriteLine("\n#### Agent Reasoning ####");
Console.WriteLine($"\e[92m{string.Join("\n", reasoningContents.Select(c => c.Text))}\e[0m");
}
// Collect generated files from CodeInterpreterToolResultContent outputs
List<HostedFileContent> hostedFiles = response.Messages
.SelectMany(m => m.Contents.OfType<CodeInterpreterToolResultContent>())
.Where(c => c.Outputs is not null)
.SelectMany(c => c.Outputs!.OfType<HostedFileContent>())
.ToList();
if (hostedFiles.Count > 0)
{
Console.WriteLine("\n#### Generated Files ####");
foreach (HostedFileContent file in hostedFiles)
{
Console.WriteLine($" FileId: {file.FileId}");
// Download the file using the Anthropic Files API
using HttpResponse fileResponse = await anthropicClient.Beta.Files.Download(
file.FileId,
new FileDownloadParams { Betas = ["files-api-2025-04-14"] });
// Save the file to disk
string fileName = $"presentation_{file.FileId.Substring(0, 8)}.pptx";
using FileStream fileStream = File.Create(fileName);
Stream contentStream = await fileResponse.ReadAsStream();
await contentStream.CopyToAsync(fileStream);
Console.WriteLine($" Saved to: {fileName}");
}
}
Console.WriteLine("\nToken usage:");
Console.WriteLine($"Input: {response.Usage?.InputTokenCount}, Output: {response.Usage?.OutputTokenCount}");
if (response.Usage?.AdditionalCounts is not null)
{
Console.WriteLine($"Additional: {string.Join(", ", response.Usage.AdditionalCounts)}");
}
@@ -0,0 +1,119 @@
# Using Anthropic Skills with agents
This sample demonstrates how to use Anthropic-managed Skills with AI agents. Skills are pre-built capabilities provided by Anthropic that can be used with the Claude API.
## What this sample demonstrates
- Listing available Anthropic-managed skills
- Creating an AI agent with Anthropic Claude Skills support using the simplified `AsAITool()` approach
- Using the pptx skill to create PowerPoint presentations
- Downloading and saving generated files to disk
- Handling agent responses with generated content
## Prerequisites
Before you begin, ensure you have the following prerequisites:
- .NET 10.0 SDK or later
- Anthropic API key configured
- Access to Anthropic Claude models with Skills support
**Note**: This sample uses Anthropic Claude models with Skills. Skills are a beta feature. For more information, see [Anthropic documentation](https://docs.anthropic.com/).
Set the following environment variables:
```powershell
$env:ANTHROPIC_API_KEY="your-anthropic-api-key" # Replace with your Anthropic API key
$env:ANTHROPIC_MODEL="your-anthropic-model" # Replace with your Anthropic model (e.g., claude-sonnet-4-5-20250929)
```
## Run the sample
Navigate to the AgentWithAnthropic sample directory and run:
```powershell
cd dotnet\samples\GettingStarted\AgentWithAnthropic
dotnet run --project .\Agent_Anthropic_Step04_UsingSkills
```
## Available Anthropic Skills
Anthropic provides several managed skills that can be used with the Claude API:
- `pptx` - Create PowerPoint presentations
- `xlsx` - Create Excel spreadsheets
- `docx` - Create Word documents
- `pdf` - Create and analyze PDF documents
You can list available skills using the Anthropic SDK:
```csharp
SkillListPage skills = await anthropicClient.Beta.Skills.List(
new SkillListParams { Source = "anthropic", Betas = [AnthropicBeta.Skills2025_10_02] });
foreach (var skill in skills.Items)
{
Console.WriteLine($"{skill.Source}: {skill.ID} (version: {skill.LatestVersion})");
}
```
## Expected behavior
The sample will:
1. List all available Anthropic-managed skills
2. Create an agent with the pptx skill enabled
3. Run the agent with a request to create a presentation
4. Display the agent's response text
5. Download any generated files and save them to disk
6. Display token usage statistics
## Code highlights
### Simplified skill configuration
The Anthropic SDK handles all beta flags and container configuration automatically when using `AsAITool()`:
```csharp
// Define the pptx skill
BetaSkillParams pptxSkill = new()
{
Type = BetaSkillParamsType.Anthropic,
SkillID = "pptx",
Version = "latest"
};
// Create an agent - the SDK handles beta flags automatically!
ChatClientAgent agent = anthropicClient.Beta.AsAIAgent(
model: model,
instructions: "You are a helpful agent for creating PowerPoint presentations.",
tools: [pptxSkill.AsAITool()]);
```
**Note**: No manual `RawRepresentationFactory`, `Betas`, or `Container` configuration is needed. The SDK automatically adds the required beta headers (`skills-2025-10-02`, `code-execution-2025-08-25`) and configures the container with the skill.
### Handling generated files
Generated files are returned as `HostedFileContent` within `CodeInterpreterToolResultContent`:
```csharp
// Collect generated files from response
List<HostedFileContent> hostedFiles = response.Messages
.SelectMany(m => m.Contents.OfType<CodeInterpreterToolResultContent>())
.Where(c => c.Outputs is not null)
.SelectMany(c => c.Outputs!.OfType<HostedFileContent>())
.ToList();
// Download and save each file
foreach (HostedFileContent file in hostedFiles)
{
using HttpResponse fileResponse = await anthropicClient.Beta.Files.Download(
file.FileId,
new FileDownloadParams { Betas = ["files-api-2025-04-14"] });
string fileName = $"presentation_{file.FileId.Substring(0, 8)}.pptx";
await using FileStream fileStream = File.Create(fileName);
Stream contentStream = await fileResponse.ReadAsStream();
await contentStream.CopyToAsync(fileStream);
}
```
@@ -29,6 +29,7 @@ To use Anthropic with Azure Foundry, you can check the sample [AgentProviders/Ag
|[Running a simple agent](./Agent_Anthropic_Step01_Running/)|This sample demonstrates how to create and run a basic agent with Anthropic Claude|
|[Using reasoning with an agent](./Agent_Anthropic_Step02_Reasoning/)|This sample demonstrates how to use extended thinking/reasoning capabilities with Anthropic Claude agents|
|[Using function tools with an agent](./Agent_Anthropic_Step03_UsingFunctionTools/)|This sample demonstrates how to use function tools with an Anthropic Claude agent|
|[Using Skills with an agent](./Agent_Anthropic_Step04_UsingSkills/)|This sample demonstrates how to use Anthropic-managed Skills (e.g., pptx) with an Anthropic Claude agent|
## Running the samples from the console
@@ -0,0 +1,71 @@
// Copyright (c) Microsoft. All rights reserved.
using System.Threading.Tasks;
using AgentConformance.IntegrationTests.Support;
using Anthropic;
using Anthropic.Models.Beta;
using Anthropic.Models.Beta.Messages;
using Anthropic.Models.Beta.Skills;
using Anthropic.Services;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using Shared.IntegrationTests;
namespace AnthropicChatCompletion.IntegrationTests;
/// <summary>
/// Integration tests for Anthropic Skills functionality.
/// These tests are designed to be run locally with a valid Anthropic API key.
/// </summary>
public sealed class AnthropicSkillsIntegrationTests
{
// All tests for Anthropic are intended to be ran locally as the CI pipeline for Anthropic is not setup.
private const string SkipReason = "Integrations tests for local execution only";
private static readonly AnthropicConfiguration s_config = TestConfiguration.LoadSection<AnthropicConfiguration>();
[Fact(Skip = SkipReason)]
public async Task CreateAgentWithPptxSkillAsync()
{
// Arrange
AnthropicClient anthropicClient = new() { ApiKey = s_config.ApiKey };
string model = s_config.ChatModelId;
BetaSkillParams pptxSkill = new()
{
Type = BetaSkillParamsType.Anthropic,
SkillID = "pptx",
Version = "latest"
};
ChatClientAgent agent = anthropicClient.Beta.AsAIAgent(
model: model,
instructions: "You are a helpful agent for creating PowerPoint presentations.",
tools: [pptxSkill.AsAITool()]);
// Act
AgentResponse response = await agent.RunAsync(
"Create a simple 2-slide presentation: a title slide and one content slide about AI.");
// Assert
Assert.NotNull(response);
Assert.NotNull(response.Text);
Assert.NotEmpty(response.Text);
}
[Fact(Skip = SkipReason)]
public async Task ListAnthropicManagedSkillsAsync()
{
// Arrange
AnthropicClient anthropicClient = new() { ApiKey = s_config.ApiKey };
// Act
SkillListPage skills = await anthropicClient.Beta.Skills.List(
new SkillListParams { Source = "anthropic", Betas = [AnthropicBeta.Skills2025_10_02] });
// Assert
Assert.NotNull(skills);
Assert.NotNull(skills.Items);
Assert.Contains(skills.Items, skill => skill.ID == "pptx");
}
}