-
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: Processes Sample - Account Creation (#8990)
### 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. --> ### Description Adding New Processes Feature Sample - Create Account This sample helps showcase the capabilities of process showing the use of: - cycles - conditional outputs - use of multiple outputs/inputs -> fan-in/fan-out behavior - complex example that showcases a real life scenario Adding Processes Samples README with diagrams to make it easier to understand how the sample processes flow works ### 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: Ben Thomas <bentho@microsoft.com>
- Loading branch information
1 parent
5b0a1af
commit bd4d12b
Showing
21 changed files
with
1,138 additions
and
77 deletions.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
dotnet/samples/GettingStartedWithProcesses/Events/CommonEvents.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,11 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
namespace Events; | ||
|
||
/// <summary> | ||
/// Processes Events emitted by shared steps.<br/> | ||
/// </summary> | ||
public static class CommonEvents | ||
{ | ||
public static readonly string UserInputReceived = nameof(UserInputReceived); | ||
public static readonly string AssistantResponseGenerated = nameof(AssistantResponseGenerated); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
# Semantic Kernel Processes - Getting Started | ||
|
||
This project contains a step by step guide to get started with _Semantic Kernel Processes_. | ||
|
||
|
||
#### NuGet: | ||
- [Microsoft.SemanticKernel.Process.Abstractions](https://www.nuget.org/packages/Microsoft.SemanticKernel.Process.Abstractions) | ||
- [Microsoft.SemanticKernel.Process.Core](https://www.nuget.org/packages/Microsoft.SemanticKernel.Process.Core) | ||
- [Microsoft.SemanticKernel.Process.LocalRuntime](https://www.nuget.org/packages/Microsoft.SemanticKernel.Process.LocalRuntime) | ||
|
||
#### Sources | ||
- [Semantic Kernel Processes - Abstractions](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Experimental/Process.Abstractions) | ||
- [Semantic Kernel Processes - Core](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Experimental/Process.Core) | ||
- [Semantic Kernel Processes - LocalRuntime](https://github.com/microsoft/semantic-kernel/tree/main/dotnet/src/Experimental/Process.LocalRuntime) | ||
|
||
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 | ||
---|--- | ||
[Step01_Processes](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/GettingStartedWithProcesses/Step01_Processes.cs)|How to create a simple process with a loop and a conditional exit | ||
[Step02_AccountOpening](https://github.com/microsoft/semantic-kernel/blob/main/dotnet/samples/GettingStartedWithProcesses/Step02_AccountOpening.cs)|Showcasing processes cycles, fan in, fan out for opening an account. | ||
|
||
### Step01_Processes | ||
|
||
```mermaid | ||
flowchart LR | ||
Intro(Intro)--> UserInput(User Input) | ||
UserInput-->|User message == 'exit'| Exit(Exit) | ||
UserInput-->|User message| AssistantResponse(Assistant Response) | ||
AssistantResponse--> UserInput | ||
``` | ||
|
||
### Step02_AccountOpening | ||
|
||
```mermaid | ||
flowchart LR | ||
User(User) -->|Provides user details| FillForm(Fill New <br/> Customer <br/> Form) | ||
FillForm -->|Need more info| AssistantMessage(Assistant <br/> Message) | ||
FillForm -->|Welcome Message| AssistantMessage | ||
FillForm --> CompletedForm((Completed Form)) | ||
AssistantMessage --> User | ||
CompletedForm --> CreditCheck(Customer <br/> Credit Score <br/> Check) | ||
CompletedForm --> Fraud(Fraud Detection) | ||
CompletedForm -->|New Customer Form + Conversation Transcript| CoreSystem | ||
CreditCheck -->|Failed - Notify user about insufficient credit score| Mailer(Mail <br/> Service) | ||
CreditCheck -->|Approved| Fraud | ||
Fraud --> |Failed - Notify user about failure to confirm user identity| Mailer | ||
Fraud --> |Passed| CoreSystem(Core System <br/> Record <br/> Creation) | ||
CoreSystem --> Marketing(New Marketing <br/> Record Creation) | ||
CoreSystem --> CRM(CRM Record <br/> Creation) | ||
CoreSystem -->|Account Details| Welcome(Welcome <br/> Packet) | ||
Marketing -->|Success| Welcome | ||
CRM -->|Success| Welcome | ||
Welcome -->|Success: Notify User about Account Creation| Mailer | ||
Mailer -->|End of Interaction| User | ||
``` | ||
|
||
|
||
## 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: | ||
|
||
``` | ||
dotnet test --filter Step01_Processes | ||
``` | ||
|
||
## Configuring Secrets | ||
|
||
Each example requires secrets / credentials to access OpenAI or Azure OpenAI. | ||
|
||
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/GettingStartedWithProcesses | ||
``` | ||
|
||
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; | ||
``` |
29 changes: 29 additions & 0 deletions
29
dotnet/samples/GettingStartedWithProcesses/SharedSteps/DisplayAssistantMessageStep.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,29 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
|
||
using Events; | ||
using Microsoft.SemanticKernel; | ||
|
||
namespace SharedSteps; | ||
|
||
/// <summary> | ||
/// Step used in the Processes Samples: | ||
/// - Step_02_AccountOpening.cs | ||
/// </summary> | ||
public class DisplayAssistantMessageStep : KernelProcessStep | ||
{ | ||
public static class Functions | ||
{ | ||
public const string DisplayAssistantMessage = nameof(DisplayAssistantMessage); | ||
} | ||
|
||
[KernelFunction(Functions.DisplayAssistantMessage)] | ||
public async ValueTask DisplayAssistantMessageAsync(KernelProcessStepContext context, string assistantMessage) | ||
{ | ||
Console.ForegroundColor = ConsoleColor.Blue; | ||
Console.WriteLine($"ASSISTANT: {assistantMessage}\n"); | ||
Console.ResetColor(); | ||
|
||
// Emit the assistantMessageGenerated | ||
await context.EmitEventAsync(new() { Id = CommonEvents.AssistantResponseGenerated, Data = assistantMessage }); | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
dotnet/samples/GettingStartedWithProcesses/SharedSteps/ScriptedUserInputStep.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,80 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
|
||
using Events; | ||
using Microsoft.SemanticKernel; | ||
|
||
namespace SharedSteps; | ||
|
||
/// <summary> | ||
/// A step that elicits user input. | ||
/// | ||
/// Step used in the Processes Samples: | ||
/// - Step_01_Processes.cs | ||
/// - Step_02_AccountOpening.cs | ||
/// </summary> | ||
public class ScriptedUserInputStep : KernelProcessStep<UserInputState> | ||
{ | ||
public static class Functions | ||
{ | ||
public const string GetUserInput = nameof(GetUserInput); | ||
} | ||
|
||
/// <summary> | ||
/// The state object for the user input step. This object holds the user inputs and the current input index. | ||
/// </summary> | ||
protected UserInputState? _state; | ||
|
||
/// <summary> | ||
/// Method to be overridden by the user to populate with custom user messages | ||
/// </summary> | ||
public virtual void PopulateUserInputs() | ||
{ | ||
return; | ||
} | ||
|
||
/// <summary> | ||
/// Activates the user input step by initializing the state object. This method is called when the process is started | ||
/// and before any of the KernelFunctions are invoked. | ||
/// </summary> | ||
/// <param name="state">The state object for the step.</param> | ||
/// <returns>A <see cref="ValueTask"/></returns> | ||
public override ValueTask ActivateAsync(KernelProcessStepState<UserInputState> state) | ||
{ | ||
state.State ??= new(); | ||
_state = state.State; | ||
|
||
PopulateUserInputs(); | ||
|
||
return ValueTask.CompletedTask; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the user input. | ||
/// </summary> | ||
/// <param name="context">An instance of <see cref="KernelProcessStepContext"/> which can be | ||
/// used to emit events from within a KernelFunction.</param> | ||
/// <returns>A <see cref="ValueTask"/></returns> | ||
[KernelFunction(Functions.GetUserInput)] | ||
public async ValueTask GetUserInputAsync(KernelProcessStepContext context) | ||
{ | ||
var userMessage = _state!.UserInputs[_state.CurrentInputIndex]; | ||
_state.CurrentInputIndex++; | ||
|
||
Console.ForegroundColor = ConsoleColor.Yellow; | ||
Console.WriteLine($"USER: {userMessage}"); | ||
Console.ResetColor(); | ||
|
||
// Emit the user input | ||
await context.EmitEventAsync(new() { Id = CommonEvents.UserInputReceived, Data = userMessage }); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// The state object for the <see cref="ScriptedUserInputStep"/> | ||
/// </summary> | ||
public record UserInputState | ||
{ | ||
public List<string> UserInputs { get; init; } = []; | ||
|
||
public int CurrentInputIndex { get; set; } = 0; | ||
} |
Oops, something went wrong.