Skip to content

Commit dbebb5f

Browse files
committed
Added MCP client sample
1 parent 53720dd commit dbebb5f

File tree

22 files changed

+503
-31
lines changed

22 files changed

+503
-31
lines changed

Diff for: SemanticKernel.Agents/.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"prompty.currentModelConfiguration": "default"
3+
}

Diff for: SemanticKernel.Agents/Program.cs

+11
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
Console.WriteLine("2) Prompt Improvement");
66
Console.WriteLine("3) Developer");
77
Console.WriteLine("4) Rap battle");
8+
Console.WriteLine("5) Creator Writer");
89
Console.WriteLine("Type the number of the scenario you want to run and press Enter");
10+
911
string response = Console.ReadLine();
1012
string prompt = string.Empty;
1113
switch (response)
@@ -43,6 +45,15 @@
4345
prompt = Console.ReadLine();
4446
await rapBattleScenario.ExecuteScenario(prompt);
4547
break;
48+
case "5":
49+
50+
CreatorWriterScenario creatorWriterScenario = new CreatorWriterScenario();
51+
await creatorWriterScenario.InitializeScenarioAsync(false);
52+
53+
Console.WriteLine("Write your topic:");
54+
prompt = Console.ReadLine();
55+
await creatorWriterScenario.ExecuteScenario(prompt);
56+
break;
4657
default:
4758
Console.WriteLine("Invalid option");
4859
break;

Diff for: SemanticKernel.Agents/Prompts/writerAgent.prompty

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
name: WriterAgent
3+
description: Instructions for an agent that can generate a text based on a set of information about a given topic
4+
authors:
5+
- Matteo Pagani
6+
model:
7+
api: chat
8+
configuration:
9+
type: azure_openai
10+
azure_endpoint: ${env:AZURE_OPENAI_ENDPOINT}
11+
azure_deployment: ${env:AZURE_OPENAI_DEPLOYMENT}
12+
api_key: ${env:AZURE_OPENAI_API_KEY}
13+
parameters:
14+
max_tokens: 5000
15+
sample:
16+
context: >
17+
Contoso Electronics is a leader in the aerospace industry, providing advanced electronic
18+
components for both commercial and military aircraft. We specialize in creating cutting edge systems that are both reliable and efficient. Our mission is to provide the highest
19+
quality aircraft components to our customers, while maintaining a commitment to safety
20+
and excellence. We are proud to have built a strong reputation in the aerospace industry
21+
and strive to continually improve our products and services. Our experienced team of
22+
engineers and technicians are dedicated to providing the best products and services to our
23+
customers. With our commitment to excellence, we are sure to remain a leader in the aerospace industry for years to come.
24+
---
25+
26+
system:
27+
You are a creative writer and your goal is to write a text based on the user request.
28+
Below you can find information, insights and context about a topic, and your task is to synthesize this information into a coherent and engaging text.
29+
You must write a text that is clear, concise, and engaging. The text should be well-structured and easy to read. Use emojis to make the text more engaging and fun.
30+
# Context
31+
{{context}}

Diff for: SemanticKernel.Agents/Scenarios/BaseScenario.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,14 @@ public abstract class BaseScenario
88
{
99
protected AgentGroupChat chat;
1010

11-
public abstract void InitializeScenario(bool useAzureOpenAI);
11+
public virtual void InitializeScenario(bool useAzureOpenAI)
12+
{
13+
}
14+
15+
public virtual Task InitializeScenarioAsync(bool useAzureOpenAI)
16+
{
17+
return Task.CompletedTask;
18+
}
1219

1320
public async Task ExecuteScenario(string prompt)
1421
{
+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
using Azure.AI.Projects;
2+
using Azure.Identity;
3+
using Microsoft.SemanticKernel;
4+
using Microsoft.SemanticKernel.Agents;
5+
using Microsoft.SemanticKernel.Agents.AzureAI;
6+
using Microsoft.SemanticKernel.Agents.Chat;
7+
using Microsoft.SemanticKernel.ChatCompletion;
8+
using Microsoft.SemanticKernel.PromptTemplates.Liquid;
9+
using Microsoft.SemanticKernel.Prompty;
10+
11+
namespace SemanticKernel.Agents.Scenarios
12+
{
13+
public class CreatorWriterScenario : BaseScenario
14+
{
15+
public override async Task InitializeScenarioAsync(bool useAzureOpenAI)
16+
{
17+
//AzureEventSourceListener listener = new AzureEventSourceListener(
18+
// (args, text) => Console.WriteLine(text),
19+
// level: System.Diagnostics.Tracing.EventLevel.Verbose);
20+
21+
AIProjectClient client = new AIProjectClient("swedencentral.api.azureml.ms;bc06be43-f36c-449a-b690-4fea320f3e73;ai-agents;ai-agents-project", new DefaultAzureCredential(new DefaultAzureCredentialOptions
22+
{
23+
ExcludeVisualStudioCredential = true,
24+
ExcludeEnvironmentCredential = true,
25+
ExcludeManagedIdentityCredential = true
26+
}));
27+
var agentsClient = client.GetAgentsClient();
28+
var agent = await agentsClient.GetAgentAsync("asst_XlORPWTtq4FSyMItEw2lbT2a");
29+
30+
string researcherAgentName = "ResearcherAgent";
31+
32+
AzureAIAgent researcherAgent = new(agent, agentsClient)
33+
{
34+
Name = researcherAgentName,
35+
Kernel = KernelCreator.CreateKernel(useAzureOpenAI)
36+
};
37+
38+
string writerAgentName = "WriterAgent";
39+
string promptyTemplate = await File.ReadAllTextAsync("Prompts/writerAgent.prompty");
40+
var promptTemplate = KernelFunctionPrompty.ToPromptTemplateConfig(promptyTemplate);
41+
42+
ChatCompletionAgent writerAgent = new ChatCompletionAgent(promptTemplate, new LiquidPromptTemplateFactory())
43+
{
44+
Name = writerAgentName,
45+
Kernel = KernelCreator.CreateKernel(useAzureOpenAI)
46+
};
47+
48+
string reviewerAgentName = "WriterFeedback";
49+
string reviewerAgentInstructions = """
50+
You are an expert agent specialized in reviewing and providing detailed feedback on texts. Your task is to carefully analyze the provided text and offer actionable suggestions to enhance its quality and effectiveness.
51+
52+
When providing feedback, always clearly address the following points:
53+
54+
1) Clarity and Readability:
55+
- Evaluate if the ideas and explanations are clearly presented and easily understandable.
56+
- Suggest ways to simplify complex or unclear sentences.
57+
58+
2) Grammar and Style:
59+
- Identify and correct grammatical, spelling, or punctuation errors.
60+
- Suggest improvements in sentence structure and overall writing style to enhance readability.
61+
- Terminology and Accuracy:
62+
63+
Ensure the text correctly uses terminology appropriate to the topic.
64+
65+
Provide corrections or suggest better terminology choices if inaccuracies or inconsistencies are found.
66+
67+
Present your feedback clearly, organizing your suggestions into the three points listed above. Include examples from the original text where relevant, and suggest revised formulations when providing corrections.
68+
69+
Once you have provided the feedback, you must approve the work saying "I approve".
70+
""";
71+
72+
ChatCompletionAgent reviewerAgent = new ChatCompletionAgent
73+
{
74+
Name = reviewerAgentName,
75+
Instructions = reviewerAgentInstructions,
76+
Kernel = KernelCreator.CreateKernel(useAzureOpenAI)
77+
};
78+
79+
KernelFunction selectionFunction =
80+
AgentGroupChat.CreatePromptFunctionForStrategy(
81+
$$$"""
82+
Determine which participant takes the next turn in a conversation based on the the most recent participant.
83+
State only the name of the participant to take the next turn.
84+
No participant should take more than one turn in a row.
85+
86+
Choose only from these participants:
87+
- {{{researcherAgentName}}}
88+
- {{{writerAgentName}}}
89+
- {{{reviewerAgentName}}}
90+
91+
Always follow these rules when selecting the next participant:
92+
- The user will share a topic to research
93+
- After the user, it's {{{researcherAgentName}}}'s turn to research the given topic.
94+
- After {{{researcherAgentName}}}, it is {{{writerAgentName}}}'s turn to write the text.
95+
- After {{{writerAgentName}}}, it is {{{reviewerAgentName}}}'s turn to review the text.
96+
97+
History:
98+
{{$history}}
99+
""",
100+
safeParameterNames: "history");
101+
102+
// Define the selection strategy
103+
KernelFunctionSelectionStrategy selectionStrategy =
104+
new(selectionFunction, KernelCreator.CreateKernel(useAzureOpenAI))
105+
{
106+
// Always start with the writer agent.
107+
InitialAgent = researcherAgent,
108+
// Parse the function response.
109+
ResultParser = (result) => result.GetValue<string>() ?? researcherAgentName,
110+
// The prompt variable name for the history argument.
111+
HistoryVariableName = "history",
112+
// Save tokens by not including the entire history in the prompt
113+
HistoryReducer = new ChatHistoryTruncationReducer(3),
114+
};
115+
116+
KernelFunction terminationFunction =
117+
AgentGroupChat.CreatePromptFunctionForStrategy(
118+
$$$"""
119+
Determine if the reviewer has approved. If so, respond with a single word: yes
120+
121+
History:
122+
{{$history}}
123+
""",
124+
safeParameterNames: "history");
125+
126+
// Define the termination strategy
127+
KernelFunctionTerminationStrategy terminationStrategy =
128+
new(terminationFunction, KernelCreator.CreateKernel(useAzureOpenAI))
129+
{
130+
// Only the reviewer may give approval.
131+
Agents = [reviewerAgent],
132+
// Parse the function response.
133+
ResultParser = (result) =>
134+
result.GetValue<string>()?.Contains("yes", StringComparison.OrdinalIgnoreCase) ?? false,
135+
// The prompt variable name for the history argument.
136+
HistoryVariableName = "history",
137+
// Save tokens by not including the entire history in the prompt
138+
HistoryReducer = new ChatHistoryTruncationReducer(1),
139+
// Limit total number of turns no matter what
140+
MaximumIterations = 10,
141+
};
142+
143+
chat = new(researcherAgent, writerAgent, reviewerAgent)
144+
{
145+
ExecutionSettings = new()
146+
{
147+
SelectionStrategy = selectionStrategy,
148+
TerminationStrategy = terminationStrategy
149+
}
150+
};
151+
}
152+
}
153+
}

Diff for: SemanticKernel.Agents/Scenarios/RapBattleScenario.cs

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public override void InitializeScenario(bool useAzureOpenAI)
2525
Kernel = KernelCreator.CreateKernel(useAzureOpenAI)
2626
};
2727

28-
2928
ChatCompletionAgent eminemAgent = new ChatCompletionAgent
3029
{
3130
Name = eminemName,

Diff for: SemanticKernel.Agents/Scenarios/TravelScenario.cs

+1-5
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@
44

55
namespace SemanticKernel.Agents.Scenarios
66
{
7-
public class TravelScenario: BaseScenario
7+
public class TravelScenario : BaseScenario
88
{
99
const string travelManagerName = "TravelManager";
1010
const string travelAgentName = "TravelAgent";
1111
const string flightExpertName = "FlightExpert";
1212
const string trainExpertName = "TrainExpert";
1313

14-
private AgentGroupChat chat;
15-
1614
public override void InitializeScenario(bool useAzureOpenAI)
1715
{
1816
string travelManagerInstructions = """
@@ -89,8 +87,6 @@ Your goal is to create a train plan to reach a city based on the user prefences
8987
"""
9088
);
9189

92-
93-
9490
KernelFunction selectionFunction = KernelFunctionFactory.CreateFromPrompt(
9591
$$$"""
9692
Your job is to determine which participant takes the next turn in a conversation according to the action of the most recent participant.

Diff for: SemanticKernel.Agents/SemanticKernel.Agents.csproj

+17-4
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,30 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net9.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
<UserSecretsId>a8d0dcc4-025d-4992-b2a4-8ec9e9380af1</UserSecretsId>
99
<NoWarn>$(NoWarn);CS8618,IDE0009,CA1051,CA1050,CA1707,CA1054,CA2007,VSTHRD111,CS1591,RCS1110,RCS1243,CA5394,SKEXP0001,SKEXP0010,SKEXP0020,SKEXP0040,SKEXP0050,SKEXP0060,SKEXP0070,SKEXP0101</NoWarn>
1010
</PropertyGroup>
1111

1212
<ItemGroup>
13-
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
14-
<PackageReference Include="Microsoft.SemanticKernel" Version="1.18.2" />
15-
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" Version="1.16.2-alpha" />
13+
<None Remove="Prompts\writerAgent.prompty" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<Content Include="Prompts\writerAgent.prompty">
18+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
19+
</Content>
20+
</ItemGroup>
21+
22+
<ItemGroup>
23+
<PackageReference Include="Azure.Identity" Version="1.12.0" />
24+
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" />
25+
<PackageReference Include="Microsoft.SemanticKernel" Version="1.42.0" />
26+
<PackageReference Include="Microsoft.SemanticKernel.Agents.AzureAI" Version="1.42.0-preview" />
27+
<PackageReference Include="Microsoft.SemanticKernel.Agents.Core" Version="1.42.0-preview" />
28+
<PackageReference Include="Microsoft.SemanticKernel.Prompty" Version="1.42.0-alpha" />
1629
</ItemGroup>
1730

1831
</Project>

Diff for: SemanticKernel.Agents/SemanticKernel.Agents.sln

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
Microsoft Visual Studio Solution File, Format Version 12.00
2+
# Visual Studio Version 17
3+
VisualStudioVersion = 17.5.2.0
4+
MinimumVisualStudioVersion = 10.0.40219.1
5+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SemanticKernel.Agents", "SemanticKernel.Agents.csproj", "{942511B3-A161-E471-F7BA-AB29D0957EBA}"
6+
EndProject
7+
Global
8+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
9+
Debug|Any CPU = Debug|Any CPU
10+
Release|Any CPU = Release|Any CPU
11+
EndGlobalSection
12+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
13+
{942511B3-A161-E471-F7BA-AB29D0957EBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
14+
{942511B3-A161-E471-F7BA-AB29D0957EBA}.Debug|Any CPU.Build.0 = Debug|Any CPU
15+
{942511B3-A161-E471-F7BA-AB29D0957EBA}.Release|Any CPU.ActiveCfg = Release|Any CPU
16+
{942511B3-A161-E471-F7BA-AB29D0957EBA}.Release|Any CPU.Build.0 = Release|Any CPU
17+
EndGlobalSection
18+
GlobalSection(SolutionProperties) = preSolution
19+
HideSolutionNode = FALSE
20+
EndGlobalSection
21+
GlobalSection(ExtensibilityGlobals) = postSolution
22+
SolutionGuid = {0125D39A-0DA4-482A-B29F-0E4BB2698BDE}
23+
EndGlobalSection
24+
EndGlobal

Diff for: SemanticKernel.Basic/SemanticKernel.Basic.csproj

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net9.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
<UserSecretsId>8a4821ee-3680-41af-8b37-1b9a978ac962</UserSecretsId>
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
13-
<PackageReference Include="Microsoft.SemanticKernel" Version="1.18.2" />
12+
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" />
13+
<PackageReference Include="Microsoft.SemanticKernel" Version="1.40.1" />
1414
</ItemGroup>
1515

1616
</Project>

Diff for: SemanticKernel.BuiltinPlugins/SemanticKernel.BingPlugin.csproj

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919

2020

2121
<ItemGroup>
22-
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
23-
<PackageReference Include="Microsoft.SemanticKernel" Version="1.18.2" />
24-
<PackageReference Include="Microsoft.SemanticKernel.Plugins.Web" Version="1.18.2-alpha" />
22+
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.2" />
23+
<PackageReference Include="Microsoft.SemanticKernel" Version="1.40.1" />
24+
<PackageReference Include="Microsoft.SemanticKernel.Plugins.Web" Version="1.40.1-alpha" />
2525
</ItemGroup>
2626

2727
</Project>

0 commit comments

Comments
 (0)