DeepSeek API 401 排查:密钥与请求头配置检查清单

调用 DeepSeek API 返回 401,第一反应往往是「密钥过期了」。但按排障顺序看,401 更常见的原因是:请求在进入服务端鉴权逻辑时,携带的凭据已经不是你以为的那个值了——被截断、被引号包住、没被注入、被代理覆盖或丢弃。

先说明事实边界:本文没有可依据的 DeepSeek 官方鉴权文档,因此不给出具体的头字段名、endpoint 路径、鉴权方案前缀、错误体结构和 SDK 参数名。下面所有方法只用于把 401 收敛到「密钥值 / 注入方式 / 请求头构造 / 中间代理」这四类原因之一,具体字段仍需回到官方文档与官方 SDK 实现核对。

先确认 401 代表什么,别在权限上浪费时间

HTTP 语义中,401 表示请求缺少有效的认证凭据,响应通常带 WWW-Authenticate 头说明期望的认证方案;403 是凭据已被识别但无权访问;400 / 404 往往在网关层就被返回,与鉴权无关。

对 LLM API 而言,鉴权中间件通常先于业务逻辑执行。这意味着只要凭据不合法,请求会在模型校验、路径校验之前就被拒。一个可用的判断是:401 几乎总指向「请求怎么构造的」,而不是「模型或配额」。

第一步:把 SDK 剥离,用最小请求复现

排查不要从读 SDK 源码开始,先从「不依赖 SDK 能否打通」开始。

# 下方所有尖括号占位符请按官方文档替换,不要照抄
curl -i -X POST "" \
  -H ": " \
  -H "Content-Type: application/json" \
  -d ''

这里刻意不写死 Authorization: Bearer ...。Bearer 只是 HTTP 中常见的一种认证方案,是否适用、前缀写法如何、大小写是否敏感,都要以官方文档为准。

拿到结果后按二分法判断:

  • curl 通、SDK 不通 → 问题在 SDK 配置或环境注入;
  • 两者都不通 → 问题在密钥值本身或凭据已被吊销;
  • 直连通、走代理不通 → 问题在代理或网关这一层。

密钥字符串本身:先做指纹,而不是打印全文

从控制台复制密钥是最容易出问题的一步,常见形态包括:

  • 首尾带入空白、换行、零宽字符或 BOM;
  • 复制时被引号包住,请求头里变成 Bearer "",引号成为凭据的一部分;
  • 页面显示时做了截断,实际只复制了前半段;
  • 从文档或聊天窗口复制带入全角字符、智能引号。

不要靠肉眼比对。用长度加前缀做指纹校验,日志里也只记录指纹:

printf '%s' "$API_KEY" | wc -c
printf '%s' "$API_KEY" | head -c 6

注意 wc -c 统计的是字节数,密钥含非 ASCII 字符时字节数会大于字符数,这本身就是一种异常信号。

环境变量是否真的注入,往往比密钥对不对更常见

  • shell 中 export VAR=x 与单命令行前缀 VAR=x cmd 的作用域不同,后者不影响其他进程;
  • .env 文件不会被自动加载,需要 dotenv 或编排工具的 env_file 显式声明;
  • 容器场景中,构建期参数不会自动变成运行期环境变量,两者是不同机制;
  • CI 中 secret 有作用域,不同 job、不同环境(预发与生产)取到的值可能不同;
  • systemd、supervisor 等进程管理器默认不继承交互式 shell 的环境。

验证方式是在应用进程内读取该变量并输出长度与前缀,而不是依赖「我明明设置过」。

Authorization 头:注意「名字」和「值」的规则并不一样

HTTP 头字段名大小写不敏感,authorizationAuthorization 等价;但字段值里的认证方案前缀、拼接方式与空格是有意义的,写错大小写或漏掉分隔空格,可能被直接判定为无效凭据。

工程上更常踩的坑是同名头被叠加或覆盖:框架默认注入的头、业务代码手动加的头、代理追加的头,最终只有一个(或拼在一起)到达服务端。自定义 base_url 后 SDK 仍把凭据发往旧地址、进程中存在多个客户端实例其中一个用了默认配置,也会产生「同一份代码有时通有时不通」的现象。

代理与网关:最容易被跳过的一层

反向代理、API 网关、企业出网代理、服务网格都可能改写请求头。典型情况是:代理自身携带一个用于内部鉴权的凭据,覆盖或追加到你的头上;或者代理只转发白名单头,你的鉴权头因拼写不在名单内被丢弃,服务端看到的是一个无凭据请求,于是返回 401。

定位方法是在代理日志中查看转发后的请求头(脱敏),并对比「直连」与「走代理」两条路径的响应差异。这一步不做,前面所有检查都可能是在错误的方向上消耗时间。

把手动排查固化成可持续的检查

  • 启动时发一次轻量预检请求,失败即快速失败,不要等第一个业务请求才暴露配置问题;
  • 日志只记录密钥指纹(长度加前后若干位),避免凭据进入日志系统;
  • 不同环境使用不同凭据,避免跨环境串用造成「某个环境总是 401」;
  • 在 CI 中保留一个调用真实接口的冒烟步骤,环境变量漏注入会立刻失败。

哪些结论本文不给出

由于缺少官方鉴权资料,本文不给出 DeepSeek 的具体鉴权头名称、请求地址、凭据格式、错误响应结构、SDK 配置项与版本行为。这些必须以官方文档和官方 SDK 实际实现为准。在核对之前,本文的方法只解决一件事:把 401 稳定地归因到密钥值、注入方式、请求头构造或中间代理这四类之一,缩小范围后再去查对应细节。