forked from microsoft/semantic-kernel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathStep01_Agent.cs
182 lines (157 loc) · 6.83 KB
/
Step01_Agent.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// Copyright (c) Microsoft. All rights reserved.
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Agents;
using Microsoft.SemanticKernel.ChatCompletion;
using Resources;
namespace GettingStarted;
/// <summary>
/// Demonstrate creation of <see cref="ChatCompletionAgent"/> and
/// eliciting its response to three explicit user messages.
/// </summary>
public class Step01_Agent(ITestOutputHelper output) : BaseAgentsTest(output)
{
private const string ParrotName = "Parrot";
private const string ParrotInstructions = "Repeat the user message in the voice of a pirate and then end with a parrot sound.";
private const string JokerName = "Joker";
private const string JokerInstructions = "You are good at telling jokes.";
/// <summary>
/// Demonstrate the usage of <see cref="ChatCompletionAgent"/> where each invocation is
/// a unique interaction with no conversation history between them.
/// </summary>
[Fact]
public async Task UseSingleChatCompletionAgentAsync()
{
Kernel kernel = this.CreateKernelWithChatCompletion();
// Define the agent
ChatCompletionAgent agent =
new()
{
Name = ParrotName,
Instructions = ParrotInstructions,
Kernel = this.CreateKernelWithChatCompletion(),
};
// Respond to user input
await InvokeAgentAsync("Fortune favors the bold.");
await InvokeAgentAsync("I came, I saw, I conquered.");
await InvokeAgentAsync("Practice makes perfect.");
// Local function to invoke agent and display the conversation messages.
async Task InvokeAgentAsync(string input)
{
ChatMessageContent message = new(AuthorRole.User, input);
this.WriteAgentChatMessage(message);
await foreach (AgentResponseItem<ChatMessageContent> response in agent.InvokeAsync(message))
{
this.WriteAgentChatMessage(response);
}
}
}
/// <summary>
/// Demonstrate the usage of <see cref="ChatCompletionAgent"/> where a conversation history is maintained.
/// </summary>
[Fact]
public async Task UseSingleChatCompletionAgentWithConversationAsync()
{
Kernel kernel = this.CreateKernelWithChatCompletion();
// Define the agent
ChatCompletionAgent agent =
new()
{
Name = JokerName,
Instructions = JokerInstructions,
Kernel = this.CreateKernelWithChatCompletion(),
};
// Define a thread variable to maintain the conversation context.
// Since we are passing a null thread to InvokeAsync on the first invocation,
// the agent will create a new thread for the conversation.
AgentThread? thread = null;
// Respond to user input
await InvokeAgentAsync("Tell me a joke about a pirate.");
await InvokeAgentAsync("Now add some emojis to the joke.");
// Local function to invoke agent and display the conversation messages.
async Task InvokeAgentAsync(string input)
{
ChatMessageContent message = new(AuthorRole.User, input);
this.WriteAgentChatMessage(message);
await foreach (AgentResponseItem<ChatMessageContent> response in agent.InvokeAsync(message, thread))
{
this.WriteAgentChatMessage(response);
thread = response.Thread;
}
}
}
/// <summary>
/// Demonstrate the usage of <see cref="ChatCompletionAgent"/> where a conversation history is maintained
/// and where the thread containing the conversation is created manually.
/// </summary>
[Fact]
public async Task UseSingleChatCompletionAgentWithManuallyCreatedThreadAsync()
{
Kernel kernel = this.CreateKernelWithChatCompletion();
// Define the agent
ChatCompletionAgent agent =
new()
{
Name = JokerName,
Instructions = JokerInstructions,
Kernel = this.CreateKernelWithChatCompletion(),
};
// Define a thread variable to maintain the conversation context.
// Since we are creating the thread, we can pass some initial messages to it.
AgentThread? thread = new ChatHistoryAgentThread(
[
new ChatMessageContent(AuthorRole.User, "Tell me a joke about a pirate."),
new ChatMessageContent(AuthorRole.Assistant, "Why did the pirate go to school? Because he wanted to improve his \"arrrrrrrrrticulation\""),
]);
// Respond to user input
await InvokeAgentAsync("Now add some emojis to the joke.");
await InvokeAgentAsync("Now make the joke sillier.");
// Local function to invoke agent and display the conversation messages.
async Task InvokeAgentAsync(string input)
{
ChatMessageContent message = new(AuthorRole.User, input);
this.WriteAgentChatMessage(message);
// Use the thread we created earlier to continue the conversation.
await foreach (AgentResponseItem<ChatMessageContent> response in agent.InvokeAsync(message, thread))
{
this.WriteAgentChatMessage(response);
}
}
}
[Fact]
public async Task UseTemplateForChatCompletionAgentAsync()
{
// Define the agent
string generateStoryYaml = EmbeddedResource.Read("GenerateStory.yaml");
PromptTemplateConfig templateConfig = KernelFunctionYaml.ToPromptTemplateConfig(generateStoryYaml);
KernelPromptTemplateFactory templateFactory = new();
// Instructions, Name and Description properties defined via the config.
ChatCompletionAgent agent =
new(templateConfig, templateFactory)
{
Kernel = this.CreateKernelWithChatCompletion(),
Arguments = new()
{
{ "topic", "Dog" },
{ "length", "3" },
}
};
// Invoke the agent with the default arguments.
await InvokeAgentAsync();
// Invoke the agent with the override arguments.
await InvokeAgentAsync(
new()
{
{ "topic", "Cat" },
{ "length", "3" },
});
// Local function to invoke agent and display the conversation messages.
async Task InvokeAgentAsync(KernelArguments? arguments = null)
{
// Invoke the agent without any messages, since the agent has all that it needs via the template and arguments.
await foreach (ChatMessageContent content in agent.InvokeAsync(options: new() { KernelArguments = arguments }))
{
WriteAgentChatMessage(content);
}
}
}
}