DeepSeek API 调用避坑指南

2 阅读1分钟

常见错误及解决方案

1. API Key 错误

Error: Invalid API key

原因

  • Key 复制时多了空格
  • Key 已过期
  • Key 没有权限

解决

# 检查 Key 格式
echo $DEEPSEEK_API_KEY | wc -c
# 应该是 32-64 字符

# 测试 Key
curl https://api.deepseek.com/v1/chat/completions \
  -H "Authorization: Bearer $DEEPSEEK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"deepseek-chat","messages":[{"role":"user","content":"hi"}]}'

2. 余额不足

Error: Insufficient balance

原因:账户余额不足

解决

# 检查余额
curl https://api.deepseek.com/v1/users/me/balance \
  -H "Authorization: Bearer $DEEPSEEK_API_KEY"

3. 请求超时

Error: Request timeout

原因

  • 网络问题
  • 服务器响应慢
  • 请求体太大

解决

// 增加超时时间
const response = await fetch(url, {
  ...options,
  signal: AbortSignal.timeout(60000)  // 60 秒
});

4. 频率限制

Error: Rate limit exceeded

原因:请求过于频繁

解决

// 添加重试逻辑
async function withRetry(fn, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      return await fn();
    } catch (error) {
      if (error.status === 429) {
        const waitTime = error.headers?.['retry-after'] || 60;
        await sleep(waitTime * 1000);
        continue;
      }
      throw error;
    }
  }
}

5. 上下文超长

Error: Context length exceeded

原因:对话历史太长

解决

// 裁剪历史对话
function trimHistory(messages, maxTokens = 4000) {
  let total = 0;
  const trimmed = [];

  for (let i = messages.length - 1; i >= 0; i--) {
    const msg = messages[i];
    const tokens = estimateTokens(msg.content);

    if (total + tokens > maxTokens) break;

    trimmed.unshift(msg);
    total += tokens;
  }

  return trimmed;
}

最佳实践

1. 连接池管理

// 复用连接,减少开销
const agent = new http.Agent({
  keepAlive: true,
  maxSockets: 10
});

2. 批量请求

// 批量处理,提高效率
async function batchProcess(items, batchSize = 10) {
  const results = [];

  for (let i = 0; i < items.length; i += batchSize) {
    const batch = items.slice(i, i + batchSize);
    const batchResults = await Promise.all(
      batch.map(item => processItem(item))
    );
    results.push(...batchResults);
  }

  return results;
}

3. 缓存策略

// 缓存常见问题
const cache = new Map();

async function chatWithCache(message) {
  const key = hashMessage(message);

  if (cache.has(key)) {
    return cache.get(key);
  }

  const response = await deepseek.chat(message);
  cache.set(key, response);

  return response;
}

4. 错误监控

// 监控错误率
const metrics = {
  total: 0,
  errors: 0,
  latency: []
};

async function monitoredChat(message) {
  const start = Date.now();

  try {
    const response = await deepseek.chat(message);
    metrics.total++;
    metrics.latency.push(Date.now() - start);
    return response;
  } catch (error) {
    metrics.errors++;
    metrics.total++;

    // 错误率超过 10% 告警
    if (metrics.errors / metrics.total > 0.1) {
      alert("High error rate!");
    }

    throw error;
  }
}

5. 成本优化

// 选择合适的模型
function selectModel(complexity) {
  switch (complexity) {
    case 'simple':
      return 'deepseek-chat';  // 便宜
    case 'complex':
      return 'deepseek-reasoner';  // 强大但贵
    default:
      return 'deepseek-chat';
  }
}

// 估算成本
function estimateCost(tokens) {
  // DeepSeek: ¥0.27/百万 tokens
  return (tokens / 1000000) * 0.27;
}

调试技巧

1. 日志记录

const logger = {
  debug: (msg, data) => console.debug(`[DEBUG] ${msg}`, data),
  info: (msg, data) => console.info(`[INFO] ${msg}`, data),
  error: (msg, data) => console.error(`[ERROR] ${msg}`, data)
};

async function loggedChat(message) {
  logger.debug("Sending message", { message });

  try {
    const response = await deepseek.chat(message);
    logger.info("Response received", { response });
    return response;
  } catch (error) {
    logger.error("Request failed", { error });
    throw error;
  }
}

2. Mock 测试

// 开发时使用 Mock
const mockDeepseek = {
  chat: async (message) => {
    return { content: `Mock: ${message}` };
  }
};

const client = process.env.NODE_ENV === 'test'
  ? mockDeepseek
  : realDeepseek;

3. 性能分析

// 分析耗时分布
async function profiledChat(message) {
  const timings = {};

  timings.start = Date.now();
  timings.beforeAPI = Date.now();

  const response = await deepseek.chat(message);

  timings.afterAPI = Date.now();
  timings.end = Date.now();

  console.log({
    total: timings.end - timings.start,
    api: timings.afterAPI - timings.beforeAPI
  });

  return response;
}

成本监控

月度成本追踪

// 记录每日用量
const dailyUsage = {
  date: new Date().toISOString().split('T')[0],
  tokens: 0,
  cost: 0
};

function trackUsage(tokens) {
  dailyUsage.tokens += tokens;
  dailyUsage.cost = (dailyUsage.tokens / 1000000) * 0.27;

  // 超过预算告警
  if (dailyUsage.cost > 100) {
    alert("Cost exceeds ¥100/day!");
  }
}

总结:避开这些坑,DeepSeek API 调用会更顺畅。有问题可以找我,微信 yanghu-dev,服务页面:yang1002378395-cmyk.github.io/openclaw-in…