Chapter 12 · Domain 2(权重 18%)
MCP 集成结构化错误、.mcp.json 作用域、built-in tools 选型
本章三块内容对应三条 TS,考试各有各的出法:错误结构考「agent 能不能据此恢复」,配置作用域考 P9 的共享轴,built-in tools 考「哪个工具干哪件事」的机械对应。第一块最重要——它是 P6「信息保全」在工具层的实现。
一、错误四分类与 isError
MCP 用 isError flag 把工具失败告诉 agent。但仅仅说「失败了」远远不够:统一的泛化错误("Operation failed")会阻断 agent 做出恰当的恢复决策 ——它无从判断该重试、该换路径、还是该告诉用户这事办不成。
类别 含义 具体错误示例 agent 该怎么做 可重试
transient 超时、服务暂时不可用 索引查询超时,立刻重试就成功(本章 Q2) 本地重试(见下) 是
validation 输入不合法 调用缺了工具 schema 里的 required 字段 修正参数后重试 是(改了参数才有意义)
business 违反业务策略 订单已超出退货窗口,退款被拒(本章 Q1) 向用户解释,走替代流程 否
permission 无权限 当前凭证读不到这个客户的账单记录 升级或换身份 否
两条边界单独记:business 与 permission 都不可重试,处置却完全不同 ——business 是「规则不允许这么做」,要向客户解释并给替代路径;permission 是「你这个身份不允许这么做」,要升级或换凭证,把它当业务拒绝讲给客户就是答非所问。validation 的「可重试」是有条件的 ——原样重试注定再失败一次,只有改了参数 的那次重试才有意义;这也是它与 transient 的分界:transient 的同一份入参重试就可能成功。
结构化错误载荷应当包含三样东西:errorCategory、isRetryable 布尔、以及人类可读的描述 。业务规则违规还要额外带上 retriable: false 与面向客户的解释 ,让 agent 能得体地把「这事我们不能做」告诉用户,而不是干巴巴地报错。
一个措辞细节 — Exam Guide 在概念 层面区分四类错误(transient / validation / business / permission),但在描述结构化元数据时给出的 errorCategory 取值例子是 transient/validation/permission。所以:四分类是用来判断处置方式 的思维框架,不要把「enum 里必须有 business 这个字面值」当成考点去背。考试考的是分类带来的处置差异 。
局部恢复:不是所有错误都该上抛
subagent 应当先在本地处理 transient 故障 ,只把本地解决不了 的错误上抛给 coordinator,并附上已尝试了什么 与partial results 。这条与 P6 的边界一致:保全信息不等于把一切立刻甩给上层。
access failure ≠ valid empty result
这条被 guide 单列,且在 TS 5.3 里重复了一次——重复出现的知识点通常就是考点。访问失败 (超时、连不上)意味着「我不知道有没有结果」,需要 coordinator 决定重试或换路;有效空结果 意味着「查询成功了,确实没有匹配」,是一个可信的事实。把前者伪装成后者,就是 D5 吞错。
二、MCP 配置:作用域与凭证
<repo>/.mcp.json ✔ 真实存在 · project 级 · 团队共享的 MCP 服务器,入版本库
~/.claude.json ✔ 真实存在 · user 级 · 个人/实验性服务器,不共享
// .mcp.json
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" } ✔ 真实存在 · ${VAR} 环境变量展开,凭证不入库
}
}
}
三条要点:
作用域 ——共享用 .mcp.json,个人实验用 ~/.claude.json。P9 的第一条轴,与 CLAUDE.md、commands 完全同构。
${VAR} 环境变量展开 ——这是 guide 唯一提到的凭证管理机制(OAuth、密钥轮换等属于 out-of-scope)。作用是把配置入库而把密钥留在环境里 。
所有已配置服务器的工具在连接时被发现,并同时可用 ——这既是能力,也是 ch11 里「18 个工具」问题的来源。
Resources:给 agent 一份目录
MCP resources 用来暴露内容目录 ——issue 摘要、文档层级、数据库 schema。它的价值是减少探索性工具调用 :agent 不必靠一连串试探性查询去摸清有什么数据,直接看目录即可。考场识别信号:题干出现「agent 花大量调用在搞清楚有哪些数据」时,答案往往是把目录做成 resource,而不是加更多查询工具。
自建还是用现成的
guide 的立场很明确:标准集成优先选社区已有的 MCP 服务器 (原例:Jira),自建只留给团队特有的流程 。这是 P2 比例原则在集成层的应用。
让 agent 别老想着 built-in 工具
还有一条很具体的 skill:增强 MCP 工具的描述 ,详细说明它的能力与输出,以防 agent 偏好 built-in 工具(如 Grep)而放着更强的 MCP 工具不用。这与 TS 2.1 是同一个机制——描述决定选择。
三、Built-in tools 选型
工具 干什么 典型场景
Grep搜文件内容 找函数的所有调用方、定位报错文本、找 import 语句
Glob按路径模式 找文件 **/*.test.tsx 这类按名字/扩展名找文件
Read / Write整文件读写 需要全文时
Edit用唯一锚文本 定点修改 局部改动;锚文本不唯一时会失败
Bash执行命令 —
Glob / Grep 在 macOS、Linux、WSL 上默认不在工具集里 :考纲(TS 2.5)点名六件套,本章和题目按这个口径,考试也按这个口径作答 。当前 Claude Code 在这三个平台上默认不提供 Glob 和 Grep,改由 Claude 通过 Bash 调用 find / grep 搜索(Windows 上两者仍在默认工具集里)。想拿回这两个工具:启动时在 --tools 或 --allowedTools(或 Agent SDK 的对应选项)里点名;把 Bash 从会话里移除;或让 subagent 的 tools 列出它们且不含 Bash。照 ch00 建议上手实操时,别因为工具列表里没有它们而困惑。
来源:Tools reference · Glob tool behavior 。查阅于 2026-10-16。
三条被点名的操作规程:
Edit 失败于锚文本不唯一时 → 退回 Read + Write 。这是 guide 明写的 fallback,不是自由发挥。
增量建立代码库理解 :先 Grep 找入口 → 再 Read 顺着 import 追踪流程,不要上来读全库 。
追踪 wrapper 模块里的函数使用 :先列出全部导出名 ,再逐个名字 在全库搜索。(只搜原始函数名会漏掉经 wrapper 重新导出后的调用点。)
实际使用中,Edit 的「唯一锚文本」要求常被低估——同一行代码在文件里出现两次(比如两个分支里同样的 return nil, err)就足以让它失败。工程上的常见做法是把锚文本上下多带一行来制造唯一性,而不是立刻退回全文重写。Exam Guide 只给了 Read+Write 这一条 fallback,考试按 guide 答即可。
外部课程 · CertSafari — 本章 3 个考点(展开查看)
用于补读和错题复盘;第三方 AI 生成练习材料,非官方题库。核验答案时以 Exam Guide 和官方文档为依据。复盘方法 · 链接核对:2026-10-16。
考点回链 — 本章覆盖:TS 2.2(isError、四类错误、泛化错误阻断恢复、errorCategory/isRetryable/人类可读描述、业务违规带 retriable: false 与客户友好解释、subagent 局部恢复 transient、access failure ≠ valid empty result)、TS 2.4(.mcp.json vs ~/.claude.json、${VAR} 展开、多服务器工具同时可用、resources 暴露内容目录、优选社区服务器、增强描述防偏好 built-in)、TS 2.5(Grep/Glob/Read/Write/Edit/Bash 选型、Edit 锚不唯一时退回 Read+Write、增量理解代码库、wrapper 追踪先列导出名)。相邻考点:工具分配见 ch11,错误传播见 ch14。
本章题组
ch12 · Q1 · 准则 P6
Your MCP tools currently return {"isError": true, "message": "Operation failed"} for every failure. The agent responds by retrying three times and then telling the customer to try later — including when the refund was blocked because the order is outside the return window. What should the tools return instead?
A Structured error metadata: an errorCategory, an isRetryable boolean, and a human-readable description — with business rule violations carrying retriable: false and a customer-friendly explanation.
B The same generic message, but with the retry count reduced to one so wasted retries are cheaper, which also shortens the customer's wait.
C The raw upstream exception and stack trace, so the agent has complete information about what went wrong, including the exact business rule that blocked this refund.
D A success response with an empty result set for policy blocks, so the agent stops retrying and moves on, ending the pointless retry loop.
正确 A TS 2.2:统一的泛化错误阻断了 agent 的恢复决策。结构化元数据三件套(errorCategory、isRetryable、人类可读描述)让 agent 区分「重试有意义」与「这是策略限制」;业务违规额外带 retriable: false 与客户友好解释,agent 才能得体地说明而不是让客户「稍后再试」。
D3 治标不治本 违反 P6 B :减少重试次数只是让浪费变便宜。客户依然会被告知「稍后再试」——而那笔退款永远不会因为等待而变得可退。信息缺失这个根因没动。
D2 过度工程 违反 P6 C :堆栈跟踪对 agent 的决策没有帮助(它需要的是类别 与可重试性 这两个结构化判据),却会大量占用上下文,还可能把内部实现细节泄露到面向客户的回复里。
D5 吞错或炸链 违反 P6 D :把失败伪装成成功的空结果,是 TS 2.2 与 TS 5.3 双双点名的反模式。它确实止住了重试,代价是 agent 与用户都不知道发生了什么。
ch12 · Q2 · 准则 P6
Your search subagent queries an index that occasionally times out. Currently every timeout is propagated straight to the coordinator, which restarts the whole research run. Roughly 80% of these timeouts succeed on an immediate retry. What is the correct design?
A Have the coordinator retry the subagent invocation whenever it receives a timeout, keeping all recovery logic centralized, easier to reason about than recovery scattered across subagents.
B Have the subagent catch timeouts and return an empty result set so the run can proceed without interruption, since one flaky index should not stall a research run that is otherwise complete.
C Have the subagent perform local recovery for transient failures, and propagate to the coordinator only what it cannot resolve — including what was attempted and any partial results.
D Increase the index client's timeout so transient slowness no longer registers as a failure, removing the trigger for the restart cascade in the first place.
正确 C TS 2.2 / TS 5.3:subagent 对 transient 故障实施局部恢复 ,只上抛无法本地解决的错误,并附带「已尝试了什么」与 partial results。这是 P6 的完整形态——既不吞(B)也不炸(现状),且尊重了「不是所有错误都该立刻上抛」这条边界。
D2 过度工程 违反 P6 A :让 coordinator 重启整个 subagent 调用来处理一个立刻重试就能解决的瞬时故障,代价高得多(丢掉该 subagent 已完成的工作),而恢复本可以在最靠近故障的地方发生。
D5 吞错或炸链 违反 P6 B :把访问失败伪装成有效空结果——TS 2.2 明确要求区分二者。coordinator 会以为「这个主题确实没有资料」,从而在报告里留下一个无人知晓的缺口。
D3 治标不治本 违反 P1 D :调大超时能掩盖一部分慢响应,但真正的失败仍会发生,届时依然会炸掉整条流程——错误传播的设计缺陷原封不动。
ch12 · Q3 · 准则 P9
Your team needs a shared Jira MCP server available to every developer on the repo, authenticated with a token that must not be committed. You also want to try an experimental in-house metrics MCP server yourself without exposing it to the team. How do you configure this?
A Jira in the project's .mcp.json with the token as ${JIRA_TOKEN}; the experimental server in your ~/.claude.json.
B Both in the project's .mcp.json, with the experimental server commented out so teammates can enable it if they want.
C Both in ~/.claude.json, and ask each teammate to copy the Jira block into their own file.
D Jira in .mcp.json with the token inlined but the file added to .gitignore, and the experimental server in the project's .claude/config.json.
正确 A TS 2.4 的两条作用域规则加凭证规则:团队共享 → project 级 .mcp.json;个人/实验性 → user 级 ~/.claude.json;凭证用 ${VAR} 环境变量展开,让配置入库而密钥留在环境里。三个要求逐一对应。
D3 治标不治本 违反 P9 B :注释掉的实验性服务器仍然出现在团队共享文件里,等于把个人实验的维护负担摊给所有人;而 user 级作用域正是为此存在的。
D4 甩锅错位 违反 P9 C :让每个队友手工复制配置,正是 project 级作用域要消除的工作。任何一次配置变更都要全员重做一遍,且必然出现版本漂移。
D1 凭空捏造 违反 P9 D :两处都错。把 .mcp.json 加进 .gitignore 直接取消了它「团队共享」的意义(明文密钥也不该落盘);而 .claude/config.json 这个机制不存在(官方样题 Q4 的 D 选项)。
ch12 · Q4 · 准则 P1
Your developer-productivity agent has an MCP server exposing a powerful search_code_semantic tool that understands the codebase's symbol graph. Traces show the agent almost always uses the built-in Grep instead, producing noisier results. The MCP tool's description reads "Searches code." What should you do?
A Remove Grep from the agent's tool set so the MCP tool is the only search option, trimming the tool surface.
B Add a system prompt instruction stating that search_code_semantic must be preferred over Grep for all code searches, the cheapest change available.
C Set tool_choice to force search_code_semantic on turns that involve code search, making the choice deterministic rather than probabilistic.
D Enhance the MCP tool's description to explain its capabilities and outputs in detail, so the agent stops defaulting to the built-in tool.
正确 D TS 2.4 点名的 skill:增强 MCP 工具描述 ,详细说明其能力与输出,以防 agent 偏好 built-in 工具(guide 举的正是 Grep)。根因与 TS 2.1 同源——描述是选择机制,"Searches code" 四个字给不出任何选它的理由。
D2 过度工程 违反 P4 A :Grep 有它真正合适的场景(按字面模式搜内容,TS 2.5)。为了纠正一次选择偏好而删掉一个正当能力,是用截肢治偏头痛。
D6 概率当保证 违反 P1 B :system prompt 里的偏好指令是概率性的,而且 TS 2.1 提醒关键词敏感的 system prompt 指令本身就会制造非预期的工具关联——用一个已知会产生副作用的机制去补描述的缺。
D2 过度工程 违反 P2 C :forced 选择要求先判断「这一轮算不算 code search」,等于在应用层重建一个路由器;而根因只是描述写得太少。
ch12 · Q5 · 准则 P2
Your agent burns 30–40 tool calls at the start of each session probing which database tables exist, what columns they have, and which issue queues are available, before it can do useful work. The MCP server backing these systems is yours to modify. What is the appropriate change?
A Add a describe_everything tool that returns the full schema and queue list in one call, replacing 30 probes.
B Expose the schemas and queue catalogs as MCP resources, giving the agent visibility into available data without exploratory tool calls.
C Cache the probe results in the agent's scratchpad file and reuse them across sessions, paying the probe cost once.
D Paste the schema documentation into the project CLAUDE.md so it is always loaded, with no server work needed.
正确 B TS 2.4:MCP resources 的定义用途就是暴露内容目录(guide 举例:issue 摘要、文档层级、数据库 schema ),从而减少探索性工具调用 。题干的症状与这条 skill 的适应症逐字对应。
D3 治标不治本 违反 P4 A :把 30 次探索压成 1 次调用有改善,但它把目录信息塞进了工具返回值——每次会话仍要主动调用一次,而且这个泛化「查一切」工具与 TS 2.1 提倡的明确 I/O 契约背道而驰。resources 正是为目录场景准备的机制。
D2 过度工程 违反 P2 C :自建缓存要处理失效问题(schema 会变),而现成的 resources 机制没用。scratchpad 的正当用途是跨上下文边界持久化发现 (TS 5.4),不是替代服务端的目录能力。
D3 治标不治本 违反 P9 D :把会变动的 schema 手工抄进始终加载的 CLAUDE.md,既占满每个会话的 context,又立刻开始过期——文档与真实 schema 的漂移会让 agent 基于错误信息写查询。
ch12 · Q6 · 准则 P5
You need to find every place a deprecated formatCurrency helper is used, but the codebase re-exports it through three wrapper modules under different names. What sequence of built-in tool usage is correct?
A Use Glob on **/*.ts to enumerate files, then Read each one and inspect it for usage.
B Grep for formatCurrency across the codebase; that finds every call site since re-exports preserve the original name internally, including inside the wrappers.
C First identify all exported names the wrappers expose for this helper, then Grep for each name across the codebase.
D Use Edit to rename the helper at its definition and let the resulting compile errors enumerate the call sites.
正确 C TS 2.5 点名的 skill:追踪函数在 wrapper 模块间的使用,做法是先识别出全部导出名,再逐个名字在全库搜索 。这正是为了覆盖重新导出后改名的调用点。
D2 过度工程 违反 P5 A :Glob 按路径模式 找文件,Grep 才是搜内容 的工具(TS 2.5 的基本分工)。逐个 Read 全部 TS 文件还会迅速耗尽 context,与「增量建立理解」的原则相反。
D3 治标不治本 违反 P1 B :题干已明说三个 wrapper 用不同的名字 重新导出。只搜原名恰好会漏掉这些调用点——这就是 guide 专门给出「先列导出名」这条规程的原因。
D5 吞错或炸链 违反 P6 D :用破坏性改名换编译错误来做只读的调查,把一次搜索变成一次可能失败的重构;动态调用或字符串引用的场景还根本编译不出错,会静默漏掉。
ch12 · Q7 · 准则 P5
Your agent tries to modify a Go file with Edit, anchoring on return nil, err. The edit fails because that exact text appears in six places in the file. What is the documented fallback?
A Use Read to load the full file contents, then Write the modified version back.
B Use Bash with sed and a line-number address to perform the edit precisely, avoiding a full rewrite.
C Use Grep to count the occurrences, then call Edit repeatedly until the correct one is modified, one occurrence at a time.
D Use Glob to locate a differently structured version of the file elsewhere in the repo and edit that instead, where the anchor is unique.
正确 A TS 2.5 明写的 fallback:当 Edit 因锚文本不唯一而失败时,用 Read + Write 做可靠的文件修改。Edit 的机制前提就是唯一文本匹配,前提不成立时就换整文件路径。
D2 过度工程 违反 P5 B :绕到 shell 里用行号做编辑,脆弱(行号随任何前置改动失效)且绕开了内置工具的既定分工。与 ch07 Q1 的 < /dev/null 同一工艺:shell 技巧输给产品既定路径。
D5 吞错或炸链 违反 P6 C :反复调用一个前提已经不成立的工具,每次都会同样失败;「直到改对为止」在这里没有收敛机制,只会产生一串失败调用。
D4 甩锅错位 违反 P1 D :改另一个文件不是修改目标文件。Glob 按路径模式找文件,与解决锚文本不唯一毫无关系。
ch12 · Q8 · 准则 P5
A React repo has 240 test files matching **/*.test.tsx, scattered across 30 feature directories. Each of them imports render from @testing-library/react on exactly one line, and every one of those lines must now point at the team's local test-utils wrapper instead. The identical import line also appears in roughly 60 *.stories.tsx files, which have to keep importing from the library. Which use of the built-in tools is correct?
A Grep the repo for the @testing-library/react import line to build the list of files to change, then Edit that line in every file the search returns.
B Glob for **/*.test.tsx to build the list, then Edit the import line in each of those files.
C Glob for **/*.tsx to enumerate every component file, Read each one to judge whether it is a test file, and Edit the import line in the ones that turn out to be.
D Glob for **/*.test.tsx, then Read and Write each file in full, because that import line occurs some 300 times across the repo and Edit needs a unique anchor.
正确 B TS 2.5 的两条分工在这题里各管一半。要改哪些文件由路径模式定义 (**/*.test.tsx 正是 guide 给 Glob 的原例),所以列文件用 Glob 而不是 Grep;每个文件里那行 import 只出现一次 ,锚文本唯一,所以定点改用 Edit,用不着退回 Read+Write。两个前提都成立时,这就是 guide 正面给出的组合。
D4 甩锅错位 违反 P1 A :Grep 搜的是内容 ,而这题的选择标准是文件在不在这个路径模式里 。按内容搜出来的集合会带上 60 个 *.stories.tsx——题干明说它们必须保持原样。工具选错,直接改到了不该动的对象上。
D2 过度工程 违反 P5 C :把模式放宽到全部组件文件,再逐个 Read 去判断「它是不是测试文件」,是让模型接手 Glob 的本职工作。几百个文件的全文读入还会迅速吃满 context,与 TS 2.5「先定位再顺着追踪、不上来读全库」的增量原则正相反。
D1 凭空捏造 违反 P5 D :给 Edit 安上一条它没有的前提。它要求的唯一性是文件内 唯一——每次编辑只作用于一个文件,别处有多少行长得一样都不影响。这个选项把本章 Q7 那条正当的 Read+Write 回退搬到了前提不成立的地方:那里锚文本在同一个文件 里出现六次,这里是一次。