Tool grouping
Summary
This PR demonstrates a prototype middleware that allows grouping related tools. Groups are hidden from the inner chat client by default, but a well-known "expand" function can be called to expand one group at a time. By reducing the number of tools available to the model at a time, its ability to select the correct tool improves.
Following is an overview of the changes in this PR:
- Add
ToolGroupingChatClient, which provides tool grouping and expansion functionality. - Introduce
AIToolGroupto model stable, named batches of tools. - Add integration tests validating the feasibility of approach.
Usage example
using Microsoft.Extensions.AI;
var travelUtilities = AIToolGroup.Create(
"TravelUtilities",
"Travel planning helpers that generate itinerary tokens.",
[generateItinerary, summarizePacking]);
var financeUtilities = AIToolGroup.Create(
name: "FinanceUtilities",
description: "Budgeting helpers.",
tools: [budgetTool]));
var options = new ChatOptions
{
Tools = [travelUtilities, financeUtilities]
};
IChatClient client = baseClient
.AsBuilder()
.UseToolGrouping(/* ... */)
.UseToolReduction(/* ... */) // Optionally further reduce the set of available tools
.UseFunctionInvocation()
.Build();
var response = await client.GetResponseAsync("Plan a weekend getaway to Lisbon and include a budget tip.");
// ...
Implementation notes
This middleware contains a lot of the same complexities present in FunctionInvokingChatClient: cloning options, honoring ConversationId, aggregating Usage across inner calls, and replaying tool-result messages into the history. The expansion loop is deliberately limited to one active group per top-level request to prevent degradation of tool selection as the number of expanded groups increases.