소스 검색

fix(mcp): explore skeleton/focused tag steers to codegraph_explore, not Read

The per-symbol skeletonization tag said "skeleton (signatures only; Read for a
full body)" / "focused (…; Read for more)" — inviting a Read of the very file
just skeletonized. Harmless when it only fired on off-spine sibling files, but
the god-file rework engaged skeletonization on CENTRAL, wanted files
(Session.swift, DataRequest.swift), so the "Read for more" invitation landed on
files the agent needs — and it followed it: Alamofire A/B showed the agent
Read exactly the [skeleton]-tagged files (DataRequest, URLConvertible), then
spiraled into 19–30-tool / 400s+ over-investigation in ~half the runs.

CLAUDE.md is explicit: explore output must never tell the agent to Read — steer
to another codegraph_explore. Tag now reads "codegraph_explore a signature by
name for its body; do NOT Read."

A/B (Opus 4.8, n=4): spirals 2/4 → 0/4; tools median 13 → 5.5; reads → 0.5;
time WITH 128s vs WITHOUT 141s (was 4m23s vs 2m15s — the spirals had inverted
it). The god-file rework's bigger output was never the problem; the Read-
inviting tag was.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Colby McHenry 3 주 전
부모
커밋
5d7388cc5a
1개의 변경된 파일8개의 추가작업 그리고 2개의 파일을 삭제
  1. 8 2
      src/mcp/tools.ts

+ 8 - 2
src/mcp/tools.ts

@@ -2542,9 +2542,15 @@ export class ToolHandler {
         if (skel.length > 0) {
           const names = [...new Set(group.nodes.filter(n => n.kind !== 'import' && n.kind !== 'export').map(n => n.name))]
             .slice(0, budget.maxSymbolsInFileHeader).join(', ');
+          // Steer the agent to codegraph_explore for an elided body — NEVER to
+          // Read. The old "Read for more" / "Read for a full body" tags invited
+          // a Read of the very file just skeletonized; on a central, wanted file
+          // (Session.swift, DataRequest.swift) that fired an over-investigation
+          // spiral (the agent Read the skeletonized file, then kept digging).
+          // CLAUDE.md: explore output must never tell the agent to Read.
           const tag = bodyIds.size > 0
-            ? 'focused (the methods you named in full, the rest as signatures; Read for more)'
-            : 'skeleton (signatures only; Read for a full body)';
+            ? 'focused (the methods you named in full, the rest as signatures — codegraph_explore a signature by name for its body; do NOT Read)'
+            : 'skeleton (signatures only — codegraph_explore a name for its full body; do NOT Read)';
           lines.push(`#### ${filePath} — ${names} · ${tag}`, '', '```' + lang, skel.join('\n'), '```', '');
           totalChars += skel.join('\n').length + 120;
           filesIncluded++;