Summary
I found a small reproducible ambiguous tool-ranking case while testing @ratel-ai/sdk locally with a toy tool catalog.
For a documentation/configuration-related query, the expected tool search_docs is retrieved in the top-K, but an unrelated tool, weather_lookup, ranks above it.
This seems useful as a diagnostic case because it looks like a ranking-quality issue rather than a recall issue.
Edited: Updated script with correct reproduction step
Reproduction
import { ToolCatalog } from "@ratel-ai/sdk";
const catalog = new ToolCatalog();
const makeTextTool = (
id: string,
description: string,
handler: (args: Record<string, unknown>) => Promise<Record<string, unknown>>,
) => {
catalog.register({
id,
name: id,
description,
inputSchema: {
properties: {
query: {
type: "string",
description: "Natural language request or search query",
},
path: {
type: "string",
description: "Optional file path or directory path",
},
pattern: {
type: "string",
description: "Optional keyword or regular expression pattern",
},
},
},
outputSchema: {
properties: {
summary: {
type: "string",
description: "Textual summary of the tool result",
},
},
},
execute: handler,
});
};
makeTextTool(
"read_file",
"Read a file from local disk and return its textual contents.",
async ({ path }) => ({
summary: `Read file at ${String(path ?? "<missing>")}`,
}),
);
makeTextTool(
"search_code",
"Search source code across a repository for keywords, symbols, or configuration values.",
async ({ pattern }) => ({
summary: `Searched code for pattern ${String(pattern ?? "<missing>")}`,
}),
);
makeTextTool(
"search_docs",
"Search project documentation, markdown files, and technical docs for relevant explanations.",
async ({ query }) => ({
summary: `Searched docs for ${String(query ?? "<missing>")}`,
}),
);
makeTextTool(
"search_logs",
"Search application logs and runtime logs for errors, warnings, and diagnostics.",
async ({ query }) => ({
summary: `Searched logs for ${String(query ?? "<missing>")}`,
}),
);
makeTextTool(
"read_env_file",
"Read environment variable files such as .env, .env.production, or deployment config files.",
async ({ path }) => ({
summary: `Read env file ${String(path ?? "<missing>")}`,
}),
);
makeTextTool(
"read_config_file",
"Read structured configuration files like JSON, YAML, TOML, or application config files.",
async ({ path }) => ({
summary: `Read config file ${String(path ?? "<missing>")}`,
}),
);
makeTextTool(
"send_email",
"Send an email message to one or more recipients.",
async ({ query }) => ({
summary: `Sent email request: ${String(query ?? "<missing>")}`,
}),
);
makeTextTool(
"send_slack_message",
"Send a Slack message to a user or channel.",
async ({ query }) => ({
summary: `Sent Slack message: ${String(query ?? "<missing>")}`,
}),
);
makeTextTool(
"currency_convert",
"Convert an amount of money from one currency to another using exchange rates.",
async ({ query }) => ({
summary: `Converted currency for request: ${String(query ?? "<missing>")}`,
}),
);
makeTextTool(
"weather_lookup",
"Look up weather forecast for a city or location.",
async ({ query }) => ({
summary: `Looked up weather for ${String(query ?? "<missing>")}`,
}),
);
makeTextTool(
"create_issue",
"Create a GitHub issue with title, body, labels, and assignee information.",
async ({ query }) => ({
summary: `Created issue for ${String(query ?? "<missing>")}`,
}),
);
makeTextTool(
"create_pull_request",
"Create a GitHub pull request with title, description, and branch information.",
async ({ query }) => ({
summary: `Created pull request for ${String(query ?? "<missing>")}`,
}),
);
const scenarios = [
{
query: "find where redis host is configured in the repo",
topK: 5,
invoke: { toolId: "search_code", args: { pattern: "REDIS_HOST" } },
},
{
query: "read the production environment variables file",
topK: 5,
invoke: { toolId: "read_env_file", args: { path: ".env.production" } },
},
{
query: "look for documentation about deployment configuration",
topK: 5,
invoke: {
toolId: "search_docs",
args: { query: "deployment configuration" },
},
},
{
query: "message the team that the release is out",
topK: 5,
invoke: {
toolId: "send_slack_message",
args: { query: "The release is out" },
},
},
{
query: "open a PR for the release branch",
topK: 5,
invoke: {
toolId: "create_pull_request",
args: { query: "release branch PR" },
},
},
];
for (const scenario of scenarios) {
const hits = catalog.search(scenario.query, scenario.topK);
console.log(`\nScenario query: ${scenario.query}`);
console.log("Top hits:");
console.log(hits);
const result = await catalog.invoke(
scenario.invoke.toolId,
scenario.invoke.args,
);
console.log(`Invoke ${scenario.invoke.toolId}:`);
console.log(result);
}
Observed output for "look for documentation about deployment configuration" query
[
{ toolId: "weather_lookup", score: 2.1971445083618164 },
{ toolId: "search_docs", score: 2.1485352516174316 },
{ toolId: "read_env_file", score: 2.1367175579071045 },
{ toolId: "search_code", score: 1.6402997970581055 },
{ toolId: "read_config_file", score: 1.6135268211364746 }
]
Expected behavior
Since the query explicitly asks for documentation, I expected search_docs to rank first.
Actual behavior
search_docs is retrieved, but it ranks second behind weather_lookup.
This does not look like a recall failure, because the expected tool is present in the top-K, it looks more like a ranking-quality issue caused by ambiguous lexical overlap. In this case, weather_lookup may be benefiting from overlap around terms like look / lookup, while the semantically better documentation tool remains slightly below it
Summary
I found a small reproducible ambiguous tool-ranking case while testing
@ratel-ai/sdklocally with a toy tool catalog.For a documentation/configuration-related query, the expected tool
search_docsis retrieved in the top-K, but an unrelated tool,weather_lookup, ranks above it.This seems useful as a diagnostic case because it looks like a ranking-quality issue rather than a recall issue.
Edited: Updated script with correct reproduction step
Reproduction
Observed output for "look for documentation about deployment configuration" query
Expected behavior
Since the query explicitly asks for documentation, I expected search_docs to rank first.
Actual behavior
search_docs is retrieved, but it ranks second behind weather_lookup.
This does not look like a recall failure, because the expected tool is present in the top-K, it looks more like a ranking-quality issue caused by ambiguous lexical overlap. In this case, weather_lookup may be benefiting from overlap around terms like look / lookup, while the semantically better documentation tool remains slightly below it