-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
.Net Agents - Support Prompt Template (#8631)
### 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. --> Support ability to paramaterize agent instructions (à la `IKernelTemplate`). This also includes the ability to initialize an agent using a _yaml_ based prompt-template. ### Description **Core:** - Update `ChatCompletionAgent` and `OpenAIAssistantAgent` to support initialization via `PromptTemplateConfig`. - Also allow both agent types to support _semantic-kernel_ template format for string based `Instructions` - Formalize templating contracts on `KernelAgent` (base class) - Added _GettingStartedWithAgents_ samples using _yaml_ template: _Step01_ & _Step08_ - Added templating samples under `Concepts/Agents` to explore full range of templating patterns **Structural:** - Split off `OpenAIAssistantCapabilities` from `OpenAIAssistantDefinition` to clarify creation via `PromptTemplateConfig` - Re-ordered method parameters for `OpenAIAssistant.CreateAsync` and `RetrieveAsync` to rationalize functional grouping and optionality. - Externalized internal `AssistantCreationOptionsFactory` (from private `OpenAIAssistant` method) for clarity and ease of testing - Persisting _template-format_ as part of assistant metadata for retrieval case (in the event of any ambiguity) **Additionally:** - Updated/added comments where appropriate - Updated sample conventions (argument labels, explicit types) - Updated all call sites for creating `OpenAIAssistantAgent` (due to parameter ordering) - Added test coverage where able ### 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 😄 --------- Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com> Co-authored-by: Dmytro Struk <13853051+dmytrostruk@users.noreply.github.com>
- Loading branch information
1 parent
8924bdc
commit a5570b1
Showing
37 changed files
with
1,949 additions
and
883 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
132 changes: 132 additions & 0 deletions
132
dotnet/samples/Concepts/Agents/ChatCompletion_Templating.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,132 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
using Microsoft.SemanticKernel; | ||
using Microsoft.SemanticKernel.Agents; | ||
using Microsoft.SemanticKernel.ChatCompletion; | ||
using Microsoft.SemanticKernel.PromptTemplates.Handlebars; | ||
using Microsoft.SemanticKernel.PromptTemplates.Liquid; | ||
|
||
namespace Agents; | ||
|
||
/// <summary> | ||
/// Demonstrate parameterized template instruction for <see cref="ChatCompletionAgent"/>. | ||
/// </summary> | ||
public class ChatCompletion_Templating(ITestOutputHelper output) : BaseAgentsTest(output) | ||
{ | ||
private readonly static (string Input, string? Style)[] s_inputs = | ||
[ | ||
(Input: "Home cooking is great.", Style: null), | ||
(Input: "Talk about world peace.", Style: "iambic pentameter"), | ||
(Input: "Say something about doing your best.", Style: "e. e. cummings"), | ||
(Input: "What do you think about having fun?", Style: "old school rap") | ||
]; | ||
|
||
[Fact] | ||
public async Task InvokeAgentWithInstructionsTemplateAsync() | ||
{ | ||
// Instruction based template always processed by KernelPromptTemplateFactory | ||
ChatCompletionAgent agent = | ||
new() | ||
{ | ||
Kernel = this.CreateKernelWithChatCompletion(), | ||
Instructions = | ||
""" | ||
Write a one verse poem on the requested topic in the style of {{$style}}. | ||
Always state the requested style of the poem. | ||
""", | ||
Arguments = new KernelArguments() | ||
{ | ||
{"style", "haiku"} | ||
} | ||
}; | ||
|
||
await InvokeChatCompletionAgentWithTemplateAsync(agent); | ||
} | ||
|
||
[Fact] | ||
public async Task InvokeAgentWithKernelTemplateAsync() | ||
{ | ||
// Default factory is KernelPromptTemplateFactory | ||
await InvokeChatCompletionAgentWithTemplateAsync( | ||
""" | ||
Write a one verse poem on the requested topic in the style of {{$style}}. | ||
Always state the requested style of the poem. | ||
"""); | ||
} | ||
|
||
[Fact] | ||
public async Task InvokeAgentWithHandlebarsTemplateAsync() | ||
{ | ||
await InvokeChatCompletionAgentWithTemplateAsync( | ||
""" | ||
Write a one verse poem on the requested topic in the style of {{style}}. | ||
Always state the requested style of the poem. | ||
""", | ||
HandlebarsPromptTemplateFactory.HandlebarsTemplateFormat, | ||
new HandlebarsPromptTemplateFactory()); | ||
} | ||
|
||
[Fact] | ||
public async Task InvokeAgentWithLiquidTemplateAsync() | ||
{ | ||
await InvokeChatCompletionAgentWithTemplateAsync( | ||
""" | ||
Write a one verse poem on the requested topic in the style of {{style}}. | ||
Always state the requested style of the poem. | ||
""", | ||
LiquidPromptTemplateFactory.LiquidTemplateFormat, | ||
new LiquidPromptTemplateFactory()); | ||
} | ||
|
||
private async Task InvokeChatCompletionAgentWithTemplateAsync( | ||
string instructionTemplate, | ||
string? templateFormat = null, | ||
IPromptTemplateFactory? templateFactory = null) | ||
{ | ||
// Define the agent | ||
PromptTemplateConfig templateConfig = | ||
new() | ||
{ | ||
Template = instructionTemplate, | ||
TemplateFormat = templateFormat, | ||
}; | ||
ChatCompletionAgent agent = | ||
new(templateConfig, templateFactory) | ||
{ | ||
Kernel = this.CreateKernelWithChatCompletion(), | ||
Arguments = new KernelArguments() | ||
{ | ||
{"style", "haiku"} | ||
} | ||
}; | ||
|
||
await InvokeChatCompletionAgentWithTemplateAsync(agent); | ||
} | ||
|
||
private async Task InvokeChatCompletionAgentWithTemplateAsync(ChatCompletionAgent agent) | ||
{ | ||
ChatHistory chat = []; | ||
|
||
foreach ((string input, string? style) in s_inputs) | ||
{ | ||
// Add input to chat | ||
ChatMessageContent request = new(AuthorRole.User, input); | ||
chat.Add(request); | ||
this.WriteAgentChatMessage(request); | ||
|
||
KernelArguments? arguments = null; | ||
|
||
if (!string.IsNullOrWhiteSpace(style)) | ||
{ | ||
// Override style template parameter | ||
arguments = new() { { "style", style } }; | ||
} | ||
|
||
// Process agent response | ||
await foreach (ChatMessageContent message in agent.InvokeAsync(chat, arguments)) | ||
{ | ||
chat.Add(message); | ||
this.WriteAgentChatMessage(message); | ||
} | ||
} | ||
} | ||
} |
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
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.