news 2026/10/7 13:42:55

claude code接入纯文本大模型,API Error: 400 Model only support text input 彻底解决方案:把 settings 改到 TaoToken

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
claude code接入纯文本大模型,API Error: 400 Model only support text input 彻底解决方案:把 settings 改到 TaoToken

1. 报错现场:Read 一张 png 就 400,问题到底出在哪

如果你正在用 Claude Code 接一个纯文本大模型(比如 GLM 系列),大概率会遇到这个画面:模型说"让我目视检查一下生成的图片",然后调用 Read 去读layout_7classes.png,紧接着终端甩出一行红字:

API Error: 400 Model only support text input Request id: 02178...

这不是网络问题,也不是 Key 过期,更不是模型"抽风"。它的含义非常直白:你接入的这个模型只接受文本输入,而 Claude Code 的 harness 在 Read 图片时,把图片字节当成多模态内容打包发给了模型,模型直接拒绝。

很多人第一反应是去CLAUDE.md里写一句"当前模型不支持多模态,请不要上传图片"。我试过,没用。原因在于CLAUDE.md只是一段进入模型上下文的文字,靠模型"自觉"遵守。模型一旦决定调用 Read 读图片,这段提示就被绕过了。真正把图片字节发出去的是 Claude Code 本体(harness),它不读CLAUDE.md,只认工具调用。

所以正确的解法是在"工具调用真正执行之前"由本地代码硬性阻断,这就是PreToolUse钩子的职责。本文会带你从复现报错开始,一步步把settings.json改到 TaoToken 统一通道,再用PreToolUse钩子彻底堵住图片读取这条路。适合正在用 Claude Code + 纯文本模型做开发、被这个 400 反复打断的人。

先明确一个概念:Claude Code 的工具体系里,Read是读取文件的核心工具,PreToolUse是工具执行前的本地钩子,Bash/Edit/Write是另外几个常用工具。钩子由 Claude Code 本体在本地执行 shell 命令,和后端接的是 GLM 还是别的模型无关。只要钩子返回exit 2,这次工具调用就被阻断,stderr的内容会作为反馈发回给模型,引导它换一种方式。

理解了这一层,你就明白为什么"改 settings"才是根治手段,而不是在提示词里反复叮嘱。

2. 前置准备:把 Claude Code 的 Key 和 Base URL 统一到 TaoToken

在动钩子之前,先把接入通道理顺。Claude Code 通过环境变量读取ANTHROPIC_BASE_URL和ANTHROPIC_AUTH_TOKEN,如果你之前是直连某个厂商的 Ark 地址,模型能力(是否多模态)就由那个厂商决定。统一走 TaoToken 的好处是:一个 Key、一个 Base URL,模型切换和通道管理都在一处,排查 400 时变量更少。

TaoToken 的 API 地址是https://taotoken.net/api,官网在https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=。你需要先在控制台创建一个 API Key,然后把它写进 Claude Code 的配置。

Claude Code 的全局配置在~/.claude/settings.json,环境变量写在env字段里。下面是一份可直接复制的片段,把 Base URL 指向 TaoToken,Key 换成你自己的:

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "sk-你的TaoToken密钥", "ANTHROPIC_MODEL": "glm-4.6" }, "includeCoAuthoredBy": false, "permissions": { "allow": [], "deny": [] }, "effortLevel": "xhigh", "theme": "dark", "autoCompactEnabled": true }

这里三个字段要写全,也就是常说的"三件套":Base URL、Key、Model ID。ANTHROPIC_BASE_URL决定请求发到哪,ANTHROPIC_AUTH_TOKEN是身份凭证,ANTHROPIC_MODEL指定具体模型。Model ID 要和你账号里可用的模型一致,写错了会直接 404 或 400。

如果你用的是 Codex 那套配置,对应的是~/.codex/auth.json,结构不同但三件套逻辑一样:

{ "OPENAI_BASE_URL": "https://taotoken.net/api", "OPENAI_API_KEY": "sk-你的TaoToken密钥", "model": "glm-4.6" }

改完配置后,Claude Code 需要重启会话才会重新读取env。这一步别省,很多人改完发现没生效,就是因为旧会话还挂着老的环境变量。

注意:Key 不要提交到 Git,也不要写进项目级.claude/settings.json后推到公开仓库。全局配置放在用户目录下更安全。

通道理顺之后,我们再来处理图片拦截。因为即使 Base URL 换成了 TaoToken,只要你选的模型是纯文本的,Read 图片依然会触发同样的 400。通道解决的是"请求发到哪",钩子解决的是"什么请求不该发"。

3. 可复制配置:PreToolUse 钩子硬拦截图片读取

这一节是全文的核心。我们要做两件事:写一个拦截脚本,然后在settings.json里注册它。

先建目录和脚本文件。钩子脚本放在~/.claude/hooks/block_images.sh:

#!/usr/bin/env bash # PreToolUse hook:拦截对图片文件的 Read 调用。 # 原因:当前接入的大模型仅支持文本输入,读取图片会被当作多模态内容上传并触发 400 错误。 # 行为:匹配到图片扩展名时以 exit 2 阻断,stderr 作为反馈发回给模型,引导其改用文本方式。 input=$(cat) tool_name=$(printf '%s' "$input" | jq -r '.tool_name // empty' 2>/dev/null) [ "$tool_name" = "Read" ] || exit 0 file_path=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty' 2>/dev/null) [ -n "$file_path" ] || exit 0 # 取扩展名;无扩展名则放行 ext="${file_path##*.}" [ "$ext" = "$file_path" ] && exit 0 ext=$(printf '%s' "$ext" | tr '[:upper:]' '[:lower:]') case "$ext" in png|jpg|jpeg|gif|webp|bmp|tiff|tif|svg|ico|heic|heif|avif) printf '%s\n' "已阻断:当前大模型仅支持文本输入,禁止读取图片文件(.${ext})。请改用文本方式获取信息:例如用 .venv/bin/python 配合 PIL 读取图像尺寸/模式、用 cv2/numpy 输出像素统计,或请用户在编辑器中自行查看图像。" >&2 exit 2 ;; esac exit 0

几个关键点解释一下。Claude Code 通过 stdin 传入一段 JSON,形如{"tool_name": "Read", "tool_input": {"file_path": "/path/to/file.png"}}。脚本用jq解析出tool_name和file_path,缺失时安全放行。扩展名用${file_path##*.}取最后一段,如果和原路径相等说明没有扩展名,直接放行。大小写用tr统一转小写,这样.JPG、.Png也能命中。命中图片扩展名时exit 2,Claude Code 会阻断这次调用,并把stderr发回给模型。

脚本依赖jq,确认一下系统里有:

which jq && jq --version

然后把它注册到全局~/.claude/settings.json。在原有配置末尾追加hooks字段,完整结构如下:

{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "sk-你的TaoToken密钥", "ANTHROPIC_MODEL": "glm-4.6" }, "includeCoAuthoredBy": false, "permissions": { "allow": [], "deny": [] }, "effortLevel": "xhigh", "theme": "dark", "autoCompactEnabled": true, "hooks": { "PreToolUse": [ { "matcher": "Read", "hooks": [ { "type": "command", "command": "bash /home/你的用户名/.claude/hooks/block_images.sh" } ] } ] } }

matcher写"Read"是精确匹配 Read 工具,不会影响Bash、Edit、Write。command用bash <path>显式调用,不依赖脚本的可执行位,即使没chmod +x也能跑。放在全局 settings 而不是项目级,是因为"模型仅支持文本"是跨项目的全局约束。

如果你用的是 Cline MCP 或 CC Switch 这类工具管理配置,逻辑一样:找到它读取的 settings 文件,把hooks.PreToolUse加进去,三件套(Base URL、Key、Model ID)保持和 TaoToken 一致。CC Switch 切换配置时注意别把hooks字段覆盖掉。

4. 验证请求:模拟 stdin 测试钩子是否真的拦住了

配置写完不能直接信,得验证。钩子的输入是 stdin 的 JSON,我们可以手动喂给它,看退出码和输出。

先测最关键的场景——读 png 应该被阻断:

echo '{"tool_name":"Read","tool_input":{"file_path":"/tmp/test.png"}}' \ | bash ~/.claude/hooks/block_images.sh; echo "exit=$?"

预期输出是那段中文引导文案,并且exit=2。如果输出为空且exit=0,说明脚本没命中,检查jq是否安装、路径是否正确。

再测读普通代码文件应该放行:

echo '{"tool_name":"Read","tool_input":{"file_path":"/home/user/project/train.py"}}' \ | bash ~/.claude/hooks/block_images.sh; echo "exit=$?"

预期exit=0,无输出。再测大写扩展名和非 Read 工具:

echo '{"tool_name":"Read","tool_input":{"file_path":"/tmp/IMG_1234.JPG"}}' \ | bash ~/.claude/hooks/block_images.sh; echo "exit=$?" echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' \ | bash ~/.claude/hooks/block_images.sh; echo "exit=$?"

第一个应该exit=2,第二个应该exit=0。四种场景全过,说明脚本逻辑没问题。

接着校验settings.json的合法性,避免 JSON 语法错误导致整个配置失效:

jq -e '.hooks.PreToolUse[0].matcher' ~/.claude/settings.json

输出应该是"Read"。如果报parse error,说明 JSON 有语法问题,多半是逗号或括号写错了。

最后做端到端验证。重启 Claude Code 会话,然后给它一个明确指令:

我在测试图片拦截钩子。请直接用 Read 工具读取 dataset/image.png,不要用任何替代方式,我要看这个工具调用本身的结果。

如果钩子生效,你会看到工具调用被阻断,模型收到"已阻断:当前大模型仅支持文本输入"的反馈,而不是抛出 400。模型通常会转而用 Python + PIL 去读图像尺寸,或者请你自行查看。

注意:钩子在会话启动时加载。修改settings.json或新增钩子后,当前会话不会立即生效,必须退出并重新打开 Claude Code。这一步是踩坑高发区。

5. 常见报错排查:401、local proxy failed、reading choices 逐个拆

配置过程中会遇到各种报错,这一节按真实错误对照排查。

401 Unauthorized:Key 不对或没带上。检查ANTHROPIC_AUTH_TOKEN是否以sk-开头、有没有多余空格、是不是复制时漏了字符。如果走 TaoToken,确认 Key 是在控制台新建的、状态正常。401 和 400 的区别要分清:401 是身份问题,400 是请求内容问题,本文的Model only support text input属于后者。

local proxy failed / connection refused:Base URL 写错或本地网络到不了。确认ANTHROPIC_BASE_URL是https://taotoken.net/api,注意结尾不要多加/v1或斜杠,除非文档明确要求。用 curl 直接探一下:

curl -s -o /dev/null -w "%{http_code}" https://taotoken.net/api

能返回状态码说明网络通。

Error reading choices / 响应解析失败:多半是 Model ID 写错,或者模型返回了非预期格式。检查ANTHROPIC_MODEL是否和账号可用模型一致。有些纯文本模型对多模态字段敏感,即使你没主动发图片,harness 在某些工具调用里也可能带上额外字段,这时钩子拦截就更必要。

OAuth 相关报错:如果你之前用 OAuth 登录过官方账号,环境变量和 OAuth 凭证可能冲突。清理掉旧的 OAuth 缓存,确保走的是ANTHROPIC_AUTH_TOKEN这条路径。

钩子不生效:按顺序查——settings.json里hooks.PreToolUse是否存在且 JSON 合法;matcher是否为"Read";脚本路径是否绝对路径且文件存在;jq是否安装;会话是否重启过。用第 4 节的模拟命令单独测脚本,能快速定位是脚本问题还是注册问题。

PDF 仍然触发 400:这是钩子的已知边界。Read 读 PDF 时,harness 会把每页渲染成图片发给模型,同样触发 400。解决办法是在脚本的case分支里加上pdf,引导模型改用pdftotext:

pdftotext input.pdf - # 输出到 stdout pdftotext input.pdf out.txt # 输出到文件后用 Read 读 .txt

用户直接拖拽/粘贴图片:这种情况不经过工具调用,钩子拦不住,图片会直接发给模型。这需要用户自己避免,钩子只能覆盖 Read 这条路径。

把上面这些对照一遍,基本能覆盖 90% 的接入问题。剩下的多半是配置拼写错误,用jq校验一遍就能发现。

6. 长期编码与 Agent 场景:把通道和拦截固化下来

如果你打算长期用 Claude Code 做编码或跑 Agent,建议把两件事固化:通道统一走 TaoToken,拦截统一走PreToolUse钩子。

通道方面,TaoToken 的 Coding Plan 适合长期编码场景,一个 Key 管理多个模型,切换时不用改一堆环境变量。API Keys 页面用来创建和轮换密钥,接入文档里有各客户端的配置示例。需要验证某个模型是否可用时,可以直接在模型对话里发一条测试请求,确认返回正常再写进 settings。

拦截方面,把block_images.sh纳入你的 dotfiles 管理,换机器时直接同步。脚本里的扩展名清单可以按需增删,比如你经常处理 PDF,就把pdf加进case分支。回退也简单:删掉settings.json里的hooks字段,或者删掉脚本文件,Read 的日常读取功能不受影响。

CLAUDE.md里的软提示可以保留,作为对模型行为的备份提醒无害,但防线以钩子为准。两者是"软"和"硬"的关系,别指望软提示能兜住。

最后给一个实用技巧:把第 4 节的模拟测试命令存成一个test_hook.sh,每次改完脚本跑一遍,四种场景全绿再重启会话。这样能避免"改了脚本但没生效"的反复折腾。钩子这东西,验证一次比读十遍文档都管用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 13:42:51

AIGC单图写真全流程:从InstantID到ComfyUI部署实战

简介&#xff1a;面向AIGC图像生成开发者的项目分享包&#xff0c;基于深度学习与生成对抗网络实现单张图片快速定制逼真照片。该方案以生成器与判别器的对抗博弈为核心&#xff0c;结合卷积神经网络理解输入图片内容&#xff0c;从而保证输出风格与主题匹配&#xff1b;资源涵…

作者头像 李华
网站建设 2026/10/7 13:42:34

端侧Agent工程化实战:编排适配、可观测性与资源调度

1. 端侧 Agent 工程化到底在解决什么问题1.1 从“能跑”到“能扛”的分水岭端侧 Agent 的工程化&#xff0c;说白了就是把一个在开发机上跑得挺欢的 demo&#xff0c;变成一个能在用户设备上稳定运行、出了问题能查、版本能迭代、资源不爆炸的正式产品。这个跨越比很多人想象的…

作者头像 李华
网站建设 2026/10/7 13:41:23

医学图像分割实战:乳腺肿瘤细胞核2类数据集处理与训练指南

简介&#xff1a;面向医学图像分割学习者的乳腺肿瘤细胞核分割数据集&#xff0c;覆盖256256与10001000两种分辨率&#xff0c;PNG原图与PNG掩膜一一对应&#xff0c;mask采用0/1阈值模板&#xff0c;类别信息可在classes文本中查看。资源内含训练集与测试集&#xff0c;训练集…

作者头像 李华
网站建设 2026/10/7 13:40:39

生产级Coding Agent调优实战:从提示词到RAG与工具闭环

先说一个我自己的真实场景。三个月前&#xff0c;我把一个内部工具链接入Coding Agent&#xff0c;本地demo跑得飞起&#xff0c;AI三秒生成一个模块&#xff0c;同事围观直呼“以后不用写代码了”。可一旦放进正式业务仓库&#xff0c;问题像开闸一样涌出来&#xff1a;模型上…

作者头像 李华
网站建设 2026/10/7 13:40:33

LCC补偿网络:无线充电效率跃升90%+的核心原理与工程实践

1. 什么是LCC补偿网络&#xff1f;它凭什么让无线充电效率从75%跃升到90%以上&#xff1f; “无线充电效率从75%到90%”——这个数字变化看起来只差15个百分点&#xff0c;但背后是整车热管理压力降低40%、车载散热系统体积缩减30%、单次充电时间缩短近8分钟的实质性突破。我做…

作者头像 李华
网站建设 2026/10/7 13:39:39

SAP PS项目结算实战:从CJ20N到CJ88的完整操作指南

1. 先把账算明白&#xff1a;CJ20N看到的项目成本到底意味着什么 1.1 项目结算到底是什么&#xff0c;为什么不能等到月底再拍脑袋 SAP PS的项目结算&#xff0c;从表面上看就是把CJ20N项目构造器里归集的成本&#xff0c;通过CJ88批量结算程序&#xff0c;按事先定义好的规则…

作者头像 李华