Skip to content

Commit

Permalink
.Net - Update Agent Readme (#6070)
Browse files Browse the repository at this point in the history
### Motivation and Context
<!-- Thank you for your contribution to the semantic-kernel repo!
Please help reviewers and future users, providing the following
information:
  1. Why is this change required?
  2. What problem does it solve?
  3. What scenario does it contribute to?
  4. If it fixes an open issue, please link to the issue here.
-->

Enhance `readme.md` associated with _Agent_ samples.

Also include _ agent sample in _Getting Started with Agents_.

### Description
<!-- Describe your changes, the overall approach, the underlying design.
These notes will help understanding how your code works. Thanks! -->

- Updated readmes
- Clean-up pass on samples
- Added an OpenAI Assistant to _Getting Started_

### Contribution Checklist
<!-- Before submitting this PR, please make sure: -->

- [X] The code builds clean without any errors or warnings
- [X] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [X] All unit tests pass, and I have added new tests where possible
- [X] I didn't break anyone 😄
  • Loading branch information
crickman committed May 1, 2024
1 parent e51c34d commit 75dccb3
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 60 deletions.
24 changes: 12 additions & 12 deletions dotnet/samples/Concepts/Agents/ComplexChat_NestedShopper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public class ComplexChat_NestedShopper(ITestOutputHelper output) : BaseTest(outp
[Fact]
public async Task RunAsync()
{
this.WriteLine($"! {Model}");
Console.WriteLine($"! {Model}");

OpenAIPromptExecutionSettings jsonSettings = new() { ResponseFormat = ChatCompletionsResponseFormat.JsonObject };
OpenAIPromptExecutionSettings autoInvokeSettings = new() { ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions };
Expand Down Expand Up @@ -137,9 +137,9 @@ public async Task RunAsync()
};

// Invoke chat and display messages.
this.WriteLine("\n######################################");
this.WriteLine("# DYNAMIC CHAT");
this.WriteLine("######################################");
Console.WriteLine("\n######################################");
Console.WriteLine("# DYNAMIC CHAT");
Console.WriteLine("######################################");

await InvokeChatAsync("Can you provide three original birthday gift ideas. I don't want a gift that someone else will also pick.");

Expand All @@ -150,27 +150,27 @@ public async Task RunAsync()
await InvokeChatAsync("He likes photography.");
}

this.WriteLine("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
this.WriteLine(">>>> AGGREGATED CHAT");
this.WriteLine(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
Console.WriteLine("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
Console.WriteLine(">>>> AGGREGATED CHAT");
Console.WriteLine(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

await foreach (var content in chat.GetChatMessagesAsync(personalShopperAgent).Reverse())
{
this.WriteLine($">>>> {content.Role} - {content.AuthorName ?? "*"}: '{content.Content}'");
Console.WriteLine($">>>> {content.Role} - {content.AuthorName ?? "*"}: '{content.Content}'");
}

async Task InvokeChatAsync(string input)
{
chat.AddChatMessage(new ChatMessageContent(AuthorRole.User, input));

this.WriteLine($"# {AuthorRole.User}: '{input}'");
Console.WriteLine($"# {AuthorRole.User}: '{input}'");

await foreach (var content in chat.InvokeAsync(personalShopperAgent))
{
this.WriteLine($"# {content.Role} - {content.AuthorName ?? "*"}: '{content.Content}'");
Console.WriteLine($"# {content.Role} - {content.AuthorName ?? "*"}: '{content.Content}'");
}

this.WriteLine($"\n# IS COMPLETE: {chat.IsComplete}");
Console.WriteLine($"\n# IS COMPLETE: {chat.IsComplete}");
}

ChatCompletionAgent CreateAgent(string agentName, string agentInstructions) =>
Expand Down Expand Up @@ -198,7 +198,7 @@ await foreach (var content in chat.InvokeAsync(personalShopperAgent))
string? agentName = string.IsNullOrWhiteSpace(jsonResult?.name) ? null : jsonResult?.name;
agentName ??= InternalGiftIdeaAgentName;
this.WriteLine($"\t>>>> INNER TURN: {agentName}");
Console.WriteLine($"\t>>>> INNER TURN: {agentName}");
return agentName;
}
Expand Down
93 changes: 73 additions & 20 deletions dotnet/samples/Concepts/Agents/README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,89 @@
# Semantic Kernel: Agent syntax examples
This project contains a collection of examples on how to use _Semantic Kernel Agents_.

This project contains a collection of examples on how to use SK Agents.
#### NuGet:
- [Microsoft.SemanticKernel.Agents.Abstractions](https://www.nuget.org/packages/Microsoft.SemanticKernel.Agents.Abstractions)
- [Microsoft.SemanticKernel.Agents.Core](https://www.nuget.org/packages/Microsoft.SemanticKernel.Agents.Core)
- [Microsoft.SemanticKernel.Agents.OpenAI](https://www.nuget.org/packages/Microsoft.SemanticKernel.Agents.OpenAI)

#### Source
- [Semantic Kernel Agent Framework](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Agents)

The examples can be run as integration tests but their code can also be copied to stand-alone programs.

## Running Examples with Filters
## Examples

You can run specific examples in the KernelSyntaxExamples project by using test filters (dotnet test --filter).
Type "dotnet test --help" at the command line for more details.
The concept agents examples are grouped by prefix:

## Configuring Secrets
Prefix|Description
---|---
OpenAIAssistant|How to use agents based on the [Open AI Assistant API](https://platform.openai.com/docs/assistants).
MixedChat|How to combine different agent types.
ComplexChat|How to deveop complex agent chat solutions.
Legacy|How to use the legacy _Experimental Agent API_.

## Legacy Agents

Most of the examples will require secrets and credentials, to access OpenAI, Azure OpenAI,
Bing and other resources. We suggest using .NET
[Secret Manager](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets)
to avoid the risk of leaking secrets into the repository, branches and pull requests.
You can also use environment variables if you prefer.
Support for the OpenAI Assistant API was originally published in `Microsoft.SemanticKernel.Experimental.Agents` package:
[Microsoft.SemanticKernel.Experimental.Agents](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Experimental/Agents)

To set your secrets with Secret Manager:
This package has been superseded by _Semantic Kernel Agents_, which includes support for Open AI Assistant agents.

## Running Examples
Examples may be explored and ran within _Visual Studio_ using _Test Explorer_.

You can also run specific examples via the command-line by using test filters (`dotnet test --filter`). Type `dotnet test --help` at the command line for more details.

Example:

```
dotnet test --filter OpenAIAssistant_CodeInterpreter
```
cd dotnet/samples/AgentSyntaxExamples

dotnet user-secrets init
## Configuring Secrets

dotnet user-secrets set "OpenAI:ChatModelId" "..."
dotnet user-secrets set "OpenAI:ApiKey" "..."
Each example requires secrets / credentials to access OpenAI or Azure OpenAI.

dotnet user-secrets set "AzureOpenAI:DeploymentName" "..."
dotnet user-secrets set "AzureOpenAI:ChatDeploymentName" "..."
dotnet user-secrets set "AzureOpenAI:Endpoint" "https://... .openai.azure.com/"
dotnet user-secrets set "AzureOpenAI:ApiKey" "..."
We suggest using .NET [Secret Manager](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets) to avoid the risk of leaking secrets into the repository, branches and pull requests. You can also use environment variables if you prefer.

```
To set your secrets with .NET Secret Manager:

1. Navigate the console to the project folder:

```
cd dotnet/samples/GettingStartedWithAgents
```

2. Examine existing secret definitions:

```
dotnet user-secrets list
```

3. If needed, perform first time initialization:

```
dotnet user-secrets init
```

4. Define secrets for either Open AI:

```
dotnet user-secrets set "OpenAI:ChatModelId" "..."
dotnet user-secrets set "OpenAI:ApiKey" "..."
```

5. Or Azure Open AI:

```
dotnet user-secrets set "AzureOpenAI:DeploymentName" "..."
dotnet user-secrets set "AzureOpenAI:ChatDeploymentName" "..."
dotnet user-secrets set "AzureOpenAI:Endpoint" "https://... .openai.azure.com/"
dotnet user-secrets set "AzureOpenAI:ApiKey" "..."
```

> NOTE: Azure secrets will take precedence, if both Open AI and Azure Open AI secrets are defined, unless `ForceOpenAI` is set:
```
protected override bool ForceOpenAI => true;
```
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

<ItemGroup>
<ProjectReference Include="..\..\src\Agents\Core\Agents.Core.csproj" />
<ProjectReference Include="..\..\src\Agents\OpenAI\Agents.OpenAI.csproj" />
<ProjectReference Include="..\..\src\Connectors\Connectors.OpenAI\Connectors.OpenAI.csproj" />
<ProjectReference Include="..\..\src\SemanticKernel.Abstractions\SemanticKernel.Abstractions.csproj" />
<ProjectReference Include="..\..\src\SemanticKernel.Core\SemanticKernel.Core.csproj" />
Expand Down
96 changes: 78 additions & 18 deletions dotnet/samples/GettingStartedWithAgents/README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,95 @@
# Semantic Kernel Agents - Getting Started

This project contains a collection of examples on how to use SK Agents.
This project contains a step by step guide to get started with _Semantic Kernel Agents_.


#### NuGet:
- [Microsoft.SemanticKernel.Agents.Abstractions](https://www.nuget.org/packages/Microsoft.SemanticKernel.Agents.Abstractions)
- [Microsoft.SemanticKernel.Agents.Core](https://www.nuget.org/packages/Microsoft.SemanticKernel.Agents.Core)
- [Microsoft.SemanticKernel.Agents.OpenAI](https://www.nuget.org/packages/Microsoft.SemanticKernel.Agents.OpenAI)

#### Source
- [Semantic Kernel Agent Framework](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Agents)

The examples can be run as integration tests but their code can also be copied to stand-alone programs.

## Examples

The getting started with agents examples include:

Example|Description
---|---
[Step1_Agent](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/GettingStartedWithAgents/Step1_Agent.cs)|How to create and use an agent.
[Step2_Plugins](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/GettingStartedWithAgents/Step2_Plugins.cs)|How to associate plug-ins with an agent.
[Step3_Chat](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/GettingStartedWithAgents/Step3_Chat.cs)|How to create a conversation between agents.
[Step4_KernelFunctionStrategies](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/Step4_KernelFunctionStrategies/Step1_Agent.cs)|How to utilize a `KernelFunction` as a _chat strategy_.
[Step5_JsonResult](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/GettingStartedWithAgents/Step5_JsonResult.cs)|How to have an agent produce JSON.
[Step6_DependencyInjection](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/GettingStartedWithAgents/Step6_DependencyInjection.cs)|How to define dependency injection patterns for agents.
[Step7_OpenAIAssistant](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/GettingStartedWithAgents/Step7_OpenAIAssistant.cs)|How to create an Open AI Assistant agent.

## Legacy Agents

Support for the OpenAI Assistant API was originally published in `Microsoft.SemanticKernel.Experimental.Agents` package:
[Microsoft.SemanticKernel.Experimental.Agents](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Experimental/Agents)

This package has been superseded by _Semantic Kernel Agents_, which includes support for Open AI Assistant agents.


## Running Examples with Filters
Examples may be explored and ran within _Visual Studio_ using _Test Explorer_.

You can also run specific examples via the command-line by using test filters (`dotnet test --filter`). Type `dotnet test --help` at the command line for more details.

Example:

You can run specific examples in the project by using test filters (dotnet test --filter).
Type "dotnet test --help" at the command line for more details.
```
dotnet test --filter Step3_Chat
```

## Configuring Secrets

Most of the examples will require secrets and credentials, to access OpenAI, Azure OpenAI,
Bing and other resources. We suggest using .NET
[Secret Manager](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets)
to avoid the risk of leaking secrets into the repository, branches and pull requests.
You can also use environment variables if you prefer.
Each example requires secrets / credentials to access OpenAI or Azure OpenAI.

To set your secrets with Secret Manager:
We suggest using .NET [Secret Manager](https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets) to avoid the risk of leaking secrets into the repository, branches and pull requests. You can also use environment variables if you prefer.

```
cd dotnet/samples/AgentSyntaxExamples
To set your secrets with .NET Secret Manager:

1. Navigate the console to the project folder:

```
cd dotnet/samples/GettingStartedWithAgents
```

2. Examine existing secret definitions:

dotnet user-secrets init
```
dotnet user-secrets list
```

dotnet user-secrets set "OpenAI:ChatModelId" "..."
dotnet user-secrets set "OpenAI:ApiKey" "..."
3. If needed, perform first time initialization:

dotnet user-secrets set "AzureOpenAI:DeploymentName" "..."
dotnet user-secrets set "AzureOpenAI:ChatDeploymentName" "..."
dotnet user-secrets set "AzureOpenAI:Endpoint" "https://... .openai.azure.com/"
dotnet user-secrets set "AzureOpenAI:ApiKey" "..."
```
dotnet user-secrets init
```

4. Define secrets for either Open AI:

```
dotnet user-secrets set "OpenAI:ChatModelId" "..."
dotnet user-secrets set "OpenAI:ApiKey" "..."
```

5. Or Azure Open AI:

```
dotnet user-secrets set "AzureOpenAI:DeploymentName" "..."
dotnet user-secrets set "AzureOpenAI:ChatDeploymentName" "..."
dotnet user-secrets set "AzureOpenAI:Endpoint" "https://... .openai.azure.com/"
dotnet user-secrets set "AzureOpenAI:ApiKey" "..."
```

> NOTE: Azure secrets will take precedence, if both Open AI and Azure Open AI secrets are defined, unless `ForceOpenAI` is set:
```
protected override bool ForceOpenAI => true;
```
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ public async Task RunAsync()
// Local function to invoke agent and display the conversation messages.
async Task WriteAgentResponse(string input)
{
this.WriteLine($"# {AuthorRole.User}: {input}");
Console.WriteLine($"# {AuthorRole.User}: {input}");

await foreach (var content in agentClient.RunDemoAsync(input))
{
this.WriteLine($"# {content.Role} - {content.AuthorName ?? "*"}: '{content.Content}'");
Console.WriteLine($"# {content.Role} - {content.AuthorName ?? "*"}: '{content.Content}'");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.Agents.OpenAI;
using Microsoft.SemanticKernel.ChatCompletion;
using Plugins;

namespace Agents;
namespace GettingStarted;

/// <summary>
/// Demonstrate creation of <see cref="OpenAIAssistantAgent"/> and
/// eliciting its response to three explicit user messages.
/// </summary>
/// <remarks>
/// This example demonstrates that outside of initialization (and cleanup), using
/// <see cref="OpenAIAssistantAgent"/> is no different from <see cref="ChatCompletionAgent"/>
/// even with with a <see cref="KernelPlugin"/>.
/// </remarks>
public class OpenAIAssistant_Agent(ITestOutputHelper output) : BaseTest(output)
/// </summary>
public class Step7_OpenAIAssistant(ITestOutputHelper output) : BaseTest(output)
{
private const string HostName = "Host";
private const string HostInstructions = "Answer questions about the menu.";
Expand Down Expand Up @@ -68,4 +65,32 @@ await foreach (var content in chat.InvokeAsync(agent))
}
}
}

private sealed class MenuPlugin
{
public const string CorrelationIdArgument = "correlationId";

private readonly List<string> _correlationIds = [];

public IReadOnlyList<string> CorrelationIds => this._correlationIds;

[KernelFunction, Description("Provides a list of specials from the menu.")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1024:Use properties where appropriate", Justification = "Too smart")]
public string GetSpecials()
{
return @"
Special Soup: Clam Chowder
Special Salad: Cobb Salad
Special Drink: Chai Tea
";
}

[KernelFunction, Description("Provides the price of the requested menu item.")]
public string GetItemPrice(
[Description("The name of the menu item.")]
string menuItem)
{
return "$9.99";
}
}
}

0 comments on commit 75dccb3

Please sign in to comment.