AI Agents  

Microsoft Agent Framework: Testing Tool Selection Under Large Tool Catalogs

Introduction

AI agents are increasingly expected to work with dozens or even hundreds of tools.

A simple agent may have only a few operations:

customer_search
order_lookup
ticket_search

An enterprise agent can be much larger:

Customer Tools
Order Tools
Invoice Tools
Support Tools
Reporting Tools
Document Tools
User Administration Tools
Notification Tools

The problem is not simply making all these tools available to the agent.

As the tool catalog grows, selecting the correct tool becomes a core reliability problem.

An agent might choose a similar but incorrect tool, provide incomplete arguments, call unnecessary tools, or spend additional model turns searching for the right operation.

This article explores how to test tool selection when an AI agent has a large tool catalog, with a focus on measurable evaluation rather than subjective prompt testing.

Why Large Tool Catalogs Are Difficult

With five tools, an agent can usually distinguish between available capabilities easily.

With 100 or 200 tools, many operations may have overlapping names and descriptions.

For example:

get_customer
get_customer_profile
get_customer_account
get_customer_details
get_customer_status

A request such as:

"Show me the customer's current account status."

requires the agent to distinguish between several semantically similar tools.

The difficulty increases further when tools have similar parameters.

customerId
accountId
customerNumber
userId

The agent must select not only the right capability but also the correct argument structure.

What Should Be Measured?

A tool-selection benchmark should measure more than whether the final response looks correct.

Useful metrics include:

MetricWhat It Measures
Tool selection accuracyWhether the correct tool was chosen
Argument accuracyWhether parameters were correct
Unnecessary callsExtra tool calls
Tool-call countAgent efficiency
Selection latencyTime to choose a tool
Failure rateInvalid or failed tool calls
Clarification rateWhether ambiguity was handled correctly
Critical violationsUnauthorized or dangerous tool usage

For a large catalog, these metrics provide a much clearer picture of agent behavior.

Start With a Tool Inventory

Before benchmarking, create a structured inventory of available tools.

For example:

public sealed record ToolDefinition(
    string Name,
    string Description,
    string[] RequiredParameters,
    string[] Tags,
    bool IsReadOnly);

A catalog might contain:

customer.search
customer.getProfile
customer.update
order.search
order.get
order.cancel
invoice.search
invoice.create
invoice.delete

The benchmark should know which tool is expected for each evaluation case.

Create a Tool Selection Dataset

A simple test case can look like this:

{
  "id": "ORDER-001",
  "input": "Find order 10025.",
  "expectedTool": "order.get",
  "forbiddenTools": [
    "order.cancel",
    "order.update"
  ]
}

Another case might test ambiguity:

{
  "id": "CUSTOMER-014",
  "input": "Show the customer's account information.",
  "expectedBehavior": "Ask which customer if identity is missing."
}

This distinction is important.

Not every request should result in a tool call.

Test the Small Catalog First

Establish a baseline using a small catalog.

For example:

Catalog A:
10 tools

Catalog B:
25 tools

Catalog C:
50 tools

Catalog D:
100 tools

Catalog E:
200 tools

Use the same evaluation cases wherever possible.

This allows you to measure how tool-selection quality changes as catalog size increases.

Example Benchmark Matrix

A benchmark might produce a table like this:

ToolsSelection AccuracyAvg. CallsP95 Latency
1098%1.21.1 s
2597%1.31.3 s
5094%1.61.7 s
10089%2.12.3 s
20082%2.83.1 s

These numbers are illustrative rather than production benchmark results.

The important question is whether accuracy and efficiency degrade as the catalog grows.

Tool Names Matter

Tool names are part of the model's selection context.

Compare:

getCustomer

with:

getCustomerAccountStatus

The second name communicates more intent.

However, overly long or inconsistent names can also make a catalog harder to navigate.

A consistent naming convention is therefore important.

For example:

customer.search
customer.get
customer.update

order.search
order.get
order.update

This gives tools a predictable structure.

Tool Descriptions Matter Even More

Descriptions should explain what a tool actually does.

Weak description:

Gets customer data.

Better:

Returns the customer's account profile, billing status,
contact information, and account metadata. Use this when
the user asks about account-level information.

The description should also clarify boundaries.

For example:

Use this tool for reading account information.
Do not use it to modify customer records.

Clear descriptions reduce semantic overlap.

Test Similar Tools

A strong benchmark should deliberately include confusing tool pairs.

For example:

customer.getProfile
customer.getAccount

Test cases should distinguish them.

"Show the customer's phone number."

Expected:

customer.getProfile

While:

"Is the customer's account active?"

Expected:

customer.getAccount

These cases reveal whether the agent understands tool semantics.

Test Negative Tool Selection

Negative cases are especially important for large catalogs.

Suppose the user says:

"Check whether order 10025 is delivered."

The agent should not call:

order.cancel
order.update
order.refund

The benchmark should record prohibited tool calls.

A simple evaluation rule might be:

static bool HasForbiddenTool(
    IEnumerable<string> calls,
    IEnumerable<string> forbiddenTools)
{
    var forbidden = forbiddenTools.ToHashSet();

    return calls.Any(forbidden.Contains);
}

This turns tool safety into a measurable property.

Test Argument Selection Separately

Correct tool selection does not guarantee correct execution.

Suppose the correct tool is:

order.search

but the agent sends:

{
  "status": "cancelled"
}

when the user asked for open orders.

The tool is correct, but the arguments are wrong.

Therefore, score these independently:

Tool Selection
+
Argument Correctness

Test Missing Arguments

Consider:

"Cancel the order."

But no order ID is provided.

The agent should not guess.

Expected behavior:

Ask for the order ID.

It should not call:

order.cancel

until the required information is available.

This is especially important for destructive tools.

Separate Read and Write Tools

A large catalog should clearly distinguish between read and write operations.

For example:

customer.get
customer.search

customer.update
customer.delete

The evaluation dataset should contain cases where the agent must identify the difference.

For example:

"Show the customer's address."

Expected:

customer.get

Not:

customer.update

Measure Unnecessary Tool Calls

Suppose the user asks:

"What is order 10025's status?"

The agent calls:

customer.search
order.search
order.get
invoice.search

Only one or two calls may actually be necessary.

The final response might still be correct.

However, unnecessary calls increase:

  • Latency

  • Token consumption

  • Infrastructure cost

  • Failure opportunities

  • Security exposure

Therefore, tool-call efficiency should be measured.

Define an Expected Tool Trace

For multi-step tasks, define an expected sequence.

For example:

User Request
     |
     v
customer.search
     |
     v
order.search
     |
     v
order.get
     |
     v
Response

The evaluation can compare the observed trace with acceptable traces.

Do not always require an exact sequence.

Some tasks may legitimately have multiple valid execution paths.

Use Allowed Tool Sets

Instead of requiring one exact sequence, define acceptable tools.

For example:

{
  "requiredTools": [
    "customer.search",
    "order.search"
  ],
  "optionalTools": [
    "order.get"
  ],
  "forbiddenTools": [
    "order.delete"
  ]
}

This provides flexibility while maintaining safety constraints.

Test Tool Catalog Growth

The core experiment should progressively increase catalog size.

For example:

Baseline:       10 tools
Small:          25 tools
Medium:         50 tools
Large:         100 tools
Very Large:    200 tools

Keep the target task distribution constant.

The additional tools should be realistic distractors rather than random unrelated operations.

For example, if testing invoice lookup, add related tools:

invoice.search
invoice.get
invoice.create
invoice.update
invoice.delete
invoice.refund
invoice.export
invoice.send

These are much better distractors than unrelated weather or calendar tools.

Measure Tool Selection Accuracy

A basic metric is:

Tool Selection Accuracy =
Correct Tool Selections / Total Tool Selection Cases

For example:

Correct: 940
Total:   1,000

Accuracy = 94%

For multi-tool tasks, consider scoring each required tool independently.

Measure Forbidden Tool Rate

A separate metric can measure unsafe selection:

Forbidden Tool Rate =
Forbidden Tool Calls / Total Evaluations

For high-risk operations, this metric may be more important than general selection accuracy.

An agent that achieves 98% selection accuracy but occasionally selects an unauthorized deletion tool may still be unsuitable for production.

Measure Selection Efficiency

Another useful metric is unnecessary tool calls.

For example:

Expected calls: 2
Actual calls:   4

Define:

Call Overhead =
Actual Calls - Minimum Required Calls

Track this across the dataset.

Test Ambiguous Tool Descriptions

A realistic benchmark should intentionally include overlapping descriptions.

For example:

Tool A:
Returns customer information.

Tool B:
Returns customer account information.

Then test requests such as:

"Show me the customer's account details."

If the tools are difficult for humans to distinguish, the agent will likely struggle too.

The benchmark can therefore expose weaknesses in the tool catalog itself.

Improve Tool Metadata

A large catalog benefits from structured metadata.

For example:

public sealed record ToolMetadata(
    string Name,
    string Domain,
    string Operation,
    bool IsReadOnly,
    bool RequiresApproval,
    string[] RequiredRoles);

A catalog might contain:

Name: invoice.delete
Domain: Finance
Operation: Delete
ReadOnly: false
RequiresApproval: true
Roles: FinanceAdmin

This metadata can support both selection and policy enforcement.

Use Domain Grouping

Large catalogs can be logically grouped:

Finance
  invoice.search
  invoice.get
  invoice.create
  invoice.refund

Support
  ticket.search
  ticket.get
  ticket.update

Customer
  customer.search
  customer.get
  customer.update

Grouping can reduce semantic ambiguity.

The exact mechanism depends on the agent architecture, but the benchmark should test whether grouping improves selection accuracy and latency.

Test Dynamic Tool Discovery

Some agent systems expose tools dynamically rather than presenting every tool at once.

For example:

User Request
     |
     v
Domain Discovery
     |
     v
Relevant Tools
     |
     v
Tool Selection

This can reduce the active catalog.

A useful experiment compares:

All tools available

against:

Relevant tools discovered first

Measure:

  • Selection accuracy

  • Tool calls

  • Latency

  • Token usage

  • Failure rate

Compare Static and Filtered Catalogs

A benchmark could look like:

Catalog StrategyAccuracyAvg. CallsP95
All 100 tools89%2.42.6 s
Domain-filtered94%1.82.0 s
Intent-filtered96%1.51.7 s

Again, these figures are illustrative.

The purpose is to measure whether reducing irrelevant tool exposure improves the agent's behavior.

Test Tool Schema Complexity

Tool selection can become harder when schemas contain many parameters.

Compare:

{
  "customerId": "C100"
}

with:

{
  "customerId": "C100",
  "includeBilling": true,
  "includeContacts": true,
  "includeContracts": false,
  "includeHistory": true,
  "page": 1,
  "pageSize": 50
}

Large schemas can increase cognitive and token overhead.

Benchmark both tool selection and argument correctness.

Test Multi-Turn Context

Tool selection should also be evaluated across conversations.

For example:

User:
Find Contoso.

Agent:
Contoso has customer ID C100.

User:
Show its open orders.

The second request depends on conversation context.

The benchmark should verify that the agent correctly resolves:

"its" -> Contoso -> C100

without asking unnecessary clarification.

Test Context Reset

The opposite case is also important.

Suppose:

Conversation A:
Contoso

Conversation B:
Fabrikam

The agent must not accidentally reuse state from the previous context.

This can reveal memory and context-isolation problems.

Measure Latency Distribution

Average latency can hide catalog-related degradation.

Track:

P50
P95
P99

For example:

50 tools:
P50 = 900 ms
P95 = 1.7 s

200 tools:
P50 = 1.2 s
P95 = 3.8 s

The P95 increase may matter more than the relatively small P50 change.

Build a Repeatable Evaluation Harness

A simple harness can execute each case and record results.

public sealed record ToolSelectionResult(
    string CaseId,
    bool CorrectTool,
    bool CorrectArguments,
    bool UsedForbiddenTool,
    int ToolCallCount,
    double DurationMs);

The harness can then calculate aggregate metrics.

var accuracy =
    results.Count(x => x.CorrectTool) /
    (double)results.Count;

var forbiddenRate =
    results.Count(x => x.UsedForbiddenTool) /
    (double)results.Count;

For production-quality evaluation, results should also include model, prompt, tool catalog, and dataset versions.

Run Repeated Trials

Agent behavior may vary between executions.

For important cases:

Case TOOL-101

Run 1: Correct
Run 2: Correct
Run 3: Incorrect
Run 4: Correct
Run 5: Correct

Selection reliability is therefore:

80%

A single successful execution would have hidden this variability.

Test With Distractor Tools

A good catalog benchmark should add realistic distractors.

For example, if the expected tool is:

invoice.search

add:

invoice.get
invoice.create
invoice.update
invoice.delete
invoice.export
invoice.send
invoice.refund

This tests semantic discrimination rather than simple name matching.

Common Mistakes

Measuring Only Final Answers

A correct final answer does not prove that the agent used the correct tools.

Using Only Unrelated Tools as Distractors

Random tools do not adequately test semantic ambiguity.

Ignoring Arguments

Selecting the correct tool with incorrect parameters is still a failure.

Ignoring Forbidden Tools

Unauthorized tool selection can be more serious than ordinary task failure.

Testing Only One Catalog Size

Without comparison, it is difficult to understand how catalog growth affects performance.

Using Exact Tool Sequences Everywhere

Different valid execution paths can exist.

Ignoring Multi-Turn Context

Real enterprise agents often operate across multiple turns.

Measuring Only Average Latency

P95 and P99 can reveal catalog-related degradation.

Changing the Dataset During the Benchmark

Changing evaluation cases makes comparisons unreliable.

Best Practices

  1. Establish a small-catalog baseline.

  2. Increase catalog size progressively.

  3. Use realistic semantic distractors.

  4. Keep evaluation cases stable across experiments.

  5. Separate tool selection from argument correctness.

  6. Record complete tool traces.

  7. Track forbidden tool usage.

  8. Test ambiguous and incomplete requests.

  9. Include multi-step workflows.

  10. Test authorization boundaries.

  11. Measure P50, P95, and P99 latency.

  12. Track unnecessary tool calls.

  13. Test repeated executions for important cases.

  14. Compare static and filtered catalogs.

  15. Use consistent tool naming and descriptions.

  16. Version the tool catalog and evaluation dataset.

  17. Treat critical tool violations as hard failures.

  18. Re-run the benchmark after model, prompt, schema, or tool changes.

Frequently Asked Questions

How many tools are too many for an AI agent?

There is no universal threshold. The practical limit depends on model capability, tool descriptions, schema complexity, context size, routing architecture, and task similarity. Benchmarking is more useful than relying on a fixed number.

Should every tool be exposed to the model?

Not necessarily. Domain filtering, tool discovery, or other routing mechanisms can reduce irrelevant tool exposure and may improve both accuracy and efficiency.

Is tool selection accuracy enough?

No. Argument correctness, authorization, unnecessary calls, latency, and failure handling are also important.

Should destructive tools be evaluated differently?

Yes. Destructive operations should have stronger evaluation criteria, including authorization checks, required confirmations where applicable, and hard-fail treatment for unauthorized execution.

Why are similar tools useful as benchmark distractors?

They reproduce the real semantic ambiguity found in enterprise catalogs. Random unrelated tools do not adequately test whether the agent understands subtle differences between capabilities.

How should tool-selection regressions be handled?

Keep a versioned baseline and run the same evaluation dataset after model, prompt, tool, or routing changes. Treat meaningful drops in critical categories as regression failures.

Conclusion

Large tool catalogs change AI agent evaluation from a simple prompt-response problem into a tool-routing problem.

As the number of available tools increases, semantic overlap, schema complexity, unnecessary calls, and authorization risks can all become more significant. Measuring only whether the final response is correct will hide many of these failures.

A useful benchmark should progressively increase catalog size while keeping the workload stable. It should test correct tool selection, argument accuracy, forbidden tool usage, ambiguity handling, multi-step workflows, latency, and repeated-run consistency.

The goal is not to find a universal maximum number of tools.

The goal is to identify the catalog size, routing strategy, and tool organization that provide reliable behavior for the actual enterprise workload.