When the LLM calls the same web search query 4+ times consecutively, return an error telling it to stop and use existing results instead of silently returning cached results that the LLM ignores. Tracks consecutive duplicate searches via a simple counter keyed on the normalized query + parameters. Resets when a different query is searched. Threshold is 3 consecutive duplicates before the guard fires. File changed: search-the-web/tool-search.ts
This commit is contained in:
parent
1b1df58749
commit
aa224b5944
1 changed files with 26 additions and 0 deletions
|
|
@ -104,6 +104,12 @@ interface SearchDetails {
|
|||
const searchCache = new LRUTTLCache<CachedSearchResult>({ max: 100, ttlMs: 600_000 });
|
||||
searchCache.startPurgeInterval(60_000);
|
||||
|
||||
// Consecutive duplicate search guard (#949)
|
||||
// Tracks recent query keys to detect and break search loops.
|
||||
const MAX_CONSECUTIVE_DUPES = 3;
|
||||
let lastSearchKey = "";
|
||||
let consecutiveDupeCount = 0;
|
||||
|
||||
// Summarizer responses: max 50 entries, 15-minute TTL
|
||||
const summarizerCache = new LRUTTLCache<string>({ max: 50, ttlMs: 900_000 });
|
||||
|
||||
|
|
@ -388,6 +394,26 @@ export function registerSearchTool(pi: ExtensionAPI) {
|
|||
// Cache lookup (provider-prefixed key)
|
||||
// ------------------------------------------------------------------
|
||||
const cacheKey = normalizeQuery(effectiveQuery) + `|f:${freshness || ""}|s:${wantSummary}|p:${provider}`;
|
||||
|
||||
// ── Consecutive duplicate search guard (#949) ──────────────────────
|
||||
// If the LLM keeps calling the same search query, break the loop
|
||||
// with an explicit warning instead of returning the same results.
|
||||
if (cacheKey === lastSearchKey) {
|
||||
consecutiveDupeCount++;
|
||||
if (consecutiveDupeCount >= MAX_CONSECUTIVE_DUPES) {
|
||||
consecutiveDupeCount = 0;
|
||||
lastSearchKey = "";
|
||||
return {
|
||||
content: [{ type: "text" as const, text: `⚠️ Search loop detected: the query "${params.query}" has been searched ${MAX_CONSECUTIVE_DUPES + 1} times consecutively with identical results. The information you need is already in the previous search results above. Stop searching and use those results to proceed with your task.` }],
|
||||
isError: true,
|
||||
details: { errorKind: "search_loop", error: "Consecutive duplicate search detected" } satisfies Partial<SearchDetails>,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
lastSearchKey = cacheKey;
|
||||
consecutiveDupeCount = 0;
|
||||
}
|
||||
|
||||
const cached = searchCache.get(cacheKey);
|
||||
|
||||
if (cached) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue