-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Closed
Labels
.NETIssue or Pull requests regarding .NET codeIssue or Pull requests regarding .NET codeBuildFeatures planned for next Build conferenceFeatures planned for next Build conferenceagentsexperimentalAssociated with an experimental featureAssociated with an experimental featurequestionFurther information is requestedFurther information is requestedsk team issueA tag to denote issues that where created by the Semantic Kernel team (i.e., not the community)A tag to denote issues that where created by the Semantic Kernel team (i.e., not the community)staleIssue is stale because it has been open for a while and has no activityIssue is stale because it has been open for a while and has no activity
Description
1. Use KernelFunction return value
The default KernelFunctionTerminationStrategy.ResultParser is:
public Func<FunctionResult, bool> ResultParser { get; init; } = (_) => true;
If the KernelFunction returns false then this will override this return value and cause termination.
Why doesn't the default implementation change the function result?
2. Pass Agent and ChatHistory in KernelArguments
Consider this code
protected sealed override async Task<bool> ShouldAgentTerminateAsync(Agent agent, IReadOnlyList<ChatMessageContent> history, CancellationToken cancellationToken = default)
{
history = await history.ReduceAsync(this.HistoryReducer, cancellationToken).ConfigureAwait(false);
KernelArguments originalArguments = this.Arguments ?? [];
KernelArguments arguments =
new(originalArguments, originalArguments.ExecutionSettings?.ToDictionary(kvp => kvp.Key, kvp => kvp.Value))
{
{ this.AgentVariableName, agent.Name ?? agent.Id },
{ this.HistoryVariableName, ChatMessageForPrompt.Format(history, this.EvaluateNameOnly) },
};
this.Logger.LogKernelFunctionTerminationStrategyInvokingFunction(nameof(ShouldAgentTerminateAsync), this.Function.PluginName, this.Function.Name);
FunctionResult result = await this.Function.InvokeAsync(this.Kernel, arguments, cancellationToken).ConfigureAwait(false);
this.Logger.LogKernelFunctionTerminationStrategyInvokedFunction(nameof(ShouldAgentTerminateAsync), this.Function.PluginName, this.Function.Name, result.ValueType);
return this.ResultParser.Invoke(result);
}It would be more convenient to:
- Pass
Agentinstance rather than the name or id - Pass the
ChatHistoryrather than a string (which cannot be parsed back into a ChatHistory - Allow for
KernelFunctionswhich has a signature which takes typedAgentandChatHistoryparameters
3. Should we have a standard way to Invoke an Agent
When we support declarative agents the follow will look something like this
- Load the
Agentinstance from a file which contains a declarative definition of anAgent - Invoke the
Agentinstance optionally using a provided input and other arguments - Capture the result which should contain everything needed to invoke the
Agentinstance again and maintain context
Here's some psuedo code:
Kernel kernel = ...
string agentYaml = EmbeddedResource.Read("MyAgent.yaml");
AgentFactory agentFactory = new AggregatorAgentFactory(
new ChatCompletionFactory(),
new OpenAIAssistantAgentFactory(),
new XXXAgentFactory());
Agent agent = kernel.LoadAgentFromYaml(agentYaml); // What return type should we use to standardise?
// Should we have a unified pattern here?
ChatHistory chatHistory = new();
chatHistory.AddUserMessage(input);
await foreach (ChatMessageContent content in agent.InvokeAsync(chatHistory))
{
chatHistory.Add(content);
}At the moment the code to "Invoke" a ChatCompletionAgent versus a OpenAIAssistantAgent is different. Should we have an abstraction in the Agent framework that allows us to standardise?
Metadata
Metadata
Assignees
Labels
.NETIssue or Pull requests regarding .NET codeIssue or Pull requests regarding .NET codeBuildFeatures planned for next Build conferenceFeatures planned for next Build conferenceagentsexperimentalAssociated with an experimental featureAssociated with an experimental featurequestionFurther information is requestedFurther information is requestedsk team issueA tag to denote issues that where created by the Semantic Kernel team (i.e., not the community)A tag to denote issues that where created by the Semantic Kernel team (i.e., not the community)staleIssue is stale because it has been open for a while and has no activityIssue is stale because it has been open for a while and has no activity
Type
Projects
Status
No status