
最近我们在将 Claude Code 接入智谱(ZhiPu)Chat API 协议时,遇到了一个非常诡异的问题。当对话上下文超过模型的最大长度限制时,智谱 API 会返回如下错误:
// HTTP 400
{
"error": {
"type": "1261",
"message": "Prompt exceeds max length (request id: 202609010551316670846648268d9d6ZFTaku45)"
},
"type": "error"
}按照预期,Claude Code 在收到上下文超长错误时,应该触发自动压缩(Auto-Compact)机制来缩减历史消息。但在实际运行中,Claude Code 并没有执行任何压缩操作,而是直接将错误抛给了用户,导致长对话直接中断。
为了解决这个问题,我深入阅读了 Claude Code 的源码。经过排查,发现问题的根源在于 Claude Code 内部对“上下文超长”错误的判定逻辑极其严格。
在 errors.ts 文件的第 563-565 行,Claude Code 是这样判断是否需要触发自动压缩的:
error.message.toLowerCase().includes('prompt is too long')没错,仅仅是一行代码。它通过字符串匹配的方式,检查错误信息中是否包含 prompt is too long 这个特定的短语。
而智谱 API 返回的错误信息是 Prompt exceeds max length,虽然语义完全一致,但因为不包含 prompt is too long 这个子串,Claude Code 的压缩机制被完美地“骗”过了,直接跳过了自动压缩流程。
既然找到了症结,解决思路就非常清晰了:我们需要在请求到达 Claude Code 之前,将智谱 API 的错误信息“翻译”成 Claude Code 能听懂的格式。
为了避免直接修改 Claude Code 的源码(这不利于后续的升级和维护),我选择使用 Go 语言编写了一个轻量级的 API 代理。
这个 Go 代理的核心逻辑非常简单:
Prompt exceeds max length,则将其替换为 prompt is too long。// 伪代码示例,展示核心拦截逻辑
if response.StatusCode == http.StatusBadRequest {
var errResp map[string]interface{}
json.Unmarshal(body, &errResp)
if errObj, ok := errResp["error"].(map[string]interface{}); ok {
if msg, ok := errObj["message"].(string); ok {
if strings.Contains(strings.ToLower(msg), "prompt exceeds max length") {
// 修改错误信息,使其符合 Claude Code 的判定逻辑
errObj["message"] = "prompt is too long: " + msg
}
}
}
// 重新序列化并返回给 Claude Code
}原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。