当前位置: 首页 > news >正文

我把整个代码库喂给 Claude Code,工具超 50 个就静默丢失,这个坑太阴了

先说说我们为什么要搭 MCP 检索层

大多数工程师用 Claude Code 的方式是:遇到问题,让它读几个文件,回答完事。

这在小项目里够用。但我们的代码库是 47 个开发维护了 4 年的 Spring Boot 单体,180K 行,模块间依赖错综复杂,一个业务改动往往牵扯 5 到 8 个 service。

用"喂文件"的方式让 Claude 分析,有两个死穴:

第一,Claude 的上下文窗口是 200K tokens,但一次深度分析很容易把它耗光。按每个 Java 文件 300 行、每行 10 token 粗估,200K tokens 大约能装 600 个文件。听起来不少,但 Claude 读依赖时是递归的——你问一个 OrderService,它会连带读 PaymentService、InventoryService、UserService……读完一轮,上下文已经满了一半。

第二,全量读代码效率极低,Claude 的注意力被稀释了。60 个文件里,真正和问题相关的可能只有 5 个。让 Claude 全量读完再找答案,相当于让一个工程师把整个代码库背一遍再回答你的问题。

MCP Server 的思路是反过来:不是给 Claude 代码,是给 Claude 查代码的能力。

就像给一个新工程师 IDE 的搜索功能,而不是印一本代码全集塞给他。


图:传统全量读取消耗 150K tokens,MCP 检索层每次查询约 2500 tokens,降幅 83%

工具数量超限会静默失效——这是最坑的地方

我们搭的第一版 MCP Server 暴露了 60 个工具:按模块细分的依赖查询、按服务维度的接口列表、历史 PR 摘要、配置项检索……

跑了两周,Claude 的表现时好时坏。有时候问它 OrderService 的依赖关系,它能给出很准确的结果;有时候问同样的问题,它说"我没有查询依赖关系的工具"。

一开始以为是 prompt 的问题,后来在 Claude Code 的 GitHub issue 里找到了答案。

MCP Server 注册的工具数量过多时,服务器可能在启动时静默失败。没有报错,没有警告,就是工具消失了。受影响最大的是工具数量较多的服务——community 反馈里,10 个工具的 server 几乎从不出问题,50 个工具的 server 偶发失败,169 个工具的 server 是高频失败。

这里有个额外的维度:工具描述消耗 context 的量超乎想象。一个实测数据是,开启所有 MCP server 的情况下,工具描述就消耗了整个上下文窗口的 41%(约 82000 tokens)——在任何对话开始之前。

这有双重危害:一方面减少了真正用来推理的上下文空间,另一方面,研究数据显示 LLM 在工具数量超过 10-20 个时会出现"认知过载",开始混淆工具或者选错工具。

我们的解法分两步:

第一步:把 60 个工具合并成 12 个,用参数区分意图而非用独立工具区分。

// 改之前:4 个独立工具 search_order_service_deps() search_payment_service_deps() search_inventory_service_deps() search_user_service_deps() // 改之后:1 个工具,service_name 参数区分 search_service_dependencies(service_name: string) // 同理,5 种 Firecrawl 模式 → 1 个工具 + mode 参数 query_codebase(query: string, scope: "service" | "api" | "config" | "pr_history" | "metrics")

这一步让工具数量从 60 降到 12,context 消耗从原来的 40000+ tokens 降到约 8000 tokens,减少了 80%。

第二步:把工具描述缩减到极致。

工具描述越长,占用的 context 越多,且不影响 Claude 的实际理解。我们把所有工具描述从平均 87 token 压到平均 20 token。

// 改之前(87 tokens) description: "This tool allows you to search for dependencies between microservices in our Spring Boot monolithic architecture. Provide a service name to get a complete list of all services that depend on it and all services it depends on, including transitive dependencies..." // 改之后(15 tokens) description: "Query service dependency graph. service_name: target service."

原则是:描述只告诉 Claude「这个工具做什么」,不要教 Claude「怎么用这个工具」——那是参数 schema 的工作。

结构化代码检索的正确设计

第一版我们设计 MCP Server 的时候走了一个弯路:把整个 service 的代码文本直接塞进工具返回值。

// 错误做法:返回原始代码文本 tool: get_service_code return: "public class OrderService { \n @Autowired\n PaymentService paymentService..." // 一个大 service 返回 5000+ tokens

这等于把全量读文件的问题移到了工具调用层面,治标不治本。

正确的做法是:工具只返回结构化的元信息,原始代码文本按需提供。

我们重新设计了三层检索接口:

第一层:意图识别层,返回高度摘要的信息,帮 Claude 判断"值不值得深挖"

// 示例:查询服务依赖关系 tool: query_service_graph input: { service: "OrderService", depth: 1 } output: { direct_dependencies: ["PaymentService", "InventoryService"], depended_by: ["ApiGateway", "BatchProcessor"], last_modified: "2026-04-12", complexity_score: 7.2 // 1-10,越高越复杂 } // 返回约 200 tokens,而非原始代码的 5000 tokens

第二层:符号级查询层,精确到函数/接口级别

// 查询某个接口的所有实现 tool: find_implementations input: { interface: "PaymentGateway" } output: { implementations: [ { class: "AlipayGateway", file: "src/payment/AlipayGateway.java", line: 23 }, { class: "WechatPayGateway", file: "src/payment/WechatPayGateway.java", line: 18 } ] } // 精确定位,Claude 知道去哪里读源码

第三层:原文获取层,只在前两层锁定目标后才调用

// Claude 确认要读之后,按需获取原始代码 tool: read_source_fragment input: { file: "src/payment/AlipayGateway.java", start_line: 23, end_line: 80 } output: { code: "..." } // 57 行,约 600 tokens

三层下来,平均每个问题的 context 消耗从 15000 tokens 降到了 2500 tokens 左右。同时,Claude 的回答质量反而更好——因为它拿到的是精准信息,不是噪音。

这个设计有一个副作用我没预料到:它迫使我们把代码库的结构化信息维护成一个独立的 index。这个 index 本身就成了团队新人快速理解系统的文档——比任何手写的架构文档都准确,因为它是从代码自动生成的。

http://www.jsqmd.com/news/1091186/

相关文章:

  • 2.1 告别“单体应用”:为什么你的记账和炒股混在一起就是灾难
  • 大模型幻觉怎么治?引用溯源兜底实操
  • PostgreSQL 索引里到底存了什么?
  • MSP430FR5969 LaunchPad开发板:FRAM与超低功耗设计实战指南
  • SpringBoot 配置文件详细指南
  • 用 OllamaHub 让 Visual Studio Copilot 可以对接任意模型
  • 超链接以字段(Field) 的形式存储。每个超链接字段包含两个核心部分:
  • 德州仪器DRV2667压电触觉驱动器评估与开发全攻略
  • 2026高考志愿资料(本科+专科)免费分享
  • 工业互联网组建与维护全域学习总结、技术体系探究与行业未来发展就业全景分析
  • 很多人一提到“省钱”,第一反应就是别用最新模型。但从一条真实的开发账单看,影响成本的关键,未必只是模型新不新,而是这次请求里有没有把缓存价值吃满。
  • Shell 脚本从入门到写出第一个自动化脚本
  • 【WorkBuddy专栏50】代码开发技术体系深度分析——前端、后端、全栈、移动端、数据工程,WB和CODEBUDDY谁更擅长?
  • Win11Debloat:如何用4个步骤让Windows 11运行速度快65%?
  • 第01篇:从一颗芯片看透智能座舱——座舱MCU的“世界观”
  • 基于物联网、时序模型、大模型和智能问数,设备预测性维护【智能体】应用案例
  • Web安全实战:路径遍历漏洞原理、复现与防御指南
  • VinXiangQi:基于YOLOv5的中国象棋智能辅助工具终极指南
  • 基于微信小程序的贵阳市特色农产品交易系统的设计与实现
  • 从多引擎探测到优化闭环
  • SpringBoot 本地项目部署云服务器 + 公网域名流程
  • 用 Claude Opus 4.8 辅助故障复盘:从告警日志到可验证 RCA 的一套工作流
  • 年薪73W,AI产品经理面经
  • API Key 泄露后会发生什么——5 个真实泄露场景和防御方案
  • 三步构建个人数字图书馆:novel-downloader完全指南
  • 电气工程考核基础
  • WSUS服务器遭CVE-2025-59287漏洞攻击后的进程行为审计与应急响应实战
  • 如何5分钟实现Windows和Office永久激活:KMS智能激活完整指南
  • DeepSeek幫我設計的會員模塊
  • OBS-ASIO插件深度解析:专业音频采集的技术实现与架构设计