22 KiB
Claude Code 服务层详解
概述
服务层(services/)是 Claude Code 的核心业务逻辑层,提供 API 通信、协议管理、数据处理等功能。本文档详细介绍各服务的职责、实现和协作关系。
1. services/api/ - Anthropic API 客户端
client.ts - API 客户端工厂
文件位置: src/services/api/client.ts
核心功能: 创建配置好的 Anthropic API 客户端实例。
支持的认证方式:
1. 直接 API 访问
// 环境变量: ANTHROPIC_API_KEY
2. AWS Bedrock
// 环境变量配置
AWS_REGION 或 AWS_DEFAULT_REGION
ANTHROPIC_SMALL_FAST_MODEL_AWS_REGION (可选,用于 Haiku 模型)
- 支持
AWS_BEARER_TOKEN_BEDROCK进行 API Key 认证 - 支持自动凭证刷新
3. Azure Foundry
// 环境变量
ANTHROPIC_FOUNDRY_RESOURCE 或 ANTHROPIC_FOUNDRY_BASE_URL
ANTHROPIC_FOUNDRY_API_KEY (可选)
- 支持 Azure AD 认证(
DefaultAzureCredential) - 支持自定义回调端口
4. Google Vertex AI
// 环境变量
VERTEX_REGION_* (模型特定区域)
CLOUD_ML_REGION (默认区域)
ANTHROPIC_VERTEX_PROJECT_ID
- 支持
google-auth-library凭证系统 - 防止元数据服务器超时
关键函数:
export async function getAnthropicClient({
apiKey,
maxRetries,
model,
fetchOverride,
source,
}: {
apiKey?: string
maxRetries: number
model?: string
fetchOverride?: ClientOptions['fetch']
source?: string
}): Promise<Anthropic>
请求拦截:
- 注入自定义头:
x-app: cli,User-Agent,X-Claude-Code-Session-Id - 支持
ANTHROPIC_CUSTOM_HEADERS环境变量自定义头 - 支持
x-anthropic-additional-protection头 - 生成客户端请求 ID (
x-client-request-id) 用于追踪
代理支持:
fetchOptions: getProxyFetchOptions({ forAnthropicAPI: true })
claude.ts - API 调用封装
文件位置: src/services/api/claude.ts
核心功能:
queryModelWithStreaming()- 流式查询模型getMaxOutputTokensForModel()- 获取模型最大输出 tokengetPromptTooLongTokenGap()- 解析 prompt 太长错误PROMPT_TOO_LONG_ERROR_MESSAGE- 错误消息常量
filesApi.ts - 文件 API
功能: 处理文件上传到 Claude API。
errors.ts - 错误处理
核心类型:
export const PROMPT_TOO_LONG_ERROR_MESSAGE =
'Conversation too long. Press esc twice to go up a few messages and try again.'
export function startsWithApiErrorPrefix(text: string | null): boolean
export function isPromptTooLongError(error: Error): boolean
withRetry.ts - 重试逻辑
功能: 提供指数退避重试机制。
export async function withRetry<T>(
fn: () => Promise<T>,
options: {
maxRetries?: number
initialDelayMs?: number
maxDelayMs?: number
}
): Promise<T>
usage.ts - 使用量追踪
功能: 追踪 API 调用使用量(输入/输出 token)。
2. services/mcp/ - Model Context Protocol
类型系统 (types.ts)
配置作用域 (ConfigScope):
z.enum(['local', 'user', 'project', 'dynamic', 'enterprise', 'claudeai', 'managed'])
传输类型 (Transport):
z.enum(['stdio', 'sse', 'sse-ide', 'http', 'ws', 'sdk'])
服务器配置:
// Stdio 配置
McpStdioServerConfigSchema = z.object({
type: z.literal('stdio'),
command: z.string(),
args: z.array(z.string()),
env: z.record(z.string()),
})
// SSE 配置
McpSSEServerConfigSchema = z.object({
type: z.literal('sse'),
url: z.string(),
headers: z.record(z.string()),
oauth: McpOAuthConfigSchema,
})
// WebSocket 配置
McpWebSocketServerConfigSchema = z.object({
type: z.literal('ws'),
url: z.string(),
headers: z.record(z.string()),
})
连接状态类型:
ConnectedMCPServer = { client, name, type: 'connected', capabilities, serverInfo, cleanup }
FailedMCPServer = { name, type: 'failed', error }
NeedsAuthMCPServer = { name, type: 'needs-auth' }
PendingMCPServer = { name, type: 'pending', reconnectAttempt }
DisabledMCPServer = { name, type: 'disabled' }
useManageMCPConnections.ts - 连接管理 Hook
文件位置: src/services/mcp/useManageMCPConnections.ts
核心职责:
- 初始化 MCP 客户端连接
- 设置连接生命周期处理器
- 管理自动重连(SSE 连接)
- 同步 appState
关键特性:
自动重连
- 最大重试次数: 5
- 初始退避: 1000ms
- 最大退避: 30000ms
- 指数退避策略
通知处理器
// 工具列表变更
client.client.setNotificationHandler(ToolListChangedNotificationSchema, ...)
// 提示列表变更
client.client.setNotificationHandler(PromptListChangedNotificationSchema, ...)
// 资源列表变更
client.client.setNotificationHandler(ResourceListChangedNotificationSchema, ...)
通道推送 (KAIROS 特性)
// 注册通道通知处理器
client.client.setNotificationHandler(ChannelMessageNotificationSchema, async notification => {
enqueue({
mode: 'prompt',
value: wrapChannelMessage(client.name, content, meta),
priority: 'next',
isMeta: true,
})
})
channelNotification.ts - 通道通知
功能: 处理 MCP 服务器的通道消息通知。
channelPermissions.ts - 通道权限
功能: 管理通道权限回调。
auth.ts - MCP 认证
功能: 处理 MCP 服务器的 OAuth 认证流程。
oauthPort.ts - OAuth 端口管理
功能: 管理 OAuth 回调端口。
elicitationHandler.ts - 信息请求处理
功能: 处理 MCP 服务器的信息请求(elicitation)。
normalization.ts - 工具名称规范化
功能: 规范化 MCP 工具名称,避免命名冲突。
3. services/oauth/ - OAuth 2.0 认证
文件位置: src/services/oauth/index.ts
OAuthService 类
核心功能: 实现 OAuth 2.0 授权码流程(支持 PKCE)。
export class OAuthService {
async startOAuthFlow(
authURLHandler: (url: string, automaticUrl?: string) => Promise<void>,
options?: {
loginWithClaudeAi?: boolean
inferenceOnly?: boolean
expiresIn?: number
orgUUID?: string
loginHint?: string
loginMethod?: string
skipBrowserOpen?: boolean
}
): Promise<OAuthTokens>
}
两种授权流程:
1. 自动流程
- 打开浏览器,跳转到授权页面
- 用户在浏览器中完成授权
- 回调到本地监听服务器
2. 手动流程
- 显示手动授权 URL
- 用户复制 URL 到浏览器
- 用户复制授权码回来
核心步骤:
- 创建本地授权码监听器 (
AuthCodeListener) - 生成 PKCE 值(
code_verifier,code_challenge) - 构建授权 URL
- 等待授权码
- 交换令牌
client.ts - OAuth 客户端
功能: 与 OAuth 服务器通信。
export async function exchangeCodeForTokens(
code: string,
state: string,
codeVerifier: string,
port: number,
isManual: boolean,
expiresIn?: number
): Promise<OAuthTokenExchangeResponse>
export function buildAuthUrl(opts: {
codeChallenge: string
state: string
port: number
isManual: boolean
loginWithClaudeAi?: boolean
inferenceOnly?: boolean
orgUUID?: string
loginHint?: string
loginMethod?: string
}): string
crypto.ts - 加密工具
功能: PKCE 加密操作。
export function generateCodeVerifier(): string
export function generateCodeChallenge(verifier: string): string
export function generateState(): string
auth-code-listener.ts - 授权码监听
功能: 启动本地 HTTP 服务器监听 OAuth 回调。
export class AuthCodeListener {
async start(): Promise<number> // 返回监听端口
waitForAuthorization(state: string, onReady: () => Promise<void>): Promise<string>
handleSuccessRedirect(scopes: string[]): void
handleErrorRedirect(): void
close(): void
}
4. services/lsp/ - Language Server Protocol
manager.ts - LSP 管理器
文件位置: src/services/lsp/manager.ts
核心接口:
export interface LSPServerManager {
getAllServers(): Map<string, LSPServerInstance>
getServer(name: string): LSPServerInstance | undefined
getServerCapabilities(name: string): ServerCapabilities | undefined
initialize(): Promise<void>
shutdown(): Promise<void>
}
初始化流程:
initializeLspServerManager()- 初始化管理器单例createLSPServerManager()- 创建管理器实例registerLSPNotificationHandlers()- 注册通知处理器
状态管理:
type InitializationState = 'not-started' | 'pending' | 'success' | 'failed'
关键函数:
export function getLspServerManager(): LSPServerManager | undefined
export function isLspConnected(): boolean
export async function waitForInitialization(): Promise<void>
export function reinitializeLspServerManager(): void // 用于 /reload-plugins
export async function shutdownLspServerManager(): Promise<void>
LSPServerInstance.ts - 服务器实例
功能: 管理单个 LSP 服务器实例。
LSPClient.ts - LSP 客户端
功能: 实现 LSP 协议客户端逻辑。
LSPDiagnosticRegistry.ts - 诊断注册
功能: 注册和管理 LSP 诊断信息。
passiveFeedback.ts - 被动反馈
功能: 处理 LSP 的被动反馈(如悬停信息、定义跳转)。
5. services/analytics/ - 分析服务
index.ts - 分析服务入口
文件位置: src/services/analytics/index.ts
核心功能:
- 事件日志记录
- GrowthBook 特性开关
- 事件队列管理
事件日志:
export function logEvent(
eventName: string,
metadata: Record<string, boolean | number | undefined>
): void
export async function logEventAsync(
eventName: string,
metadata: Record<string, boolean | number | undefined>
): Promise<void>
设计原则:
- 无依赖设计,避免导入循环
- 事件在 sink 连接前进入队列
- 支持同步/异步事件记录
GrowthBook 集成:
export function getFeatureValue_CACHED_MAY_BE_STALE(
featureName: string,
defaultValue: T
): T
6. services/plugins/ - 插件系统
pluginOperations.ts - 插件操作
文件位置: src/services/plugins/pluginOperations.ts
核心操作:
export async function installPluginOp(
plugin: string,
scope: InstallableScope = 'user'
): Promise<PluginOperationResult>
export async function uninstallPluginOp(
plugin: string,
scope: InstallableScope = 'user',
deleteDataDir = true
): Promise<PluginOperationResult>
export async function setPluginEnabledOp(
plugin: string,
enabled: boolean,
scope?: InstallableScope
): Promise<PluginOperationResult>
export async function updatePluginOp(
plugin: string,
scope: PluginScope
): Promise<PluginUpdateResult>
安装作用域:
export const VALID_INSTALLABLE_SCOPES = ['user', 'project', 'local'] as const
操作原则:
- 搜索市场获取插件信息
- 写入设置(声明意图)
- 缓存插件并记录版本
PluginInstallationManager.ts - 安装管理
功能: 管理插件的下载、安装、更新。
7. services/compact/ - 对话压缩
compact.ts - 核心压缩逻辑
文件位置: src/services/compact/compact.ts
核心接口:
export interface CompactionResult {
boundaryMarker: SystemMessage
summaryMessages: UserMessage[]
attachments: AttachmentMessage[]
hookResults: HookResultMessage[]
messagesToKeep?: Message[]
userDisplayMessage?: string
preCompactTokenCount?: number
postCompactTokenCount?: number
truePostCompactTokenCount?: number
compactionUsage?: ReturnType<typeof getTokenUsage>
}
压缩类型:
完整压缩 (compactConversation)
export async function compactConversation(
messages: Message[],
context: ToolUseContext,
cacheSafeParams: CacheSafeParams,
suppressFollowUpQuestions: boolean,
customInstructions?: string,
isAutoCompact: boolean = false,
recompactionInfo?: RecompactionInfo
): Promise<CompactionResult>
部分压缩 (partialCompactConversation)
export async function partialCompactConversation(
allMessages: Message[],
pivotIndex: number,
context: ToolUseContext,
cacheSafeParams: CacheSafeParams,
userFeedback?: string,
direction: PartialCompactDirection = 'from'
): Promise<CompactionResult>
核心流程:
- 执行 PreCompact hooks
- 剥离图片/文档(节省 token)
- 调用 AI 生成摘要
- 创建压缩边界标记
- 执行 SessionStart hooks
- 清理缓存
microCompact.ts - 微压缩
功能: 在调用压缩 API 前减少消息 token 数量。
export async function microcompactMessages(
messages: Message[],
context: ToolUseContext
): Promise<{ messages: Message[] }>
sessionMemoryCompact.ts - 会话内存压缩
功能: 快速压缩,无需调用 AI。
autoCompact.ts - 自动压缩
功能: 当上下文即将达到限制时自动触发压缩。
8. services/policyLimits/ - 组织策略限制
文件位置: src/services/policyLimits/index.ts
功能: 获取并应用组织级别的策略限制。
资格条件:
- Console 用户(API Key): 全部符合
- OAuth 用户(Claude.ai): 仅 Team 和 Enterprise 订阅
核心函数:
export function isPolicyLimitsEligible(): boolean
export async function waitForPolicyLimitsToLoad(): Promise<void>
export function isPolicyAllowed(policy: string): boolean
export async function loadPolicyLimits(): Promise<void>
export async function refreshPolicyLimits(): Promise<void>
export async function clearPolicyLimitsCache(): Promise<void>
缓存策略:
- 文件缓存:
~/.claude/policy-limits.json - ETag 校验
- 后台轮询(每小时)
失败处理: 失败时继续运行(fail open)
9. services/remoteManagedSettings/ - 远程托管设置
文件位置: src/services/remoteManagedSettings/index.ts
功能: 为企业客户获取和管理远程托管设置。
核心函数:
export function isEligibleForRemoteManagedSettings(): boolean
export async function waitForRemoteManagedSettingsToLoad(): Promise<void>
export async function loadRemoteManagedSettings(): Promise<void>
export async function refreshRemoteManagedSettings(): Promise<void>
export async function clearRemoteManagedSettingsCache(): Promise<void>
安全检查:
export async function checkManagedSettingsSecurity(
cachedSettings: SettingsJson,
newSettings: SettingsJson
): Promise<SecurityCheckResult>
10. services/extractMemories/ - 自动记忆提取
文件位置: src/services/extractMemories/extractMemories.ts
功能: 从当前会话中提取持久记忆并写入自动记忆目录。
触发时机: 在查询循环结束时(模型生成最终响应后)
核心接口:
export function initExtractMemories(): void
export async function executeExtractMemories(
context: REPLHookContext,
appendSystemMessage?: AppendSystemMessageFn
): Promise<void>
export async function drainPendingExtraction(timeoutMs?: number): Promise<void>
工具权限:
export function createAutoMemCanUseTool(memoryDir: string): CanUseToolFn
// 允许: Read, Grep, Glob, 只读 Bash
// 允许: Edit, Write 仅限 auto-memory 路径
特性开关:
tengu_passport_quail- 启用/禁用记忆提取tengu_bramble_lintel- 提取频率控制TEAMMEM- 团队记忆支持
11. services/tokenEstimation.ts - Token 估算
文件位置: src/services/tokenEstimation.ts
核心功能: 估算文本和消息的 token 数量。
主要函数:
export async function countTokensWithAPI(content: string): Promise<number | null>
export async function countMessagesTokensWithAPI(
messages: Anthropic.Beta.Messages.BetaMessageParam[],
tools: Anthropic.Beta.Messages.BetaToolUnion[]
): Promise<number | null>
export function roughTokenCountEstimation(
content: string,
bytesPerToken: number = 4
): number
export async function countTokensViaHaikuFallback(
messages: Anthropic.Beta.Messages.BetaMessageParam[],
tools: Anthropic.Beta.Messages.BetaToolUnion[]
): Promise<number | null>
文件类型估算:
export function bytesPerTokenForFileType(fileExtension: string): number {
switch (fileExtension) {
case 'json':
case 'jsonl':
case 'jsonc':
return 2 // JSON 更密集
default:
return 4
}
}
图像 token 估算:
// tokens = (width px * height px) / 750
// 最大 2000x2000 (约 5333 tokens)
12. services/teamMemorySync/ - 团队记忆同步
(参见 extractMemories/ 中的 TEAMMEM 特性)
功能: 在团队成员之间同步记忆文件。
服务层架构图
┌─────────────────────────────────────────────────────────────┐
│ CLI 入口 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 命令层 (commands/) │
│ /commit /review /compact /mcp /config /doctor 等 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 服务层 (services/) │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ api/ │ │ mcp/ │ │ lsp/ │ │
│ │ Anthropic │ │ Model Context│ │ Language │ │
│ │ API 客户端 │ │ Protocol │ │ Server │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ oauth/ │ │ analytics/ │ │ plugins/ │ │
│ │ OAuth 2.0 │ │ GrowthBook │ │ 插件系统 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ compact/ │ │policyLimits/│ │remoteManage │ │
│ │ 对话压缩 │ │ 策略限制 │ │ dSettings/ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │extractMemories│ │tokenEstim ation│ │
│ │ 自动记忆提取 │ │ Token 估算 │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 工具层 (tools/) │
│ Read / Write / Edit / Bash / Grep / Glob 等 │
└─────────────────────────────────────────────────────────────┘
相关源码文件索引
| 服务 | 主要文件 |
|---|---|
| API Client | src/services/api/client.ts, claude.ts |
| MCP | src/services/mcp/ |
| OAuth | src/services/oauth/ |
| LSP | src/services/lsp/ |
| Analytics | src/services/analytics/ |
| Plugins | src/services/plugins/ |
| Compact | src/services/compact/ |
| Policy Limits | src/services/policyLimits/ |
| Remote Settings | src/services/remoteManagedSettings/ |
| Extract Memories | src/services/extractMemories/ |
| Token Estimation | src/services/tokenEstimation.ts |