CRM Server (example)
6 tools · automated analysis by ToolChoice · input schemas are hidden on public pages
Synthetic heuristic simulation. No external language model was used. Results estimate likely tool ambiguity and do not represent measured production model accuracy.
Executive summary
The simulator routed the correct tool in 6 of 10 scored scenarios and produced valid arguments 4/10 of the time. The main observed failures were a boundary request that selected update_customer instead of get_customer, a boundary request that selected update_customer instead of create_customer. Overall readiness is held back by static definition-quality and safety findings, not by behavioral performance.
score breakdown · deterministic weighted sum
Observed failures
Failures that actually occurred during behavioral evaluation
“I already know the customer ID — it's cus_6398. Pull up the complete customer record.”
Reasoning: get_customer, update_customer, create_customer, search_customers all appear to handle customer requests and none states when to use which; picked the most detailed description.
“We just signed a brand-new customer, Northwind — they are not in the system yet. Add them.”
Reasoning: create_customer, update_customer all appear to handle customer requests and none states when to use which; picked the most detailed description.
“Retrieve the full customer profile for cus_1111.”
Reasoning: create_customer, get_customer, search_customers, update_customer all appear to handle customer requests and none states when to use which; picked the most detailed description.
“Merge customer cus_1200 and cus_1201 into a single record.”
Reasoning: update_customer, create_customer, get_customer, search_customers all appear to handle customer requests and none states when to use which; picked the most detailed description.
Behavioral test results
10 scored + 0 exploratory · temperature 0
“I already know the customer ID — it's cus_6398. Pull up the complete customer record.”
FAILargs: missing fields
Reasoning: get_customer, update_customer, create_customer, search_customers all appear to handle customer requests and none states when to use which; picked the most detailed description.
“We just signed a brand-new customer, Northwind — they are not in the system yet. Add them.”
FAILargs: missing id, fields
Reasoning: create_customer, update_customer all appear to handle customer requests and none states when to use which; picked the most detailed description.
“Retrieve the full customer profile for cus_1111.”
FAILReasoning: create_customer, get_customer, search_customers, update_customer all appear to handle customer requests and none states when to use which; picked the most detailed description.
“Merge customer cus_1200 and cus_1201 into a single record.”
FAILargs: missing fields
Reasoning: update_customer, create_customer, get_customer, search_customers all appear to handle customer requests and none states when to use which; picked the most detailed description.
“Find the customer whose email address is deniz@acme.io. I don't have an ID.”
PASS“Add a new customer for Globex — they just signed up.”
PASSargs: missing email
“Change the billing address on customer cus_1222 to their new office.”
PASSargs: missing fields
“Show me all contacts we have on file.”
PASS“Find the contact whose email address is priya@northwind.dev.”
PASSargs: missing query
“Find the customer with email alex@example.com.”
PASSObserved confusion
4 misroutes during behavioral evaluation
| expected ↓ / selected → | get_customer | search_customers | create_customer | update_customer | list_contacts | search_contacts | NO_TOOL |
|---|---|---|---|---|---|---|---|
| get_customer | · | 1 | · | 1 | · | · | · |
| search_customers | · | 2 | · | · | · | · | · |
| create_customer | · | · | 1 | 1 | · | · | · |
| update_customer | · | · | · | 1 | · | · | · |
| list_contacts | · | · | · | · | 1 | · | · |
| search_contacts | · | · | · | · | · | 1 | · |
| NO_TOOL | · | · | · | 1 | · | · | · |
Diagonal cells (green) are correct selections; off-diagonal cells (red, bordered) are misroutes. Exact counts shown in every cell.
Likely cause: the names are lexically close; neither description says when it should not be used.
- · Rename get_customer to get_customer_by_id
- · Add a "when to use" sentence to both tools
- · Add a "do not use for …" sentence naming the sibling capability
Likely cause: the names are lexically close; neither description says when it should not be used.
- · Add a "when to use" sentence to both tools
- · Add a "do not use for …" sentence naming the sibling capability
Likely cause: the names are lexically close; neither description says when it should not be used.
- · Rename get_customer to get_customer_by_id
- · Add a "when to use" sentence to both tools
- · Add a "do not use for …" sentence naming the sibling capability
Potential ambiguity
Risks inferred from static analysis — not observed failures
Observed failure: a scored intent was routed to the wrong tool in this pair. These two tools cover related actions on the same object and neither description states a usage boundary, so a model may route intents to the wrong one. This is a potential ambiguity, not an observed failure.
"get_customer" vs "search_customers" · get/search on "customer" · description overlap 33% · no usage boundaries
Fix: Add a "use this when …" sentence to each tool naming the distinguishing condition.
A get-by-id tool and a search tool cover the same object, and at least one of them does not state its boundary. This is the most common tool-selection failure pattern.
"get_customer" and "search_customers" both operate on "customer"
Fix: Make the get tool say the identifier must already be known ("Do not use to search"), and the search tool say it finds records by attributes.
Observed failure: a scored intent was routed to the wrong tool in this pair. These two tools cover related actions on the same object and neither description states a usage boundary, so a model may route intents to the wrong one. This is a potential ambiguity, not an observed failure.
"create_customer" vs "update_customer" · create/update on "customer" · description overlap 40% · no usage boundaries
Fix: Add a "use this when …" sentence to each tool naming the distinguishing condition.
Sibling operations on the same object do not explain when each should be used.
"create_customer" and "update_customer"
Fix: Add one "Use this when…" sentence to each tool that names the distinguishing condition.
These two tools cover related actions on the same object and neither description states a usage boundary, so a model may route intents to the wrong one. This is a potential ambiguity, not an observed failure.
"list_contacts" vs "search_contacts" · list/search on "contact" · description overlap 33% · no usage boundaries
Fix: Add a "use this when …" sentence to each tool naming the distinguishing condition.
Sibling operations on the same object do not explain when each should be used.
"list_contacts" and "search_contacts"
Fix: Add one "Use this when…" sentence to each tool that names the distinguishing condition.
Argument reliability
4/10 generated argument sets were schema-valid (required coverage, no hallucinated keys, correct types and enums).
- update_customer: missing fields
- update_customer: missing id, fields
- create_customer: missing email
- update_customer: missing fields
- search_contacts: missing query
- update_customer: missing fields
Tool-by-tool analysis
get_customer0/2 selected correctly · 5 findings
Gets customer data.
- warningTC008_SHORT_DESCRIPTION Description is extremely short — Expand to 1–3 sentences covering action, required context and usage boundary. Do not pad with filler.
- warningTC004_UNDOCUMENTED_PARAMETER Required parameter has no description — Describe "id": what it is, its format, and one example value.
- infoTC010_GENERIC_PARAMETER_NAME Parameter name is generic — Rename to a scoped name such as "customer_id" or add an explicit description.
- warningTC006_AMBIGUOUS_IDENTIFIER Identifier format is unclear — Document the format, e.g. "Customer ID with the cus_ prefix, e.g. cus_9f3k2".
- infoTC016_UNDOCUMENTED_OUTPUT Tool output is undocumented — Add an outputSchema, or a final sentence: "Returns the full customer record."
search_customers2/2 selected correctly · 1 finding
Gets customer information from the CRM.
- infoTC016_UNDOCUMENTED_OUTPUT Tool output is undocumented — Add an outputSchema, or a final sentence: "Returns the full customer record."
create_customer1/2 selected correctly · 4 findings
Creates a customer.
- warningTC008_SHORT_DESCRIPTION Description is extremely short — Expand to 1–3 sentences covering action, required context and usage boundary. Do not pad with filler.
- warningTC009_DESCRIPTION_ECHOES_NAME Description merely repeats the tool name — State what the tool does, which inputs it needs, and when it should be preferred over its siblings.
- warningTC004_UNDOCUMENTED_PARAMETER Required parameter has no description — Describe "email": what it is, its format, and one example value.
- infoTC016_UNDOCUMENTED_OUTPUT Tool output is undocumented — Add an outputSchema, or a final sentence: "Returns the full customer record."
update_customer1/1 selected correctly · 5 findings
Creates or updates customer records in the system.
- warningTC004_UNDOCUMENTED_PARAMETER Required parameter has no description — Describe "id": what it is, its format, and one example value.
- infoTC010_GENERIC_PARAMETER_NAME Parameter name is generic — Rename to a scoped name such as "customer_id" or add an explicit description.
- warningTC006_AMBIGUOUS_IDENTIFIER Identifier format is unclear — Document the format, e.g. "Customer ID with the cus_ prefix, e.g. cus_9f3k2".
- warningTC004_UNDOCUMENTED_PARAMETER Required parameter has no description — Describe "fields": what it is, its format, and one example value.
- infoTC016_UNDOCUMENTED_OUTPUT Tool output is undocumented — Add an outputSchema, or a final sentence: "Returns the full customer record."
list_contacts1/1 selected correctly · 4 findings
Contact list.
- warningTC008_SHORT_DESCRIPTION Description is extremely short — Expand to 1–3 sentences covering action, required context and usage boundary. Do not pad with filler.
- warningTC009_DESCRIPTION_ECHOES_NAME Description merely repeats the tool name — State what the tool does, which inputs it needs, and when it should be preferred over its siblings.
- warningTC006_AMBIGUOUS_IDENTIFIER Identifier format is unclear — Document the format, e.g. "Customer ID with the cus_ prefix, e.g. cus_9f3k2".
- infoTC016_UNDOCUMENTED_OUTPUT Tool output is undocumented — Add an outputSchema, or a final sentence: "Returns the full customer record."
search_contacts1/1 selected correctly · 3 findings
Find contacts.
- warningTC008_SHORT_DESCRIPTION Description is extremely short — Expand to 1–3 sentences covering action, required context and usage boundary. Do not pad with filler.
- warningTC004_UNDOCUMENTED_PARAMETER Required parameter has no description — Describe "query": what it is, its format, and one example value.
- infoTC016_UNDOCUMENTED_OUTPUT Tool output is undocumented — Add an outputSchema, or a final sentence: "Returns the full customer record."
Static schema findings
Deterministic rules — same input, same findings, every run
get_customerDescription is extremely short — Expand to 1–3 sentences covering action, required context and usage boundary. Do not pad with filler.get_customerRequired parameter has no description — Describe "id": what it is, its format, and one example value.get_customerParameter name is generic — Rename to a scoped name such as "customer_id" or add an explicit description.get_customerIdentifier format is unclear — Document the format, e.g. "Customer ID with the cus_ prefix, e.g. cus_9f3k2".get_customerTool output is undocumented — Add an outputSchema, or a final sentence: "Returns the full customer record."search_customersTool output is undocumented — Add an outputSchema, or a final sentence: "Returns the full customer record."create_customerDescription is extremely short — Expand to 1–3 sentences covering action, required context and usage boundary. Do not pad with filler.create_customerDescription merely repeats the tool name — State what the tool does, which inputs it needs, and when it should be preferred over its siblings.create_customerRequired parameter has no description — Describe "email": what it is, its format, and one example value.create_customerTool output is undocumented — Add an outputSchema, or a final sentence: "Returns the full customer record."update_customerRequired parameter has no description — Describe "id": what it is, its format, and one example value.update_customerParameter name is generic — Rename to a scoped name such as "customer_id" or add an explicit description.update_customerIdentifier format is unclear — Document the format, e.g. "Customer ID with the cus_ prefix, e.g. cus_9f3k2".update_customerRequired parameter has no description — Describe "fields": what it is, its format, and one example value.update_customerTool output is undocumented — Add an outputSchema, or a final sentence: "Returns the full customer record."list_contactsDescription is extremely short — Expand to 1–3 sentences covering action, required context and usage boundary. Do not pad with filler.list_contactsDescription merely repeats the tool name — State what the tool does, which inputs it needs, and when it should be preferred over its siblings.list_contactsIdentifier format is unclear — Document the format, e.g. "Customer ID with the cus_ prefix, e.g. cus_9f3k2".list_contactsTool output is undocumented — Add an outputSchema, or a final sentence: "Returns the full customer record."search_contactsDescription is extremely short — Expand to 1–3 sentences covering action, required context and usage boundary. Do not pad with filler.search_contactsRequired parameter has no description — Describe "query": what it is, its format, and one example value.search_contactsTool output is undocumented — Add an outputSchema, or a final sentence: "Returns the full customer record."Recommended improvements
Evidence → problem → change → expected effect
get_customernameconfidence: highevidence: a boundary test involving get_customer misrouted during evaluation
get_customer
get_customer_by_id
Why: The original description was too short to disambiguate. It shares an object with search_customers, create_customer, update_customer, so explicit boundaries were added. The rename encodes the required-identifier constraint in the name itself.
Validation: applied as a rewrite candidate and re-evaluated on the identical test suite (see Rewrite validation). Only adopted if it passes the gate.
get_customerdescriptionconfidence: highevidence: a boundary test involving get_customer misrouted during evaluation
Gets customer data.
Retrieve one customer by its unique id. Use this tool when the customer id is already known. Do not use it to search by name, email, or other attributes — use search_customers for that.
Why: The original description was too short to disambiguate. It shares an object with search_customers, create_customer, update_customer, so explicit boundaries were added. The rename encodes the required-identifier constraint in the name itself.
Validation: applied as a rewrite candidate and re-evaluated on the identical test suite (see Rewrite validation). Only adopted if it passes the gate.
search_customersdescriptionconfidence: highevidence: a boundary test involving search_customers misrouted during evaluation
Gets customer information from the CRM.
Search customer by attributes such as name, email, or company and return matching results. Use this tool when the identifier is not known. Do not use it when the customer ID is already known — use get_customer for that.
Why: The original description was too short to disambiguate. It shares an object with get_customer, create_customer, update_customer, so explicit boundaries were added.
Validation: applied as a rewrite candidate and re-evaluated on the identical test suite (see Rewrite validation). Only adopted if it passes the gate.
create_customerdescriptionconfidence: highevidence: a boundary test involving create_customer misrouted during evaluation
Creates a customer.
Create a new customer record. The customer must not already exist. Do not use it to change an existing customer — use the update tool instead.
Why: The original description was too short to disambiguate. It shares an object with get_customer, search_customers, update_customer, so explicit boundaries were added.
Validation: applied as a rewrite candidate and re-evaluated on the identical test suite (see Rewrite validation). Only adopted if it passes the gate.
update_customerdescriptionconfidence: highevidence: a boundary test involving update_customer misrouted during evaluation
Creates or updates customer records in the system.
Update fields on an existing customer identified by id. Do not use it to create a new customer.
Why: It shares an object with get_customer, search_customers, create_customer, so explicit boundaries were added.
Validation: applied as a rewrite candidate and re-evaluated on the identical test suite (see Rewrite validation). Only adopted if it passes the gate.
list_contactsdescriptionconfidence: mediumContact list.
List contact with optional filters and pagination. Use this tool to browse or enumerate; use a search tool for attribute matching.
Why: The original description was too short to disambiguate. It shares an object with search_contacts, so explicit boundaries were added.
Validation: applied as a rewrite candidate and re-evaluated on the identical test suite (see Rewrite validation). Only adopted if it passes the gate.
search_contactsdescriptionconfidence: mediumFind contacts.
Search contact by attributes such as name, email, or company and return matching results. Use this tool when the identifier is not known.
Why: The original description was too short to disambiguate. It shares an object with list_contacts, so explicit boundaries were added.
Validation: applied as a rewrite candidate and re-evaluated on the identical test suite (see Rewrite validation). Only adopted if it passes the gate.
Rewrite validation
Each candidate re-evaluated on the identical heuristic engine and test suite
No rewrite candidate passed validation on the identical test suite. Every candidate either lowered selection accuracy or argument reliability, introduced a new behavioral failure, or failed to improve overall readiness. Your original definitions are unchanged, and the downloadable JSON contains the originals — no regressing rewrite is shipped as “optimized”.
2 distinct rewrite candidates were generated and each was evaluated on the identical test suite.
1 tool rename (breaking):
- get_customer → get_customer_by_id
Consumers, prompts, allowlists, tests, analytics, and integrations that reference the old names may require updates.
- · 1 test that passed on the baseline now fail.
- · 3 tests that failed on the baseline now pass.
| intent | expected | baseline | candidate | change |
|---|---|---|---|---|
| I already know the customer ID — it's cus_6398. Pull up the complete customer record. | get_customer | update_customer | get_customer_by_id | ▲ improvement |
| We just signed a brand-new customer, Northwind — they are not in the system yet. Add them. | create_customer | update_customer | create_customer | ▲ improvement |
| Retrieve the full customer profile for cus_1111. | get_customer | search_customers | get_customer_by_id | ▲ improvement |
| Change the billing address on customer cus_1222 to their new office. | update_customer | update_customer | create_customer | ▼ regression |
| Merge customer cus_1200 and cus_1201 into a single record. | NO_TOOL | update_customer | create_customer | ↔ lateral |
- · 1 test that passed on the baseline now fail.
- · 3 tests that failed on the baseline now pass.
| intent | expected | baseline | candidate | change |
|---|---|---|---|---|
| I already know the customer ID — it's cus_6398. Pull up the complete customer record. | get_customer | update_customer | get_customer | ▲ improvement |
| We just signed a brand-new customer, Northwind — they are not in the system yet. Add them. | create_customer | update_customer | create_customer | ▲ improvement |
| Retrieve the full customer profile for cus_1111. | get_customer | search_customers | get_customer | ▲ improvement |
| Change the billing address on customer cus_1222 to their new office. | update_customer | update_customer | create_customer | ▼ regression |
| Merge customer cus_1200 and cus_1201 into a single record. | NO_TOOL | update_customer | create_customer | ↔ lateral |
Synthetic-mode caveat: the rewrites and the selection heuristic come from the same system. Treat validated gains as clarity added, not measured model improvement — rerun in live-model mode to measure real improvement.
Methodology
How this score is computed — modes, weights, ground truth, and what “synthetic” means
This report was produced in synthetic mode. No external language model was called; a deterministic heuristic simulator estimated likely tool ambiguity. Results do not represent measured production model accuracy.
Behavioral performance (selection accuracy, argument reliability) measures what the simulator actually did. Definition quality (distinguishability, description quality, parameter clarity, safety) measures the static tool schemas. Overall readinessis the deterministic weighted sum: selection 35%, distinguishability 20%, description 15%, parameters 15%, arguments 10%, safety 5%. No language model invents any number.
Observed confusion (the matrix) is misroutes that actually happened during evaluation. Potential ambiguity is inferred from static analysis and is never labeled an observed failure. Tools that merely share an object noun (e.g. get/create/delete customer) are not flagged as overlapping — only genuinely confusable verb pairs without usage boundaries are, and severity rises to critical only when a real misroute is observed.
Only high-confidence tests (≥ 0.7) are scored; the rest are exploratory. Before/after reruns the identical suite — improvements are only claimed when the second evaluation supports them, and regressions are shown. Results depend on the selected model, prompt format, tool set, and client behavior; they do not guarantee identical production performance.
mode: synthetic · model: toolchoice-simulator-v1 · tokens: 8,238 in / 1,800 out · est. cost $0.0517 · evaluated 2026-07-16
This report was generated automatically and describes simulated tool-selection behavior, not verified production incidents. Server owners can request corrections or removal at hello@toolchoice.dev.