解决 Claude Code 报错 API Error: 400 Model only support text input:TaoToken 统一 Key 通道配置与验证

📅 发布时间:2026/9/28 4:14:19
解决 Claude Code 报错 API Error: 400 Model only support text input:TaoToken 统一 Key 通道配置与验证
1. 这个 400 报错到底在说什么如果你在用 Claude Code 跑任务某天突然蹦出一行红字API Error: 400 Model only support text input然后整个会话卡死resume 也进不去之前的上下文全断——别慌这不是你的 Key 失效也不是网络问题而是请求体里混进了模型不接受的输入类型。Claude Code 的会话记录存在~/.claude/projects/项目编码/*.jsonl里。当你用 Read 工具读过 PNG 截图、UI 设计稿、报错截图这类图片时消息流里会留下imageblock。原本你用的是支持视觉输入的模型一切正常可一旦你切到只吃文本的模型比如某些 glm 系列、纯文本推理模型resume 旧会话时这些历史 image block 会被原样塞进请求体服务端一看这模型只支持 text input你塞图片干嘛直接 400 拒绝。关键点在于报错发生在 resume 阶段而不是你当次操作。所以很多人第一反应是「我这次没传图啊」其实图是几天前留下的藏在 jsonl 里。这篇就围绕这个场景给你一套可复制的排查 规避方案用 TaoToken 统一 Key 通道把模型调用收敛到一个入口配好settings.json和config.toml再用一次最小请求验证把「模型能力」和「会话内容」对齐从根上绕开这个 400。适合谁看正在用 Claude Code 做长期编码、频繁 resume 会话、又会在多个模型之间切换的开发者。如果你只是偶尔问一句就关可能碰不到但只要你有跨天任务、有截图习惯这坑迟早踩。2. 先搞懂请求体里的 image block 从哪来要解决问题得先看清问题长什么样。Claude Code 的消息结构大致是这样每条消息有role和contentcontent是个数组里面可以是textblock也可以是imageblock。当你让 Claude Code 读一张图它会调用 Read 工具把图片编码后作为imageblock 追加进对话历史。我试过用 Read 读一张架构图然后切模型 resume立刻复现。你可以自己验证打开会话文件看一眼。# 找到当前项目的会话目录 ls ~/.claude/projects/ # 进去看某个 jsonl搜 image 关键字 grep -l image ~/.claude/projects/项目编码/*.jsonl如果 grep 命中了说明这个会话里确实有图片内容。这时候你切到纯文本模型resume 必炸。那为什么换个模型就炸因为不同模型对输入模态的支持不一样。支持视觉的模型能吞下imageblock纯文本模型只认text。服务端在请求入口做校验发现模态不匹配直接返回 400错误信息就是那句Model only support text input。这里有个容易误解的点不是 Claude Code 的 bug也不是模型坏了而是「历史内容」和「当前模型能力」之间的契约被打破了。你等于拿一份带图的简历去投一个只收纯文本的岗位HR 直接退回。解决思路有两条一是清理会话里的 image block二是把模型调用统一到一个可控通道让能力匹配这件事变得可预期。前者治标后者治本。下面重点讲后者顺带给你清理的兜底手段。3. TaoToken 统一 Key 通道把模型入口收拢TaoToken 在这里扮演的角色是一个统一的模型调用入口。你不用在 Claude Code 里为每个模型单独配一套 Key 和 endpoint而是通过一个统一 Key 走 API 通道把「用哪个模型」这件事集中管理。官网在 https://taotoken.net API 入口是 https://taotoken.net/api 。为什么这对 400 报错有帮助因为当你的调用入口统一后模型切换、能力对照、请求体检查都集中在一处排查时不用在多个配置之间来回跳。你可以清楚地知道「我现在这个会话用的是哪个模型、它支不支持图片」而不是切完模型一脸懵。具体操作上你需要拿到一个 API Key。进控制台创建https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentclaude_code_400_fix创建完 Key去 API Keys 页面管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentclaude_code_400_fix拿到 Key 之后别急着往 Claude Code 里塞。先想清楚你的模型策略如果你经常读图就固定用支持视觉的模型如果你就是要用纯文本模型那就要保证会话里没有 image block。统一通道的价值在于你可以在一个地方切换模型而不用改一堆环境变量。注意TaoToken 是模型调用通道不是编辑器替代品。Claude Code 本身还是你的编码工具TaoToken 负责把请求稳定地送到模型那边。如果你做的是长期编码、Agent 类任务建议了解一下 Coding Plan它更适合持续性的调用场景https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentclaude_code_400_fix4. 可复制配置settings.json 与 config.toml 骨架Claude Code 的配置分两块一块是settings.json管 Claude Code 自身的行为一块是config.toml管模型通道和参数。下面给你可直接复制的骨架把你的Key换成上一步创建的 Key。先看settings.json一般放在项目根目录或~/.claude/下{ model: claude-sonnet-4-20250514, env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_API_KEY: 你的Key }, permissions: { allow: [Read, Write, Bash] } }这里ANTHROPIC_BASE_URL指向 TaoToken 的 API 入口ANTHROPIC_API_KEY填你的统一 Key。model字段决定默认用哪个模型——如果你要读图这里必须选支持视觉的模型如果你确定只用纯文本那就选纯文本模型但记得别 resume 带图的旧会话。再看config.toml用于更细的通道参数[api] base_url https://taotoken.net/api api_key 你的Key timeout 120 [model] name claude-sonnet-4-20250514 max_tokens 8192 supports_vision true [retry] max_attempts 3 backoff_ms 500supports_vision这个字段是我建议你显式写上的它不一定会被程序读取但作为配置注释能提醒你当前模型的能力边界。当你切换模型时先改这里再改settings.json的model形成肌肉记忆。两个文件的关系settings.json是 Claude Code 读的config.toml是你自己维护的通道说明。实际生效以settings.json为准config.toml作为对照和文档。配完之后检查一下环境变量有没有冲突echo $ANTHROPIC_BASE_URL echo $ANTHROPIC_API_KEY如果 shell 里已经设了旧值会覆盖配置文件。建议清掉unset ANTHROPIC_BASE_URL unset ANTHROPIC_API_KEY5. 最小请求验证一次调用确认通道通了配置写完别直接 resume 旧会话——那可能又触发 400。先做一次最小请求确认通道本身是通的。用 curl 发一个纯文本请求curl -X POST https://taotoken.net/api/v1/messages \ -H Content-Type: application/json \ -H x-api-key: 你的Key \ -H anthropic-version: 2023-06-01 \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [ {role: user, content: reply with ok} ] }如果返回里有正常的文本内容说明 Key、endpoint、模型名三者都对。这一步排除了「Key 错、地址错、模型名错」这三类基础问题。接着验证「带图会不会被拒」。发一个带 image block 的请求看目标模型是否接受curl -X POST https://taotoken.net/api/v1/messages \ -H Content-Type: application/json \ -H x-api-key: 你的Key \ -H anthropic-version: 2023-06-01 \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [ {role: user, content: [ {type: text, text: what is this}, {type: image, source: {type: base64, media_type: image/png, data: base64}} ]} ] }如果这个模型支持视觉会正常返回如果返回 400 且提示Model only support text input说明你选的模型不吃图。这时候你就知道要么换模型要么清掉会话里的图。验证通过后回到 Claude Code 里跑一个全新会话别 resume 旧的确认能正常对话。全新会话没有历史 image block不会触发那个 400。6. 本篇常见错排查错误一改了配置但没生效。最常见的原因是环境变量覆盖。Claude Code 启动时会读 shell 环境如果ANTHROPIC_BASE_URL在 shell 里被设成旧值配置文件里的会被忽略。用env | grep ANTHROPIC查一遍有就 unset。错误二resume 旧会话仍然 400。这说明会话 jsonl 里的 image block 还在。配置只影响新请求的通道不会自动清理历史。你需要手动处理会话文件或者干脆开新会话。清理思路是找到含 image 的 jsonl把 image block 删掉或整条消息移除操作前先备份。错误三模型名写错。model字段必须和通道支持的模型名完全一致大小写、日期后缀都不能错。写错了可能返回 404 或 400错误信息不一定是Model only support text input但同样连不上。用第 5 节的最小请求先验证模型名。错误四把纯文本模型和带图会话混用。这是 400 的根因。解决办法是建立习惯切模型前先看会话里有没有图。你可以用 grep 快速检查grep -c image ~/.claude/projects/项目编码/会话.jsonl返回大于 0 就说明有图切纯文本模型前先处理。错误五以为换个 Key 就能解决。Key 只负责鉴权不负责模态匹配。400 是请求体内容的问题换 Key 没用。别在这上面浪费时间。错误六timeout 设太短导致误判。带图请求体积大如果timeout设成 10 秒可能还没传完就断了报错看起来像网络问题。建议至少 120 秒config.toml里已经给了参考值。7. 把模型能力和会话内容对齐回到最初那个 400。它的本质不是「通道坏了」而是「你给模型喂了它不认的东西」。TaoToken 统一 Key 通道解决的是「入口可控、切换可预期」但最终对齐模型能力和会话内容还是得靠你的操作习惯。给你三个实用建议。第一读图用支持视觉的模型纯文本任务用纯文本模型别混。第二切模型前先 grep 一下会话里有没有 image有就先清理或开新会话。第三把supports_vision写进你的config.toml每次切模型先改这个字段形成条件反射。如果你需要长期跑编码任务Coding Plan 那条通道更适合持续调用https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentclaude_code_400_fix想直接验证模型对话行为用模型对话入口https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentclaude_code_400_fix接入细节和参数说明看文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentclaude_code_400_fix最后说个我踩过的坑有次我以为是模型不支持图折腾半天换模型结果发现是会话文件里混进了一张很早之前的截图grep 一下就定位了。所以遇到这个 400先 grep再动配置顺序别反。