20. API 服务层所属分组服务层概述API 服务层位于services/api/目录下是 Claude Code 与 Anthropic 模型 API 之间唯一的通信通道。它向上承接 QueryEngine/主循环的查询请求向下封装 Anthropic SDK 与多家云厂商Anthropic 第一方、AWS Bedrock、Azure Foundry、GCP Vertex AI的鉴权差异并向调用方暴露出queryModelWithStreaming/queryModelWithoutStreaming这类流式与非流式两类入口。这一层并不只是一个简单的 HTTP 客户端封装它承担了请求组装beta headers、prompt cache、effort、task budget、错误分类与用户友好提示、重试与回退529 过载回退、fast-mode 冷却、persistent retry、用量统计与可观测性logAPIQuery / logAPISuccessAndDuration / logAPIError、文件上传下载filesApi、以及启动时的 bootstrap 配置拉取。可以说Claude Code 中所有与模型交互相关的可靠性策略都集中在此处。理解 API 服务层是理解整个 Claude Code 行为的钥匙为什么 529 错误会自动降级到 Sonnet为什么 OAuth token 失效后会自动刷新为什么 fast mode 撞上 429 时会进入冷却这些问题的答案都藏在本层的源码里。源码位置[claude.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/claude.ts) — API 查询主入口组装请求参数并执行流式/非流式调用[client.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/client.ts) —getAnthropicClient客户端工厂处理多厂商鉴权[withRetry.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/withRetry.ts) —withRetry重试调度器[errors.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/errors.ts) — 错误分类与用户态消息生成[bootstrap.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/bootstrap.ts) — 启动期配置拉取[filesApi.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/filesApi.ts) — 文件上传/下载[logging.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/logging.ts) — API 调用埋点与可观测性[usage.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/usage.ts) — 用量利用率查询[errorUtils.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/errorUtils.ts) — 连接错误/SSL 错误细节提取核心实现分析1. 客户端工厂getAnthropicClientclient.ts中的getAnthropicClient是所有 API 调用的起点负责根据环境变量构造出正确的 SDK 实例。它需要兼容四类后端第一方 Anthropic API、AWS Bedrock、Azure Foundry、GCP Vertex AI。函数首先组装一组通用的defaultHeadersconstdefaultHeaders:{[key:string]:string}{x-app:cli,User-Agent:getUserAgent(),X-Claude-Code-Session-Id:getSessionId(),...customHeaders,...(containerId?{x-claude-remote-container-id:containerId}:{}),...(remoteSessionId?{x-claude-remote-session-id:remoteSessionId}:{}),...(clientApp?{x-client-app:clientApp}:{}),}这些 header 用于后端的会话追踪、HFI 调度以及远程容器标识。随后调用checkAndRefreshOAuthTokenIfNeeded()保证 OAuth token 新鲜并在非订阅用户路径上调用configureApiKeyHeaders写入Authorization: Bearer token。接下来根据环境变量分流CLAUDE_CODE_USE_BEDROCK走AnthropicBedrockCLAUDE_CODE_USE_FOUNDRY走AnthropicFoundry支持 Azure ADDefaultAzureCredentialCLAUDE_CODE_USE_VERTEX走AnthropicVertex特别注意要避免 google-auth-library 触发 12s 元数据服务器超时因此在没有 project env var/keyfile 时显式传入ANTHROPIC_VERTEX_PROJECT_ID。最后兜底用第一方new Anthropic(clientConfig)。值得注意的细节是client.ts文件顶部那段长注释它详细记录了每种后端所需的环境变量与 region 解析优先级——例如 Vertex 的 region 优先级是模型专属 env → CLOUD_ML_REGION → 配置默认 → us-east5 兜底这种文档化的注释是理解多云部署的钥匙。2. 查询主入口queryModel系列claude.ts中导出了三个层级的方法queryModelWithStreaming—— 流式入口返回AsyncGeneratorStreamEvent | AssistantMessage | SystemAPIErrorMessage是 REPL 主循环使用的路径queryModelWithoutStreaming—— 非流式入口内部仍走流式实现但只取最终的AssistantMessageexecuteNonStreamingRequest—— 真正的非流式 fallback用于流式请求被服务器拒绝后的兜底。三者都通过withStreamingVCR(messages, async function* () { ... })包装把请求/响应记录到 VCRVideo Cassette Recorder此处指会话回放机制以便测试与诊断。queryModelWithoutStreaming的实现体现了 generator 的精妙用法forawait(constmessageofwithStreamingVCR(messages,asyncfunction*(){yield*queryModel(messages,systemPrompt,thinkingConfig,tools,signal,options)})){if(message.typeassistant){assistantMessagemessage}}它故意消费整个 generator 而不是break目的在于确保logAPISuccessAndDuration这类放在 generator 末尾的埋点逻辑一定被执行。请求参数组装部分集中在getExtraBodyParams、getCacheControl、configureEffortParams、configureTaskBudgetParams等函数中。getCacheControl决定是否启用 1 小时 TTL 的 prompt cache逻辑通过should1hCacheTTL实现先用getPromptCache1hEligible()在 bootstrap state 中 latched 用户资格避免 session 中途 overage 翻转导致 cache TTL 抖动、prompt cache 失效再用 GrowthBook 的tengu_prompt_cache_1h_configallowlist 匹配querySource。这种资格 allowlist 双层 latch的设计是为了最大化 prompt cache 命中率。3. 重试调度器withRetrywithRetry.ts是整个 API 层最复杂的文件它是一个AsyncGeneratorSystemAPIErrorMessage, T在重试过程中向调用方 yield 系统消息用于 UI 显示等待 N 秒后重试最终 return 成功结果。重试策略覆盖了多种场景fast-mode 冷却当 fast mode 撞上 429/529 且retry-after较短20s时保持 fast mode 等待重试以保留 prompt cache若retry-after较长则触发triggerFastModeCooldown切换到标准速度最低冷却 10 分钟以避免抖动529 模型回退连续 3 次 529MAX_529_RETRIES后若配置了fallbackModel抛出FallbackTriggeredError通知上层切换模型典型场景Opus → Sonnet前台/后台区分FOREGROUND_529_RETRY_SOURCES是一个白名单只有 repl 主线程、agent、compact、安全分类器等用户在等的 querySource 才会重试 529后台任务标题生成、摘要、建议直接放弃避免在过载级联时放大流量persistent retryCLAUDE_CODE_UNATTENDED_RETRY启用后429/529 会无限重试最长 backoff 5 分钟并通过每 30s yield 一次心跳消息防止宿主环境把会话标记为 idlemax_tokens 上下文溢出解析 400 错误中的input length and max_tokens exceed context limit: N M L文本自动调低maxTokensOverride并重试。shouldRetry函数决定了单次错误是否可重试遵循x-should-retryheader但有几处例外CCRClaude Code Remote模式下 401/403 视为瞬时网络抖动而非凭证错误enterprise 用户可重试 429ant用户可对 5xx 无视x-should-retry: false。4. 错误处理errors.tserrors.ts中的getAssistantMessageFromError是把 SDK 抛出的原始错误翻译成用户可见AssistantMessage的核心。它是一个长达数百行的 if-else 链但每一条都对应一类真实场景APIConnectionTimeoutError→ “Request timed out”ImageSizeError/ImageResizeError→ 图片过大提示区分交互/非交互模式给不同文案429 withanthropic-ratelimit-unified-*headers → 调用getRateLimitErrorMessage生成精细化限额提示若返回null则返回NO_RESPONSE_REQUESTED用户不可见但仍写入对话历史供 Claude 引用429 without quota headers → 不再笼统说达到限额而是剥离 SDK 加的429前缀露出真实 inner message“prompt is too long” → 把原始错误塞进errorDetails供 reactive compact 解析 token gaptool_use/tool_result配对错误 → ant 用户给反馈渠道指引外部用户给/rewind恢复指引401/403 → CCR 模式下说网络瞬时问题否则说请 /login404 → 提示/model切换3P 用户还会按get3PModelFallbackSuggestion给出具体的回退模型建议如 Opus 4.6 → Opus 4.1。classifyAPIError则把同样的错误归一化为 analytics 用的字符串 tagrate_limit、server_overload、prompt_too_long、tool_use_mismatch、bedrock_model_access等用于 Datadog/Statsig 上报。这两个函数的字符串匹配模式必须保持同步源码注释明确指出 “Patterns MUST stay in sync”。5. Bootstrap 与 Files APIbootstrap.ts的fetchBootstrapData在启动时调用/api/claude_cli/bootstrap拉取客户端配置client_data、additional_model_options。它只在 firstParty provider 下执行优先用带user:profilescope 的 OAuth token服务密钥 OAuth 缺少该 scope 会 403失败时回退到 API key。返回结果用 zod schema 校验后写入globalConfig并通过isEqual比较避免无谓的磁盘写入。filesApi.ts提供文件上传/下载能力用于会话启动时拉取附件。它使用files-api-2025-04-14,oauth-2025-04-20双 beta header自带retryWithBackoff重试最多 3 次、500ms 起步指数退避并限制单文件 500MB。6. 可观测性logging.tslogging.ts的三个核心函数logAPIQuery、logAPISuccessAndDuration、logAPIError负责把每次 API 调用转换为 analytics 事件。其中logAPISuccessAndDuration会拆解newMessages统计textContentLength、thinkingContentLength、toolUseContentLengths、connectorTextBlockCount并通过detectGateway从响应 header / base URL 中识别 litellm、helicone、portkey、cloudflare-ai-gateway、kong、braintrust、databricks 等 AI 网关。它还会调用endLLMRequestSpan关闭 OpenTelemetry span把ttftMs、requestSetupMs、attemptStartTimes写入 Perfetto trace这是性能分析的关键数据源。usage.ts的fetchUtilization调用/api/oauth/usage拉取 5 小时/7 天/Opus/Sonnet 各档位限额利用率供 UI 显示进度条它会在 OAuth token 过期时直接返回null而非发请求避免无谓的 401。关键设计要点多厂商抽象在客户端工厂层完成getAnthropicClient通过环境变量分流到 4 个 SDK但返回统一的Anthropic类型注释坦承 “we have always been lying about the return type”上层无需感知后端差异重试与回退策略集中在withRetryfast-mode 冷却、529 模型回退、persistent retry、max_tokens 自动调参、前后台 querySource 区分全部在一个 generator 中编排并通过 yield 系统消息与 UI 协作prompt cache 稳定性优先1h TTL 资格与 allowlist 都在 bootstrap state 中 latch避免 session 中途翻转导致 cache 抖动fast-mode 撞 429 时优先短重试以保留同名模型 cache错误信息面向用户getAssistantMessageFromError区分交互/非交互、ant/external、第一方/3P、CCR/普通模式给每一类错误定制最可操作的恢复指引/login、/model、/rewind、–model、pdftotext 等可观测性是一等公民每次调用都会产出tengu_api_query/tengu_api_success/tengu_api_error事件附带 gateway 识别、token 计数、ttft、build age、teleport 状态等维度既能定位个体故障也能做聚合分析。与其他模块的关系主循环 / QueryEngine消费queryModelWithStreaming把StreamEvent渲染到 TUI把SystemAPIErrorMessage渲染成等待重试提示compact 服务apiMicrocompact.ts提供getAPIContextManagement被claude.ts用于 micro-compact 注入reactive compact 则消费getPromptTooLongTokenGap决定跳过多少 groupanalytics 服务logging.ts直接调用logEvent所有tengu_api_*事件由此产生oauth 服务client.ts调用checkAndRefreshOAuthTokenIfNeeded、handleOAuth401Error鉴权链路深度依赖 oauth 模块claudeAiLimitscurrentLimits决定 1h cache 资格extractQuotaStatusFromHeaders/extractQuotaStatusFromError把限额状态回填到currentLimitsfastMode 工具utils/fastMode.ts提供冷却状态机withRetry调用其triggerFastModeCooldown/isFastModeCooldownvcr 服务withStreamingVCR包装所有查询入口使 API 调用可被录制回放mcp / lsp 服务claude.ts调用isToolFromMcpServer判断工具来源调用getInitializationStatus决定是否 defer LSP 工具加载。小结API 服务层是 Claude Code 的通信中枢它把调用模型这件看似简单的事拆解成了客户端构造、参数组装、流式执行、错误翻译、重试回退、用量统计六段流水线。其设计哲学是把不可靠的远程调用包装成可靠的本地 generator通过withRetry的 yield 协议上层既能拿到最终结果也能实时感知每一次重试通过getAssistantMessageFromError的精细化分支用户看到的不再是 “API Error: 400”而是PDF too large (max 100 pages, 32MB)请用 pdftotext 转换。理解这一层之后再读 QueryEngine 主循环就会顺畅很多。
20-API服务层
20. API 服务层所属分组服务层概述API 服务层位于services/api/目录下是 Claude Code 与 Anthropic 模型 API 之间唯一的通信通道。它向上承接 QueryEngine/主循环的查询请求向下封装 Anthropic SDK 与多家云厂商Anthropic 第一方、AWS Bedrock、Azure Foundry、GCP Vertex AI的鉴权差异并向调用方暴露出queryModelWithStreaming/queryModelWithoutStreaming这类流式与非流式两类入口。这一层并不只是一个简单的 HTTP 客户端封装它承担了请求组装beta headers、prompt cache、effort、task budget、错误分类与用户友好提示、重试与回退529 过载回退、fast-mode 冷却、persistent retry、用量统计与可观测性logAPIQuery / logAPISuccessAndDuration / logAPIError、文件上传下载filesApi、以及启动时的 bootstrap 配置拉取。可以说Claude Code 中所有与模型交互相关的可靠性策略都集中在此处。理解 API 服务层是理解整个 Claude Code 行为的钥匙为什么 529 错误会自动降级到 Sonnet为什么 OAuth token 失效后会自动刷新为什么 fast mode 撞上 429 时会进入冷却这些问题的答案都藏在本层的源码里。源码位置[claude.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/claude.ts) — API 查询主入口组装请求参数并执行流式/非流式调用[client.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/client.ts) —getAnthropicClient客户端工厂处理多厂商鉴权[withRetry.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/withRetry.ts) —withRetry重试调度器[errors.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/errors.ts) — 错误分类与用户态消息生成[bootstrap.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/bootstrap.ts) — 启动期配置拉取[filesApi.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/filesApi.ts) — 文件上传/下载[logging.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/logging.ts) — API 调用埋点与可观测性[usage.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/usage.ts) — 用量利用率查询[errorUtils.ts](file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/services/api/errorUtils.ts) — 连接错误/SSL 错误细节提取核心实现分析1. 客户端工厂getAnthropicClientclient.ts中的getAnthropicClient是所有 API 调用的起点负责根据环境变量构造出正确的 SDK 实例。它需要兼容四类后端第一方 Anthropic API、AWS Bedrock、Azure Foundry、GCP Vertex AI。函数首先组装一组通用的defaultHeadersconstdefaultHeaders:{[key:string]:string}{x-app:cli,User-Agent:getUserAgent(),X-Claude-Code-Session-Id:getSessionId(),...customHeaders,...(containerId?{x-claude-remote-container-id:containerId}:{}),...(remoteSessionId?{x-claude-remote-session-id:remoteSessionId}:{}),...(clientApp?{x-client-app:clientApp}:{}),}这些 header 用于后端的会话追踪、HFI 调度以及远程容器标识。随后调用checkAndRefreshOAuthTokenIfNeeded()保证 OAuth token 新鲜并在非订阅用户路径上调用configureApiKeyHeaders写入Authorization: Bearer token。接下来根据环境变量分流CLAUDE_CODE_USE_BEDROCK走AnthropicBedrockCLAUDE_CODE_USE_FOUNDRY走AnthropicFoundry支持 Azure ADDefaultAzureCredentialCLAUDE_CODE_USE_VERTEX走AnthropicVertex特别注意要避免 google-auth-library 触发 12s 元数据服务器超时因此在没有 project env var/keyfile 时显式传入ANTHROPIC_VERTEX_PROJECT_ID。最后兜底用第一方new Anthropic(clientConfig)。值得注意的细节是client.ts文件顶部那段长注释它详细记录了每种后端所需的环境变量与 region 解析优先级——例如 Vertex 的 region 优先级是模型专属 env → CLOUD_ML_REGION → 配置默认 → us-east5 兜底这种文档化的注释是理解多云部署的钥匙。2. 查询主入口queryModel系列claude.ts中导出了三个层级的方法queryModelWithStreaming—— 流式入口返回AsyncGeneratorStreamEvent | AssistantMessage | SystemAPIErrorMessage是 REPL 主循环使用的路径queryModelWithoutStreaming—— 非流式入口内部仍走流式实现但只取最终的AssistantMessageexecuteNonStreamingRequest—— 真正的非流式 fallback用于流式请求被服务器拒绝后的兜底。三者都通过withStreamingVCR(messages, async function* () { ... })包装把请求/响应记录到 VCRVideo Cassette Recorder此处指会话回放机制以便测试与诊断。queryModelWithoutStreaming的实现体现了 generator 的精妙用法forawait(constmessageofwithStreamingVCR(messages,asyncfunction*(){yield*queryModel(messages,systemPrompt,thinkingConfig,tools,signal,options)})){if(message.typeassistant){assistantMessagemessage}}它故意消费整个 generator 而不是break目的在于确保logAPISuccessAndDuration这类放在 generator 末尾的埋点逻辑一定被执行。请求参数组装部分集中在getExtraBodyParams、getCacheControl、configureEffortParams、configureTaskBudgetParams等函数中。getCacheControl决定是否启用 1 小时 TTL 的 prompt cache逻辑通过should1hCacheTTL实现先用getPromptCache1hEligible()在 bootstrap state 中 latched 用户资格避免 session 中途 overage 翻转导致 cache TTL 抖动、prompt cache 失效再用 GrowthBook 的tengu_prompt_cache_1h_configallowlist 匹配querySource。这种资格 allowlist 双层 latch的设计是为了最大化 prompt cache 命中率。3. 重试调度器withRetrywithRetry.ts是整个 API 层最复杂的文件它是一个AsyncGeneratorSystemAPIErrorMessage, T在重试过程中向调用方 yield 系统消息用于 UI 显示等待 N 秒后重试最终 return 成功结果。重试策略覆盖了多种场景fast-mode 冷却当 fast mode 撞上 429/529 且retry-after较短20s时保持 fast mode 等待重试以保留 prompt cache若retry-after较长则触发triggerFastModeCooldown切换到标准速度最低冷却 10 分钟以避免抖动529 模型回退连续 3 次 529MAX_529_RETRIES后若配置了fallbackModel抛出FallbackTriggeredError通知上层切换模型典型场景Opus → Sonnet前台/后台区分FOREGROUND_529_RETRY_SOURCES是一个白名单只有 repl 主线程、agent、compact、安全分类器等用户在等的 querySource 才会重试 529后台任务标题生成、摘要、建议直接放弃避免在过载级联时放大流量persistent retryCLAUDE_CODE_UNATTENDED_RETRY启用后429/529 会无限重试最长 backoff 5 分钟并通过每 30s yield 一次心跳消息防止宿主环境把会话标记为 idlemax_tokens 上下文溢出解析 400 错误中的input length and max_tokens exceed context limit: N M L文本自动调低maxTokensOverride并重试。shouldRetry函数决定了单次错误是否可重试遵循x-should-retryheader但有几处例外CCRClaude Code Remote模式下 401/403 视为瞬时网络抖动而非凭证错误enterprise 用户可重试 429ant用户可对 5xx 无视x-should-retry: false。4. 错误处理errors.tserrors.ts中的getAssistantMessageFromError是把 SDK 抛出的原始错误翻译成用户可见AssistantMessage的核心。它是一个长达数百行的 if-else 链但每一条都对应一类真实场景APIConnectionTimeoutError→ “Request timed out”ImageSizeError/ImageResizeError→ 图片过大提示区分交互/非交互模式给不同文案429 withanthropic-ratelimit-unified-*headers → 调用getRateLimitErrorMessage生成精细化限额提示若返回null则返回NO_RESPONSE_REQUESTED用户不可见但仍写入对话历史供 Claude 引用429 without quota headers → 不再笼统说达到限额而是剥离 SDK 加的429前缀露出真实 inner message“prompt is too long” → 把原始错误塞进errorDetails供 reactive compact 解析 token gaptool_use/tool_result配对错误 → ant 用户给反馈渠道指引外部用户给/rewind恢复指引401/403 → CCR 模式下说网络瞬时问题否则说请 /login404 → 提示/model切换3P 用户还会按get3PModelFallbackSuggestion给出具体的回退模型建议如 Opus 4.6 → Opus 4.1。classifyAPIError则把同样的错误归一化为 analytics 用的字符串 tagrate_limit、server_overload、prompt_too_long、tool_use_mismatch、bedrock_model_access等用于 Datadog/Statsig 上报。这两个函数的字符串匹配模式必须保持同步源码注释明确指出 “Patterns MUST stay in sync”。5. Bootstrap 与 Files APIbootstrap.ts的fetchBootstrapData在启动时调用/api/claude_cli/bootstrap拉取客户端配置client_data、additional_model_options。它只在 firstParty provider 下执行优先用带user:profilescope 的 OAuth token服务密钥 OAuth 缺少该 scope 会 403失败时回退到 API key。返回结果用 zod schema 校验后写入globalConfig并通过isEqual比较避免无谓的磁盘写入。filesApi.ts提供文件上传/下载能力用于会话启动时拉取附件。它使用files-api-2025-04-14,oauth-2025-04-20双 beta header自带retryWithBackoff重试最多 3 次、500ms 起步指数退避并限制单文件 500MB。6. 可观测性logging.tslogging.ts的三个核心函数logAPIQuery、logAPISuccessAndDuration、logAPIError负责把每次 API 调用转换为 analytics 事件。其中logAPISuccessAndDuration会拆解newMessages统计textContentLength、thinkingContentLength、toolUseContentLengths、connectorTextBlockCount并通过detectGateway从响应 header / base URL 中识别 litellm、helicone、portkey、cloudflare-ai-gateway、kong、braintrust、databricks 等 AI 网关。它还会调用endLLMRequestSpan关闭 OpenTelemetry span把ttftMs、requestSetupMs、attemptStartTimes写入 Perfetto trace这是性能分析的关键数据源。usage.ts的fetchUtilization调用/api/oauth/usage拉取 5 小时/7 天/Opus/Sonnet 各档位限额利用率供 UI 显示进度条它会在 OAuth token 过期时直接返回null而非发请求避免无谓的 401。关键设计要点多厂商抽象在客户端工厂层完成getAnthropicClient通过环境变量分流到 4 个 SDK但返回统一的Anthropic类型注释坦承 “we have always been lying about the return type”上层无需感知后端差异重试与回退策略集中在withRetryfast-mode 冷却、529 模型回退、persistent retry、max_tokens 自动调参、前后台 querySource 区分全部在一个 generator 中编排并通过 yield 系统消息与 UI 协作prompt cache 稳定性优先1h TTL 资格与 allowlist 都在 bootstrap state 中 latch避免 session 中途翻转导致 cache 抖动fast-mode 撞 429 时优先短重试以保留同名模型 cache错误信息面向用户getAssistantMessageFromError区分交互/非交互、ant/external、第一方/3P、CCR/普通模式给每一类错误定制最可操作的恢复指引/login、/model、/rewind、–model、pdftotext 等可观测性是一等公民每次调用都会产出tengu_api_query/tengu_api_success/tengu_api_error事件附带 gateway 识别、token 计数、ttft、build age、teleport 状态等维度既能定位个体故障也能做聚合分析。与其他模块的关系主循环 / QueryEngine消费queryModelWithStreaming把StreamEvent渲染到 TUI把SystemAPIErrorMessage渲染成等待重试提示compact 服务apiMicrocompact.ts提供getAPIContextManagement被claude.ts用于 micro-compact 注入reactive compact 则消费getPromptTooLongTokenGap决定跳过多少 groupanalytics 服务logging.ts直接调用logEvent所有tengu_api_*事件由此产生oauth 服务client.ts调用checkAndRefreshOAuthTokenIfNeeded、handleOAuth401Error鉴权链路深度依赖 oauth 模块claudeAiLimitscurrentLimits决定 1h cache 资格extractQuotaStatusFromHeaders/extractQuotaStatusFromError把限额状态回填到currentLimitsfastMode 工具utils/fastMode.ts提供冷却状态机withRetry调用其triggerFastModeCooldown/isFastModeCooldownvcr 服务withStreamingVCR包装所有查询入口使 API 调用可被录制回放mcp / lsp 服务claude.ts调用isToolFromMcpServer判断工具来源调用getInitializationStatus决定是否 defer LSP 工具加载。小结API 服务层是 Claude Code 的通信中枢它把调用模型这件看似简单的事拆解成了客户端构造、参数组装、流式执行、错误翻译、重试回退、用量统计六段流水线。其设计哲学是把不可靠的远程调用包装成可靠的本地 generator通过withRetry的 yield 协议上层既能拿到最终结果也能实时感知每一次重试通过getAssistantMessageFromError的精细化分支用户看到的不再是 “API Error: 400”而是PDF too large (max 100 pages, 32MB)请用 pdftotext 转换。理解这一层之后再读 QueryEngine 主循环就会顺畅很多。