forked from microsoft/semantic-kernel
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
.Net Agents -
ChatCompletionAgent
Pre-Graduation (microsoft#7900)
### 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. --> Update public signatures / interface of `ChatCompletionAgent` in preparation for removing experimental tag. Fixes: microsoft#6037 Fixes: microsoft#6523 ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> - Include `Kernel` and `KernelArguments` in agent invocation signatures for `ChatCompletionAgent` - Change `ChatCompletionAgent.ExeuctionSettings` to `ChatCompletionAgent.KernelArguments` - Mirror pattern for `OpenAIAssistantAgent` - Integrate `Kernel` and `KernelArguments.ExecutionSettings` as overrides for agent invocation - Added new sample that explores the entire selection matrix: `ChatCompletion_ServiceSelection` ### 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
Showing
15 changed files
with
218 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
128 changes: 128 additions & 0 deletions
128
dotnet/samples/Concepts/Agents/ChatCompletion_ServiceSelection.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
using Microsoft.SemanticKernel; | ||
using Microsoft.SemanticKernel.Agents; | ||
using Microsoft.SemanticKernel.ChatCompletion; | ||
using Microsoft.SemanticKernel.Connectors.OpenAI; | ||
|
||
namespace Agents; | ||
|
||
/// <summary> | ||
/// Demonstrate service selection for <see cref="ChatCompletionAgent"/> through setting service-id | ||
/// on <see cref="ChatCompletionAgent.Arguments"/> and also providing override <see cref="KernelArguments"/> | ||
/// when calling <see cref="ChatCompletionAgent.InvokeAsync"/> | ||
/// </summary> | ||
public class ChatCompletion_ServiceSelection(ITestOutputHelper output) : BaseTest(output) | ||
{ | ||
private const string ServiceKeyGood = "chat-good"; | ||
private const string ServiceKeyBad = "chat-bad"; | ||
|
||
[Fact] | ||
public async Task UseServiceSelectionWithChatCompletionAgentAsync() | ||
{ | ||
// Create kernel with two instances of IChatCompletionService | ||
// One service is configured with a valid API key and the other with an | ||
// invalid key that will result in a 401 Unauthorized error. | ||
Kernel kernel = CreateKernelWithTwoServices(); | ||
|
||
// Define the agent targeting ServiceId = ServiceKeyGood | ||
ChatCompletionAgent agentGood = | ||
new() | ||
{ | ||
Kernel = kernel, | ||
Arguments = new KernelArguments(new OpenAIPromptExecutionSettings() { ServiceId = ServiceKeyGood }), | ||
}; | ||
|
||
// Define the agent targeting ServiceId = ServiceKeyBad | ||
ChatCompletionAgent agentBad = | ||
new() | ||
{ | ||
Kernel = kernel, | ||
Arguments = new KernelArguments(new OpenAIPromptExecutionSettings() { ServiceId = ServiceKeyBad }), | ||
}; | ||
|
||
// Define the agent with no explicit ServiceId defined | ||
ChatCompletionAgent agentDefault = new() { Kernel = kernel }; | ||
|
||
// Invoke agent as initialized with ServiceId = ServiceKeyGood: Expect agent response | ||
Console.WriteLine("\n[Agent With Good ServiceId]"); | ||
await InvokeAgentAsync(agentGood); | ||
|
||
// Invoke agent as initialized with ServiceId = ServiceKeyBad: Expect failure due to invalid service key | ||
Console.WriteLine("\n[Agent With Bad ServiceId]"); | ||
await InvokeAgentAsync(agentBad); | ||
|
||
// Invoke agent as initialized with no explicit ServiceId: Expect agent response | ||
Console.WriteLine("\n[Agent With No ServiceId]"); | ||
await InvokeAgentAsync(agentDefault); | ||
|
||
// Invoke agent with override arguments where ServiceId = ServiceKeyGood: Expect agent response | ||
Console.WriteLine("\n[Bad Agent: Good ServiceId Override]"); | ||
await InvokeAgentAsync(agentBad, new(new OpenAIPromptExecutionSettings() { ServiceId = ServiceKeyGood })); | ||
|
||
// Invoke agent with override arguments where ServiceId = ServiceKeyBad: Expect failure due to invalid service key | ||
Console.WriteLine("\n[Good Agent: Bad ServiceId Override]"); | ||
await InvokeAgentAsync(agentGood, new(new OpenAIPromptExecutionSettings() { ServiceId = ServiceKeyBad })); | ||
Console.WriteLine("\n[Default Agent: Bad ServiceId Override]"); | ||
await InvokeAgentAsync(agentDefault, new(new OpenAIPromptExecutionSettings() { ServiceId = ServiceKeyBad })); | ||
|
||
// Invoke agent with override arguments with no explicit ServiceId: Expect agent response | ||
Console.WriteLine("\n[Good Agent: No ServiceId Override]"); | ||
await InvokeAgentAsync(agentGood, new(new OpenAIPromptExecutionSettings())); | ||
Console.WriteLine("\n[Bad Agent: No ServiceId Override]"); | ||
await InvokeAgentAsync(agentBad, new(new OpenAIPromptExecutionSettings())); | ||
Console.WriteLine("\n[Default Agent: No ServiceId Override]"); | ||
await InvokeAgentAsync(agentDefault, new(new OpenAIPromptExecutionSettings())); | ||
|
||
// Local function to invoke agent and display the conversation messages. | ||
async Task InvokeAgentAsync(ChatCompletionAgent agent, KernelArguments? arguments = null) | ||
{ | ||
ChatHistory chat = [new(AuthorRole.User, "Hello")]; | ||
|
||
try | ||
{ | ||
await foreach (ChatMessageContent response in agent.InvokeAsync(chat, arguments)) | ||
{ | ||
Console.WriteLine(response.Content); | ||
} | ||
} | ||
catch (HttpOperationException exception) | ||
{ | ||
Console.WriteLine($"Status: {exception.StatusCode}"); | ||
} | ||
} | ||
} | ||
|
||
private Kernel CreateKernelWithTwoServices() | ||
{ | ||
IKernelBuilder builder = Kernel.CreateBuilder(); | ||
|
||
if (this.UseOpenAIConfig) | ||
{ | ||
builder.AddOpenAIChatCompletion( | ||
TestConfiguration.OpenAI.ChatModelId, | ||
"bad-key", | ||
serviceId: ServiceKeyBad); | ||
|
||
builder.AddOpenAIChatCompletion( | ||
TestConfiguration.OpenAI.ChatModelId, | ||
TestConfiguration.OpenAI.ApiKey, | ||
serviceId: ServiceKeyGood); | ||
} | ||
else | ||
{ | ||
builder.AddAzureOpenAIChatCompletion( | ||
TestConfiguration.AzureOpenAI.ChatDeploymentName, | ||
TestConfiguration.AzureOpenAI.Endpoint, | ||
"bad-key", | ||
serviceId: ServiceKeyBad); | ||
|
||
builder.AddAzureOpenAIChatCompletion( | ||
TestConfiguration.AzureOpenAI.ChatDeploymentName, | ||
TestConfiguration.AzureOpenAI.Endpoint, | ||
TestConfiguration.AzureOpenAI.ApiKey, | ||
serviceId: ServiceKeyGood); | ||
} | ||
|
||
return builder.Build(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.