Claude-Mem 自定义API支持:突破速率限制的解决方案

前言
在AI辅助编程实践中,Claude Code已成为开发者的得力助手。然而,Claude Code的对话历史无法持久化保存,每次新会话都无法访问之前的上下文信息,这影响了开发效率。
为解决这个问题,Claude-Mem作为一个专门为Claude Code设计的插件应运而生,提供持久化记忆能力。但Claude-Mem原生支持的GEMINI和OPENROUTER等AI提供商存在速率和额度限制,成为新的瓶颈。
本文介绍Claude-Mem如何通过自定义API支持功能突破这些限制,并修复因Claude平台升级导致的上下文显示问题,具有实际应用价值。
问题分析
速率和额度限制问题
Claude-Mem原生支持Anthropic、GEMINI、OPENROUTER等多种AI提供商,但存在以下限制:
- 用户无法使用自己的模型部署(如本地模型、企业模型)
- 无法使用其他AI提供商的API(如OpenAI、Azure OpenAI等)
- 不同地区访问官方API可能面临网络或合规性问题
- 原生提供商的速率和额度限制影响高频使用场景
上下文显示问题
由于Claude平台升级,原有的上下文处理机制出现兼容性问题,导致:
- 对话历史无法正常显示
- 上下文注入功能失效
- 用户无法查看和管理会话记忆
- 降低整体用户体验
解决方案
自定义API代理实现
Claude-Mem引入了CustomApiAgent类,这是自定义API支持的核心实现。通过配置参数动态选择API端点,包含速率限制、错误处理等重要功能。
1// src/services/worker/CustomApiAgent.ts
2export class CustomApiAgent {
3 private dbManager: DatabaseManager;
4 private sessionManager: SessionManager;
5 private fallbackAgent: FallbackAgent | null = null;
6
7 // Rate limiting implementation
8 private requestQueue: Array<{
9 config: CustomApiConfig;
10 history: ConversationMessage[];
11 resolve: (value: { content: string; tokensUsed?: number }) => void;
12 reject: (reason: any) => void;
13 }> = [];
14 private isProcessing: boolean = false;
15 private readonly rateLimitDelay: number = 1000; // 1 second delay between requests
16
17 constructor(dbManager: DatabaseManager, sessionManager: SessionManager) {
18 this.dbManager = dbManager;
19 this.sessionManager = sessionManager;
20 }
21
22 // ... 其他实现细节
23}
这个实现包含多个关键特性:
1. 队列管理与速率限制
CustomApiAgent使用队列机制管理API请求频率,避免请求过于频繁:
1private async processQueue(): Promise<void> {
2 if (this.isProcessing || this.requestQueue.length === 0) {
3 return;
4 }
5
6 this.isProcessing = true;
7
8 while (this.requestQueue.length > 0) {
9 const { config, history, resolve, reject } = this.requestQueue.shift()!;
10
11 try {
12 const result = await this.executeCustomApiRequest(config, history);
13 resolve(result);
14 } catch (error) {
15 reject(error);
16 }
17
18 // Wait before processing the next request to implement rate limiting
19 if (this.requestQueue.length > 0) {
20 await this.delay(this.rateLimitDelay);
21 }
22 }
23
24 this.isProcessing = false;
25}
注意事项: 通过1秒的延迟机制,有效防止API调用超限。
2. 多格式API适配
CustomApiAgent支持Anthropic和OpenAI兼容的API格式,可动态识别不同提供商的API端点:
1private async executeCustomApiRequest(
2 config: CustomApiConfig,
3 history: ConversationMessage[]
4): Promise<{ content: string; tokensUsed?: number }> {
5 const messages = this.conversationToOpenAIMessages(history);
6
7 // Determine the correct API endpoint based on provider name
8 let apiUrl: string;
9 if (config.providerName.toLowerCase() === 'anthropic') {
10 // For Anthropic-compatible API
11 apiUrl = `${config.baseUrl}/v1/messages`;
12 } else if (config.providerName.toLowerCase() === 'openai') {
13 // For OpenAI-compatible API
14 apiUrl = `${config.baseUrl}/v1/chat/completions`;
15 } else {
16 // Default to Anthropic-compatible API
17 apiUrl = `${config.baseUrl}/v1/messages`;
18 }
19
20 let requestBody: any;
21 if (config.providerName.toLowerCase() === 'anthropic') {
22 // Anthropic-compatible request format
23 requestBody = {
24 model: config.model,
25 messages,
26 max_tokens: 4096,
27 temperature: 0.3,
28 };
29 } else {
30 // OpenAI-compatible request format (default)
31 requestBody = {
32 model: config.model,
33 messages,
34 temperature: 0.3,
35 max_tokens: 4096,
36 };
37 }
38
39 // ... 请求执行和响应处理
40}
配置同步功能
Claude-Mem新增配置同步功能,自动从Claude Code的设置文件中读取API配置并应用到Claude-Mem中:
1// src/utils/config-sync.ts
2export function syncClaudeCodeSettingsToCustomApi(): void {
3 try {
4 const claudeCodeSettingsPath = join(homedir(), '.claude', 'settings.json');
5
6 if (!existsSync(claudeCodeSettingsPath)) {
7 logger.info('CONFIG', 'Claude Code settings file not found, skipping sync', {
8 path: claudeCodeSettingsPath
9 });
10 return;
11 }
12
13 const settingsContent = readFileSync(claudeCodeSettingsPath, 'utf-8');
14 const settings: ClaudeCodeSettings = JSON.parse(settingsContent);
15
16 // Extract environment variables from Claude Code settings
17 const env = settings.env || {};
18
19 // Map Claude Code env variables to claude-mem custom API settings
20 const customApiSettings = {
21 CLAUDE_MEM_CUSTOM_API_BASE_URL: env.ANTHROPIC_BASE_URL || '',
22 CLAUDE_MEM_CUSTOM_API_KEY: env.ANTHROPIC_API_KEY || env.ANTHROPIC_AUTH_TOKEN || '',
23 CLAUDE_MEM_CUSTOM_API_MODEL: env.CLAUDE_MEM_CUSTOM_API_MODEL || 'iflow,qwen3-coder-plus',
24 CLAUDE_MEM_CUSTOM_API_PROVIDER_NAME: env.ANTHROPIC_BASE_URL ? 'anthropic' : 'custom'
25 };
26
27 // Update claude-mem settings if custom provider is selected
28 const currentSettingsPath = join(homedir(), '.claude-mem', 'settings.json');
29 const currentSettings = SettingsDefaultsManager.loadFromFile(currentSettingsPath);
30
31 if (currentSettings.CLAUDE_MEM_PROVIDER === 'custom') {
32 // Only update if custom API settings are not already configured
33 // This prevents overwriting user's manual settings
34 if (!currentSettings.CLAUDE_MEM_CUSTOM_API_BASE_URL) {
35 logger.info('CONFIG', 'Syncing Claude Code settings to claude-mem custom API', {
36 ANTHROPIC_BASE_URL: customApiSettings.CLAUDE_MEM_CUSTOM_API_BASE_URL,
37 ANTHROPIC_API_KEY: customApiSettings.CLAUDE_MEM_CUSTOM_API_KEY ? '[HIDDEN]' : '[NOT SET]'
38 });
39
40 // Write updated settings to claude-mem settings file
41 updateClaudeMemSettings(customApiSettings, currentSettingsPath);
42 }
43 }
44 } catch (error) {
45 logger.error('CONFIG', 'Failed to sync Claude Code settings to custom API', {}, error as Error);
46 }
47}
注意事项: 配置同步会先检查是否已有手动配置,避免覆盖用户设置。
会话路由重构
Claude-Mem实现智能代理选择机制,根据设置自动选择合适的AI提供商:
1private getActiveAgent(): SDKAgent | GeminiAgent | OpenRouterAgent | CustomApiAgent {
2 if (isCustomApiSelected()) {
3 if (isCustomApiAvailable()) {
4 logger.debug('SESSION', 'Using Custom API agent');
5 return this.customApiAgent;
6 } else {
7 throw new Error('Custom API provider selected but no base URL configured. Set CLAUDE_MEM_CUSTOM_API_BASE_URL in settings.');
8 }
9 }
10 if (isOpenRouterSelected()) {
11 if (isOpenRouterAvailable()) {
12 logger.debug('SESSION', 'Using OpenRouter agent');
13 return this.openRouterAgent;
14 } else {
15 throw new Error('OpenRouter provider selected but no API key configured. Set CLAUDE_MEM_OPENROUTER_API_KEY in settings or OPENROUTER_API_KEY environment variable.');
16 }
17 }
18 if (isGeminiSelected()) {
19 if (isGeminiAvailable()) {
20 logger.debug('SESSION', 'Using Gemini agent');
21 return this.geminiAgent;
22 } else {
23 throw new Error('Gemini provider selected but no API key configured. Set CLAUDE_MEM_GEMINI_API_KEY in settings or GEMINI_API_KEY environment variable.');
24 }
25 }
26 return this.sdkAgent;
27}
上下文处理修复
针对Claude升级导致的上下文显示问题,Claude-Mem修改了上下文传递方式:
1// src/cli/adapters/claude-code.ts
2formatOutput(result) {
3 if (result.hookSpecificOutput) {
4 if (result.hookSpecificOutput.additionalContext) {
5 return { hookSpecificOutput: result.hookSpecificOutput, systemMessage: result.hookSpecificOutput.additionalContext };
6 } else {
7 return { hookSpecificOutput: result.hookSpecificOutput };
8 }
9 }
10 return { continue: result.continue ?? true, suppressOutput: result.suppressOutput ?? true };
11}
关键改进: 通过添加systemMessage字段,确保上下文信息正确注入Claude会话。
使用说明
配置自定义API
用户可以通过以下方式配置自定义API:
方式一:通过Claude Code设置文件(推荐)
在 ~/.claude/settings.json 中添加配置:
1{
2 "env": {
3 "ANTHROPIC_BASE_URL": "https://your-custom-endpoint.com/v1",
4 "ANTHROPIC_API_KEY": "your-api-key",
5 "CLAUDE_MEM_CUSTOM_API_MODEL": "your-model-name"
6 }
7}
方式二:直接配置Claude-Mem设置
在 ~/.claude-mem/settings.json 中配置:
1{
2 "CLAUDE_MEM_PROVIDER": "custom",
3 "CLAUDE_MEM_CUSTOM_API_BASE_URL": "https://your-custom-endpoint.com/v1",
4 "CLAUDE_MEM_CUSTOM_API_KEY": "your-api-key",
5 "CLAUDE_MEM_CUSTOM_API_MODEL": "your-model-name",
6 "CLAUDE_MEM_CUSTOM_API_PROVIDER_NAME": "anthropic"
7}
配置更改后,重启Claude-Mem服务:
1# 停止服务
2claude-mem stop
3
4# 启动服务
5claude-mem start
总结
Claude-Mem的自定义API支持功能解决了原生API提供商的速率和额度限制问题。通过CustomApiAgent实现多格式API适配,配置同步功能简化设置流程,上下文处理修复确保兼容性。
该功能为开发者提供了更灵活的AI编程助手,可根据需求选择合适的API提供商,专注于创造性工作。
