Lion Cipher Lab
Measure an agent's tool-selection accuracy as its toolbox grows from 5 to 100 tools, then win it back with tool retrieval and better tool descriptions (stub model, offline)
- AI Security
- Advanced
- ~2 hours
- Free · no account required
Why it matters
Every agent platform now makes it trivial to bolt on another integration: install an MCP server and its tools appear in the model's context next to the ones you had. Each one looks harmless. Together they change the job the model is doing - it is no longer choosing between five clearly different tools, it is choosing among dozens, several of which are three vendors' copies of the same capability, and some of which sit one word away from a destructive action. When the model picks disable_user instead of lookup_user, or sinkhole_domain instead of fetch_dns_logs, a lookup becomes an outage. This…
What you'll learn
- building an answer-keyed tool-selection benchmark - 300 SOC requests, each with the one tool that should answer it - and a toolbox that grows 5 -> 10 -> 20 -> 50 -> 100 while the requests stay fixed, so the only variable is how many tools the model can see
- measuring the fall with numbers instead of a hunch: accuracy 0.9933, 0.8867, 0.7933, 0.3700, 0.3500 as the toolbox grows, with the prompt swelling from 124 to 1,158 tokens per request
- counting the dangerous errors separately: a read-only request answered by a destructive tool (17 of them at 20 tools - DNS lookups sent to a sinkhole, reputation checks sent to a firewall block), and wrong picks that are really near-duplicates from another vendor (152 of 195 at 100 tools)
- writing a BM25 tool retriever in pure Python and measuring it honestly: top-3 lifts 100-tool accuracy from 0.3500 to 0.5267 while cutting the prompt 94%, but recall@3 of 0.7500 is a hard ceiling, top-1 sends 43 read-only requests to destructive tools, and top-10 scores 0.3200 - worse than no retrieval
- fixing the toolbox itself - merging near-duplicates, namespacing names by system, rewriting descriptions with 'Use this when...' in the analyst's own words - and measuring each move: 0.7633 merged, 0.8400 rewritten, 0.9367 with top-3 retrieval at 86 tokens per request
- catching the side effect of a good fix: namespacing put dns_fetch_query_logs and dns_sinkhole_domain under one prefix and raised read-to-destructive DNS picks from 7 to 13, which is why a confirm-before-acting gate on destructive tools (131 prompts, all 17 wrong destructive picks stopped) is not optional
- making the judgment call: retrieval is overkill under roughly 10-20 tools (no change at 5, +0.0133 at 10), and a pruned, rewritten 20-tool box with no retrieval (0.8900) beats retrieval bolted onto the unfixed one (0.8633)
Steps in this lab
- The words first: agent, tool, toolbox, MCP server, context, answer key, destructive, near-duplicate, retrieval - and the fact that the chooser here is a stub
- Open a terminal and make a scratch folder (all three operating systems)
- The toolbox: 5 core tools, then siblings, then three vendors' MCP servers, then unrelated integrations - 100 in all
- The answer key: 300 analyst requests, each owned by one core tool
- The chooser is a DETERMINISTIC STUB - here is its entire behaviour, in writing
- Grow the toolbox and measure: the same 300 requests at 5, 10, 20, 50 and 100 tools
- Fix 1: tool retrieval - a pure-Python BM25 shortlist, and the chooser sees only the top k
- Fix 2: merge the near-duplicates, namespace the names, rewrite the descriptions - and measure each move
- The side effect of a good fix: namespacing made one destructive confusion worse - so gate destructive tools
- When NOT to add retrieval, and why this rather than that
- The way a pro does it differently
- Rerun the evidence, change one constant, and clean up